mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2024-11-22 17:00:18 +01:00
WaveMix v2.
This commit is contained in:
parent
e824307b27
commit
10af864767
3 changed files with 373 additions and 26 deletions
Binary file not shown.
|
@ -7,12 +7,19 @@ CHANNELNODE WaveMix::channel_nodes[MAXQUEUEDWAVES];
|
||||||
CHANNELNODE* WaveMix::free_channel_nodes;
|
CHANNELNODE* WaveMix::free_channel_nodes;
|
||||||
char WaveMix::volume_table[256 * 11];
|
char WaveMix::volume_table[256 * 11];
|
||||||
int WaveMix::debug_flag;
|
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;
|
HMODULE WaveMix::HModule;
|
||||||
PCMWAVEFORMAT WaveMix::gpFormat = {{1u, 1u, 11025u, 11025u, 1u}, 8u};
|
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";
|
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;
|
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()
|
HANDLE WaveMix::Init()
|
||||||
{
|
{
|
||||||
|
@ -60,8 +67,8 @@ HANDLE WaveMix::ConfigureInit(MIXCONFIG* lpConfig)
|
||||||
globals->CmixPtr = cmixit_ptr;
|
globals->CmixPtr = cmixit_ptr;
|
||||||
globals->wMagic2 = 21554;
|
globals->wMagic2 = 21554;
|
||||||
globals->wMagic1 = 21554;
|
globals->wMagic1 = 21554;
|
||||||
globals->unknown102 = 0;
|
globals->WaveBlockArray = nullptr;
|
||||||
globals->unknown5 = 0;
|
globals->SettingsDialogActiveFlag = 0;
|
||||||
globals->unknown44 = 655370;
|
globals->unknown44 = 655370;
|
||||||
memset(globals->aChannel, 0xFFu, sizeof globals->aChannel);
|
memset(globals->aChannel, 0xFFu, sizeof globals->aChannel);
|
||||||
memmove(&globals->PCM, &gpFormat, 0x10u);
|
memmove(&globals->PCM, &gpFormat, 0x10u);
|
||||||
|
@ -189,7 +196,7 @@ int WaveMix::Startup(HMODULE hModule)
|
||||||
return 0;
|
return 0;
|
||||||
InitVolumeTable();
|
InitVolumeTable();
|
||||||
debug_flag = GetPrivateProfileIntA("general", "debug", 0, FileName);
|
debug_flag = GetPrivateProfileIntA("general", "debug", 0, FileName);
|
||||||
cmixit_ptr = (int)cmixit;
|
cmixit_ptr = cmixit;
|
||||||
HModule = hModule;
|
HModule = hModule;
|
||||||
|
|
||||||
WndClass.hCursor = LoadCursorA(nullptr, IDC_ARROW);
|
WndClass.hCursor = LoadCursorA(nullptr, IDC_ARROW);
|
||||||
|
@ -344,7 +351,7 @@ int WaveMix::ReadRegistryForAppSpecificConfigs(MIXCONFIG* lpConfig)
|
||||||
if ((dwFlags & 2) == 0)
|
if ((dwFlags & 2) == 0)
|
||||||
lpConfig->wSamplingRate = ReadRegistryInt(phkResult, "SamplesPerSec", 11);
|
lpConfig->wSamplingRate = ReadRegistryInt(phkResult, "SamplesPerSec", 11);
|
||||||
if ((dwFlags & 4) == 0)
|
if ((dwFlags & 4) == 0)
|
||||||
lpConfig->WaveBlocks = static_cast<short>(ReadRegistryInt(phkResult, "WaveBlocks", 3));
|
lpConfig->WaveBlockCount = static_cast<short>(ReadRegistryInt(phkResult, "WaveBlocks", 3));
|
||||||
if ((dwFlags & 8) == 0)
|
if ((dwFlags & 8) == 0)
|
||||||
lpConfig->WaveBlockLen = static_cast<short>(ReadRegistryInt(phkResult, "WaveBlockLen", 0));
|
lpConfig->WaveBlockLen = static_cast<short>(ReadRegistryInt(phkResult, "WaveBlockLen", 0));
|
||||||
lpConfig->CmixPtrDefaultFlag = 1;
|
lpConfig->CmixPtrDefaultFlag = 1;
|
||||||
|
@ -360,7 +367,7 @@ int WaveMix::ReadRegistryForAppSpecificConfigs(MIXCONFIG* lpConfig)
|
||||||
lpConfig->ShowDebugDialogs = static_cast<short>(ReadRegistryInt(phkResult, "ShowDebugDialogs", 0));
|
lpConfig->ShowDebugDialogs = static_cast<short>(ReadRegistryInt(phkResult, "ShowDebugDialogs", 0));
|
||||||
if ((dwFlags & 0x200) == 0)
|
if ((dwFlags & 0x200) == 0)
|
||||||
{
|
{
|
||||||
int defaultPauseBlocks = DefaultPauseBlocks(static_cast<unsigned __int16>(lpConfig->WaveBlocks));
|
int defaultPauseBlocks = DefaultPauseBlocks(static_cast<unsigned __int16>(lpConfig->WaveBlockCount));
|
||||||
lpConfig->PauseBlocks = static_cast<short>(ReadRegistryInt(phkResult, "PauseBlocks", defaultPauseBlocks));
|
lpConfig->PauseBlocks = static_cast<short>(ReadRegistryInt(phkResult, "PauseBlocks", defaultPauseBlocks));
|
||||||
}
|
}
|
||||||
lpConfig->dwFlags = 1023;
|
lpConfig->dwFlags = 1023;
|
||||||
|
@ -395,7 +402,7 @@ int WaveMix::DefaultGoodWavePos(unsigned uDeviceID)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = (LOBYTE(pwoc.dwSupport) >> 5) & 1;
|
result = LOBYTE(pwoc.dwSupport) >> 5 & 1;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -414,15 +421,72 @@ int WaveMix::DefaultPauseBlocks(int waveBlocks)
|
||||||
|
|
||||||
int WaveMix::Configure(GLOBALS* hMixSession, HWND hWndParent, MIXCONFIG* lpConfig, int* flag1Ptr, int saveConfigFlag)
|
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<GLOBALS*>(hMixSession), &mixConfigLocal);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int WaveMix::GetConfig(HANDLE hMixSession, MIXCONFIG* lpConfig)
|
||||||
|
{
|
||||||
|
GLOBALS* globals = SessionToGlobalDataPtr(static_cast<GLOBALS*>(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)
|
unsigned WaveMix::MyWaveOutGetPosition(HWAVEOUT hwo, int fGoodGetPos)
|
||||||
{
|
{
|
||||||
mmtime_tag pmmt{};
|
mmtime_tag pmmt{};
|
||||||
|
|
||||||
if (!fGoodGetPos)
|
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;
|
pmmt.wType = 4;
|
||||||
waveOutGetPosition(hwo, &pmmt, 0xCu);
|
waveOutGetPosition(hwo, &pmmt, 0xCu);
|
||||||
return Globals->pfnSampleAdjust(pmmt.u.ms, Globals->dwWaveOutPos);
|
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<LPSTR>(&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<CHANNELNODE*>(-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<unsigned char*>(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)
|
LRESULT WaveMix::WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
|
@ -10,6 +10,15 @@
|
||||||
#define MAXCHANNELS 16
|
#define MAXCHANNELS 16
|
||||||
#define MAXQUEUEDWAVES 100
|
#define MAXQUEUEDWAVES 100
|
||||||
|
|
||||||
|
struct GLOBALS;
|
||||||
|
|
||||||
|
struct volume_struct
|
||||||
|
{
|
||||||
|
unsigned __int16 L;
|
||||||
|
unsigned __int16 R;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct MIXWAVE
|
struct MIXWAVE
|
||||||
{
|
{
|
||||||
PCMWAVEFORMAT pcm;
|
PCMWAVEFORMAT pcm;
|
||||||
|
@ -27,6 +36,7 @@ struct MIXPLAYPARAMS
|
||||||
HWND hWndNotify;
|
HWND hWndNotify;
|
||||||
DWORD dwFlags;
|
DWORD dwFlags;
|
||||||
WORD wLoops;
|
WORD wLoops;
|
||||||
|
int Unknown0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CHANNELNODE
|
struct CHANNELNODE
|
||||||
|
@ -37,10 +47,9 @@ struct CHANNELNODE
|
||||||
DWORD dwNumSamples;
|
DWORD dwNumSamples;
|
||||||
DWORD dwStartPos;
|
DWORD dwStartPos;
|
||||||
DWORD dwEndPos;
|
DWORD dwEndPos;
|
||||||
char* lpPos;
|
unsigned char* lpPos;
|
||||||
char* lpEnd;
|
unsigned char* lpEnd;
|
||||||
int Unknown0;
|
volume_struct Volume;
|
||||||
int Unknown1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MIXCONFIG
|
struct MIXCONFIG
|
||||||
|
@ -49,7 +58,7 @@ struct MIXCONFIG
|
||||||
DWORD dwFlags;
|
DWORD dwFlags;
|
||||||
WORD wChannels;
|
WORD wChannels;
|
||||||
WORD wSamplingRate;
|
WORD wSamplingRate;
|
||||||
__int16 WaveBlocks;
|
__int16 WaveBlockCount;
|
||||||
__int16 WaveBlockLen;
|
__int16 WaveBlockLen;
|
||||||
__int16 CmixPtrDefaultFlag;
|
__int16 CmixPtrDefaultFlag;
|
||||||
unsigned __int16 ResetMixDefaultFlag;
|
unsigned __int16 ResetMixDefaultFlag;
|
||||||
|
@ -60,6 +69,21 @@ struct MIXCONFIG
|
||||||
HKEY RegistryKey;
|
HKEY RegistryKey;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct XWAVEHDR
|
||||||
|
{
|
||||||
|
WAVEHDR wh;
|
||||||
|
BOOL fAvailable;
|
||||||
|
DWORD dwWavePos;
|
||||||
|
GLOBALS* g;
|
||||||
|
struct XWAVEHDR* QNext;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PLAYQUEUE
|
||||||
|
{
|
||||||
|
XWAVEHDR* first;
|
||||||
|
XWAVEHDR* last;
|
||||||
|
};
|
||||||
|
|
||||||
struct GLOBALS
|
struct GLOBALS
|
||||||
{
|
{
|
||||||
WORD wMagic1;
|
WORD wMagic1;
|
||||||
|
@ -68,7 +92,7 @@ struct GLOBALS
|
||||||
int unknown2;
|
int unknown2;
|
||||||
HWAVEOUT hWaveOut;
|
HWAVEOUT hWaveOut;
|
||||||
int fActive;
|
int fActive;
|
||||||
int unknown5;
|
int SettingsDialogActiveFlag;
|
||||||
unsigned int wDeviceID;
|
unsigned int wDeviceID;
|
||||||
int unknown7;
|
int unknown7;
|
||||||
int unknown8;
|
int unknown8;
|
||||||
|
@ -112,7 +136,7 @@ struct GLOBALS
|
||||||
int unknown58;
|
int unknown58;
|
||||||
int unknown59;
|
int unknown59;
|
||||||
int unknown60;
|
int unknown60;
|
||||||
CHANNELNODE* aChannel[16];
|
CHANNELNODE* aChannel[MAXCHANNELS];
|
||||||
int unknown77;
|
int unknown77;
|
||||||
int unknown78;
|
int unknown78;
|
||||||
int unknown79;
|
int unknown79;
|
||||||
|
@ -135,14 +159,15 @@ struct GLOBALS
|
||||||
int WaveBlockLen;
|
int WaveBlockLen;
|
||||||
int WaveBlockCount;
|
int WaveBlockCount;
|
||||||
int PauseBlocks;
|
int PauseBlocks;
|
||||||
int unknown102;
|
XWAVEHDR** WaveBlockArray;
|
||||||
int unknown103;
|
DWORD dwCurrentSample;
|
||||||
DWORD dwBaseTime;
|
DWORD dwBaseTime;
|
||||||
int fGoodGetPos;
|
int fGoodGetPos;
|
||||||
int dwWaveOutPos;
|
int dwWaveOutPos;
|
||||||
int CmixPtr;
|
void (*CmixPtr)(unsigned __int8* lpDest, unsigned __int8** rgWaveSrc, volume_struct* volume, int iNumWaves,
|
||||||
void(__stdcall* pfnRemix)(DWORD, CHANNELNODE*);
|
unsigned __int16 length);
|
||||||
int (__stdcall* pfnSampleAdjust)(int, int);
|
int (* pfnRemix)(DWORD, CHANNELNODE*);
|
||||||
|
int (* pfnSampleAdjust)(int, int);
|
||||||
int unknown110;
|
int unknown110;
|
||||||
__int16 wMagic2;
|
__int16 wMagic2;
|
||||||
__int16 unknown112;
|
__int16 unknown112;
|
||||||
|
@ -178,9 +203,18 @@ private:
|
||||||
static int DefaultGoodWavePos(unsigned int uDeviceID);
|
static int DefaultGoodWavePos(unsigned int uDeviceID);
|
||||||
static int DefaultPauseBlocks(int waveBlocks);
|
static int DefaultPauseBlocks(int waveBlocks);
|
||||||
static int Configure(GLOBALS* hMixSession, HWND hWndParent, MIXCONFIG* lpConfig, int* flag1Ptr, int saveConfigFlag);
|
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 unsigned MyWaveOutGetPosition(HWAVEOUT hwo, int fGoodGetPos);
|
||||||
static void FreeChannelNode(CHANNELNODE* channel);
|
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 LRESULT __stdcall WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
static int initialized_flag;
|
static int initialized_flag;
|
||||||
|
@ -189,10 +223,17 @@ private:
|
||||||
static CHANNELNODE* free_channel_nodes;
|
static CHANNELNODE* free_channel_nodes;
|
||||||
static char volume_table[256 * 11];
|
static char volume_table[256 * 11];
|
||||||
static int debug_flag;
|
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 HMODULE HModule;
|
||||||
static GLOBALS* Globals;
|
static GLOBALS *Globals, *GlobalsActive;
|
||||||
static PCMWAVEFORMAT gpFormat;
|
static PCMWAVEFORMAT gpFormat;
|
||||||
static int ShowDebugDialogs;
|
static int ShowDebugDialogs;
|
||||||
static char string_buffer[256];
|
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];
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue