Here is a modified simple event example, that shows how to add a compressor to a bus (EventCategory), and have the compressor’s threshold sidechained by another signal from a different bus (EventCategory).

To do this, the example FDP has been modified slightly to add some bus structure, using Event Categories.
The screenshot here shows that everything except [b:kuyjyp5t]/examples/FeatureDemonstration/Basics/Footstep[/b:kuyjyp5t] has been put into a new ‘effects1’ category.
[b:kuyjyp5t]/examples/FeatureDemonstration/Basics/Footstep[/b:kuyjyp5t] has been put into a new ‘effects2’ category.

This is what the example code below uses.


The code below adds a compressor to ‘effects1’ and a sidechain analyzer to ‘effects2’.
Any time there is a signal going into effects 2, it will tell the compressor to change the threshold and will attenuate effects1 (all the other effects) accordingly.

SimpleEvent Example
Copyright (c), Firelight Technologies Pty, Ltd 2004-2014.

Demonstrates basic usage of FMOD’s data-driven event library (fmod_event.dll)

include "../../api/inc/fmod_event.hpp"

include "../../api/inc/fmod_errors.h"

include <windows.h>

include <stdio.h>

include <stdlib.h>

include <conio.h>

include <math.h>

if (result != FMOD_OK)
printf("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));

FMOD_RESULT F_CALLBACK sidechainRead(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels)
unsigned int count;
float sidechain_level;
void *userdata;
} u;

u.sidechain_level = 0;

memcpy(outbuffer, inbuffer, length * outchannels * sizeof(float));

for (count = 0; count &lt; length; count++)
    float channelmax = 0;
    int count2;

    for (count2 = 0; count2 &lt; inchannels; count2++)
        float val = fabsf(inbuffer[count2]);
        channelmax = channelmax &gt; val ? channelmax : val;

    u.sidechain_level = channelmax &gt; u.sidechain_level ? channelmax : u.sidechain_level;

    inbuffer += inchannels;

FMOD_DSP_SetUserData(dsp_state-&gt;instance, u.userdata);

return FMOD_OK;


int main(int argc, char *argv[])
FMOD::EventSystem *eventsystem;
FMOD::EventCategory *effects1, *effects2;
FMOD::Event *event, *event2;
FMOD::System *lowlevelsystem;
FMOD::DSP *sidechain, *compressor;
FMOD::ChannelGroup *effects1_channelgroup, *effects2_channelgroup;
int key;

printf(&quot;Simple Event Example.  Copyright (c) Firelight Technologies 2004-2014.\n&quot;);
printf(&quot;This example simply plays an event created with the FMOD Designer tool.\n&quot;);
printf(&quot;A compressor is on the bus with ambience playing in it.\n&quot;);
printf(&quot;A sidechain analyzer is on the bus with footsteps playing in it.\n&quot;);

ERRCHECK(result = FMOD::EventSystem_Create(&amp;eventsystem));
ERRCHECK(result = eventsystem-&gt;init(64, FMOD_INIT_NORMAL, 0, FMOD_EVENT_INIT_NORMAL));
ERRCHECK(result = eventsystem-&gt;getSystemObject(&amp;lowlevelsystem));

ERRCHECK(result = eventsystem-&gt;setMediaPath(&quot;..\\media\\&quot;));
ERRCHECK(result = eventsystem-&gt;load(&quot;examples.fev&quot;, 0, 0));
ERRCHECK(result = eventsystem-&gt;getEvent(&quot;examples/Tutorials/Simple Event Tutorial 2&quot;, FMOD_EVENT_DEFAULT, &amp;event));
ERRCHECK(result = eventsystem-&gt;getEvent(&quot;examples/FeatureDemonstration/Basics/FootStep&quot;, FMOD_EVENT_DEFAULT, &amp;event2));

/* Get the 2 busses we are interested in. */
ERRCHECK(result = eventsystem-&gt;getCategory(&quot;effects1&quot;, &amp;effects1));  /* Most of the sfx. */
ERRCHECK(result = eventsystem-&gt;getCategory(&quot;effects2&quot;, &amp;effects2));  /* Footsteps. */
ERRCHECK(result = effects1-&gt;getChannelGroup(&amp;effects1_channelgroup));
ERRCHECK(result = effects2-&gt;getChannelGroup(&amp;effects2_channelgroup));

/* Create a compressor for bus 1, and a sidechain analyzer for bus 2. */
ERRCHECK(result = lowlevelsystem-&gt;createDSPByType(FMOD_DSP_TYPE_COMPRESSOR, &amp;compressor));
ERRCHECK(result = compressor-&gt;setParameter(FMOD_DSP_COMPRESSOR_RELEASE, 500));     /* Exaggerate the release to make it more obvious. */

memset(&amp;description, 0, sizeof(FMOD_DSP_DESCRIPTION));
description.read = sidechainRead;
ERRCHECK(result = lowlevelsystem-&gt;createDSP(&amp;description, &amp;sidechain));

/* Add the effects to each bus. */
ERRCHECK(result = effects1_channelgroup-&gt;addDSP(compressor, 0));
ERRCHECK(result = effects2_channelgroup-&gt;addDSP(sidechain, 0));

ERRCHECK(result = event-&gt;start());

printf(&quot;Press SPACE to play the footstep event.\n&quot;);
printf(&quot;Press ESC   to quit\n&quot;);

key = 0;
    if (_kbhit())
        key = _getch();

        if (key == ' ')
            ERRCHECK(result = event2-&gt;start());

    ERRCHECK(result = eventsystem-&gt;update());

    ERRCHECK(result = event-&gt;getState(&amp;state));

        float sidechain_level;
        void *userdata;
    } u;

    sidechain-&gt;getUserData(&amp;u.userdata);                                            /* Get the analyzed value from the compressor. */
    float lin = u.sidechain_level * 1.2;                                            /* exaggerate it a bit for this demo due to footstep sound content.  Adjust as necessary for your content */
    float db = 10.0f*logf(lin &gt; 0.99f ? 0.01f : 1.0f - lin);                        /* Convert linear to db. */
    ERRCHECK(result = compressor-&gt;setParameter(FMOD_DSP_COMPRESSOR_THRESHOLD, db)); /* Lower the threshold of the compressor */

    printf(&quot;Event is %s       : sidechain %.02f (%.02f db)\r&quot;, (state &amp; FMOD_EVENT_STATE_PLAYING) ? &quot;playing&quot; : &quot;stopped&quot;, u.sidechain_level, db);

} while (key != 27);

ERRCHECK(result = eventsystem-&gt;release());
return 0;


  • You must to post comments

Just an update, to analyze the signal you would be better off using RMS (http://en.wikipedia.org/wiki/Root_mean_square) rather than just getting the max, to stop peaks throwing your otherwise quiet signal out. This is left as an exercise for the reader.

  • You must to post comments
Showing 1 result
Your Answer

Please first to submit.