int FMOD_Main() { FMOD::System *system; FMOD::Sound *sound; FMOD::Channel *channel; FMOD::DSP *mydsp; FMOD::ChannelGroup *mastergroup; FMOD_RESULT result; unsigned int version; void *extradriverdata = 0; Common_Init(&extradriverdata); /* Create a System object and initialize. */ result = FMOD::System_Create(&system); ERRCHECK(result); result = system->getVersion(&version); ERRCHECK(result); if (version < FMOD_VERSION) { Common_Fatal("FMOD lib version %08x doesn't match header version %08x", version, FMOD_VERSION); } result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); ERRCHECK(result); result = system->createSound(Common_MediaPath("drumloop.wav"), FMOD_SOFTWARE | FMOD_LOOP_NORMAL, 0, &sound); ERRCHECK(result); result = system->playSound(sound, 0, false, &channel); ERRCHECK(result); /* Create the DSP effect. */ { FMOD_DSP_DESCRIPTION dspdesc; memset(&dspdesc, 0, sizeof(dspdesc)); strncpy(dspdesc.name, "My first DSP unit", sizeof(dspdesc.name)); dspdesc.version = 0x00010000; dspdesc.numinputbuffers = 1; dspdesc.numoutputbuffers = 1; dspdesc.read = myDSPCallback; dspdesc.userdata = (void *)0x12345678; result = system->createDSP(&dspdesc, &mydsp); ERRCHECK(result); } /* Attach the DSP, inactive by default. */ result = mydsp->setBypass(true); ERRCHECK(result); result = system->getMasterChannelGroup(&mastergroup); ERRCHECK(result); result = mastergroup->addDSP(0, mydsp, 0); ERRCHECK(result); /* Main loop. */ do { bool bypass; Common_Update(); result = mydsp->getBypass(&bypass); ERRCHECK(result); if (Common_BtnPress(BTN_ACTION1)) { bypass = !bypass; result = mydsp->setBypass(bypass); ERRCHECK(result); } result = system->update(); ERRCHECK(result); Common_Draw("=================================================="); Common_Draw("Custom DSP Example."); Common_Draw("Copyright (c) Firelight Technologies 2004-2014."); Common_Draw("=================================================="); Common_Draw(""); Common_Draw("Press %s to toggle filter bypass", Common_BtnStr(BTN_ACTION1)); Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); Common_Draw(""); Common_Draw("Filter is %s", bypass ? "inactive" : "active"); Common_Sleep(50); } while (!Common_BtnPress(BTN_QUIT)); /* Shut down */ result = sound->release(); ERRCHECK(result); result = mastergroup->removeDSP(mydsp); ERRCHECK(result); result = mydsp->release(); ERRCHECK(result); result = system->close(); ERRCHECK(result); result = system->release(); ERRCHECK(result); Common_Close(); return 0; }
int FMOD_Main() { FMOD::System *system = 0; FMOD::Sound *sound = 0; FMOD::Channel *channel = 0; FMOD::ChannelGroup *mastergroup = 0; FMOD::DSP *dsplowpass = 0; FMOD::DSP *dsphighpass = 0; FMOD::DSP *dspecho = 0; FMOD::DSP *dspflange = 0; FMOD_RESULT result; unsigned int version; void *extradriverdata = 0; Common_Init(&extradriverdata); /* Create a System object and initialize */ result = FMOD::System_Create(&system); ERRCHECK(result); result = system->getVersion(&version); ERRCHECK(result); if (version < FMOD_VERSION) { Common_Fatal("FMOD lib version %08x doesn't match header version %08x", version, FMOD_VERSION); } result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); ERRCHECK(result); result = system->getMasterChannelGroup(&mastergroup); ERRCHECK(result); result = system->createSound(Common_MediaPath("drumloop.wav"), FMOD_DEFAULT, 0, &sound); ERRCHECK(result); result = system->playSound(sound, 0, false, &channel); ERRCHECK(result); /* Create some effects to play with */ result = system->createDSPByType(FMOD_DSP_TYPE_LOWPASS, &dsplowpass); ERRCHECK(result); result = system->createDSPByType(FMOD_DSP_TYPE_HIGHPASS, &dsphighpass); ERRCHECK(result); result = system->createDSPByType(FMOD_DSP_TYPE_ECHO, &dspecho); ERRCHECK(result); result = system->createDSPByType(FMOD_DSP_TYPE_FLANGE, &dspflange); ERRCHECK(result); /* Add them to the master channel group. Each time an effect is added (to position 0) it pushes the others down the list. */ result = mastergroup->addDSP(0, dsplowpass); ERRCHECK(result); result = mastergroup->addDSP(0, dsphighpass); ERRCHECK(result); result = mastergroup->addDSP(0, dspecho); ERRCHECK(result); result = mastergroup->addDSP(0, dspflange); ERRCHECK(result); /* By default, bypass all effects. This means let the original signal go through without processing. It will sound 'dry' until effects are enabled by the user. */ result = dsplowpass->setBypass(true); ERRCHECK(result); result = dsphighpass->setBypass(true); ERRCHECK(result); result = dspecho->setBypass(true); ERRCHECK(result); result = dspflange->setBypass(true); ERRCHECK(result); /* Main loop */ do { Common_Update(); if (Common_BtnPress(BTN_MORE)) { bool paused; result = channel->getPaused(&paused); ERRCHECK(result); paused = !paused; result = channel->setPaused(paused); ERRCHECK(result); } if (Common_BtnPress(BTN_ACTION1)) { bool bypass; result = dsplowpass->getBypass(&bypass); ERRCHECK(result); bypass = !bypass; result = dsplowpass->setBypass(bypass); ERRCHECK(result); } if (Common_BtnPress(BTN_ACTION2)) { bool bypass; result = dsphighpass->getBypass(&bypass); ERRCHECK(result); bypass = !bypass; result = dsphighpass->setBypass(bypass); ERRCHECK(result); } if (Common_BtnPress(BTN_ACTION3)) { bool bypass; result = dspecho->getBypass(&bypass); ERRCHECK(result); bypass = !bypass; result = dspecho->setBypass(bypass); ERRCHECK(result); } if (Common_BtnPress(BTN_ACTION4)) { bool bypass; result = dspflange->getBypass(&bypass); ERRCHECK(result); bypass = !bypass; result = dspflange->setBypass(bypass); ERRCHECK(result); } result = system->update(); ERRCHECK(result); { bool paused = 0; bool dsplowpass_bypass; bool dsphighpass_bypass; bool dspecho_bypass; bool dspflange_bypass; dsplowpass ->getBypass(&dsplowpass_bypass); dsphighpass ->getBypass(&dsphighpass_bypass); dspecho ->getBypass(&dspecho_bypass); dspflange ->getBypass(&dspflange_bypass); if (channel) { result = channel->getPaused(&paused); if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) { ERRCHECK(result); } } Common_Draw("=================================================="); Common_Draw("Effects Example."); Common_Draw("Copyright (c) Firelight Technologies 2004-2015."); Common_Draw("=================================================="); Common_Draw(""); Common_Draw("Press %s to pause/unpause sound", Common_BtnStr(BTN_MORE)); Common_Draw("Press %s to toggle dsplowpass effect", Common_BtnStr(BTN_ACTION1)); Common_Draw("Press %s to toggle dsphighpass effect", Common_BtnStr(BTN_ACTION2)); Common_Draw("Press %s to toggle dspecho effect", Common_BtnStr(BTN_ACTION3)); Common_Draw("Press %s to toggle dspflange effect", Common_BtnStr(BTN_ACTION4)); Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); Common_Draw(""); Common_Draw("%s : lowpass[%c] highpass[%c] echo[%c] flange[%c]", paused ? "Paused " : "Playing", dsplowpass_bypass ? ' ' : 'x', dsphighpass_bypass ? ' ' : 'x', dspecho_bypass ? ' ' : 'x', dspflange_bypass ? ' ' : 'x'); } Common_Sleep(50); } while (!Common_BtnPress(BTN_QUIT)); /* Shut down */ result = mastergroup->removeDSP(dsplowpass); ERRCHECK(result); result = mastergroup->removeDSP(dsphighpass); ERRCHECK(result); result = mastergroup->removeDSP(dspecho); ERRCHECK(result); result = mastergroup->removeDSP(dspflange); ERRCHECK(result); result = dsplowpass->release(); ERRCHECK(result); result = dsphighpass->release(); ERRCHECK(result); result = dspecho->release(); ERRCHECK(result); result = dspflange->release(); ERRCHECK(result); result = sound->release(); ERRCHECK(result); result = system->close(); ERRCHECK(result); result = system->release(); ERRCHECK(result); Common_Close(); return 0; }
int FMOD_Main() { void *extradriverdata = 0; Common_Init(&extradriverdata); /* Create a System object and initialize */ FMOD_RESULT result; FMOD::System* system; result = FMOD::System_Create(&system); ERRCHECK(result); unsigned int version; result = system->getVersion(&version); ERRCHECK(result); if (version < FMOD_VERSION) { Common_Fatal("FMOD lib version %08x doesn't match header version %08x", version, FMOD_VERSION); } result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); ERRCHECK(result); /* Create a new channel group to hold the convolution DSP unit */ FMOD::ChannelGroup* reverbGroup; result = system->createChannelGroup("reverb", &reverbGroup); ERRCHECK(result); /* Create a new channel group to hold all the channels and process the dry path */ FMOD::ChannelGroup* mainGroup; result = system->createChannelGroup("main", &mainGroup); ERRCHECK(result); /* Create the convultion DSP unit and set it as the tail of the channel group */ FMOD::DSP* reverbUnit; result = system->createDSPByType(FMOD_DSP_TYPE_CONVOLUTIONREVERB, &reverbUnit); ERRCHECK(result); result = reverbGroup->addDSP(FMOD_CHANNELCONTROL_DSP_TAIL, reverbUnit); ERRCHECK(result); /* Open the impulse response wav file, but use FMOD_OPENONLY as we want to read the data into a seperate buffer */ FMOD::Sound* irSound; result = system->createSound(Common_MediaPath("standrews.wav"), FMOD_DEFAULT | FMOD_OPENONLY, NULL, &irSound); ERRCHECK(result); /* Retrieve the sound information for the Impulse Response input file */ FMOD_SOUND_FORMAT irSoundFormat; FMOD_SOUND_TYPE irSoundType; int irSoundBits, irSoundChannels; result = irSound->getFormat(&irSoundType, &irSoundFormat, &irSoundChannels, &irSoundBits); ERRCHECK(result); unsigned int irSoundLength; result = irSound->getLength(&irSoundLength, FMOD_TIMEUNIT_PCM); ERRCHECK(result); if (irSoundFormat != FMOD_SOUND_FORMAT_PCM16) { /* For simplicity of the example, if the impulse response is the wrong format just display an error */ Common_Fatal("Impulse Response file is the wrong audio format"); } /* The reverb unit expects a block of data containing a single 16 bit int containing the number of channels in the impulse response, followed by PCM 16 data */ unsigned int irDataLength = sizeof(short) * (irSoundLength * irSoundChannels + 1); short* irData = (short*)malloc(irDataLength); irData[0] = irSoundChannels; unsigned int irDataRead; result = irSound->readData(&irData[1], irDataLength - sizeof(short), &irDataRead); ERRCHECK(result); result = reverbUnit->setParameterData(FMOD_DSP_CONVOLUTION_REVERB_PARAM_IR, irData, irDataLength); ERRCHECK(result); /* Don't pass any dry signal from the reverb unit, instead take the dry part of the mix from the main signal path */ result = reverbUnit->setParameterFloat(FMOD_DSP_CONVOLUTION_REVERB_PARAM_DRY, -80.0f); ERRCHECK(result); /* We can now free our copy of the IR data and release the sound object, the reverb unit has created it's internal data */ free(irData); result = irSound->release(); ERRCHECK(result); /* Load up and play a sample clip recorded in an anechoic chamber */ FMOD::Sound* sound; system->createSound(Common_MediaPath("singing.wav"), FMOD_3D | FMOD_LOOP_NORMAL, NULL, &sound); ERRCHECK(result); FMOD::Channel* channel; system->playSound(sound, mainGroup, true, &channel); ERRCHECK(result); /* Create a send connection between the channel head and the reverb unit */ FMOD::DSP* channelHead; channel->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &channelHead); ERRCHECK(result); FMOD::DSPConnection* reverbConnection; result = reverbUnit->addInput(channelHead, &reverbConnection, FMOD_DSPCONNECTION_TYPE_SEND); ERRCHECK(result); result = channel->setPaused(false); ERRCHECK(result); float wetVolume = 1.0; float dryVolume = 1.0; /* Main loop */ do { Common_Update(); if (Common_BtnPress(BTN_LEFT)) { wetVolume = (wetVolume <= 0.0f) ? wetVolume : wetVolume - 0.05; } if (Common_BtnPress(BTN_RIGHT)) { wetVolume = (wetVolume >= 1.0f) ? wetVolume : wetVolume + 0.05f; } if (Common_BtnPress(BTN_DOWN)) { dryVolume = (dryVolume <= 0.0f) ? dryVolume : dryVolume - 0.05f; } if (Common_BtnPress(BTN_UP)) { dryVolume = (dryVolume >= 1.0f) ? dryVolume : dryVolume + 0.05f; } result = system->update(); ERRCHECK(result); result = reverbConnection->setMix(wetVolume); ERRCHECK(result); result = mainGroup->setVolume(dryVolume); ERRCHECK(result); Common_Draw("=================================================="); Common_Draw("Convolution Example."); Common_Draw("Copyright (c) Firelight Technologies 2004-2015."); Common_Draw("=================================================="); Common_Draw("Press %s and %s to change dry mix", Common_BtnStr(BTN_UP), Common_BtnStr(BTN_DOWN)); Common_Draw("Press %s and %s to change wet mix", Common_BtnStr(BTN_LEFT), Common_BtnStr(BTN_RIGHT)); Common_Draw("wet mix [%.2f] dry mix [%.2f]", wetVolume, dryVolume); Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); Common_Draw(""); Common_Sleep(50); } while (!Common_BtnPress(BTN_QUIT)); /* Shut down */ result = sound->release(); ERRCHECK(result); result = mainGroup->release(); ERRCHECK(result); result = reverbGroup->removeDSP(reverbUnit); ERRCHECK(result); result = reverbUnit->disconnectAll(true, true); ERRCHECK(result); result = reverbUnit->release(); ERRCHECK(result); result = reverbGroup->release(); ERRCHECK(result); result = system->close(); ERRCHECK(result); result = system->release(); ERRCHECK(result); Common_Close(); return 0; }