0
0

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.

[img:kuyjyp5t]http://www.fmod.org/images/category.png[/img:kuyjyp5t]

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.

[code:kuyjyp5t]
/*===============================================================================================
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>

void ERRCHECK(FMOD_RESULT result)
{
if (result != FMOD_OK)
{
printf("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
exit(-1);
}
}

FMOD_RESULT F_CALLBACK sidechainRead(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels)
{
unsigned int count;
union
{
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;
FMOD_RESULT result;
int key;

printf(&quot;======================================================================\n&quot;);
printf(&quot;Simple Event Example.  Copyright (c) Firelight Technologies 2004-2014.\n&quot;);
printf(&quot;======================================================================\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;);
printf(&quot;======================================================================\n\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. */

FMOD_DSP_DESCRIPTION description;
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;======================================================================\n&quot;);
printf(&quot;Press SPACE to play the footstep event.\n&quot;);
printf(&quot;Press ESC   to quit\n&quot;);
printf(&quot;======================================================================\n&quot;);

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

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

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

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

    union
    {
        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;

}
[/code:kuyjyp5t]

  • You must to post comments
0
0

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.