487 lines
7.2 KiB
C++
487 lines
7.2 KiB
C++
|
|
#include "fmod_settings.h"
|
||
|
|
|
||
|
|
#ifdef FMOD_SUPPORT_WINAMPPLUGIN
|
||
|
|
|
||
|
|
#include "fmod.h"
|
||
|
|
#include "fmod_dsp_winampplugin.h"
|
||
|
|
#include "fmod_systemi.h"
|
||
|
|
|
||
|
|
#define BUFFERSIZE 256
|
||
|
|
|
||
|
|
namespace FMOD
|
||
|
|
{
|
||
|
|
|
||
|
|
FMOD_DSP_DESCRIPTION_EX dspwinampplugin;
|
||
|
|
|
||
|
|
#ifdef PLUGIN_EXPORTS
|
||
|
|
|
||
|
|
#ifdef __cplusplus
|
||
|
|
extern "C" {
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/*
|
||
|
|
FMODGetDSPDescription is mandantory 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_DSP_DESCRIPTION_EX * F_API FMODGetDSPDescriptionEx()
|
||
|
|
{
|
||
|
|
return DSPWinampPlugin::getDescriptionEx();
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifdef __cplusplus
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#endif /* PLUGIN_EXPORTS */
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_DSP_DESCRIPTION_EX *DSPWinampPlugin::getDescriptionEx()
|
||
|
|
{
|
||
|
|
FMOD_memset(&dspwinampplugin, 0, sizeof(FMOD_DSP_DESCRIPTION_EX));
|
||
|
|
|
||
|
|
// name and version is stamped in later.
|
||
|
|
dspwinampplugin.create = DSPWinampPlugin::createCallback;
|
||
|
|
dspwinampplugin.release = DSPWinampPlugin::releaseCallback;
|
||
|
|
dspwinampplugin.reset = DSPWinampPlugin::resetCallback;
|
||
|
|
dspwinampplugin.read = DSPWinampPlugin::readCallback;
|
||
|
|
|
||
|
|
dspwinampplugin.setparameter = DSPWinampPlugin::setParameterCallback;
|
||
|
|
dspwinampplugin.getparameter = DSPWinampPlugin::getParameterCallback;
|
||
|
|
dspwinampplugin.config = DSPWinampPlugin::configCallback;
|
||
|
|
|
||
|
|
dspwinampplugin.mType = FMOD_DSP_TYPE_WINAMPPLUGIN;
|
||
|
|
dspwinampplugin.mCategory = FMOD_DSP_CATEGORY_FILTER;
|
||
|
|
dspwinampplugin.mSize = sizeof(DSPWinampPlugin);
|
||
|
|
|
||
|
|
return &dspwinampplugin;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
short *DSPWinampPlugin::mEffectBuffer = NULL;
|
||
|
|
int DSPWinampPlugin::mEffectBufferCount = 0;
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT DSPWinampPlugin::createInternal()
|
||
|
|
{
|
||
|
|
int result;
|
||
|
|
|
||
|
|
if (mEffectBufferCount == 0)
|
||
|
|
{
|
||
|
|
mEffectBuffer = (short *)FMOD_Memory_Alloc(sizeof(short) * BUFFERSIZE);
|
||
|
|
if (!mEffectBuffer)
|
||
|
|
{
|
||
|
|
return FMOD_ERR_MEMORY;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
mEffectBufferCount++;
|
||
|
|
|
||
|
|
result = mEffect->Init(mEffect);
|
||
|
|
|
||
|
|
if (result)
|
||
|
|
{
|
||
|
|
return FMOD_ERR_PLUGIN;
|
||
|
|
}
|
||
|
|
|
||
|
|
return FMOD_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT DSPWinampPlugin::releaseInternal()
|
||
|
|
{
|
||
|
|
mEffectBufferCount--;
|
||
|
|
|
||
|
|
if (mEffectBufferCount == 0)
|
||
|
|
{
|
||
|
|
FMOD_Memory_Free(mEffectBuffer);
|
||
|
|
mEffectBuffer = NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
mEffect->Quit(mEffect);
|
||
|
|
|
||
|
|
return FMOD_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
FMOD_OK
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT DSPWinampPlugin::resetInternal()
|
||
|
|
{
|
||
|
|
return FMOD_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
FMOD_OK
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT DSPWinampPlugin::readInternal(float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels)
|
||
|
|
{
|
||
|
|
int count;
|
||
|
|
int rate;
|
||
|
|
int remaining = length * outchannels;
|
||
|
|
|
||
|
|
mSystem->getSoftwareFormat(&rate, 0, 0, 0, 0, 0);
|
||
|
|
|
||
|
|
while(remaining > 0)
|
||
|
|
{
|
||
|
|
int size = remaining;
|
||
|
|
|
||
|
|
if (size > BUFFERSIZE)
|
||
|
|
{
|
||
|
|
size = BUFFERSIZE;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
Convert from float to short
|
||
|
|
*/
|
||
|
|
for (count = 0; count < size; count++)
|
||
|
|
{
|
||
|
|
float val = *inbuffer++;
|
||
|
|
|
||
|
|
mEffectBuffer[count] = (short)(val < -1.0f ? -32767 : val > 1.0f ? 32767 : val * 32767.0f);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
mEffect->ModifySamples(mEffect, mEffectBuffer, size / outchannels, 16, outchannels, rate);
|
||
|
|
|
||
|
|
/*
|
||
|
|
Convert back to floating point data
|
||
|
|
*/
|
||
|
|
for (count = 0; count < size; count++)
|
||
|
|
{
|
||
|
|
*outbuffer++ = (float)mEffectBuffer[count] / 32767.0f;
|
||
|
|
}
|
||
|
|
|
||
|
|
remaining -= size;
|
||
|
|
}
|
||
|
|
|
||
|
|
return FMOD_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
FMOD_OK
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT DSPWinampPlugin::setParameterInternal(int index, float value)
|
||
|
|
{
|
||
|
|
return FMOD_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT DSPWinampPlugin::getParameterInternal(int index, float *value, char *valuestr)
|
||
|
|
{
|
||
|
|
return FMOD_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT DSPWinampPlugin::showConfigDialogInternal(void *hwnd, int show)
|
||
|
|
{
|
||
|
|
mEffect->hwndParent = hwnd;
|
||
|
|
|
||
|
|
mEffect->Config(mEffect);
|
||
|
|
|
||
|
|
return FMOD_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
==============================================================================================================
|
||
|
|
|
||
|
|
CALLBACK INTERFACE
|
||
|
|
|
||
|
|
==============================================================================================================
|
||
|
|
*/
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT F_CALLBACK DSPWinampPlugin::createCallback(FMOD_DSP_STATE *dsp)
|
||
|
|
{
|
||
|
|
DSPWinampPlugin *winamp = (DSPWinampPlugin *)dsp;
|
||
|
|
|
||
|
|
return winamp->createInternal();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT F_CALLBACK DSPWinampPlugin::releaseCallback(FMOD_DSP_STATE *dsp)
|
||
|
|
{
|
||
|
|
DSPWinampPlugin *winamp = (DSPWinampPlugin *)dsp;
|
||
|
|
|
||
|
|
return winamp->releaseInternal();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT F_CALLBACK DSPWinampPlugin::resetCallback(FMOD_DSP_STATE *dsp)
|
||
|
|
{
|
||
|
|
DSPWinampPlugin *winamp = (DSPWinampPlugin *)dsp;
|
||
|
|
|
||
|
|
return winamp->resetInternal();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT F_CALLBACK DSPWinampPlugin::readCallback(FMOD_DSP_STATE *dsp, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels)
|
||
|
|
{
|
||
|
|
DSPWinampPlugin *winamp = (DSPWinampPlugin *)dsp;
|
||
|
|
|
||
|
|
return winamp->readInternal(inbuffer, outbuffer, length, inchannels, outchannels);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT F_CALLBACK DSPWinampPlugin::setParameterCallback(FMOD_DSP_STATE *dsp, int index, float value)
|
||
|
|
{
|
||
|
|
DSPWinampPlugin *winamp = (DSPWinampPlugin *)dsp;
|
||
|
|
|
||
|
|
return winamp->setParameterInternal(index, value);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT F_CALLBACK DSPWinampPlugin::getParameterCallback(FMOD_DSP_STATE *dsp, int index, float *value, char *valuestr)
|
||
|
|
{
|
||
|
|
DSPWinampPlugin *winamp = (DSPWinampPlugin *)dsp;
|
||
|
|
|
||
|
|
return winamp->getParameterInternal(index, value, valuestr);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[PLATFORMS]
|
||
|
|
Win32
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT F_CALLBACK DSPWinampPlugin::configCallback(FMOD_DSP_STATE *dsp, void *hwnd, int show)
|
||
|
|
{
|
||
|
|
DSPWinampPlugin *winamp = (DSPWinampPlugin *)dsp;
|
||
|
|
|
||
|
|
return winamp->showConfigDialogInternal(hwnd, show);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif
|