597 lines
10 KiB
C++
Executable file
597 lines
10 KiB
C++
Executable file
#include "fmod_settings.h"
|
|
|
|
#ifdef FMOD_SUPPORT_FREEVERB
|
|
|
|
#include "fmod.h"
|
|
#include "fmod_dspi.h"
|
|
#include "fmod_dsp_reverb.h"
|
|
#include "fmod_systemi.h"
|
|
|
|
namespace FMOD
|
|
{
|
|
|
|
FMOD_DSP_DESCRIPTION_EX dspreverb;
|
|
|
|
#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 DSPReverb::getDescriptionEx();
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* PLUGIN_EXPORTS */
|
|
|
|
|
|
FMOD_DSP_PARAMETERDESC dspreverb_param[6] =
|
|
{
|
|
{ 0.0f, 1.0f, 0.5f, "Roomsize", "", "Roomsize. 0.0 to 1.0. Default = 0.5" },
|
|
{ 0.0f, 1.0f, 0.5f, "Damp", "", "Damp. 0.0 to 1.0. Default = 0.5" },
|
|
{ 0.0f, 1.0f, 0.33f, "Wet", "", "Wet mix. 0.0 to 1.0. Default = 0.33" },
|
|
{ 0.0f, 1.0f, 0.66f, "Dry", "", "Dry mix. 0.0 to 1.0. Default = 0.66" },
|
|
{ 0.0f, 1.0f, 1.0f, "Width", "", "Width. 0.0 to 1.0. Default = 1.0" },
|
|
{ 0.0f, 1.0f, 0.0f, "Mode", "", "Mode. 0, 1. Default = 0" }
|
|
};
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[PLATFORMS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
FMOD_DSP_DESCRIPTION_EX *DSPReverb::getDescriptionEx()
|
|
{
|
|
FMOD_memset(&dspreverb, 0, sizeof(FMOD_DSP_DESCRIPTION_EX));
|
|
|
|
FMOD_strcpy(dspreverb.name, "FMOD Reverb");
|
|
dspreverb.version = 0x00010100;
|
|
dspreverb.create = DSPReverb::createCallback;
|
|
dspreverb.release = DSPReverb::releaseCallback;
|
|
dspreverb.reset = DSPReverb::resetCallback;
|
|
dspreverb.read = DSPReverb::readCallback;
|
|
|
|
dspreverb.numparameters = 6;
|
|
dspreverb.paramdesc = dspreverb_param;
|
|
dspreverb.setparameter = DSPReverb::setParameterCallback;
|
|
dspreverb.getparameter = DSPReverb::getParameterCallback;
|
|
#ifdef FMOD_SUPPORT_MEMORYTRACKER
|
|
dspreverb.getmemoryused = &DSPReverb::getMemoryUsedCallback;
|
|
#endif
|
|
|
|
dspreverb.mType = FMOD_DSP_TYPE_REVERB;
|
|
dspreverb.mCategory = FMOD_DSP_CATEGORY_FILTER;
|
|
dspreverb.mSize = sizeof(DSPReverb);
|
|
|
|
return &dspreverb;
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[PLATFORMS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
FMOD_RESULT DSPReverb::createInternal()
|
|
{
|
|
int count;
|
|
|
|
init();
|
|
|
|
new (&mReverb) revmodel;
|
|
|
|
for (count = 0; count < mDescription.numparameters; count++)
|
|
{
|
|
FMOD_RESULT result;
|
|
|
|
result = setParameter(count, mDescription.paramdesc[count].defaultval);
|
|
if (result != FMOD_OK)
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
return FMOD_OK;
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[PLATFORMS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
FMOD_RESULT DSPReverb::releaseInternal()
|
|
{
|
|
return FMOD_OK;
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
FMOD_OK
|
|
|
|
[REMARKS]
|
|
|
|
[PLATFORMS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
FMOD_RESULT DSPReverb::resetInternal()
|
|
{
|
|
return FMOD_OK;
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
FMOD_OK
|
|
|
|
[REMARKS]
|
|
|
|
[PLATFORMS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
FMOD_RESULT DSPReverb::readInternal(float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels)
|
|
{
|
|
float *inleft = inbuffer;
|
|
float *inright = inbuffer + 1;
|
|
|
|
float *outleft = outbuffer;
|
|
float *outright = outbuffer + 1;
|
|
|
|
if (!inbuffer)
|
|
{
|
|
return FMOD_OK;
|
|
}
|
|
|
|
if ((speakermask & 0x3) == 0) /* Both speaker channels have been set to inactive */
|
|
{
|
|
FMOD_memcpy(outbuffer, inbuffer, inchannels*length*sizeof(float));
|
|
return FMOD_OK;
|
|
}
|
|
|
|
if (inchannels > 2 || ((speakermask & 0x3) != 0x3))
|
|
{
|
|
// Prevent output buffer crosstalk by ensuring every sample is set
|
|
FMOD_memcpy(outbuffer, inbuffer, inchannels*length*sizeof(float));
|
|
}
|
|
|
|
mReverb.processreplace(inleft, inright, outleft, outright, length, inchannels, speakermask);
|
|
|
|
return FMOD_OK;
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
FMOD_OK
|
|
|
|
[REMARKS]
|
|
|
|
[PLATFORMS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
FMOD_RESULT DSPReverb::setParameterInternal(int index, float value)
|
|
{
|
|
mSystem->lockDSP();
|
|
|
|
switch (index)
|
|
{
|
|
case FMOD_DSP_REVERB_ROOMSIZE:
|
|
{
|
|
if (value > 1.0f)
|
|
{
|
|
value = 1.0f;
|
|
}
|
|
else if (value < 0.0f)
|
|
{
|
|
value = 0.0f;
|
|
}
|
|
mReverb.setroomsize(value);
|
|
break;
|
|
}
|
|
case FMOD_DSP_REVERB_DAMP:
|
|
{
|
|
if (value > 1.0f)
|
|
{
|
|
value = 1.0f;
|
|
}
|
|
else if (value < 0.0f)
|
|
{
|
|
value = 0.0f;
|
|
}
|
|
mReverb.setdamp(value);
|
|
break;
|
|
}
|
|
case FMOD_DSP_REVERB_WETMIX:
|
|
{
|
|
if (value > 1.0f)
|
|
{
|
|
value = 1.0f;
|
|
}
|
|
else if (value < 0.0f)
|
|
{
|
|
value = 0.0f;
|
|
}
|
|
mReverb.setwet(value);
|
|
break;
|
|
}
|
|
case FMOD_DSP_REVERB_DRYMIX:
|
|
{
|
|
if (value > 1.0f)
|
|
{
|
|
value = 1.0f;
|
|
}
|
|
else if (value < 0.0f)
|
|
{
|
|
value = 0.0f;
|
|
}
|
|
mReverb.setdry(value);
|
|
break;
|
|
}
|
|
case FMOD_DSP_REVERB_WIDTH:
|
|
{
|
|
if (value > 1.0f)
|
|
{
|
|
value = 1.0f;
|
|
}
|
|
else if (value < 0.0f)
|
|
{
|
|
value = 0.0f;
|
|
}
|
|
mReverb.setwidth(value);
|
|
break;
|
|
}
|
|
case FMOD_DSP_REVERB_MODE:
|
|
{
|
|
if (value >= freezemode)
|
|
{
|
|
value = 1.0f;
|
|
}
|
|
else
|
|
{
|
|
value = 0.0f;
|
|
}
|
|
mReverb.setmode(value);
|
|
break;
|
|
}
|
|
}
|
|
|
|
mSystem->unlockDSP();
|
|
|
|
return FMOD_OK;
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[PLATFORMS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
FMOD_RESULT DSPReverb::getParameterInternal(int index, float *value, char *valuestr)
|
|
{
|
|
switch (index)
|
|
{
|
|
case FMOD_DSP_REVERB_ROOMSIZE:
|
|
{
|
|
*value = mReverb.getroomsize();
|
|
sprintf(valuestr, "%0.2f", *value);
|
|
break;
|
|
}
|
|
case FMOD_DSP_REVERB_DAMP:
|
|
{
|
|
*value = mReverb.getdamp();
|
|
sprintf(valuestr, "%0.2f", *value);
|
|
break;
|
|
}
|
|
case FMOD_DSP_REVERB_WETMIX:
|
|
{
|
|
*value = mReverb.getwet();
|
|
sprintf(valuestr, "%0.2f", *value);
|
|
break;
|
|
}
|
|
case FMOD_DSP_REVERB_DRYMIX:
|
|
{
|
|
*value = mReverb.getdry();
|
|
sprintf(valuestr, "%0.2f", *value);
|
|
break;
|
|
}
|
|
case FMOD_DSP_REVERB_WIDTH:
|
|
{
|
|
*value = mReverb.getwidth();
|
|
sprintf(valuestr, "%0.2f", *value);
|
|
break;
|
|
}
|
|
case FMOD_DSP_REVERB_MODE:
|
|
{
|
|
*value = mReverb.getmode();
|
|
if (*value >= freezemode)
|
|
{
|
|
*value = 1.0f;
|
|
sprintf(valuestr, "FREEZE");
|
|
}
|
|
else
|
|
{
|
|
*value = 0.0f;
|
|
sprintf(valuestr, "NORMAL");
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return FMOD_OK;
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[PLATFORMS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
|
|
#ifdef FMOD_SUPPORT_MEMORYTRACKER
|
|
|
|
FMOD_RESULT DSPReverb::getMemoryUsedImpl(MemoryTracker *tracker)
|
|
{
|
|
// Size of this class is already accounted for (via description.mSize). Just add extra allocated memory here.
|
|
|
|
return FMOD_OK;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/*
|
|
==============================================================================================================
|
|
|
|
CALLBACK INTERFACE
|
|
|
|
==============================================================================================================
|
|
*/
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[PLATFORMS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
FMOD_RESULT F_CALLBACK DSPReverb::createCallback(FMOD_DSP_STATE *dsp)
|
|
{
|
|
DSPReverb *reverb = (DSPReverb *)dsp;
|
|
|
|
return reverb->createInternal();
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[PLATFORMS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
FMOD_RESULT F_CALLBACK DSPReverb::releaseCallback(FMOD_DSP_STATE *dsp)
|
|
{
|
|
DSPReverb *reverb = (DSPReverb *)dsp;
|
|
|
|
return reverb->releaseInternal();
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[PLATFORMS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
FMOD_RESULT F_CALLBACK DSPReverb::resetCallback(FMOD_DSP_STATE *dsp)
|
|
{
|
|
DSPReverb *reverb = (DSPReverb *)dsp;
|
|
|
|
return reverb->resetInternal();
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[PLATFORMS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
FMOD_RESULT F_CALLBACK DSPReverb::readCallback(FMOD_DSP_STATE *dsp, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels)
|
|
{
|
|
DSPReverb *reverb = (DSPReverb *)dsp;
|
|
|
|
return reverb->readInternal(inbuffer, outbuffer, length, inchannels, outchannels);
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[PLATFORMS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
FMOD_RESULT F_CALLBACK DSPReverb::setParameterCallback(FMOD_DSP_STATE *dsp, int index, float value)
|
|
{
|
|
DSPReverb *reverb = (DSPReverb *)dsp;
|
|
|
|
return reverb->setParameterInternal(index, value);
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[PLATFORMS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
FMOD_RESULT F_CALLBACK DSPReverb::getParameterCallback(FMOD_DSP_STATE *dsp, int index, float *value, char *valuestr)
|
|
{
|
|
DSPReverb *reverb = (DSPReverb *)dsp;
|
|
|
|
return reverb->getParameterInternal(index, value, valuestr);
|
|
}
|
|
|
|
|
|
#ifdef FMOD_SUPPORT_MEMORYTRACKER
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[PLATFORMS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
FMOD_RESULT F_CALLBACK DSPReverb::getMemoryUsedCallback(FMOD_DSP_STATE *dsp, MemoryTracker *tracker)
|
|
{
|
|
DSPReverb *reverb = (DSPReverb *)dsp;
|
|
|
|
return reverb->DSPReverb::getMemoryUsed(tracker);
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif
|