From 10af8647675e20cabd6148a7b815089cd88dd801 Mon Sep 17 00:00:00 2001 From: oz Date: Mon, 25 Jan 2021 17:46:50 +0300 Subject: [PATCH] WaveMix v2. --- Doc/FuncStats.xlsx | Bin 39327 -> 39324 bytes SpaceCadetPinball/WaveMix.cpp | 328 ++++++++++++++++++++++++++++++++-- SpaceCadetPinball/WaveMix.h | 71 ++++++-- 3 files changed, 373 insertions(+), 26 deletions(-) diff --git a/Doc/FuncStats.xlsx b/Doc/FuncStats.xlsx index 032240bc0f849e3bc6c51434ef7816ee4a1f705d..880365d9a6a3fe2a3337cbd35b1bfeadd8bac1ca 100644 GIT binary patch delta 31229 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 delta 31202 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 diff --git a/SpaceCadetPinball/WaveMix.cpp b/SpaceCadetPinball/WaveMix.cpp index 37cefeb..2c3f53c 100644 --- a/SpaceCadetPinball/WaveMix.cpp +++ b/SpaceCadetPinball/WaveMix.cpp @@ -7,12 +7,19 @@ CHANNELNODE WaveMix::channel_nodes[MAXQUEUEDWAVES]; CHANNELNODE* WaveMix::free_channel_nodes; char WaveMix::volume_table[256 * 11]; int WaveMix::debug_flag; -int WaveMix::cmixit_ptr; +void (*WaveMix::cmixit_ptr)(unsigned __int8* lpDest, unsigned __int8** rgWaveSrc, volume_struct* volume, int iNumWaves, + unsigned __int16 length); HMODULE WaveMix::HModule; PCMWAVEFORMAT WaveMix::gpFormat = {{1u, 1u, 11025u, 11025u, 1u}, 8u}; char WaveMix::string_buffer[256] = "WaveMix V 2.3 by Angel M. Diaz, Jr. (c) Microsoft 1993-1995"; -GLOBALS* WaveMix::Globals; +GLOBALS *WaveMix::Globals, *WaveMix::GlobalsActive; int WaveMix::ShowDebugDialogs; +PLAYQUEUE WaveMix::play_queue; +CHANNELNODE* WaveMix::play_channel_array[MAXCHANNELS]; +XWAVEHDR* WaveMix::block_array1[10]; +XWAVEHDR* WaveMix::block_array2[10]; +unsigned char* WaveMix::play_data[MAXCHANNELS]; +volume_struct WaveMix::play_volume[MAXCHANNELS]; HANDLE WaveMix::Init() { @@ -60,8 +67,8 @@ HANDLE WaveMix::ConfigureInit(MIXCONFIG* lpConfig) globals->CmixPtr = cmixit_ptr; globals->wMagic2 = 21554; globals->wMagic1 = 21554; - globals->unknown102 = 0; - globals->unknown5 = 0; + globals->WaveBlockArray = nullptr; + globals->SettingsDialogActiveFlag = 0; globals->unknown44 = 655370; memset(globals->aChannel, 0xFFu, sizeof globals->aChannel); memmove(&globals->PCM, &gpFormat, 0x10u); @@ -189,7 +196,7 @@ int WaveMix::Startup(HMODULE hModule) return 0; InitVolumeTable(); debug_flag = GetPrivateProfileIntA("general", "debug", 0, FileName); - cmixit_ptr = (int)cmixit; + cmixit_ptr = cmixit; HModule = hModule; WndClass.hCursor = LoadCursorA(nullptr, IDC_ARROW); @@ -344,7 +351,7 @@ int WaveMix::ReadRegistryForAppSpecificConfigs(MIXCONFIG* lpConfig) if ((dwFlags & 2) == 0) lpConfig->wSamplingRate = ReadRegistryInt(phkResult, "SamplesPerSec", 11); if ((dwFlags & 4) == 0) - lpConfig->WaveBlocks = static_cast(ReadRegistryInt(phkResult, "WaveBlocks", 3)); + lpConfig->WaveBlockCount = static_cast(ReadRegistryInt(phkResult, "WaveBlocks", 3)); if ((dwFlags & 8) == 0) lpConfig->WaveBlockLen = static_cast(ReadRegistryInt(phkResult, "WaveBlockLen", 0)); lpConfig->CmixPtrDefaultFlag = 1; @@ -360,7 +367,7 @@ int WaveMix::ReadRegistryForAppSpecificConfigs(MIXCONFIG* lpConfig) lpConfig->ShowDebugDialogs = static_cast(ReadRegistryInt(phkResult, "ShowDebugDialogs", 0)); if ((dwFlags & 0x200) == 0) { - int defaultPauseBlocks = DefaultPauseBlocks(static_cast(lpConfig->WaveBlocks)); + int defaultPauseBlocks = DefaultPauseBlocks(static_cast(lpConfig->WaveBlockCount)); lpConfig->PauseBlocks = static_cast(ReadRegistryInt(phkResult, "PauseBlocks", defaultPauseBlocks)); } lpConfig->dwFlags = 1023; @@ -395,7 +402,7 @@ int WaveMix::DefaultGoodWavePos(unsigned uDeviceID) } else { - result = (LOBYTE(pwoc.dwSupport) >> 5) & 1; + result = LOBYTE(pwoc.dwSupport) >> 5 & 1; } return result; } @@ -414,15 +421,72 @@ int WaveMix::DefaultPauseBlocks(int waveBlocks) int WaveMix::Configure(GLOBALS* hMixSession, HWND hWndParent, MIXCONFIG* lpConfig, int* flag1Ptr, int saveConfigFlag) { + MIXCONFIG mixConfigLocal; + + auto hMixSession2 = hMixSession; + auto mixConfig = lpConfig; + auto hMixSession3 = hMixSession; + auto flag1Ptr_2 = flag1Ptr; + auto someFlag1 = 0; + auto globals1 = SessionToGlobalDataPtr(hMixSession); + Globals = globals1; + if (!globals1) + return 5; + if (globals1->fActive) + return 4; + if (globals1->SettingsDialogActiveFlag) + return 12; + FlushChannel(hMixSession, -1, 1u); + + if (!mixConfig) + { + mixConfigLocal.wSize = 30; + mixConfigLocal.dwFlags = 1023; + GetConfig(static_cast(hMixSession), &mixConfigLocal); + } + return 1; } +int WaveMix::GetConfig(HANDLE hMixSession, MIXCONFIG* lpConfig) +{ + GLOBALS* globals = SessionToGlobalDataPtr(static_cast(hMixSession)); + Globals = globals; + if (!globals) + return 5; + if (!lpConfig) + return 11; + + DWORD dwFlags = lpConfig->dwFlags; + if ((dwFlags & 1) != 0) + lpConfig->wChannels = globals->PCM.wf.nChannels; + if ((dwFlags & 2) != 0) + lpConfig->wSamplingRate = 11 * (globals->PCM.wf.nSamplesPerSec / 0x2B11); + if ((dwFlags & 4) != 0) + lpConfig->WaveBlockCount = globals->WaveBlockCount; + if ((dwFlags & 8) != 0) + lpConfig->WaveBlockLen = globals->WaveBlockLen; + if ((dwFlags & 0x10) != 0) + lpConfig->CmixPtrDefaultFlag = globals->CmixPtr == cmixit; + if ((dwFlags & 0x20) != 0) + lpConfig->ResetMixDefaultFlag = globals->pfnRemix == ResetRemix; + if ((dwFlags & 0x40) != 0) + lpConfig->GoodWavePos = globals->fGoodGetPos; + if ((dwFlags & 0x80u) != 0) + lpConfig->wDeviceID = globals->wDeviceID; + if ((dwFlags & 0x100) != 0) + lpConfig->ShowDebugDialogs = ShowDebugDialogs != 0; + if ((dwFlags & 0x200) != 0) + lpConfig->PauseBlocks = globals->PauseBlocks; + return 0; +} + unsigned WaveMix::MyWaveOutGetPosition(HWAVEOUT hwo, int fGoodGetPos) { mmtime_tag pmmt{}; if (!fGoodGetPos) - return ((timeGetTime() - Globals->dwBaseTime) * Globals->PCM.wf.nAvgBytesPerSec / 0x3E8) & 0xFFFFFFF8; + return (timeGetTime() - Globals->dwBaseTime) * Globals->PCM.wf.nAvgBytesPerSec / 0x3E8 & 0xFFFFFFF8; pmmt.wType = 4; waveOutGetPosition(hwo, &pmmt, 0xCu); return Globals->pfnSampleAdjust(pmmt.u.ms, Globals->dwWaveOutPos); @@ -437,9 +501,251 @@ void WaveMix::FreeChannelNode(CHANNELNODE* channel) } } -short WaveMix::cmixit(BYTE* a1, char* a2, char* a3, int a4, unsigned short a5) +int WaveMix::ResetRemix(DWORD dwRemixSamplePos, CHANNELNODE* channel) +{ + Globals->dwCurrentSample = dwRemixSamplePos; + DestroyPlayQueue(); + SwapWaveBlocks(); + + while (true) + { + auto block = GetWaveBlock(); + if (!block) + break; + if (!MixerPlay(block, 0)) + { + block->fAvailable = 1; + break; + } + AddToPlayingQueue(block); + } + + return 1; +} + +XWAVEHDR* WaveMix::RemoveFromPlayingQueue(XWAVEHDR* lpXWH) +{ + if (!play_queue.first) + return nullptr; + + if (lpXWH != play_queue.first) + { + XWAVEHDR* prev = play_queue.first; + XWAVEHDR* current = play_queue.first->QNext; + while (current) + { + if (current == lpXWH) + break; + prev = current; + current = current->QNext; + } + if (!current) + return nullptr; + + prev->QNext = current->QNext; + if (current == play_queue.last) + play_queue.last = prev; + } + else + { + play_queue.first = lpXWH->QNext; + if (!play_queue.first) + play_queue.last = nullptr; + } + + lpXWH->QNext = nullptr; + return lpXWH; +} + +void WaveMix::DestroyPlayQueue() +{ + while (play_queue.first) + { + play_queue.first->fAvailable = 1; + RemoveFromPlayingQueue(play_queue.first); + } +} + +void WaveMix::SwapWaveBlocks() +{ + if (Globals->WaveBlockArray == block_array1) + Globals->WaveBlockArray = block_array2; + else + Globals->WaveBlockArray = block_array1; +} + +XWAVEHDR* WaveMix::GetWaveBlock() +{ + int index = 0; + for (; index < Globals->WaveBlockCount; index++) + if (Globals->WaveBlockArray[index]->fAvailable) + break; + if (index >= Globals->WaveBlockCount) + return nullptr; + + XWAVEHDR* result = Globals->WaveBlockArray[index]; + result->fAvailable = 0; + result->wh.dwBufferLength = Globals->WaveBlockLen; + result->wh.lpData = reinterpret_cast(&result[1]); + result->g = GlobalsActive; + return result; +} + +int WaveMix::MixerPlay(XWAVEHDR* lpXWH, int fWriteBlocks) +{ + if (!lpXWH) + return 0; + + unsigned minStartPos = -1; + auto playChannelCount = 0; + auto channelPtr = Globals->aChannel; + for (auto channelIndex = 16; channelIndex; --channelIndex) + { + auto channel = *channelPtr; + if (channel != reinterpret_cast(-1) && channel) + { + do + { + if (channel->dwEndPos > Globals->dwCurrentSample) + break; + channel = channel->next; + } + while (channel); + if (channel) + { + if (channel->dwStartPos < minStartPos) + minStartPos = channel->dwStartPos; + play_channel_array[playChannelCount++] = channel; + } + } + ++channelPtr; + } + if (!playChannelCount) + { + if (fWriteBlocks) + lpXWH->fAvailable = 1; + return 0; + } + + auto currentSample = Globals->dwCurrentSample; + auto dataPtr = reinterpret_cast(lpXWH->wh.lpData); + auto waveBlockLen = Globals->WaveBlockLen; + while (waveBlockLen) + { + if (currentSample >= minStartPos) + { + auto waveCount = 0; + auto endBlockPosition = currentSample + waveBlockLen; + + for (auto channelIndex = 0; channelIndex < playChannelCount; ++channelIndex) + { + auto channel = play_channel_array[channelIndex]; + if (channel->dwStartPos <= currentSample) + { + if (channel->dwEndPos < endBlockPosition) + endBlockPosition = channel->dwEndPos; + auto dataOffset = currentSample - channel->dwStartPos; + if (channel->PlayParams.wLoops) + { + dataOffset %= channel->dwNumSamples; + auto endBlockPosition2 = currentSample + (channel->dwNumSamples - dataOffset); + if (endBlockPosition2 < endBlockPosition) + endBlockPosition = endBlockPosition2; + } + play_data[waveCount] = &channel->lpPos[dataOffset]; + play_volume[waveCount].L = channel->Volume.L; + play_volume[waveCount].R = channel->Volume.R; + waveCount++; + } + else if (channel->dwStartPos < endBlockPosition) + { + endBlockPosition = channel->dwStartPos; + } + } + + if (waveCount) + { + auto dataLength = endBlockPosition - currentSample; + Globals->CmixPtr(dataPtr, play_data, play_volume, waveCount, dataLength); + + dataPtr += dataLength; + waveBlockLen -= dataLength; + minStartPos = -1; + currentSample += dataLength; + + + auto playChPtr = play_channel_array; + for (auto channelIndex = 0; channelIndex < playChannelCount;) + { + while (*playChPtr) + { + if ((*playChPtr)->dwEndPos > currentSample) + break; + *playChPtr = (*playChPtr)->next; + } + if (*playChPtr) + { + if ((*playChPtr)->dwStartPos < minStartPos) + minStartPos = (*playChPtr)->dwStartPos; + ++channelIndex; + ++playChPtr; + } + else + { + playChannelCount--; + *playChPtr = play_channel_array[playChannelCount]; + if (!playChannelCount) + break; + } + } + } + } + else + { + auto length = waveBlockLen; + if (waveBlockLen + currentSample >= minStartPos) + length = minStartPos - currentSample; + memset(dataPtr, 0x80u, length); + dataPtr += length; + currentSample += length; + waveBlockLen -= length; + } + } + + lpXWH->dwWavePos = Globals->dwCurrentSample; + Globals->dwCurrentSample += Globals->WaveBlockLen; + if (fWriteBlocks) + { + AddToPlayingQueue(lpXWH); + if (waveOutWrite(Globals->hWaveOut, &lpXWH->wh, 0x20u)) + { + if (ShowDebugDialogs) + MessageBoxA(nullptr, "Failed to write block to device", "WavMix32", 0x30u); + lpXWH->fAvailable = 1; + RemoveFromPlayingQueue(lpXWH); + } + } + return 1; +} + +XWAVEHDR* WaveMix::AddToPlayingQueue(XWAVEHDR* lpXWH) +{ + lpXWH->QNext = nullptr; + if (play_queue.first) + { + play_queue.last->QNext = lpXWH; + } + else + { + play_queue.first = lpXWH; + } + play_queue.last = lpXWH; + return play_queue.first; +} + +void WaveMix::cmixit(unsigned __int8* lpDest, unsigned __int8** rgWaveSrc, volume_struct* volume, int iNumWaves, + unsigned __int16 length) { - return 0; } LRESULT WaveMix::WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) diff --git a/SpaceCadetPinball/WaveMix.h b/SpaceCadetPinball/WaveMix.h index c6b7e2b..6abfea4 100644 --- a/SpaceCadetPinball/WaveMix.h +++ b/SpaceCadetPinball/WaveMix.h @@ -10,6 +10,15 @@ #define MAXCHANNELS 16 #define MAXQUEUEDWAVES 100 +struct GLOBALS; + +struct volume_struct +{ + unsigned __int16 L; + unsigned __int16 R; +}; + + struct MIXWAVE { PCMWAVEFORMAT pcm; @@ -27,6 +36,7 @@ struct MIXPLAYPARAMS HWND hWndNotify; DWORD dwFlags; WORD wLoops; + int Unknown0; }; struct CHANNELNODE @@ -37,10 +47,9 @@ struct CHANNELNODE DWORD dwNumSamples; DWORD dwStartPos; DWORD dwEndPos; - char* lpPos; - char* lpEnd; - int Unknown0; - int Unknown1; + unsigned char* lpPos; + unsigned char* lpEnd; + volume_struct Volume; }; struct MIXCONFIG @@ -49,7 +58,7 @@ struct MIXCONFIG DWORD dwFlags; WORD wChannels; WORD wSamplingRate; - __int16 WaveBlocks; + __int16 WaveBlockCount; __int16 WaveBlockLen; __int16 CmixPtrDefaultFlag; unsigned __int16 ResetMixDefaultFlag; @@ -60,6 +69,21 @@ struct MIXCONFIG HKEY RegistryKey; }; +struct XWAVEHDR +{ + WAVEHDR wh; + BOOL fAvailable; + DWORD dwWavePos; + GLOBALS* g; + struct XWAVEHDR* QNext; +}; + +struct PLAYQUEUE +{ + XWAVEHDR* first; + XWAVEHDR* last; +}; + struct GLOBALS { WORD wMagic1; @@ -68,7 +92,7 @@ struct GLOBALS int unknown2; HWAVEOUT hWaveOut; int fActive; - int unknown5; + int SettingsDialogActiveFlag; unsigned int wDeviceID; int unknown7; int unknown8; @@ -112,7 +136,7 @@ struct GLOBALS int unknown58; int unknown59; int unknown60; - CHANNELNODE* aChannel[16]; + CHANNELNODE* aChannel[MAXCHANNELS]; int unknown77; int unknown78; int unknown79; @@ -135,14 +159,15 @@ struct GLOBALS int WaveBlockLen; int WaveBlockCount; int PauseBlocks; - int unknown102; - int unknown103; + XWAVEHDR** WaveBlockArray; + DWORD dwCurrentSample; DWORD dwBaseTime; int fGoodGetPos; int dwWaveOutPos; - int CmixPtr; - void(__stdcall* pfnRemix)(DWORD, CHANNELNODE*); - int (__stdcall* pfnSampleAdjust)(int, int); + void (*CmixPtr)(unsigned __int8* lpDest, unsigned __int8** rgWaveSrc, volume_struct* volume, int iNumWaves, + unsigned __int16 length); + int (* pfnRemix)(DWORD, CHANNELNODE*); + int (* pfnSampleAdjust)(int, int); int unknown110; __int16 wMagic2; __int16 unknown112; @@ -178,9 +203,18 @@ private: static int DefaultGoodWavePos(unsigned int uDeviceID); static int DefaultPauseBlocks(int waveBlocks); static int Configure(GLOBALS* hMixSession, HWND hWndParent, MIXCONFIG* lpConfig, int* flag1Ptr, int saveConfigFlag); + static int GetConfig(HANDLE hMixSession, MIXCONFIG* lpConfig); static unsigned MyWaveOutGetPosition(HWAVEOUT hwo, int fGoodGetPos); static void FreeChannelNode(CHANNELNODE* channel); - static __int16 cmixit(BYTE* a1, char* a2, char* a3, int a4, unsigned __int16 a5); + static int ResetRemix(DWORD dwRemixSamplePos, CHANNELNODE* channel); + static XWAVEHDR* RemoveFromPlayingQueue(XWAVEHDR* lpXWH); + static void DestroyPlayQueue(); + static void SwapWaveBlocks(); + static XWAVEHDR* GetWaveBlock(); + static int MixerPlay(XWAVEHDR* lpXWH, int fWriteBlocks); + static XWAVEHDR* AddToPlayingQueue(XWAVEHDR* lpXWH); + static void cmixit(unsigned __int8* lpDest, unsigned __int8** rgWaveSrc, volume_struct* volume, int iNumWaves, + unsigned __int16 length); static LRESULT __stdcall WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); static int initialized_flag; @@ -189,10 +223,17 @@ private: static CHANNELNODE* free_channel_nodes; static char volume_table[256 * 11]; static int debug_flag; - static int cmixit_ptr; + static void (*cmixit_ptr)(unsigned __int8* lpDest, unsigned __int8** rgWaveSrc, volume_struct* volume, + int iNumWaves, unsigned __int16 length); static HMODULE HModule; - static GLOBALS* Globals; + static GLOBALS *Globals, *GlobalsActive; static PCMWAVEFORMAT gpFormat; static int ShowDebugDialogs; static char string_buffer[256]; + static PLAYQUEUE play_queue; + static CHANNELNODE* play_channel_array[MAXCHANNELS]; + static XWAVEHDR* block_array1[10]; + static XWAVEHDR* block_array2[10]; + static unsigned char* play_data[MAXCHANNELS]; + static volume_struct play_volume[MAXCHANNELS]; };