diff --git a/WaveSabreCore/CMakeLists.txt b/WaveSabreCore/CMakeLists.txt index 31ca1e2e..6f9785ab 100644 --- a/WaveSabreCore/CMakeLists.txt +++ b/WaveSabreCore/CMakeLists.txt @@ -13,6 +13,7 @@ add_library(WaveSabreCore include/WaveSabreCore/Envelope.h include/WaveSabreCore/Falcon.h include/WaveSabreCore/GmDls.h + include/WaveSabreCore/GsmSample.h include/WaveSabreCore/Helpers.h include/WaveSabreCore/Leveller.h include/WaveSabreCore/MxcsrFlagGuard.h @@ -40,6 +41,7 @@ add_library(WaveSabreCore src/Envelope.cpp src/Falcon.cpp src/GmDls.cpp + src/GsmSample.cpp src/Helpers.cpp src/Leveller.cpp src/MxcsrFlagGuard.cpp diff --git a/WaveSabreCore/include/WaveSabreCore/GsmSample.h b/WaveSabreCore/include/WaveSabreCore/GsmSample.h new file mode 100644 index 00000000..10aa36a8 --- /dev/null +++ b/WaveSabreCore/include/WaveSabreCore/GsmSample.h @@ -0,0 +1,39 @@ +#ifndef __WAVESABRECORE_GSMSAMPLE_H__ +#define __WAVESABRECORE_GSMSAMPLE_H__ + +#include "Helpers.h" + +#include + +#ifdef UNICODE +#define _UNICODE +#endif + +#include +#include + +namespace WaveSabreCore +{ + class GsmSample + { + public: + GsmSample(char *data, int compressedSize, int uncompressedSize, WAVEFORMATEX *waveFormat); + ~GsmSample(); + + char *WaveFormatData; + int CompressedSize, UncompressedSize; + + char *CompressedData; + float *SampleData; + + int SampleLength; + + private: + static BOOL __stdcall driverEnumCallback(HACMDRIVERID driverId, DWORD_PTR dwInstance, DWORD fdwSupport); + static BOOL __stdcall formatEnumCallback(HACMDRIVERID driverId, LPACMFORMATDETAILS formatDetails, DWORD_PTR dwInstance, DWORD fdwSupport); + + static HACMDRIVERID driverId; + }; +} + +#endif diff --git a/WaveSabreCore/include/WaveSabreCore/Specimen.h b/WaveSabreCore/include/WaveSabreCore/Specimen.h index 86c3d7ec..0b661f9a 100644 --- a/WaveSabreCore/include/WaveSabreCore/Specimen.h +++ b/WaveSabreCore/include/WaveSabreCore/Specimen.h @@ -5,14 +5,7 @@ #include "Envelope.h" #include "StateVariableFilter.h" #include "SamplePlayer.h" - -#include -#include - -#ifdef UNICODE -#define _UNICODE -#endif -#include +#include "GsmSample.h" namespace WaveSabreCore { @@ -70,7 +63,7 @@ namespace WaveSabreCore virtual void SetChunk(void *data, int size); virtual int GetChunk(void **data); - void LoadSample(char *data, int compressedSize, int uncompressedSize, WAVEFORMATEX *waveFormat); + void LoadSample(char *compressedDataPtr, int compressedSize, int uncompressedSize, WAVEFORMATEX *waveFormatPtr); private: class SpecimenVoice : public Voice @@ -99,18 +92,9 @@ namespace WaveSabreCore float velocity; }; - static BOOL __stdcall driverEnumCallback(HACMDRIVERID driverId, DWORD_PTR dwInstance, DWORD fdwSupport); - static BOOL __stdcall formatEnumCallback(HACMDRIVERID driverId, LPACMFORMATDETAILS formatDetails, DWORD_PTR dwInstance, DWORD fdwSupport); - - static HACMDRIVERID driverId; - char *chunkData; - char *waveFormatData; - int compressedSize, uncompressedSize; - - char *compressedData; - float *sampleData; + GsmSample* sample; float ampAttack, ampDecay, ampSustain, ampRelease; float sampleStart; @@ -121,7 +105,6 @@ namespace WaveSabreCore InterpolationMode interpolationMode; - int sampleLength; int sampleLoopStart, sampleLoopLength; float coarseTune, fineTune; float masterLevel; diff --git a/WaveSabreCore/include/WaveSabreCore/Thunder.h b/WaveSabreCore/include/WaveSabreCore/Thunder.h index 44e5d4b6..2bfad258 100644 --- a/WaveSabreCore/include/WaveSabreCore/Thunder.h +++ b/WaveSabreCore/include/WaveSabreCore/Thunder.h @@ -2,14 +2,7 @@ #define __WAVESABRECORE_THUNDER_H__ #include "SynthDevice.h" - -#include -#include - -#ifdef UNICODE -#define _UNICODE -#endif -#include +#include "GsmSample.h" namespace WaveSabreCore { @@ -24,7 +17,7 @@ namespace WaveSabreCore virtual void SetChunk(void *data, int size); virtual int GetChunk(void **data); - void LoadSample(char *data, int compressedSize, int uncompressedSize, WAVEFORMATEX *waveFormat); + void LoadSample(char *compressedDataPtr, int compressedSize, int uncompressedSize, WAVEFORMATEX *waveFormatPtr); private: class ThunderVoice : public Voice @@ -43,20 +36,9 @@ namespace WaveSabreCore int samplePos; }; - static BOOL __stdcall driverEnumCallback(HACMDRIVERID driverId, DWORD_PTR dwInstance, DWORD fdwSupport); - static BOOL __stdcall formatEnumCallback(HACMDRIVERID driverId, LPACMFORMATDETAILS formatDetails, DWORD_PTR dwInstance, DWORD fdwSupport); - - static HACMDRIVERID driverId; - char *chunkData; - char *waveFormatData; - int compressedSize, uncompressedSize; - - char *compressedData; - float *sampleData; - - int sampleLength; + GsmSample *sample; }; } diff --git a/WaveSabreCore/src/GsmSample.cpp b/WaveSabreCore/src/GsmSample.cpp new file mode 100644 index 00000000..8314c089 --- /dev/null +++ b/WaveSabreCore/src/GsmSample.cpp @@ -0,0 +1,102 @@ +#include + +#include + +namespace WaveSabreCore +{ + GsmSample::GsmSample(char *data, int compressedSize, int uncompressedSize, WAVEFORMATEX *waveFormat) + : CompressedSize(compressedSize) + , UncompressedSize(uncompressedSize) + { + WaveFormatData = new char[sizeof(WAVEFORMATEX) + waveFormat->cbSize]; + memcpy(WaveFormatData, waveFormat, sizeof(WAVEFORMATEX) + waveFormat->cbSize); + CompressedData = new char[compressedSize]; + memcpy(CompressedData, data, compressedSize); + + acmDriverEnum(driverEnumCallback, NULL, NULL); + HACMDRIVER driver = NULL; + acmDriverOpen(&driver, driverId, 0); + + WAVEFORMATEX dstWaveFormat = + { + WAVE_FORMAT_PCM, + 1, + waveFormat->nSamplesPerSec, + waveFormat->nSamplesPerSec * 2, + sizeof(short), + sizeof(short) * 8, + 0 + }; + + HACMSTREAM stream = NULL; + acmStreamOpen(&stream, driver, waveFormat, &dstWaveFormat, NULL, NULL, NULL, ACM_STREAMOPENF_NONREALTIME); + + ACMSTREAMHEADER streamHeader; + memset(&streamHeader, 0, sizeof(ACMSTREAMHEADER)); + streamHeader.cbStruct = sizeof(ACMSTREAMHEADER); + streamHeader.pbSrc = (LPBYTE)CompressedData; + streamHeader.cbSrcLength = compressedSize; + auto uncompressedData = new short[uncompressedSize * 2]; + streamHeader.pbDst = (LPBYTE)uncompressedData; + streamHeader.cbDstLength = uncompressedSize * 2; + acmStreamPrepareHeader(stream, &streamHeader, 0); + + acmStreamConvert(stream, &streamHeader, 0); + + acmStreamClose(stream, 0); + acmDriverClose(driver, 0); + + SampleLength = streamHeader.cbDstLengthUsed / sizeof(short); + SampleData = new float[SampleLength]; + for (int i = 0; i < SampleLength; i++) + SampleData[i] = (float)((double)uncompressedData[i] / 32768.0); + + delete [] uncompressedData; + } + + GsmSample::~GsmSample() + { + delete [] WaveFormatData; + delete [] CompressedData; + delete [] SampleData; + } + + HACMDRIVERID GsmSample::driverId = NULL; + + BOOL __stdcall GsmSample::driverEnumCallback(HACMDRIVERID driverId, DWORD_PTR dwInstance, DWORD fdwSupport) + { + if (GsmSample::driverId) return 1; + + HACMDRIVER driver = NULL; + acmDriverOpen(&driver, driverId, 0); + + int waveFormatSize = 0; + acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, &waveFormatSize); + auto waveFormat = (WAVEFORMATEX *)(new char[waveFormatSize]); + memset(waveFormat, 0, waveFormatSize); + ACMFORMATDETAILS formatDetails; + memset(&formatDetails, 0, sizeof(formatDetails)); + formatDetails.cbStruct = sizeof(formatDetails); + formatDetails.pwfx = waveFormat; + formatDetails.cbwfx = waveFormatSize; + formatDetails.dwFormatTag = WAVE_FORMAT_UNKNOWN; + acmFormatEnum(driver, &formatDetails, formatEnumCallback, NULL, NULL); + + delete [] (char *)waveFormat; + + acmDriverClose(driver, 0); + + return 1; + } + + BOOL __stdcall GsmSample::formatEnumCallback(HACMDRIVERID driverId, LPACMFORMATDETAILS formatDetails, DWORD_PTR dwInstance, DWORD fdwSupport) + { + if (formatDetails->pwfx->wFormatTag == WAVE_FORMAT_GSM610 && + formatDetails->pwfx->nChannels == 1 && + formatDetails->pwfx->nSamplesPerSec == 44100) + { + GsmSample::driverId = driverId; + } + return 1; + } +} diff --git a/WaveSabreCore/src/Specimen.cpp b/WaveSabreCore/src/Specimen.cpp index eb0abd88..bf401c94 100644 --- a/WaveSabreCore/src/Specimen.cpp +++ b/WaveSabreCore/src/Specimen.cpp @@ -5,22 +5,14 @@ namespace WaveSabreCore { - HACMDRIVERID Specimen::driverId = NULL; - Specimen::Specimen() - : SynthDevice(0) + : SynthDevice((int)ParamIndices::NumParams) + , sample(nullptr) { for (int i = 0; i < maxVoices; i++) voices[i] = new SpecimenVoice(this); chunkData = nullptr; - waveFormatData = nullptr; - compressedSize = uncompressedSize = 0; - compressedData = nullptr; - sampleData = nullptr; - - sampleLength = 0; - ampAttack = 1.0f; ampDecay = 1.0f; ampSustain = 1.0f; @@ -37,8 +29,6 @@ namespace WaveSabreCore interpolationMode = InterpolationMode::Linear; - sampleLength = 0; - coarseTune = 0.5f; fineTune = 0.5f; @@ -58,9 +48,7 @@ namespace WaveSabreCore Specimen::~Specimen() { if (chunkData) delete [] chunkData; - if (waveFormatData) delete [] waveFormatData; - if (compressedData) delete [] compressedData; - if (sampleData) delete [] sampleData; + if (sample) delete sample; } void Specimen::SetParam(int index, float value) @@ -186,16 +174,16 @@ namespace WaveSabreCore int Specimen::GetChunk(void **data) { - if (!compressedData) return 0; + if (!sample) return 0; // Figure out size of chunk // The names here are meant to be symmetric with those in SetChunk for clarity auto headerSize = sizeof(ChunkHeader); - auto waveFormatSize = sizeof(WAVEFORMATEX) + ((WAVEFORMATEX *)waveFormatData)->cbSize; - auto compressedDataSize = compressedSize; + auto waveFormatSize = sizeof(WAVEFORMATEX) + ((WAVEFORMATEX *)sample->WaveFormatData)->cbSize; + auto compressedDataSize = sample->CompressedSize; auto paramSize = (int)ParamIndices::NumParams * sizeof(float); auto chunkSizeSize = sizeof(int); - int size = (int)(headerSize + waveFormatSize + compressedSize + paramSize + chunkSizeSize); + int size = (int)(headerSize + waveFormatSize + sample->CompressedSize + paramSize + chunkSizeSize); // (Re)allocate chunk data if (chunkData) delete [] chunkData; @@ -203,17 +191,17 @@ namespace WaveSabreCore // Write header ChunkHeader header; - header.CompressedSize = compressedSize; - header.UncompressedSize = uncompressedSize; + header.CompressedSize = sample->CompressedSize; + header.UncompressedSize = sample->UncompressedSize; memcpy(chunkData, &header, sizeof(ChunkHeader)); // Write wave format auto waveFormatPtr = (char *)chunkData + headerSize; - memcpy(waveFormatPtr, waveFormatData, waveFormatSize); + memcpy(waveFormatPtr, sample->WaveFormatData, waveFormatSize); // Write compressed data auto compressedDataPtr = waveFormatPtr + waveFormatSize; - memcpy(compressedDataPtr, compressedData, compressedDataSize); + memcpy(compressedDataPtr, sample->CompressedData, compressedDataSize); // Write params auto paramDataPtr = (float *)(compressedDataPtr + compressedDataSize); @@ -228,60 +216,14 @@ namespace WaveSabreCore return size; } - void Specimen::LoadSample(char *data, int compressedSize, int uncompressedSize, WAVEFORMATEX *waveFormat) + void Specimen::LoadSample(char *compressedDataPtr, int compressedSize, int uncompressedSize, WAVEFORMATEX *waveFormatPtr) { - this->compressedSize = compressedSize; - this->uncompressedSize = uncompressedSize; - - if (waveFormatData) delete [] waveFormatData; - waveFormatData = new char[sizeof(WAVEFORMATEX) + waveFormat->cbSize]; - memcpy(waveFormatData, waveFormat, sizeof(WAVEFORMATEX) + waveFormat->cbSize); - if (compressedData) delete [] compressedData; - compressedData = new char[compressedSize]; - memcpy(compressedData, data, compressedSize); + if (sample) delete sample; - acmDriverEnum(driverEnumCallback, NULL, NULL); - HACMDRIVER driver = NULL; - acmDriverOpen(&driver, driverId, 0); - - WAVEFORMATEX dstWaveFormat = - { - WAVE_FORMAT_PCM, - 1, - waveFormat->nSamplesPerSec, - waveFormat->nSamplesPerSec * 2, - sizeof(short), - sizeof(short) * 8, - 0 - }; - - HACMSTREAM stream = NULL; - acmStreamOpen(&stream, driver, waveFormat, &dstWaveFormat, NULL, NULL, NULL, ACM_STREAMOPENF_NONREALTIME); - - ACMSTREAMHEADER streamHeader; - memset(&streamHeader, 0, sizeof(ACMSTREAMHEADER)); - streamHeader.cbStruct = sizeof(ACMSTREAMHEADER); - streamHeader.pbSrc = (LPBYTE)compressedData; - streamHeader.cbSrcLength = compressedSize; - auto uncompressedData = new short[uncompressedSize * 2]; - streamHeader.pbDst = (LPBYTE)uncompressedData; - streamHeader.cbDstLength = uncompressedSize * 2; - acmStreamPrepareHeader(stream, &streamHeader, 0); - - acmStreamConvert(stream, &streamHeader, 0); - - acmStreamClose(stream, 0); - acmDriverClose(driver, 0); - - sampleLength = streamHeader.cbDstLengthUsed / sizeof(short); - if (sampleData) delete [] sampleData; - sampleData = new float[sampleLength]; - for (int i = 0; i < sampleLength; i++) sampleData[i] = (float)((double)uncompressedData[i] / 32768.0); + sample = new GsmSample(compressedDataPtr, compressedSize, uncompressedSize, waveFormatPtr); sampleLoopStart = 0; - sampleLoopLength = sampleLength; - - delete [] uncompressedData; + sampleLoopLength = sample->SampleLength; } Specimen::SpecimenVoice::SpecimenVoice(Specimen *specimen) @@ -356,8 +298,8 @@ namespace WaveSabreCore modEnv.Release = specimen->modRelease; modEnv.Trigger(); - samplePlayer.SampleData = specimen->sampleData; - samplePlayer.SampleLength = specimen->sampleLength; + samplePlayer.SampleData = specimen->sample->SampleData; + samplePlayer.SampleLength = specimen->sample->SampleLength; samplePlayer.SampleLoopStart = specimen->sampleLoopStart; samplePlayer.SampleLoopLength = specimen->sampleLoopLength; @@ -390,41 +332,4 @@ namespace WaveSabreCore { samplePlayer.CalcPitch(GetNote() - 60 + Detune + specimen->fineTune * 2.0f - 1.0f + SpecimenVoice::coarseDetune(specimen->coarseTune)); } - - BOOL __stdcall Specimen::driverEnumCallback(HACMDRIVERID driverId, DWORD_PTR dwInstance, DWORD fdwSupport) - { - if (Specimen::driverId) return 1; - - HACMDRIVER driver = NULL; - acmDriverOpen(&driver, driverId, 0); - - int waveFormatSize = 0; - acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, &waveFormatSize); - auto waveFormat = (WAVEFORMATEX *)(new char[waveFormatSize]); - memset(waveFormat, 0, waveFormatSize); - ACMFORMATDETAILS formatDetails; - memset(&formatDetails, 0, sizeof(formatDetails)); - formatDetails.cbStruct = sizeof(formatDetails); - formatDetails.pwfx = waveFormat; - formatDetails.cbwfx = waveFormatSize; - formatDetails.dwFormatTag = WAVE_FORMAT_UNKNOWN; - acmFormatEnum(driver, &formatDetails, formatEnumCallback, NULL, NULL); - - delete [] (char *)waveFormat; - - acmDriverClose(driver, 0); - - return 1; - } - - BOOL __stdcall Specimen::formatEnumCallback(HACMDRIVERID driverId, LPACMFORMATDETAILS formatDetails, DWORD_PTR dwInstance, DWORD fdwSupport) - { - if (formatDetails->pwfx->wFormatTag == WAVE_FORMAT_GSM610 && - formatDetails->pwfx->nChannels == 1 && - formatDetails->pwfx->nSamplesPerSec == SampleRate) - { - Specimen::driverId = driverId; - } - return 1; - } } diff --git a/WaveSabreCore/src/Thunder.cpp b/WaveSabreCore/src/Thunder.cpp index c40d9094..0f66827e 100644 --- a/WaveSabreCore/src/Thunder.cpp +++ b/WaveSabreCore/src/Thunder.cpp @@ -5,29 +5,19 @@ namespace WaveSabreCore { - HACMDRIVERID Thunder::driverId = NULL; - Thunder::Thunder() : SynthDevice(0) + , sample(nullptr) { for (int i = 0; i < maxVoices; i++) voices[i] = new ThunderVoice(this); chunkData = nullptr; - - waveFormatData = nullptr; - compressedSize = uncompressedSize = 0; - compressedData = nullptr; - sampleData = nullptr; - - sampleLength = 0; } Thunder::~Thunder() { if (chunkData) delete [] chunkData; - if (waveFormatData) delete [] waveFormatData; - if (compressedData) delete [] compressedData; - if (sampleData) delete [] sampleData; + if (sample) delete sample; } typedef struct @@ -47,72 +37,26 @@ namespace WaveSabreCore int Thunder::GetChunk(void **data) { - if (!compressedData) return 0; + if (!sample) return 0; ChunkHeader h; - h.CompressedSize = compressedSize; - h.UncompressedSize = uncompressedSize; + h.CompressedSize = sample->CompressedSize; + h.UncompressedSize = sample->UncompressedSize; if (chunkData) delete [] chunkData; - int chunkSize = sizeof(ChunkHeader) + sizeof(WAVEFORMATEX) + ((WAVEFORMATEX *)waveFormatData)->cbSize + compressedSize + sizeof(int); + int chunkSize = sizeof(ChunkHeader) + sizeof(WAVEFORMATEX) + ((WAVEFORMATEX *)sample->WaveFormatData)->cbSize + sample->CompressedSize + sizeof(int); chunkData = new char[chunkSize]; memcpy(chunkData, &h, sizeof(ChunkHeader)); - memcpy(chunkData + sizeof(ChunkHeader), waveFormatData, sizeof(WAVEFORMATEX) + ((WAVEFORMATEX *)waveFormatData)->cbSize); - memcpy(chunkData + sizeof(ChunkHeader) + sizeof(WAVEFORMATEX) + ((WAVEFORMATEX *)waveFormatData)->cbSize, compressedData, compressedSize); + memcpy(chunkData + sizeof(ChunkHeader), sample->WaveFormatData, sizeof(WAVEFORMATEX) + ((WAVEFORMATEX *)sample->WaveFormatData)->cbSize); + memcpy(chunkData + sizeof(ChunkHeader) + sizeof(WAVEFORMATEX) + ((WAVEFORMATEX *)sample->WaveFormatData)->cbSize, sample->CompressedData, sample->CompressedSize); *(int *)(chunkData + chunkSize - sizeof(int)) = chunkSize; *data = chunkData; return chunkSize; } - void Thunder::LoadSample(char *data, int compressedSize, int uncompressedSize, WAVEFORMATEX *waveFormat) + void Thunder::LoadSample(char *compressedDataPtr, int compressedSize, int uncompressedSize, WAVEFORMATEX *waveFormatPtr) { - this->compressedSize = compressedSize; - this->uncompressedSize = uncompressedSize; - - if (waveFormatData) delete [] waveFormatData; - waveFormatData = new char[sizeof(WAVEFORMATEX) + waveFormat->cbSize]; - memcpy(waveFormatData, waveFormat, sizeof(WAVEFORMATEX) + waveFormat->cbSize); - if (compressedData) delete [] compressedData; - compressedData = new char[compressedSize]; - memcpy(compressedData, data, compressedSize); - - acmDriverEnum(driverEnumCallback, NULL, NULL); - HACMDRIVER driver = NULL; - acmDriverOpen(&driver, driverId, 0); - - WAVEFORMATEX dstWaveFormat = - { - WAVE_FORMAT_PCM, - 1, - waveFormat->nSamplesPerSec, - waveFormat->nSamplesPerSec * 2, - sizeof(short), - sizeof(short) * 8, - 0 - }; - - HACMSTREAM stream = NULL; - acmStreamOpen(&stream, driver, waveFormat, &dstWaveFormat, NULL, NULL, NULL, ACM_STREAMOPENF_NONREALTIME); - - ACMSTREAMHEADER streamHeader; - memset(&streamHeader, 0, sizeof(ACMSTREAMHEADER)); - streamHeader.cbStruct = sizeof(ACMSTREAMHEADER); - streamHeader.pbSrc = (LPBYTE)compressedData; - streamHeader.cbSrcLength = compressedSize; - auto uncompressedData = new short[uncompressedSize * 2]; - streamHeader.pbDst = (LPBYTE)uncompressedData; - streamHeader.cbDstLength = uncompressedSize * 2; - acmStreamPrepareHeader(stream, &streamHeader, 0); + if (sample) delete sample; - acmStreamConvert(stream, &streamHeader, 0); - - acmStreamClose(stream, 0); - acmDriverClose(driver, 0); - - sampleLength = streamHeader.cbDstLengthUsed / sizeof(short); - if (sampleData) delete [] sampleData; - sampleData = new float[sampleLength]; - for (int i = 0; i < sampleLength; i++) sampleData[i] = (float)((double)uncompressedData[i] / 32768.0); - - delete [] uncompressedData; + sample = new GsmSample(compressedDataPtr, compressedSize, uncompressedSize, waveFormatPtr); } Thunder::ThunderVoice::ThunderVoice(Thunder *thunder) @@ -129,12 +73,12 @@ namespace WaveSabreCore { for (int i = 0; i < numSamples; i++) { - if (samplePos >= thunder->sampleLength) + if (samplePos >= thunder->sample->SampleLength) { IsOn = false; break; } - float sample = thunder->sampleData[samplePos]; + float sample = thunder->sample->SampleData[samplePos]; outputs[0][i] += sample; outputs[1][i] += sample; samplePos++; @@ -146,41 +90,4 @@ namespace WaveSabreCore Voice::NoteOn(note, velocity, detune, pan); samplePos = 0; } - - BOOL __stdcall Thunder::driverEnumCallback(HACMDRIVERID driverId, DWORD_PTR dwInstance, DWORD fdwSupport) - { - if (Thunder::driverId) return 1; - - HACMDRIVER driver = NULL; - acmDriverOpen(&driver, driverId, 0); - - int waveFormatSize = 0; - acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, &waveFormatSize); - auto waveFormat = (WAVEFORMATEX *)(new char[waveFormatSize]); - memset(waveFormat, 0, waveFormatSize); - ACMFORMATDETAILS formatDetails; - memset(&formatDetails, 0, sizeof(formatDetails)); - formatDetails.cbStruct = sizeof(formatDetails); - formatDetails.pwfx = waveFormat; - formatDetails.cbwfx = waveFormatSize; - formatDetails.dwFormatTag = WAVE_FORMAT_UNKNOWN; - acmFormatEnum(driver, &formatDetails, formatEnumCallback, NULL, NULL); - - delete [] (char *)waveFormat; - - acmDriverClose(driver, 0); - - return 1; - } - - BOOL __stdcall Thunder::formatEnumCallback(HACMDRIVERID driverId, LPACMFORMATDETAILS formatDetails, DWORD_PTR dwInstance, DWORD fdwSupport) - { - if (formatDetails->pwfx->wFormatTag == WAVE_FORMAT_GSM610 && - formatDetails->pwfx->nChannels == 1 && - formatDetails->pwfx->nSamplesPerSec == SampleRate) - { - Thunder::driverId = driverId; - } - return 1; - } }