Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions WaveSabreCore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
39 changes: 39 additions & 0 deletions WaveSabreCore/include/WaveSabreCore/GsmSample.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#ifndef __WAVESABRECORE_GSMSAMPLE_H__
#define __WAVESABRECORE_GSMSAMPLE_H__

#include "Helpers.h"

#include <Windows.h>

#ifdef UNICODE
#define _UNICODE
#endif

#include <mmreg.h>
#include <MSAcm.h>

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
23 changes: 3 additions & 20 deletions WaveSabreCore/include/WaveSabreCore/Specimen.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,7 @@
#include "Envelope.h"
#include "StateVariableFilter.h"
#include "SamplePlayer.h"

#include <Windows.h>
#include <mmreg.h>

#ifdef UNICODE
#define _UNICODE
#endif
#include <MSAcm.h>
#include "GsmSample.h"

namespace WaveSabreCore
{
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -121,7 +105,6 @@ namespace WaveSabreCore

InterpolationMode interpolationMode;

int sampleLength;
int sampleLoopStart, sampleLoopLength;
float coarseTune, fineTune;
float masterLevel;
Expand Down
24 changes: 3 additions & 21 deletions WaveSabreCore/include/WaveSabreCore/Thunder.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,7 @@
#define __WAVESABRECORE_THUNDER_H__

#include "SynthDevice.h"

#include <Windows.h>
#include <mmreg.h>

#ifdef UNICODE
#define _UNICODE
#endif
#include <MSAcm.h>
#include "GsmSample.h"

namespace WaveSabreCore
{
Expand All @@ -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
Expand All @@ -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;
};
}

Expand Down
102 changes: 102 additions & 0 deletions WaveSabreCore/src/GsmSample.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include <WaveSabreCore/GsmSample.h>

#include <string.h>

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;
}
}
Loading