diff options
author | Wohlstand <admin@wohlnet.ru> | 2024-08-22 11:26:10 +0300 |
---|---|---|
committer | Wohlstand <admin@wohlnet.ru> | 2024-08-22 11:26:10 +0300 |
commit | c68dc6970d5b4abab13e138ac977f7212ef32e4a (patch) | |
tree | 4934c43e7329fc64a6b656a42af5efbfbdba6371 /utils | |
parent | 23dc374917acd0d7100c6e9db7ae5333338cee28 (diff) | |
download | libADLMIDI-c68dc6970d5b4abab13e138ac977f7212ef32e4a.tar.gz libADLMIDI-c68dc6970d5b4abab13e138ac977f7212ef32e4a.tar.bz2 libADLMIDI-c68dc6970d5b4abab13e138ac977f7212ef32e4a.zip |
WinMM: Use the Float32 for WaveOut
Diffstat (limited to 'utils')
-rw-r--r-- | utils/winmm_drv/src/MidiSynth.cpp | 53 | ||||
-rw-r--r-- | utils/winmm_drv/src/MidiSynth.h | 5 |
2 files changed, 43 insertions, 15 deletions
diff --git a/utils/winmm_drv/src/MidiSynth.cpp b/utils/winmm_drv/src/MidiSynth.cpp index b1baa13..a03ee42 100644 --- a/utils/winmm_drv/src/MidiSynth.cpp +++ b/utils/winmm_drv/src/MidiSynth.cpp @@ -23,6 +23,8 @@ namespace OPL3Emu static MidiSynth &midiSynth = MidiSynth::getInstance(); +static const unsigned int s_audioChannels = 2; + static class MidiStream { private: @@ -133,10 +135,13 @@ private: bool stopProcessing; public: - int Init(Bit16s *buffer, unsigned int bufferSize, unsigned int chunkSize, bool useRingBuffer, unsigned int sampleRate, UINT outDevice) + int Init(float *buffer, unsigned int bufferSize, + unsigned int chunkSize, bool useRingBuffer, + unsigned int sampleRate, UINT outDevice) { DWORD callbackType = CALLBACK_NULL; DWORD_PTR callback = (DWORD_PTR)NULL; + hEvent = NULL; if(!useRingBuffer) { @@ -145,10 +150,18 @@ public: callbackType = CALLBACK_EVENT; } - PCMWAVEFORMAT wFormat = {WAVE_FORMAT_PCM, 2, sampleRate, sampleRate * 4, 4, 16}; + PCMWAVEFORMAT wFormat = + { + WAVE_FORMAT_IEEE_FLOAT, s_audioChannels, + sampleRate, + (DWORD)(sampleRate * sizeof(float) * s_audioChannels), + s_audioChannels * sizeof(float), + 8 * sizeof(float) + }; // Open waveout device - int wResult = waveOutOpen(&hWaveOut, outDevice, (LPWAVEFORMATEX)&wFormat, callback, (DWORD_PTR)&midiSynth, callbackType); + int wResult = waveOutOpen(&hWaveOut, outDevice, (LPWAVEFORMATEX)&wFormat, + callback, (DWORD_PTR)&midiSynth, callbackType); if(wResult != MMSYSERR_NOERROR) { MessageBoxW(NULL, L"Failed to open waveform output device", L"libADLMIDI", MB_OK | MB_ICONEXCLAMATION); @@ -158,13 +171,15 @@ public: // Prepare headers chunks = useRingBuffer ? 1 : bufferSize / chunkSize; WaveHdr = new WAVEHDR[chunks]; + LPSTR chunkStart = (LPSTR)buffer; - DWORD chunkBytes = 4 * chunkSize; + DWORD chunkBytes = s_audioChannels * sizeof(float) * chunkSize; + for(UINT i = 0; i < chunks; i++) { if(useRingBuffer) { - WaveHdr[i].dwBufferLength = 4 * bufferSize; + WaveHdr[i].dwBufferLength = s_audioChannels * sizeof(float) * bufferSize; WaveHdr[i].lpData = chunkStart; WaveHdr[i].dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP; WaveHdr[i].dwLoops = -1L; @@ -237,7 +252,7 @@ public: return 4; } } - _beginthread(RenderingThread, 16384, this); + _beginthread(RenderingThread, 16384 * 2, this); return 0; } @@ -288,6 +303,7 @@ public: std::cout << "OPL3: GetPos() wrap: " << delta << "\n"; ++getPosWraps; } + prevPlayPos = mmTime.u.sample; return mmTime.u.sample + getPosWraps * (1 << 27); } @@ -314,7 +330,8 @@ void WaveOutWin32::RenderingThread(void *) if(s_waveOut.WaveHdr[i].dwFlags & WHDR_DONE) { allBuffersRendered = false; - midiSynth.Render((Bit16s *)s_waveOut.WaveHdr[i].lpData, s_waveOut.WaveHdr[i].dwBufferLength / 4); + midiSynth.Render((float *)s_waveOut.WaveHdr[i].lpData, + s_waveOut.WaveHdr[i].dwBufferLength / (sizeof(float) * 2)); if(waveOutWrite(s_waveOut.hWaveOut, &s_waveOut.WaveHdr[i], sizeof(WAVEHDR)) != MMSYSERR_NOERROR) MessageBoxW(NULL, L"Failed to write block to device", L"libADLMIDI", MB_OK | MB_ICONEXCLAMATION); @@ -373,12 +390,12 @@ void MidiSynth::RenderAvailableSpace() return; } } - midiSynth.Render(buffer + 2 * framesRendered, framesToRender); + midiSynth.Render(buffer + sizeof(float) * framesRendered, framesToRender); } // Renders totalFrames frames starting from bufpos // The number of frames rendered is added to the global counter framesRendered -void MidiSynth::Render(Bit16s *bufpos, DWORD totalFrames) +void MidiSynth::Render(float *bufpos, DWORD totalFrames) { while(totalFrames > 0) { @@ -444,10 +461,12 @@ void MidiSynth::Render(Bit16s *bufpos, DWORD totalFrames) } synthEvent.Wait(); - adl_generate(synth, framesToRender * 2, bufpos); + adl_generateFormat(synth, framesToRender * s_audioChannels, + (ADL_UInt8*)bufpos, (ADL_UInt8*)bufpos + synthAudioFormat.containerSize, + &synthAudioFormat); synthEvent.Release(); framesRendered += framesToRender; - bufpos += 2 * framesToRender; // each frame consists of two samples for both the Left and Right channels + bufpos += s_audioChannels * framesToRender; // each frame consists of two samples for both the Left and Right channels totalFrames -= framesToRender; } @@ -494,6 +513,7 @@ void MidiSynth::LoadSettings() chunkSize = MillisToFrames(10); midiLatency = MillisToFrames(0); useRingBuffer = false; + if(!useRingBuffer) { // Number of chunks should be ceil(bufferSize / chunkSize) @@ -506,7 +526,7 @@ void MidiSynth::LoadSettings() int MidiSynth::Init() { LoadSettings(); - buffer = new Bit16s[2 * bufferSize]; // each frame consists of two samples for both the Left and Right channels + buffer = new float[s_audioChannels * bufferSize]; // each frame consists of two samples for both the Left and Right channels // Init synth if(synthEvent.Init()) @@ -519,6 +539,10 @@ int MidiSynth::Init() return 1; } + synthAudioFormat.type = ADLMIDI_SampleType_F32; + synthAudioFormat.sampleOffset = s_audioChannels * sizeof(float); + synthAudioFormat.containerSize = sizeof(float); + m_setupInit = false; LoadSynthSetup(); @@ -530,7 +554,10 @@ int MidiSynth::Init() m_setupCurrent.outputDevice = m_setup.outputDevice; // Start playing stream - adl_generate(synth, bufferSize * 2, buffer); + adl_generateFormat(synth, bufferSize * s_audioChannels, + (ADL_UInt8*)buffer, + (ADL_UInt8*)buffer + synthAudioFormat.containerSize, + &synthAudioFormat); framesRendered = 0; wResult = s_waveOut.Start(); diff --git a/utils/winmm_drv/src/MidiSynth.h b/utils/winmm_drv/src/MidiSynth.h index bf2da02..a590a77 100644 --- a/utils/winmm_drv/src/MidiSynth.h +++ b/utils/winmm_drv/src/MidiSynth.h @@ -53,10 +53,11 @@ private: Bit8u reverbTime; Bit8u reverbLevel; - Bit16s *buffer; + float *buffer; DWORD framesRendered; ADL_MIDIPlayer *synth; + ADLMIDI_AudioFormat synthAudioFormat; bool m_setupInit; DriverSettings m_setup; @@ -76,7 +77,7 @@ public: void ResetSynth(); void PanicSynth(); void RenderAvailableSpace(); - void Render(Bit16s *bufpos, DWORD totalFrames); + void Render(float *bufpos, DWORD totalFrames); void CheckForSignals(); void PushMIDI(DWORD msg); void PlaySysex(Bit8u *bufpos, DWORD len); |