/*=============================================================================================== DSP_GAIN.DLL Copyright (c), Firelight Technologies Pty, Ltd 2005-2016. ===============================================================================================*/ #include #include #include "../../../api/inc/fmod.h" #include "../../../api/inc/fmod_errors.h" FMOD_RESULT F_CALLBACK dspcreate (FMOD_DSP_STATE *dsp); FMOD_RESULT F_CALLBACK dsprelease (FMOD_DSP_STATE *dsp); FMOD_RESULT F_CALLBACK dspreset (FMOD_DSP_STATE *dsp); FMOD_RESULT F_CALLBACK dspread (FMOD_DSP_STATE *dsp, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels); FMOD_RESULT F_CALLBACK dspsetparam(FMOD_DSP_STATE *dsp, int index, float value); FMOD_RESULT F_CALLBACK dspgetparam(FMOD_DSP_STATE *dsp, int index, float *value, char *valuestr); /* DSP Parameter list. */ FMOD_DSP_PARAMETERDESC dspparam[1] = { { 0.0f, 1.0f, 1.0, "Level", "%", "Gain level" }, }; FMOD_DSP_DESCRIPTION dspgaindesc = { "FMOD gain example", // name 0x00010000, // version 0xAAAABBBB A = major, B = minor. 0, // 0 = we can filter whatever you throw at us. To be most user friendly, always write a filter like this. dspcreate, // dsprelease, // dspreset, // dspread, // 0, // This is for if you want to allow the plugin to seek, which doesnt really make sense in a gain filter so we'll just leave it out. 1, // 1 parameter. "level" dspparam, // pointer to the parameter list definition. dspsetparam, // dspgetparam, // 0, // This is for if you want to pop up a dialog box to configure the plugin. Not doing that here. 0, // This is for if you want to pop up a dialog box to configure the plugin. Not doing that here. 0, // This is for if you want to pop up a dialog box to configure the plugin. Not doing that here. }; /* 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. MUST BE EXTERN'ED AS C! C++ functions will be mangled incorrectly and not load in fmod. */ #ifdef __cplusplus extern "C" { #endif F_DECLSPEC F_DLLEXPORT FMOD_DSP_DESCRIPTION * F_API FMODGetDSPDescription() { return &dspgaindesc; } #ifdef __cplusplus } #endif typedef struct dspgain_state { float gain; } dspgain_state; FMOD_RESULT F_CALLBACK dspcreate(FMOD_DSP_STATE *dsp) { dspgain_state *state; /* If we were allocating memory for buffers etc, it would be done in this function. */ state = (dspgain_state *)malloc(sizeof(dspgain_state)); if (!state) { return FMOD_ERR_MEMORY; } state->gain = dspparam[0].defaultval; dsp->plugindata = state; return FMOD_OK; } FMOD_RESULT F_CALLBACK dsprelease(FMOD_DSP_STATE *dsp) { dspgain_state *state = dsp->plugindata; /* If memory was allocated in create, it would be freed in this function. */ free(state); return FMOD_OK; } FMOD_RESULT F_CALLBACK dspreset(FMOD_DSP_STATE *dsp) { dspgain_state *state = dsp->plugindata; /* This callback isnt really needed for a gain filter. It is used to reset a filter back to it's default state. This is where buffers would be cleared so that the filter is ready for reuse. */ return FMOD_OK; } /* This callback does the work. Modify data from inbuffer and send it to outbuffer. */ FMOD_RESULT F_CALLBACK dspread(FMOD_DSP_STATE *dsp, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels) { dspgain_state *state = dsp->plugindata; unsigned int count; int count2; int channels = inchannels; // outchannels and inchannels will always be the same because this is a flexible filter. for (count = 0; count < length; count++) { for (count2 = 0; count2 < channels; count2++) { outbuffer[(count * channels) + count2] = inbuffer[(count * channels) + count2] * state->gain; } } return FMOD_OK; } /* This callback is for when the user sets a parameter. It is automatically clamped between 0 and 1. */ FMOD_RESULT F_CALLBACK dspsetparam(FMOD_DSP_STATE *dsp, int index, float value) { dspgain_state *state = dsp->plugindata; switch (index) { case 0: { state->gain = value; break; } } return FMOD_OK; } /* This callback is for when the user gets a parameter. The label for our only parameter is percent, so when the string is requested print it out as 0 to 100. */ FMOD_RESULT F_CALLBACK dspgetparam(FMOD_DSP_STATE *dsp, int index, float *value, char *valuestr) { dspgain_state *state = dsp->plugindata; switch (index) { case 0: { *value = state->gain; sprintf(valuestr, "%.02f", state->gain * 100.0f); // our units are '%', so print it out as 0 to 100. } } return FMOD_OK; }