972 lines
32 KiB
C++
972 lines
32 KiB
C++
|
|
#include "fmod_settings.h"
|
||
|
|
|
||
|
|
#ifdef FMOD_SUPPORT_DLS
|
||
|
|
|
||
|
|
#include "fmod.h"
|
||
|
|
#include "fmod_codec_dls.h"
|
||
|
|
#include "fmod_codec_wav.h"
|
||
|
|
#include "fmod_soundi.h"
|
||
|
|
|
||
|
|
#include <stdio.h>
|
||
|
|
|
||
|
|
namespace FMOD
|
||
|
|
{
|
||
|
|
|
||
|
|
FMOD_CODEC_DESCRIPTION_EX dlscodec;
|
||
|
|
|
||
|
|
|
||
|
|
#ifdef PLUGIN_EXPORTS
|
||
|
|
|
||
|
|
#ifdef __cplusplus
|
||
|
|
extern "C" {
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/*
|
||
|
|
FMODGetCodecDescription is mandatory for every fmod plugin. This is the symbol the registerplugin function searches for.
|
||
|
|
Must be declared with F_API to make it export as stdcall.
|
||
|
|
*/
|
||
|
|
F_DECLSPEC F_DLLEXPORT FMOD_CODEC_DESCRIPTION_EX * F_API FMODGetCodecDescriptionEx()
|
||
|
|
{
|
||
|
|
return CodecDLS::getDescriptionEx();
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifdef __cplusplus
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#endif /* PLUGIN_EXPORTS */
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_CODEC_DESCRIPTION_EX *CodecDLS::getDescriptionEx()
|
||
|
|
{
|
||
|
|
FMOD_memset(&dlscodec, 0, sizeof(FMOD_CODEC_DESCRIPTION_EX));
|
||
|
|
|
||
|
|
dlscodec.name = "FMOD DLS Codec";
|
||
|
|
dlscodec.version = 0x00010100;
|
||
|
|
dlscodec.timeunits = FMOD_TIMEUNIT_PCM;
|
||
|
|
dlscodec.open = &CodecDLS::openCallback;
|
||
|
|
dlscodec.close = &CodecDLS::closeCallback;
|
||
|
|
dlscodec.read = &CodecDLS::readCallback;
|
||
|
|
dlscodec.setposition = &CodecDLS::setPositionCallback;
|
||
|
|
|
||
|
|
dlscodec.mType = FMOD_SOUND_TYPE_DLS;
|
||
|
|
dlscodec.mSize = sizeof(CodecDLS);
|
||
|
|
|
||
|
|
return &dlscodec;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT CodecDLS::parseChunk(char *parentchunk, unsigned int chunksize)
|
||
|
|
{
|
||
|
|
unsigned int offset, fileoffset;
|
||
|
|
FMOD_RESULT result;
|
||
|
|
bool done = false;
|
||
|
|
|
||
|
|
result = mFile->tell(&fileoffset);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
offset = 4;
|
||
|
|
fileoffset -= sizeof(WAVE_CHUNK);
|
||
|
|
|
||
|
|
/*
|
||
|
|
Decode chunks
|
||
|
|
*/
|
||
|
|
do
|
||
|
|
{
|
||
|
|
WAVE_CHUNK chunk;
|
||
|
|
|
||
|
|
result = mFile->seek(fileoffset + sizeof(WAVE_CHUNK), SEEK_SET);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
result = mFile->read(&chunk, 1, sizeof(WAVE_CHUNK), 0);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifdef PLATFORM_ENDIAN_BIG
|
||
|
|
chunk.size = FMOD_SWAPENDIAN_DWORD(chunk.size);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
//FLOG((FMOD_DEBUG_LEVEL_LOG, __FILE__, __LINE__, "CodecDLS::parseRIFF","chunk : id %c%c%c%c size %d\n", chunk.id[0],chunk.id[1],chunk.id[2],chunk.id[3], chunk.size));
|
||
|
|
|
||
|
|
/*
|
||
|
|
CHUNKS WE DONT CARE ABOUT
|
||
|
|
*/
|
||
|
|
if (!FMOD_strncmp((const char *)chunk.id, "vers", 4) ||
|
||
|
|
!FMOD_strncmp((const char *)chunk.id, "msyn", 4) ||
|
||
|
|
!FMOD_strncmp((const char *)chunk.id, "dlid", 4))
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
NUMBER OF INSTRUMENTS CHUNK
|
||
|
|
*/
|
||
|
|
else if (!FMOD_strncmp((const char *)chunk.id, "colh", 4))
|
||
|
|
{
|
||
|
|
result = mFile->read(&mNumInstruments, 4, 1, 0);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
mInstrument = (CodecDLSInstrument *)FMOD_Memory_Calloc(mNumInstruments * sizeof(CodecDLSInstrument));
|
||
|
|
if (!mInstrument)
|
||
|
|
{
|
||
|
|
return FMOD_ERR_MEMORY;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/*
|
||
|
|
POOL TABLE CHUNK
|
||
|
|
*/
|
||
|
|
else if (!FMOD_strncmp((const char *)chunk.id, "ptbl", 4))
|
||
|
|
{
|
||
|
|
unsigned int size;
|
||
|
|
|
||
|
|
result = mFile->read(&size, 4, 1, 0);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
result = mFile->read(&mNumSamples, 4, 1, 0);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
Fill out base class members, also pointing to or allocating storage for them.
|
||
|
|
*/
|
||
|
|
waveformat = (FMOD_CODEC_WAVEFORMAT *)FMOD_Memory_Calloc(sizeof(FMOD_CODEC_WAVEFORMAT) * mNumSamples);
|
||
|
|
if (!waveformat)
|
||
|
|
{
|
||
|
|
return FMOD_ERR_MEMORY;
|
||
|
|
}
|
||
|
|
|
||
|
|
mSample = (CodecDLSSample *)FMOD_Memory_Calloc(mNumSamples *sizeof(CodecDLSSample));
|
||
|
|
if (!mSample)
|
||
|
|
{
|
||
|
|
return FMOD_ERR_MEMORY;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/*
|
||
|
|
LIST CHUNK
|
||
|
|
*/
|
||
|
|
else if (!FMOD_strncmp((const char *)chunk.id, "LIST", 4))
|
||
|
|
{
|
||
|
|
char listid[4];
|
||
|
|
|
||
|
|
result = mFile->read(listid, 1, 4, 0);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
result = parseChunk(listid, chunk.size);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!FMOD_strncmp((const char *)listid, "wave", 4))
|
||
|
|
{
|
||
|
|
mSampleID++;
|
||
|
|
}
|
||
|
|
else if (!FMOD_strncmp((const char *)listid, "ins ", 4))
|
||
|
|
{
|
||
|
|
mInstrumentID++;
|
||
|
|
if (mInstrumentID >= mNumInstruments)
|
||
|
|
{
|
||
|
|
mInstrumentID = mInstrumentID;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (!FMOD_strncmp((const char *)listid, "rgn ", 4))
|
||
|
|
{
|
||
|
|
mRegionID++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (!FMOD_strncmp((const char *)chunk.id, "dlid", 4))
|
||
|
|
{
|
||
|
|
FMOD_GUID dlsid;
|
||
|
|
|
||
|
|
result = mFile->read(&dlsid, 1, sizeof(FMOD_GUID), 0);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (!FMOD_strncmp((const char *)chunk.id, "insh", 4))
|
||
|
|
{
|
||
|
|
result = mFile->read(&mInstrument[mInstrumentID].mHeader, 1, sizeof(DLS_INSTRUMENTHEADER), 0);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifdef PLATFORM_ENDIAN_BIG
|
||
|
|
mInstrument[mInstrumentID].mHeader.cRegions = FMOD_SWAPENDIAN_DWORD(mInstrument[mInstrumentID].mHeader.cRegions);
|
||
|
|
mInstrument[mInstrumentID].mHeader.Locale.ulBank = FMOD_SWAPENDIAN_DWORD(mInstrument[mInstrumentID].mHeader.Locale.ulBank);
|
||
|
|
mInstrument[mInstrumentID].mHeader.Locale.ulInstrument = FMOD_SWAPENDIAN_DWORD(mInstrument[mInstrumentID].mHeader.Locale.ulInstrument);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
mInstrument[mInstrumentID].mRegion = (CodecDLSRegion *)FMOD_Memory_Calloc(sizeof(CodecDLSRegion) * mInstrument[mInstrumentID].mHeader.cRegions);
|
||
|
|
if (!mInstrument[mInstrumentID].mRegion)
|
||
|
|
{
|
||
|
|
return FMOD_ERR_MEMORY;
|
||
|
|
}
|
||
|
|
mRegionID = 0;
|
||
|
|
}
|
||
|
|
else if (!FMOD_strncmp((const char *)chunk.id, "rgnh", 4))
|
||
|
|
{
|
||
|
|
result = mFile->read(&mInstrument[mInstrumentID].mRegion[mRegionID].mRegionHeader, 1, sizeof(DLS_REGIONHEADER), 0);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifdef PLATFORM_ENDIAN_BIG
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mRegionHeader.RangeKey.usLow = FMOD_SWAPENDIAN_WORD(mInstrument[mInstrumentID].mRegion[mRegionID].mRegionHeader.RangeKey.usLow);
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mRegionHeader.RangeKey.usHigh = FMOD_SWAPENDIAN_WORD(mInstrument[mInstrumentID].mRegion[mRegionID].mRegionHeader.RangeKey.usHigh);
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mRegionHeader.RangeVelocity.usLow = FMOD_SWAPENDIAN_WORD(mInstrument[mInstrumentID].mRegion[mRegionID].mRegionHeader.RangeVelocity.usLow);
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mRegionHeader.RangeVelocity.usHigh = FMOD_SWAPENDIAN_WORD(mInstrument[mInstrumentID].mRegion[mRegionID].mRegionHeader.RangeVelocity.usHigh);
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mRegionHeader.fusOptions = FMOD_SWAPENDIAN_WORD(mInstrument[mInstrumentID].mRegion[mRegionID].mRegionHeader.fusOptions);
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mRegionHeader.usKeyGroup = FMOD_SWAPENDIAN_WORD(mInstrument[mInstrumentID].mRegion[mRegionID].mRegionHeader.usKeyGroup);
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
else if (!FMOD_strncmp((const char *)chunk.id, "wsmp", 4))
|
||
|
|
{
|
||
|
|
unsigned int size = sizeof(DLS_WAVESAMPLE);
|
||
|
|
|
||
|
|
if (chunk.size < size)
|
||
|
|
{
|
||
|
|
size = chunk.size;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!FMOD_strncmp(parentchunk, "wave", 4))
|
||
|
|
{
|
||
|
|
result = mFile->read(&mSample[mSampleID].mWaveSample, 1, size, 0);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifdef PLATFORM_ENDIAN_BIG
|
||
|
|
mSample[mSampleID].mWaveSample.cbSize = FMOD_SWAPENDIAN_DWORD(mSample[mSampleID].mWaveSample.cbSize);
|
||
|
|
mSample[mSampleID].mWaveSample.usUnityNote = FMOD_SWAPENDIAN_WORD(mSample[mSampleID].mWaveSample.usUnityNote);
|
||
|
|
mSample[mSampleID].mWaveSample.sFineTune = FMOD_SWAPENDIAN_WORD(mSample[mSampleID].mWaveSample.sFineTune);
|
||
|
|
mSample[mSampleID].mWaveSample.lAttenuation = FMOD_SWAPENDIAN_DWORD(mSample[mSampleID].mWaveSample.lAttenuation);
|
||
|
|
mSample[mSampleID].mWaveSample.fulOptions = FMOD_SWAPENDIAN_DWORD(mSample[mSampleID].mWaveSample.fulOptions);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
if (mSample[mSampleID].mWaveSample.cSampleLoops)
|
||
|
|
{
|
||
|
|
#ifdef PLATFORM_ENDIAN_BIG
|
||
|
|
mSample[mSampleID].mWaveSample.loop[0].cbSize = FMOD_SWAPENDIAN_DWORD(mSample[mSampleID].mWaveSample.loop[0].cbSize);
|
||
|
|
mSample[mSampleID].mWaveSample.loop[0].ulLoopType = FMOD_SWAPENDIAN_DWORD(mSample[mSampleID].mWaveSample.loop[0].ulLoopType);
|
||
|
|
mSample[mSampleID].mWaveSample.loop[0].ulLoopStart = FMOD_SWAPENDIAN_DWORD(mSample[mSampleID].mWaveSample.loop[0].ulLoopStart);
|
||
|
|
mSample[mSampleID].mWaveSample.loop[0].ulLoopLength = FMOD_SWAPENDIAN_DWORD(mSample[mSampleID].mWaveSample.loop[0].ulLoopLength);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
waveformat[mSampleID].mode = FMOD_LOOP_NORMAL;
|
||
|
|
waveformat[mSampleID].loopstart = mSample[mSampleID].mWaveSample.loop[0].ulLoopStart;
|
||
|
|
waveformat[mSampleID].loopend = mSample[mSampleID].mWaveSample.loop[0].ulLoopStart +
|
||
|
|
mSample[mSampleID].mWaveSample.loop[0].ulLoopLength - 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (!FMOD_strncmp(parentchunk, "rgn ", 4))
|
||
|
|
{
|
||
|
|
result = mFile->read(&mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample, 1, size, 0);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifdef PLATFORM_ENDIAN_BIG
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample.cbSize = FMOD_SWAPENDIAN_DWORD(mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample.cbSize);
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample.usUnityNote = FMOD_SWAPENDIAN_WORD(mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample.usUnityNote);
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample.sFineTune = FMOD_SWAPENDIAN_WORD(mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample.sFineTune);
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample.lAttenuation = FMOD_SWAPENDIAN_DWORD(mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample.lAttenuation);
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample.fulOptions = FMOD_SWAPENDIAN_DWORD(mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample.fulOptions);
|
||
|
|
|
||
|
|
if (mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample.cSampleLoops)
|
||
|
|
{
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample.loop[0].cbSize = FMOD_SWAPENDIAN_DWORD(mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample.loop[0].cbSize);
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample.loop[0].ulLoopType = FMOD_SWAPENDIAN_DWORD(mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample.loop[0].ulLoopType);
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample.loop[0].ulLoopStart = FMOD_SWAPENDIAN_DWORD(mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample.loop[0].ulLoopStart);
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample.loop[0].ulLoopLength = FMOD_SWAPENDIAN_DWORD(mInstrument[mInstrumentID].mRegion[mRegionID].mWaveSample.loop[0].ulLoopLength);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (!FMOD_strncmp((const char *)chunk.id, "wlnk", 4))
|
||
|
|
{
|
||
|
|
result = mFile->read(&mInstrument[mInstrumentID].mRegion[mRegionID].mWaveLink, 1, sizeof(DLS_WAVELINK), 0);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifdef PLATFORM_ENDIAN_BIG
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mWaveLink.fusOptions = FMOD_SWAPENDIAN_WORD(mInstrument[mInstrumentID].mRegion[mRegionID].mWaveLink.fusOptions);
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mWaveLink.usPhaseGroup = FMOD_SWAPENDIAN_WORD(mInstrument[mInstrumentID].mRegion[mRegionID].mWaveLink.usPhaseGroup);
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mWaveLink.ulChannel = FMOD_SWAPENDIAN_DWORD(mInstrument[mInstrumentID].mRegion[mRegionID].mWaveLink.ulChannel);
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mWaveLink.ulTableIndex = FMOD_SWAPENDIAN_DWORD(mInstrument[mInstrumentID].mRegion[mRegionID].mWaveLink.ulTableIndex);
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
else if (!FMOD_strncmp((const char *)chunk.id, "art1", 4))
|
||
|
|
{
|
||
|
|
struct
|
||
|
|
{
|
||
|
|
unsigned int cbSize;
|
||
|
|
unsigned int cConnectionBlocks;
|
||
|
|
} articulator;
|
||
|
|
|
||
|
|
result = mFile->read(&articulator, 1, sizeof(articulator), 0);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifdef PLATFORM_ENDIAN_BIG
|
||
|
|
articulator.cbSize = FMOD_SWAPENDIAN_DWORD(articulator.cbSize);
|
||
|
|
articulator.cConnectionBlocks = FMOD_SWAPENDIAN_DWORD(articulator.cConnectionBlocks);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
if (articulator.cbSize > sizeof(articulator))
|
||
|
|
{
|
||
|
|
mFile->seek(articulator.cbSize - sizeof(articulator), SEEK_CUR);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (mRegionID < mInstrument[mInstrumentID].mHeader.cRegions)
|
||
|
|
{
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mConnectionBlock = (DLS_CONNECTIONBLOCK *)FMOD_Memory_Calloc(sizeof(DLS_CONNECTIONBLOCK) * articulator.cConnectionBlocks);
|
||
|
|
if (!mInstrument[mInstrumentID].mRegion[mRegionID].mConnectionBlock)
|
||
|
|
{
|
||
|
|
return FMOD_ERR_MEMORY;
|
||
|
|
}
|
||
|
|
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mNumConnectionBlocks = articulator.cConnectionBlocks;
|
||
|
|
|
||
|
|
result = mFile->read(mInstrument[mInstrumentID].mRegion[mRegionID].mConnectionBlock, 1, sizeof(DLS_CONNECTIONBLOCK) * articulator.cConnectionBlocks, 0);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifdef PLATFORM_ENDIAN_BIG
|
||
|
|
{
|
||
|
|
unsigned int count;
|
||
|
|
|
||
|
|
for (count = 0; count < articulator.cConnectionBlocks; count++)
|
||
|
|
{
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mConnectionBlock[count].usSource = FMOD_SWAPENDIAN_WORD(mInstrument[mInstrumentID].mRegion[mRegionID].mConnectionBlock[count].usSource);
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mConnectionBlock[count].usControl = FMOD_SWAPENDIAN_WORD(mInstrument[mInstrumentID].mRegion[mRegionID].mConnectionBlock[count].usControl);
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mConnectionBlock[count].usDestination = FMOD_SWAPENDIAN_WORD(mInstrument[mInstrumentID].mRegion[mRegionID].mConnectionBlock[count].usDestination);
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mConnectionBlock[count].usTransform = FMOD_SWAPENDIAN_WORD(mInstrument[mInstrumentID].mRegion[mRegionID].mConnectionBlock[count].usTransform);
|
||
|
|
mInstrument[mInstrumentID].mRegion[mRegionID].mConnectionBlock[count].lScale = FMOD_SWAPENDIAN_DWORD(mInstrument[mInstrumentID].mRegion[mRegionID].mConnectionBlock[count].lScale);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
mInstrument[mInstrumentID].mConnectionBlock = (DLS_CONNECTIONBLOCK *)FMOD_Memory_Calloc(sizeof(DLS_CONNECTIONBLOCK) * articulator.cConnectionBlocks);
|
||
|
|
if (!mInstrument[mInstrumentID].mConnectionBlock)
|
||
|
|
{
|
||
|
|
return FMOD_ERR_MEMORY;
|
||
|
|
}
|
||
|
|
|
||
|
|
mInstrument[mInstrumentID].mNumConnectionBlocks = articulator.cConnectionBlocks;
|
||
|
|
|
||
|
|
result = mFile->read(mInstrument[mInstrumentID].mConnectionBlock, 1, sizeof(DLS_CONNECTIONBLOCK) * articulator.cConnectionBlocks, 0);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifdef PLATFORM_ENDIAN_BIG
|
||
|
|
unsigned int count;
|
||
|
|
|
||
|
|
for (count = 0; count < articulator.cConnectionBlocks; count++)
|
||
|
|
{
|
||
|
|
mInstrument[mInstrumentID].mConnectionBlock[count].usSource = FMOD_SWAPENDIAN_WORD(mInstrument[mInstrumentID].mConnectionBlock[count].usSource);
|
||
|
|
mInstrument[mInstrumentID].mConnectionBlock[count].usControl = FMOD_SWAPENDIAN_WORD(mInstrument[mInstrumentID].mConnectionBlock[count].usControl);
|
||
|
|
mInstrument[mInstrumentID].mConnectionBlock[count].usDestination = FMOD_SWAPENDIAN_WORD(mInstrument[mInstrumentID].mConnectionBlock[count].usDestination);
|
||
|
|
mInstrument[mInstrumentID].mConnectionBlock[count].usTransform = FMOD_SWAPENDIAN_WORD(mInstrument[mInstrumentID].mConnectionBlock[count].usTransform);
|
||
|
|
mInstrument[mInstrumentID].mConnectionBlock[count].lScale = FMOD_SWAPENDIAN_DWORD(mInstrument[mInstrumentID].mConnectionBlock[count].lScale);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/*
|
||
|
|
FORMAT CHUNK
|
||
|
|
*/
|
||
|
|
else if (!FMOD_strncmp((const char *)chunk.id, "fmt ", 4))
|
||
|
|
{
|
||
|
|
WAVE_FORMATEXTENSIBLE srcformat;
|
||
|
|
unsigned int size = chunk.size;
|
||
|
|
|
||
|
|
/* Reduced allocs here and used a local instance of waveformatextensible instead */
|
||
|
|
if (size > sizeof(WAVE_FORMATEXTENSIBLE))
|
||
|
|
{
|
||
|
|
size = sizeof(WAVE_FORMATEXTENSIBLE);
|
||
|
|
}
|
||
|
|
|
||
|
|
FMOD_memset(&srcformat, 0, sizeof(WAVE_FORMATEXTENSIBLE));
|
||
|
|
result = mFile->read(&srcformat, 1, size, 0);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (chunk.size > sizeof(WAVE_FORMATEXTENSIBLE))
|
||
|
|
{
|
||
|
|
result = mFile->seek(chunk.size - sizeof(WAVE_FORMATEXTENSIBLE), SEEK_CUR);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifdef PLATFORM_ENDIAN_BIG
|
||
|
|
srcformat.Format.wFormatTag = FMOD_SWAPENDIAN_WORD (srcformat.Format.wFormatTag);
|
||
|
|
srcformat.Format.nChannels = FMOD_SWAPENDIAN_WORD (srcformat.Format.nChannels);
|
||
|
|
srcformat.Format.nSamplesPerSec = FMOD_SWAPENDIAN_DWORD(srcformat.Format.nSamplesPerSec);
|
||
|
|
srcformat.Format.nAvgBytesPerSec = FMOD_SWAPENDIAN_DWORD(srcformat.Format.nAvgBytesPerSec);
|
||
|
|
srcformat.Format.nBlockAlign = FMOD_SWAPENDIAN_WORD (srcformat.Format.nBlockAlign);
|
||
|
|
srcformat.Format.wBitsPerSample = FMOD_SWAPENDIAN_WORD (srcformat.Format.wBitsPerSample);
|
||
|
|
srcformat.Format.cbSize = FMOD_SWAPENDIAN_WORD (srcformat.Format.cbSize);
|
||
|
|
srcformat.Samples.wValidBitsPerSample = FMOD_SWAPENDIAN_WORD (srcformat.Samples.wValidBitsPerSample);
|
||
|
|
srcformat.dwChannelMask = FMOD_SWAPENDIAN_DWORD(srcformat.dwChannelMask);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
switch (srcformat.Format.wBitsPerSample)
|
||
|
|
{
|
||
|
|
case 4:
|
||
|
|
{
|
||
|
|
if (srcformat.Format.wFormatTag == 0x6666)
|
||
|
|
{
|
||
|
|
waveformat[mSampleID].format = FMOD_SOUND_FORMAT_VAG;
|
||
|
|
}
|
||
|
|
else if (srcformat.Format.wFormatTag == 0x7777)
|
||
|
|
{
|
||
|
|
waveformat[mSampleID].format = FMOD_SOUND_FORMAT_GCADPCM;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case 8:
|
||
|
|
{
|
||
|
|
waveformat[mSampleID].format = FMOD_SOUND_FORMAT_PCM8;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case 16:
|
||
|
|
{
|
||
|
|
waveformat[mSampleID].format = FMOD_SOUND_FORMAT_PCM16;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case 24:
|
||
|
|
{
|
||
|
|
waveformat[mSampleID].format = FMOD_SOUND_FORMAT_PCM24;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case 32:
|
||
|
|
{
|
||
|
|
if (srcformat.Format.wFormatTag == WAVE_FORMAT_PCM)
|
||
|
|
{
|
||
|
|
waveformat[mSampleID].format = FMOD_SOUND_FORMAT_PCM32;
|
||
|
|
}
|
||
|
|
else if (srcformat.Format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
|
||
|
|
{
|
||
|
|
waveformat[mSampleID].format = FMOD_SOUND_FORMAT_PCMFLOAT;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
waveformat[mSampleID].channels = srcformat.Format.nChannels;
|
||
|
|
waveformat[mSampleID].frequency = srcformat.Format.nSamplesPerSec;
|
||
|
|
waveformat[mSampleID].blockalign = srcformat.Format.nBlockAlign;
|
||
|
|
}
|
||
|
|
/*
|
||
|
|
DATA CHUNK
|
||
|
|
*/
|
||
|
|
else if (!FMOD_strncmp((const char *)chunk.id, "data", 4))
|
||
|
|
{
|
||
|
|
SoundI::getSamplesFromBytes(chunk.size, &waveformat[mSampleID].lengthpcm, waveformat[mSampleID].channels, waveformat[mSampleID].format);
|
||
|
|
|
||
|
|
result = mFile->tell(&mSample[mSampleID].mDataOffset);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (!FMOD_strncmp((const char *)chunk.id, "INAM", 4))
|
||
|
|
{
|
||
|
|
if (mInstrumentID < mNumInstruments)
|
||
|
|
{
|
||
|
|
FMOD_memset(mInstrument[mInstrumentID].mName, 0, FMOD_STRING_MAXNAMELEN);
|
||
|
|
|
||
|
|
result = mFile->read(mInstrument[mInstrumentID].mName, 1, chunk.size, 0);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (mSampleID < mNumSamples)
|
||
|
|
{
|
||
|
|
FMOD_memset(mSample[mSampleID].mName, 0, FMOD_STRING_MAXNAMELEN);
|
||
|
|
|
||
|
|
result = mFile->read(mSample[mSampleID].mName, 1, chunk.size, 0);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
FMOD_strncpy(waveformat[mSampleID].name, mSample[mSampleID].mName, FMOD_STRING_MAXNAMELEN);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (!FMOD_strncmp((const char *)chunk.id, "IARL", 4) ||
|
||
|
|
!FMOD_strncmp((const char *)chunk.id, "IART", 4) ||
|
||
|
|
!FMOD_strncmp((const char *)chunk.id, "ICMS", 4) ||
|
||
|
|
!FMOD_strncmp((const char *)chunk.id, "ICMT", 4) ||
|
||
|
|
!FMOD_strncmp((const char *)chunk.id, "ICOP", 4) ||
|
||
|
|
!FMOD_strncmp((const char *)chunk.id, "ICRD", 4) ||
|
||
|
|
!FMOD_strncmp((const char *)chunk.id, "IENG", 4) ||
|
||
|
|
!FMOD_strncmp((const char *)chunk.id, "IGNR", 4) ||
|
||
|
|
!FMOD_strncmp((const char *)chunk.id, "IKEY", 4) ||
|
||
|
|
!FMOD_strncmp((const char *)chunk.id, "IMED", 4) ||
|
||
|
|
!FMOD_strncmp((const char *)chunk.id, "IPRD", 4) ||
|
||
|
|
!FMOD_strncmp((const char *)chunk.id, "ISBJ", 4) ||
|
||
|
|
!FMOD_strncmp((const char *)chunk.id, "ISFT", 4) ||
|
||
|
|
!FMOD_strncmp((const char *)chunk.id, "ISRC", 4) ||
|
||
|
|
!FMOD_strncmp((const char *)chunk.id, "ISRF", 4) ||
|
||
|
|
!FMOD_strncmp((const char *)chunk.id, "ITCH", 4))
|
||
|
|
{
|
||
|
|
result = result;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
mFile->seek(chunk.size, SEEK_CUR);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
offset += (chunk.size+sizeof(WAVE_CHUNK));
|
||
|
|
fileoffset += (chunk.size+sizeof(WAVE_CHUNK));
|
||
|
|
|
||
|
|
if (chunk.size & 1)
|
||
|
|
{
|
||
|
|
offset++;
|
||
|
|
fileoffset++;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (chunk.size < 0)
|
||
|
|
{
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
//FLOG((FMOD_DEBUG_LEVEL_LOG, __FILE__, __LINE__, "CodecDLS::parseRIFF", "offset = %d / %d\n", offset, chunksize));
|
||
|
|
|
||
|
|
} while (offset < chunksize && offset > 0 && !done);
|
||
|
|
|
||
|
|
return FMOD_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT CodecDLS::openInternal(FMOD_MODE usermode, FMOD_CREATESOUNDEXINFO *userexinfo)
|
||
|
|
{
|
||
|
|
FMOD_RESULT result = FMOD_OK;
|
||
|
|
WAVE_CHUNK chunk;
|
||
|
|
char dls[4];
|
||
|
|
|
||
|
|
init(FMOD_SOUND_TYPE_DLS);
|
||
|
|
|
||
|
|
FLOG((FMOD_DEBUG_LEVEL_LOG, __FILE__, __LINE__, "CodecDLS::openInternal", "attempting to open as DLS..\n"));
|
||
|
|
|
||
|
|
result = mFile->seek(0, SEEK_SET);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
mSrcDataOffset = 0;
|
||
|
|
mNumInstruments = 0;
|
||
|
|
mNumSamples = 0;
|
||
|
|
|
||
|
|
result = mFile->read(&chunk, 1, sizeof(WAVE_CHUNK), 0);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (FMOD_strncmp((const char *)chunk.id, "RIFF", 4))
|
||
|
|
{
|
||
|
|
return FMOD_ERR_FORMAT;
|
||
|
|
}
|
||
|
|
|
||
|
|
result = mFile->read(dls, 1, 4, 0);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (FMOD_strncmp(dls, "DLS ", 4))
|
||
|
|
{
|
||
|
|
return FMOD_ERR_FORMAT;
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifdef PLATFORM_ENDIAN_BIG
|
||
|
|
chunk.size = FMOD_SWAPENDIAN_DWORD(chunk.size);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
mSrcDataOffset = 0;
|
||
|
|
mSampleID = 0;
|
||
|
|
|
||
|
|
result = parseChunk(dls, chunk.size);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (mNumInstruments <= 0)
|
||
|
|
{
|
||
|
|
return FMOD_ERR_FORMAT;
|
||
|
|
}
|
||
|
|
|
||
|
|
numsubsounds = mNumSamples;
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT CodecDLS::closeInternal()
|
||
|
|
{
|
||
|
|
if (waveformat)
|
||
|
|
{
|
||
|
|
FMOD_Memory_Free(waveformat);
|
||
|
|
waveformat = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (mInstrument)
|
||
|
|
{
|
||
|
|
int count;
|
||
|
|
|
||
|
|
for (count = 0; count < mNumInstruments; count++)
|
||
|
|
{
|
||
|
|
if (mInstrument[count].mRegion)
|
||
|
|
{
|
||
|
|
unsigned int region;
|
||
|
|
|
||
|
|
/*
|
||
|
|
Look for special drum articulators.
|
||
|
|
*/
|
||
|
|
for (region = 0; region < mInstrument[count].mHeader.cRegions; region++)
|
||
|
|
{
|
||
|
|
if (mInstrument[count].mRegion[region].mConnectionBlock)
|
||
|
|
{
|
||
|
|
FMOD_Memory_Free(mInstrument[count].mRegion[region].mConnectionBlock);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
FMOD_Memory_Free(mInstrument[count].mRegion);
|
||
|
|
}
|
||
|
|
if (mInstrument[count].mConnectionBlock)
|
||
|
|
{
|
||
|
|
FMOD_Memory_Free(mInstrument[count].mConnectionBlock);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
FMOD_Memory_Free(mInstrument);
|
||
|
|
mInstrument = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (mSample)
|
||
|
|
{
|
||
|
|
FMOD_Memory_Free(mSample);
|
||
|
|
mSample = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
return FMOD_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT CodecDLS::readInternal(void *buffer, unsigned int sizebytes, unsigned int *bytesread)
|
||
|
|
{
|
||
|
|
FMOD_RESULT result = FMOD_OK;
|
||
|
|
|
||
|
|
result = mFile->read(buffer, 1, sizebytes, bytesread);
|
||
|
|
if (result != FMOD_OK && result != FMOD_ERR_FILE_EOF)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
PCM8 is stored in unsigned 8-bit, so convert it to signed 8-bit for FMOD
|
||
|
|
*/
|
||
|
|
if (waveformat[mCurrentIndex].format == FMOD_SOUND_FORMAT_PCM8)
|
||
|
|
{
|
||
|
|
unsigned char *wptr = (unsigned char *)buffer;
|
||
|
|
|
||
|
|
for (unsigned int count = 0; count < *bytesread; count++)
|
||
|
|
{
|
||
|
|
*wptr++ ^= 128;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else /* Must be PCM16 */
|
||
|
|
{
|
||
|
|
#ifdef PLATFORM_ENDIAN_BIG
|
||
|
|
{
|
||
|
|
signed short *wptr = (signed short *)buffer;
|
||
|
|
|
||
|
|
for (unsigned int count = 0; count < *bytesread >> 1; count++)
|
||
|
|
{
|
||
|
|
wptr[count] = FMOD_SWAPENDIAN_WORD(wptr[count]);
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT CodecDLS::setPositionInternal(int subsound, unsigned int position, FMOD_TIMEUNIT postype)
|
||
|
|
{
|
||
|
|
FMOD_RESULT result = FMOD_OK;
|
||
|
|
|
||
|
|
if (subsound < 0 || (numsubsounds && subsound >= numsubsounds))
|
||
|
|
{
|
||
|
|
return FMOD_ERR_INVALID_POSITION;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (mFile->mFlags & FMOD_FILE_SEEKABLE)
|
||
|
|
{
|
||
|
|
unsigned int posbytes;
|
||
|
|
|
||
|
|
if (subsound != mCurrentIndex)
|
||
|
|
{
|
||
|
|
mCurrentIndex = subsound;
|
||
|
|
}
|
||
|
|
|
||
|
|
result = SoundI::getBytesFromSamples(position, &posbytes, waveformat[mCurrentIndex].channels, waveformat[mCurrentIndex].format);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
posbytes += mSample[mCurrentIndex].mDataOffset;
|
||
|
|
|
||
|
|
result = mFile->seek(posbytes, SEEK_SET);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT F_CALLBACK CodecDLS::openCallback(FMOD_CODEC_STATE *codec, FMOD_MODE usermode, FMOD_CREATESOUNDEXINFO *userexinfo)
|
||
|
|
{
|
||
|
|
CodecDLS *dls = (CodecDLS *)codec;
|
||
|
|
|
||
|
|
return dls->openInternal(usermode, userexinfo);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT F_CALLBACK CodecDLS::closeCallback(FMOD_CODEC_STATE *codec)
|
||
|
|
{
|
||
|
|
CodecDLS *dls = (CodecDLS *)codec;
|
||
|
|
|
||
|
|
return dls->closeInternal();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT F_CALLBACK CodecDLS::readCallback(FMOD_CODEC_STATE *codec, void *buffer, unsigned int sizebytes, unsigned int *bytesread)
|
||
|
|
{
|
||
|
|
CodecDLS *dls = (CodecDLS *)codec;
|
||
|
|
|
||
|
|
return dls->readInternal(buffer, sizebytes, bytesread);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT F_CALLBACK CodecDLS::setPositionCallback(FMOD_CODEC_STATE *codec, int subsound, unsigned int position, FMOD_TIMEUNIT postype)
|
||
|
|
{
|
||
|
|
CodecDLS *dls = (CodecDLS *)codec;
|
||
|
|
|
||
|
|
return dls->setPositionInternal(subsound, position, postype);
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif
|
||
|
|
|