int FMOD_Main()
{
    void *extraDriverData = NULL;
    Common_Init(&extraDriverData);

    FMOD::Studio::System* system = NULL;
    ERRCHECK( FMOD::Studio::System::create(&system) );

    // The example Studio project is authored for 5.1 sound, so set up the system output mode to match
    FMOD::System* lowLevelSystem = NULL;
    ERRCHECK( system->getLowLevelSystem(&lowLevelSystem) );
    ERRCHECK( lowLevelSystem->setSoftwareFormat(0, FMOD_SPEAKERMODE_5POINT1, 0) );

    ERRCHECK( system->initialize(32, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, extraDriverData) );

    FMOD::Studio::Bank* masterBank = NULL;
    ERRCHECK( system->loadBankFile(Common_MediaPath("Master Bank.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &masterBank) );

    FMOD::Studio::Bank* stringsBank = NULL;
    ERRCHECK( system->loadBankFile(Common_MediaPath("Master Bank.strings.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &stringsBank) );

    FMOD::Studio::Bank* ambienceBank = NULL;
    ERRCHECK( system->loadBankFile(Common_MediaPath("Character.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &ambienceBank) );

    FMOD::Studio::EventDescription* eventDescription = NULL;
    ERRCHECK( system->getEvent("event:/Character/Radio/Command", &eventDescription) );

    FMOD::Studio::EventInstance* eventInstance = NULL;
    ERRCHECK( eventDescription->createInstance(&eventInstance) );
    
    ProgrammerSoundContext programmerSoundContext;
    ERRCHECK( system->getLowLevelSystem(&programmerSoundContext.system) );

    ERRCHECK( eventInstance->setUserData(&programmerSoundContext) );
    ERRCHECK( eventInstance->setCallback(programmerSoundCallback) );
    do
    {
        Common_Update();

        if (Common_BtnPress(BTN_ACTION1))
        {
            programmerSoundContext.soundName = Common_MediaPath("sequence-one.ogg");
            ERRCHECK( eventInstance->start() );
        }

        if (Common_BtnPress(BTN_ACTION2))
        {
            programmerSoundContext.soundName = Common_MediaPath("sequence-two.ogg");
            ERRCHECK( eventInstance->start() );
        }

        if (Common_BtnPress(BTN_ACTION3))
        {
            programmerSoundContext.soundName = Common_MediaPath("sequence-three.ogg");
            ERRCHECK( eventInstance->start() );
        }

        if (Common_BtnPress(BTN_ACTION4))
        {
            programmerSoundContext.soundName = Common_MediaPath("sequence-four.ogg");
            ERRCHECK( eventInstance->start() );
        }

        ERRCHECK( system->update() );

        Common_Draw("==================================================");
        Common_Draw("Event Parameter Example.");
        Common_Draw("Copyright (c) Firelight Technologies 2014-2014.");
        Common_Draw("==================================================");
        Common_Draw("");
        Common_Draw("Press %s to play event with sound 1", Common_BtnStr(BTN_ACTION1));
        Common_Draw("Press %s to play event with sound 2", Common_BtnStr(BTN_ACTION2));
        Common_Draw("Press %s to play event with sound 3", Common_BtnStr(BTN_ACTION3));
        Common_Draw("Press %s to play event with sound 4", Common_BtnStr(BTN_ACTION4));
        Common_Draw("");
        Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));

        Common_Sleep(50);
    } while (!Common_BtnPress(BTN_QUIT));

    ERRCHECK( system->release() );

    Common_Close();

    return 0;
}
Exemple #2
0
int FMOD_Main()
{
    FMOD::Channel *channel = NULL;
    unsigned int samplesRecorded = 0;
    unsigned int samplesPlayed = 0;
    bool dspEnabled = false;

    void *extraDriverData = NULL;
    Common_Init(&extraDriverData);

    /*
        Create a System object and initialize.
    */
    FMOD::System *system = NULL;
    FMOD_RESULT result = FMOD::System_Create(&system);
    ERRCHECK(result);

    unsigned int version = 0;
    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(100, FMOD_INIT_NORMAL, extraDriverData);
    ERRCHECK(result);

    int numDrivers = 0;
    result = system->getRecordNumDrivers(NULL, &numDrivers);
    ERRCHECK(result);

    if (numDrivers == 0)
    {
        Common_Fatal("No recording devices found/plugged in!  Aborting.");
    }

    /*
        Determine latency in samples.
    */
    int nativeRate = 0;
    int nativeChannels = 0;
    result = system->getRecordDriverInfo(DEVICE_INDEX, NULL, 0, NULL, &nativeRate, NULL, &nativeChannels, NULL);
    ERRCHECK(result);

    unsigned int driftThreshold = (nativeRate * DRIFT_MS) / 1000;       /* The point where we start compensating for drift */
    unsigned int desiredLatency = (nativeRate * LATENCY_MS) / 1000;     /* User specified latency */
    unsigned int adjustedLatency = desiredLatency;                      /* User specified latency adjusted for driver update granularity */
    int actualLatency = desiredLatency;                                 /* Latency measured once playback begins (smoothened for jitter) */

    /*
        Create user sound to record into, then start recording.
    */
    FMOD_CREATESOUNDEXINFO exinfo = {0};
    exinfo.cbsize           = sizeof(FMOD_CREATESOUNDEXINFO);
    exinfo.numchannels      = nativeChannels;
    exinfo.format           = FMOD_SOUND_FORMAT_PCM16;
    exinfo.defaultfrequency = nativeRate;
    exinfo.length           = nativeRate * sizeof(short) * nativeChannels; /* 1 second buffer, size here doesn't change latency */
    
    FMOD::Sound *sound = NULL;
    result = system->createSound(0, FMOD_LOOP_NORMAL | FMOD_OPENUSER, &exinfo, &sound);
    ERRCHECK(result);

    result = system->recordStart(DEVICE_INDEX, sound, true);
    ERRCHECK(result);

    unsigned int soundLength = 0;
    result = sound->getLength(&soundLength, FMOD_TIMEUNIT_PCM);
    ERRCHECK(result);

    /*
        Main loop
    */
    do
    {
        Common_Update();

        /*
            Add a DSP effect -- just for fun
        */
        if (Common_BtnPress(BTN_ACTION1))
        {
            FMOD_REVERB_PROPERTIES propOn = FMOD_PRESET_CONCERTHALL;
            FMOD_REVERB_PROPERTIES propOff = FMOD_PRESET_OFF;

            dspEnabled = !dspEnabled;

            result = system->setReverbProperties(0, dspEnabled ? &propOn : &propOff);
            ERRCHECK(result);
        }

        result = system->update();
        ERRCHECK(result);
       
        /*
            Determine how much has been recorded since we last checked
        */
        unsigned int recordPos = 0;
        result = system->getRecordPosition(DEVICE_INDEX, &recordPos);
        if (result != FMOD_ERR_RECORD_DISCONNECTED)
        {
            ERRCHECK(result);
        }

        static unsigned int lastRecordPos = 0;
        unsigned int recordDelta = (recordPos >= lastRecordPos) ? (recordPos - lastRecordPos) : (recordPos + soundLength - lastRecordPos);
        lastRecordPos = recordPos;
        samplesRecorded += recordDelta;

        static unsigned int minRecordDelta = (unsigned int)-1;
        if (recordDelta && (recordDelta < minRecordDelta))
        {
            minRecordDelta = recordDelta; /* Smallest driver granularity seen so far */
            adjustedLatency = (recordDelta <= desiredLatency) ? desiredLatency : recordDelta; /* Adjust our latency if driver granularity is high */
        }
        
        /*
            Delay playback until our desired latency is reached.
        */
        if (!channel && samplesRecorded >= adjustedLatency)
        {
            result = system->playSound(sound, 0, false, &channel);
            ERRCHECK(result);
        }

        if (channel)
        {
            /*
                Stop playback if recording stops.
            */
            bool isRecording = false;
            result = system->isRecording(DEVICE_INDEX, &isRecording);
            if (result != FMOD_ERR_RECORD_DISCONNECTED)
            {
                ERRCHECK(result);
            }

            if (!isRecording)
            {
                result = channel->setPaused(true);
                ERRCHECK(result);
            }

            /*
                Determine how much has been played since we last checked.
            */
            unsigned int playPos = 0;
            result = channel->getPosition(&playPos, FMOD_TIMEUNIT_PCM);
            ERRCHECK(result);

            static unsigned int lastPlayPos = 0;
            unsigned int playDelta = (playPos >= lastPlayPos) ? (playPos - lastPlayPos) : (playPos + soundLength - lastPlayPos);
            lastPlayPos = playPos;
            samplesPlayed += playDelta;
            
            /*
                Compensate for any drift.
            */
            int latency = samplesRecorded - samplesPlayed;
            actualLatency = (0.97f * actualLatency) + (0.03f * latency);

            int playbackRate = nativeRate;
            if (actualLatency < (adjustedLatency - driftThreshold)) 
            {
                /* Play position is catching up to the record position, slow playback down by 2% */
                playbackRate = nativeRate - (nativeRate / 50); 
            }
            else if (actualLatency > (adjustedLatency + driftThreshold))
            {
                /* Play position is falling behind the record position, speed playback up by 2% */
                playbackRate = nativeRate + (nativeRate / 50);
            }

            channel->setFrequency((float)playbackRate);
            ERRCHECK(result);
        }

        Common_Draw("==================================================");
        Common_Draw("Record Example.");
        Common_Draw("Copyright (c) Firelight Technologies 2004-2015.");
        Common_Draw("==================================================");
        Common_Draw("");
        Common_Draw("Adjust LATENCY define to compensate for stuttering");
        Common_Draw("Current value is %dms", LATENCY_MS);
        Common_Draw("");
        Common_Draw("Press %s to %s DSP effect", Common_BtnStr(BTN_ACTION1), dspEnabled ? "disable" : "enable");
        Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));
        Common_Draw("");
        Common_Draw("Adjusted latency: %4d (%dms)", adjustedLatency, adjustedLatency * 1000 / nativeRate);
        Common_Draw("Actual latency:   %4d (%dms)", actualLatency, actualLatency * 1000 / nativeRate);
        Common_Draw("");
        Common_Draw("Recorded: %5d (%ds)", samplesRecorded, samplesRecorded / nativeRate);
        Common_Draw("Played:   %5d (%ds)", samplesPlayed, samplesPlayed / nativeRate);

        Common_Sleep(10);
    } while (!Common_BtnPress(BTN_QUIT));

    /*
        Shut down
    */
    result = sound->release();
    ERRCHECK(result);
    result = system->release();
    ERRCHECK(result);

    Common_Close();

    return 0;
}
int FMOD_Main()
{
    FMOD::System       *system;
    FMOD::Sound        *sound[6];
    FMOD::Channel      *channel[6];
    FMOD::ChannelGroup *groupA, *groupB, *masterGroup;
    FMOD_RESULT         result;
    int                 count;
    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_LOOP_NORMAL, 0, &sound[0]);
    ERRCHECK(result);
    result = system->createSound(Common_MediaPath("jaguar.wav"), FMOD_LOOP_NORMAL, 0, &sound[1]);
    ERRCHECK(result);
    result = system->createSound(Common_MediaPath("swish.wav"), FMOD_LOOP_NORMAL, 0, &sound[2]);
    ERRCHECK(result);
    result = system->createSound(Common_MediaPath("c.ogg"), FMOD_LOOP_NORMAL, 0, &sound[3]);
    ERRCHECK(result);
    result = system->createSound(Common_MediaPath("d.ogg"), FMOD_LOOP_NORMAL, 0, &sound[4]);
    ERRCHECK(result);
    result = system->createSound(Common_MediaPath("e.ogg"), FMOD_LOOP_NORMAL, 0, &sound[5]);
    ERRCHECK(result);

    result = system->createChannelGroup("Group A", &groupA);
    ERRCHECK(result);
    result = system->createChannelGroup("Group B", &groupB);
    ERRCHECK(result);

    result = system->getMasterChannelGroup(&masterGroup);
    ERRCHECK(result);

    /*
        Instead of being independent, set the group A and B to be children of the master group.
    */
    result = masterGroup->addGroup(groupA);
    ERRCHECK(result);

    result = masterGroup->addGroup(groupB);
    ERRCHECK(result);

    /*
        Start all the sounds.
    */
    for (count = 0; count < 6; count++)
    {
        result = system->playSound(sound[count], 0, true, &channel[count]);
        ERRCHECK(result);
        
        result = channel[count]->setChannelGroup((count < 3) ? groupA : groupB);
        ERRCHECK(result);
        
        result = channel[count]->setPaused(false);
        ERRCHECK(result);
    }   

    /*
        Change the volume of each group, just because we can! (reduce overall noise).
    */
    result = groupA->setVolume(0.5f);
    ERRCHECK(result);
    result = groupB->setVolume(0.5f);
    ERRCHECK(result);

    /*
        Main loop.
    */
    do
    {
        Common_Update();

        if (Common_BtnPress(BTN_ACTION1))
        {
            bool mute = true;
            groupA->getMute(&mute);
            groupA->setMute(!mute);
        }

        if (Common_BtnPress(BTN_ACTION2))
        {
            bool mute = true;
            groupB->getMute(&mute);
            groupB->setMute(!mute);
        }

        if (Common_BtnPress(BTN_ACTION3))
        {
            bool mute = true;
            masterGroup->getMute(&mute);
            masterGroup->setMute(!mute);
        }

        result = system->update();
        ERRCHECK(result);

        {
            int channelsplaying = 0;

            result = system->getChannelsPlaying(&channelsplaying);
            ERRCHECK(result);

            Common_Draw("==================================================");
            Common_Draw("Channel Groups Example.");
            Common_Draw("Copyright (c) Firelight Technologies 2004-2014.");
            Common_Draw("==================================================");
            Common_Draw("");
            Common_Draw("Group A : drumloop.wav, jaguar.wav, swish.wav");
            Common_Draw("Group B : c.ogg, d.ogg, e.ogg");
            Common_Draw("");
            Common_Draw("Press %s to mute/unmute group A", Common_BtnStr(BTN_ACTION1));
            Common_Draw("Press %s to mute/unmute group B", Common_BtnStr(BTN_ACTION2));
            Common_Draw("Press %s to mute/unmute master group", Common_BtnStr(BTN_ACTION3));
            Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));
            Common_Draw("");
            Common_Draw("Channels playing %d", channelsplaying);
        }

        Common_Sleep(50);
    } while (!Common_BtnPress(BTN_QUIT));


    /*
        A little fade out over 2 seconds.
    */
    {
        float pitch = 1.0f;
        float vol = 1.0f;

        for (count = 0; count < 200; count++)
        {
            masterGroup->setPitch(pitch);
            masterGroup->setVolume(vol);

            vol   -= (1.0f / 200.0f);
            pitch -= (0.5f / 200.0f);

            Common_Sleep(10);
        }
    }

    /*
        Shut down.
    */
    for (count = 0; count < 6; count++)
    {
        result = sound[count]->release();
        ERRCHECK(result);
    }

    result = groupA->release();
    ERRCHECK(result);
    result = groupB->release();
    ERRCHECK(result);

    result = system->close();
    ERRCHECK(result);
    result = system->release();
    ERRCHECK(result);

    Common_Close();

    return 0;
}
int FMOD_Main()
{
    FMOD::System     *systemA, *systemB;
    FMOD::Sound      *soundA, *soundB;
    FMOD::Channel    *channelA = 0, *channelB = 0;
    FMOD_RESULT       result;
    int               driver;
    unsigned int      version;
    void             *extradriverdata = 0;
    
    Common_Init(&extradriverdata);

    /*
        Create Sound Card A
    */
    result = FMOD::System_Create(&systemA);
    ERRCHECK(result);

    result = systemA->getVersion(&version);
    ERRCHECK(result);

    if (version < FMOD_VERSION)
    {
        Common_Fatal("FMOD lib version %08x doesn't match header version %08x", version, FMOD_VERSION);
    }

    result = fetchDriver(systemA, &driver);
    ERRCHECK(result);

    result = systemA->setDriver(driver);
    ERRCHECK(result);

    result = systemA->init(32, FMOD_INIT_NORMAL, extradriverdata);
    ERRCHECK(result);

    /*
        Create Sound Card B
    */
    result = FMOD::System_Create(&systemB);
    ERRCHECK(result);

    result = fetchDriver(systemB, &driver);
    ERRCHECK(result);

    result = systemB->setDriver(driver);
    ERRCHECK(result);

    result = systemB->init(32, FMOD_INIT_NORMAL, extradriverdata);
    ERRCHECK(result);

    /*
        Load 1 sample into each soundcard.
    */
    result = systemA->createSound(Common_MediaPath("drumloop.wav"), FMOD_LOOP_OFF, 0, &soundA);
    ERRCHECK(result);

    result = systemB->createSound(Common_MediaPath("jaguar.wav"), FMOD_DEFAULT, 0, &soundB);
    ERRCHECK(result);

    /*
        Main loop
    */
    do
    {
        Common_Update();
        
        if (Common_BtnPress(BTN_ACTION1))
        {
            result = systemA->playSound(soundA, 0, 0, &channelA);
            ERRCHECK(result);
        }

        if (Common_BtnPress(BTN_ACTION2))
        {
            result = systemB->playSound(soundB, 0, 0, &channelB);
            ERRCHECK(result);
        }

        result = systemA->update();
        ERRCHECK(result);
        result = systemB->update();
        ERRCHECK(result);

        {
            int channelsplayingA = 0;
            int channelsplayingB = 0;

            result = systemA->getChannelsPlaying(&channelsplayingA);
            ERRCHECK(result);
            result = systemB->getChannelsPlaying(&channelsplayingB);
            ERRCHECK(result);

            Common_Draw("==================================================");
            Common_Draw("Multiple System Example.");
            Common_Draw("Copyright (c) Firelight Technologies 2004-2015.");
            Common_Draw("==================================================");
            Common_Draw("");
            Common_Draw("Press %s to play a sound on device A", Common_BtnStr(BTN_ACTION1));
            Common_Draw("Press %s to play a sound on device B", Common_BtnStr(BTN_ACTION2));
            Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));
            Common_Draw("");
            Common_Draw("Channels playing on A: %d", channelsplayingA);
            Common_Draw("Channels playing on B: %d", channelsplayingB);
        }
        
        Common_Sleep(50);
    } while (!Common_BtnPress(BTN_QUIT));

    /*
        Shut down
    */
    result = soundA->release();
    ERRCHECK(result);
    result = systemA->close();
    ERRCHECK(result);
    result = systemA->release();
    ERRCHECK(result);

    result = soundB->release();
    ERRCHECK(result);
    result = systemB->close();
    ERRCHECK(result);
    result = systemB->release();
    ERRCHECK(result);

    Common_Close();

    return 0;
}
Exemple #5
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()
{
    FMOD::System           *system;
    FMOD::Sound            *sound[3];
    FMOD::Channel          *channel = 0;
    FMOD::ChannelGroup     *channelgroup = 0;
    FMOD_RESULT             result;
    unsigned int            version, dsp_block_len, count;
    int                     outputrate = 0;
    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(100, FMOD_INIT_NORMAL, extradriverdata);
    ERRCHECK(result);

    /*
        Get information needed later for scheduling.  The mixer block size, and the output rate of the mixer.
    */
    result = system->getDSPBufferSize(&dsp_block_len, 0);
    ERRCHECK(result);

    result = system->getSoftwareFormat(&outputrate, 0, 0);
    ERRCHECK(result);

    /*
        Load 3 sounds - these are just sine wave tones at different frequencies.  C, D and E on the musical scale.
    */
    result = system->createSound(Common_MediaPath("c.ogg"), FMOD_DEFAULT, 0, &sound[NOTE_C]);
    ERRCHECK(result);
    result = system->createSound(Common_MediaPath("d.ogg"), FMOD_DEFAULT, 0, &sound[NOTE_D]);
    ERRCHECK(result);
    result = system->createSound(Common_MediaPath("e.ogg"), FMOD_DEFAULT, 0, &sound[NOTE_E]);
    ERRCHECK(result);

    /* 
        Create a channelgroup that the channels will play on.  We can use this channelgroup as our clock reference. 
        It also means we can pause and pitch bend the channelgroup, without affecting the offsets of the delays, because the channelgroup clock
        which the channels feed off, will be pausing and speeding up/slowing down and still keeping the children in sync.
    */
    result = system->createChannelGroup("Parent", &channelgroup);
    ERRCHECK(result);

    unsigned int numsounds = sizeof(note) / sizeof(note[0]);

    /*
        Play all the sounds at once! Space them apart with set delay though so that they sound like they play in order.
    */
    for (count = 0; count < numsounds; count++)
    {
        static unsigned long long clock_start = 0;
        unsigned int slen;
        FMOD::Sound *s = sound[note[count]];                            /* Pick a note from our tune. */

        result = system->playSound(s, channelgroup, true, &channel);    /* Play the sound on the channelgroup we want to use as the parent clock reference (for setDelay further down) */
        ERRCHECK(result);

        if (!clock_start)
        {
            result = channel->getDSPClock(0, &clock_start);
            ERRCHECK(result);

            clock_start += (dsp_block_len * 2);                         /* Start the sound into the future, by 2 mixer blocks worth. */
                                                                        /* Should be enough to avoid the mixer catching up and hitting the clock value before we've finished setting up everything. */
                                                                        /* Alternatively the channelgroup we're basing the clock on could be paused to stop it ticking. */
        }
        else
        {
            float freq;

            result = s->getLength(&slen, FMOD_TIMEUNIT_PCM);            /* Get the length of the sound in samples. */
            ERRCHECK(result);

            result = s->getDefaults(&freq, 0);                          /* Get the default frequency that the sound was recorded at. */
            ERRCHECK(result);

            slen = (unsigned int)((float)slen / freq * outputrate);     /* Convert the length of the sound to 'output samples' for the output timeline. */
            
            clock_start += slen;                                        /* Place the sound clock start time to this value after the last one. */
        }

        result = channel->setDelay(clock_start, 0, false);              /* Schedule the channel to start in the future at the newly calculated channelgroup clock value. */
        ERRCHECK(result);

        result = channel->setPaused(false);                             /* Unpause the sound.  Note that you won't hear the sounds, they are scheduled into the future. */
        ERRCHECK(result);
    }

    /*
        Main loop.
    */
    do
    {
        Common_Update();

        if (Common_BtnPress(BTN_ACTION1))                               /* Pausing the channelgroup as the clock parent, will pause any scheduled sounds from continuing */
        {                                                               /* If you paused the channel, this would not stop the clock it is delayed against from ticking,  */
            bool paused;                                                /* and you'd have to recalculate the delay for the channel into the future again before it was unpaused. */
            result = channelgroup->getPaused(&paused);
            ERRCHECK(result);
            result = channelgroup->setPaused(!paused);
            ERRCHECK(result);
        }
        if (Common_BtnPress(BTN_ACTION2)) 
        {                                 
            for (count = 0; count < 50; count++)
            {
                float pitch;
                result = channelgroup->getPitch(&pitch);
                ERRCHECK(result);
                pitch += 0.01f;
                result = channelgroup->setPitch(pitch);
                ERRCHECK(result);

                result = system->update();
                ERRCHECK(result);

                Common_Sleep(10);
            }
        }
        if (Common_BtnPress(BTN_ACTION3)) 
        {                                 
            for (count = 0; count < 50; count++)
            {
                float pitch;
                result = channelgroup->getPitch(&pitch);
                ERRCHECK(result);

                if (pitch > 0.1f)
                {
                    pitch -= 0.01f;
                }
                result = channelgroup->setPitch(pitch);
                ERRCHECK(result);
                
                result = system->update();
                ERRCHECK(result);

                Common_Sleep(10);
            }
        }

        result = system->update();
        ERRCHECK(result);

        /*
            Print some information
        */
        {
            bool    playing = false;
            bool    paused = false;
            int     chansplaying;

            if (channelgroup)
            {
                result = channelgroup->isPlaying(&playing);
                if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE))
                {
                    ERRCHECK(result);
                }

                result = channelgroup->getPaused(&paused);
                if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE))
                {
                    ERRCHECK(result);
                }
            }

            result = system->getChannelsPlaying(&chansplaying);
            ERRCHECK(result);

            Common_Draw("==================================================");
            Common_Draw("Gapless Playback example.");
            Common_Draw("Copyright (c) Firelight Technologies 2004-2014.");
            Common_Draw("==================================================");
            Common_Draw("");
            Common_Draw("Press %s to toggle pause", Common_BtnStr(BTN_ACTION1));
            Common_Draw("Press %s to increase pitch", Common_BtnStr(BTN_ACTION2));
            Common_Draw("Press %s to decrease pitch", Common_BtnStr(BTN_ACTION3));
            Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));
            Common_Draw("");
            Common_Draw("Channels Playing %d : %s", chansplaying, paused ? "Paused " : playing ? "Playing" : "Stopped");
        }

        Common_Sleep(50);
    } while (!Common_BtnPress(BTN_QUIT));

    /*
        Shut down
    */
    result = sound[NOTE_C]->release();
    ERRCHECK(result);
    result = sound[NOTE_D]->release();
    ERRCHECK(result);
    result = sound[NOTE_E]->release();
    ERRCHECK(result);

    result = system->close();
    ERRCHECK(result);
    result = system->release();
    ERRCHECK(result);

    Common_Close();

    return 0;
}
int FMOD_Main()
{
    FMOD::System     *system;
    FMOD::Sound      *sound1, *sound2, *sound3;
    FMOD::Channel    *channel = 0;
    FMOD_RESULT       result;
    unsigned int      version;
    void             *extradriverdata = 0;
    void             *buff = 0;
    int               length = 0;
    FMOD_CREATESOUNDEXINFO exinfo;
    
    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);
    
    Common_LoadFileMemory(Common_MediaPath("drumloop.wav"), &buff, &length);
    memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
    exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
    exinfo.length = length;

    result = system->createSound((const char *)buff, FMOD_HARDWARE | FMOD_OPENMEMORY | FMOD_LOOP_OFF, &exinfo, &sound1);
    ERRCHECK(result);
    Common_UnloadFileMemory(buff); // don't need the original memory any more.  Note!  If loading as a stream, the memory must stay active so do not free it!

    Common_LoadFileMemory(Common_MediaPath("jaguar.wav"), &buff, &length);
    memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
    exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
    exinfo.length = length;    
   
    result = system->createSound((const char *)buff, FMOD_SOFTWARE | FMOD_OPENMEMORY, &exinfo, &sound2);
    ERRCHECK(result);
    Common_UnloadFileMemory(buff); // don't need the original memory any more.  Note!  If loading as a stream, the memory must stay active so do not free it!
    
    Common_LoadFileMemory(Common_MediaPath("swish.wav"), &buff, &length);
    memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
    exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
    exinfo.length = length;    

    result = system->createSound((const char *)buff, FMOD_HARDWARE | FMOD_OPENMEMORY, &exinfo, &sound3);
    ERRCHECK(result);
    Common_UnloadFileMemory(buff); // don't need the original memory any more.  Note!  If loading as a stream, the memory must stay active so do not free it!

    /*
        Main loop
    */
    do
    {
        Common_Update();

        if (Common_BtnPress(BTN_ACTION1))
        {
            result = system->playSound(sound1, 0, false, &channel);
            ERRCHECK(result);
        }

        if (Common_BtnPress(BTN_ACTION2))
        {
            result = system->playSound(sound2, 0, false, &channel);
            ERRCHECK(result);
        }

        if (Common_BtnPress(BTN_ACTION3))
        {
            result = system->playSound(sound3, 0, false, &channel);
            ERRCHECK(result);
        }

        result = system->update();
        ERRCHECK(result);

        {
            unsigned int ms = 0;
            unsigned int lenms = 0;
            bool         playing = 0;
            bool         paused = 0;
            int          channelsplaying = 0;

            if (channel)
            {
                FMOD::Sound *currentsound = 0;

                result = channel->isPlaying(&playing);
                if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN))
                {
                    ERRCHECK(result);
                }

                result = channel->getPaused(&paused);
                if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN))
                {
                    ERRCHECK(result);
                }

                result = channel->getPosition(&ms, FMOD_TIMEUNIT_MS);
                if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN))
                {
                    ERRCHECK(result);
                }
               
                channel->getCurrentSound(&currentsound);
                if (currentsound)
                {
                    result = currentsound->getLength(&lenms, FMOD_TIMEUNIT_MS);
                    if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN))
                    {
                        ERRCHECK(result);
                    }
                }
            }

            system->getChannelsPlaying(&channelsplaying);

            Common_Draw("==================================================");
            Common_Draw("Load From Memory Example.");
            Common_Draw("Copyright (c) Firelight Technologies 2004-2014.");
            Common_Draw("==================================================");
            Common_Draw("");
            Common_Draw("Press %s to play a mono sound (drumloop)", Common_BtnStr(BTN_ACTION1));
            Common_Draw("Press %s to play a mono sound (jaguar)", Common_BtnStr(BTN_ACTION2));
            Common_Draw("Press %s to play a stereo sound (swish)", Common_BtnStr(BTN_ACTION3));
            Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));
            Common_Draw("");
            Common_Draw("Time %02d:%02d:%02d/%02d:%02d:%02d : %s", ms / 1000 / 60, ms / 1000 % 60, ms / 10 % 100, lenms / 1000 / 60, lenms / 1000 % 60, lenms / 10 % 100, paused ? "Paused " : playing ? "Playing" : "Stopped");
            Common_Draw("Channels Playing %2d", channelsplaying);
        }

        Common_Sleep(50);
    } while (!Common_BtnPress(BTN_QUIT));

    /*
        Shut down
    */
    result = sound1->release();
    ERRCHECK(result);
    result = sound2->release();
    ERRCHECK(result);
    result = sound3->release();
    ERRCHECK(result);
    result = system->close();
    ERRCHECK(result);
    result = system->release();
    ERRCHECK(result);

    Common_Close();

    return 0;
}
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()
{
    void *extraDriverData = 0;
    Common_Init(&extraDriverData);

    RunData data;
    Common_Mutex_Create(&data.criticalSection);

    FMOD::Studio::System* system;
    ERRCHECK( FMOD::Studio::System::create(&system) );
    FMOD::System* lowLevelSystem;
    ERRCHECK( system->getLowLevelSystem(&lowLevelSystem) );
    ERRCHECK( lowLevelSystem->setCallback(SystemCallback) );
    ERRCHECK( lowLevelSystem->setUserData(&data) );

    ERRCHECK( system->initialize(32, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, extraDriverData) );

    for (int i=0; i<BANK_COUNT; ++i)
    {
        data.banks[i] = NULL;
    }

    bool wantSampleLoad = false;

    do
    {
        Common_Update();
        
        if (Common_BtnPress(BTN_ACTION1))
        {
            // Start loading all the banks
            for (int i=0; i<BANK_COUNT; ++i)
            {
                if (data.banks[i] == NULL || !data.banks[i]->isValid())
                {
                    FMOD_RESULT result = system->loadBankFile(Common_MediaPath(BANK_NAMES[i]), FMOD_STUDIO_LOAD_BANK_NONBLOCKING, &data.banks[i]);
                    if (result != FMOD_OK)
                    {
                    }
                }
            }
        }
        if (Common_BtnPress(BTN_ACTION2))
        {
            // Unload all banks
            for (int i=0; i<BANK_COUNT; ++i)
            {
                FMOD_RESULT result = data.banks[i]->unload();
                if (result != FMOD_OK)
                {
                }
            }
        }
        if (Common_BtnPress(BTN_MORE))
        {
            wantSampleLoad = !wantSampleLoad;
        }
        // Load bank sample data

        for (int i=0; i<BANK_COUNT; ++i)
        {
            FMOD_STUDIO_LOADING_STATE bankLoadState = FMOD_STUDIO_LOADING_STATE_UNLOADED;
            FMOD_STUDIO_LOADING_STATE sampleLoadState = FMOD_STUDIO_LOADING_STATE_UNLOADED;
            if (data.banks[i] && data.banks[i]->isValid())
            {
                data.banks[i]->getLoadingState(&bankLoadState);
                data.banks[i]->getSampleLoadingState(&sampleLoadState);
            }
            if (bankLoadState == FMOD_STUDIO_LOADING_STATE_LOADED)
            {
                if (wantSampleLoad && sampleLoadState == FMOD_STUDIO_LOADING_STATE_UNLOADED)
                {
                    ERRCHECK(data.banks[i]->loadSampleData());
                }
                else if (!wantSampleLoad && (sampleLoadState == FMOD_STUDIO_LOADING_STATE_LOADING || sampleLoadState == FMOD_STUDIO_LOADING_STATE_LOADED))
                {
                    ERRCHECK(data.banks[i]->unloadSampleData());
                }
            }
        }


        ERRCHECK( system->update() );

        Common_Draw("==================================================");
        Common_Draw("Bank Load Example.");
        Common_Draw("Copyright (c) Firelight Technologies 2014-2014.");
        Common_Draw("==================================================");
        Common_Draw("Name              Handle  Bank-State  Sample-State");

        for (int i=0; i<BANK_COUNT; ++i)
        {
            FMOD_STUDIO_LOADING_STATE bankLoadState = FMOD_STUDIO_LOADING_STATE_UNLOADED;
            FMOD_STUDIO_LOADING_STATE sampleLoadState = FMOD_STUDIO_LOADING_STATE_UNLOADED;
            if (data.banks[i] && data.banks[i]->isValid())
            {
                data.banks[i]->getLoadingState(&bankLoadState);
                data.banks[i]->getSampleLoadingState(&sampleLoadState);
            }
            char namePad[64];
            int bankNameLen = strlen(BANK_NAMES[i]);
            memset(namePad, ' ', 63);
            namePad[16] = '\0';
            strncpy(namePad, BANK_NAMES[i], bankNameLen);

            Common_Draw("%s  %s %s   %s",
                    namePad, getHandleStateString(data.banks[i]), getLoadingStateString(bankLoadState), getLoadingStateString(sampleLoadState));
        }
        Common_Draw("");
        Common_Draw("Press %s to load banks, %s to unload banks", Common_BtnStr(BTN_ACTION1), Common_BtnStr(BTN_ACTION2));
        Common_Draw("Press %s to toggle sample data: %s", Common_BtnStr(BTN_MORE), wantSampleLoad ? "loaded" : "unloaded");
        Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));

        {
            Common_Mutex_Enter(&data.criticalSection);
            int errorCount = (int)data.errorStrings.size();
            Common_Draw("Errors (%d):", errorCount);
			int startIndex = errorCount - 6;
			if (startIndex < 0) startIndex = 0;
            for (int i=startIndex; i<errorCount; ++i)
            {
                Common_Draw(" %s", data.errorStrings[i].c_str());
            }
            Common_Mutex_Leave(&data.criticalSection);
        }

        Common_Sleep(50);
    } while (!Common_BtnPress(BTN_QUIT));
    
    for (int i=0; i<BANK_COUNT; ++i)
    {
        if (data.banks[i] != NULL && data.banks[i]->isValid())
        {
            data.banks[i]->unload();
        }
    }

    ERRCHECK( system->release() );

    Common_Mutex_Destroy(&data.criticalSection);
    Common_Close();

    return 0;
}
Exemple #10
0
int FMOD_Main()
{
    //void *extraDriverData = NULL;
    Common_Init(NULL);

    FMOD::Studio::System* system = NULL;
    ERRCHECK( FMOD::Studio::System::create(&system) );

    // The example Studio project is authored for 5.1 sound, so set up the system output mode to match
    //
    //ERRCHECK( lowLevelSystem->setSoftwareFormat(0, FMOD_SPEAKERMODE_5POINT1, 0) );

    ERRCHECK( system->initialize(32, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, NULL) );

	FMOD::System* lowLevelSystem = NULL;
    ERRCHECK( system->getLowLevelSystem(&lowLevelSystem) );

	FMOD_ADVANCEDSETTINGS set = {0};
	set.cbSize = sizeof(FMOD_ADVANCEDSETTINGS);
	
	lowLevelSystem->getAdvancedSettings(&set);

	srand(time(NULL));
	set.cbSize = sizeof(FMOD_ADVANCEDSETTINGS);
	set.randomSeed = rand();
	printf("%d\n",set.randomSeed);

	lowLevelSystem->setAdvancedSettings(&set);
    
    FMOD::Studio::Bank* masterBank = NULL;
    ERRCHECK( system->loadBankFile(Common_MediaPath("Master Bank.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &masterBank) );
    
    FMOD::Studio::Bank* stringsBank = NULL;
    ERRCHECK( system->loadBankFile(Common_MediaPath("Master Bank.strings.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &stringsBank) );
    
    FMOD::Studio::Bank* ambienceBank = NULL;
    ERRCHECK( system->loadBankFile(Common_MediaPath("Surround_Ambience.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &ambienceBank) );
    
    FMOD::Studio::Bank* menuBank = NULL;
    ERRCHECK( system->loadBankFile(Common_MediaPath("UI_Menu.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &menuBank) );
    
    FMOD::Studio::Bank* weaponsBank = NULL;
    ERRCHECK( system->loadBankFile(Common_MediaPath("Weapons.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &weaponsBank) );

	
    FMOD::Studio::Bank* characterBank = NULL;
    ERRCHECK( system->loadBankFile(Common_MediaPath("Character.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &characterBank) );

    // Get the Looping Ambience event
    FMOD::Studio::EventDescription* loopingAmbienceDescription = NULL;
    ERRCHECK( system->getEvent("event:/Ambience/Country", &loopingAmbienceDescription) );
    
    FMOD::Studio::EventInstance* loopingAmbienceInstance = NULL;
    ERRCHECK( loopingAmbienceDescription->createInstance(&loopingAmbienceInstance) );
    
    // Get the 4 Second Surge event
    FMOD::Studio::EventDescription* cancelDescription = NULL;
    ERRCHECK( system->getEvent("event:/Character/Hand Foley/Doorknob", &cancelDescription) );
    
    FMOD::Studio::EventInstance* cancelInstance = NULL;
    ERRCHECK( cancelDescription->createInstance(&cancelInstance) );
    
    // Get the Single Explosion event
    FMOD::Studio::EventDescription* explosionDescription = NULL;
    ERRCHECK( system->getEvent("event:/Explosions/Single Explosion", &explosionDescription) );

    // Start loading explosion sample data and keep it in memory
    ERRCHECK( explosionDescription->loadSampleData() );

    do
    {
        Common_Update();
        
        if (Common_BtnPress(BTN_ACTION1))
        {
            // One-shot event
            FMOD::Studio::EventInstance* eventInstance = NULL;
            ERRCHECK( explosionDescription->createInstance(&eventInstance) );

            ERRCHECK( eventInstance->start() );

            // Release will clean up the instance when it completes
            ERRCHECK( eventInstance->release() );
        }
    
        if (Common_BtnPress(BTN_ACTION2))
        {
            ERRCHECK( loopingAmbienceInstance->start() );
        }

        if (Common_BtnPress(BTN_ACTION3))
        {
            ERRCHECK( loopingAmbienceInstance->stop(FMOD_STUDIO_STOP_IMMEDIATE) );
        }

        if (Common_BtnPress(BTN_ACTION4))
        {
            // Calling start on an instance will cause it to restart if it's already playing
            ERRCHECK( cancelInstance->start() );
        }

        ERRCHECK( system->update() );

        Common_Draw("==================================================");
        Common_Draw("Simple Event Example.");
        Common_Draw("Copyright (c) Firelight Technologies 2014-2014.");
        Common_Draw("==================================================");
        Common_Draw("");
        Common_Draw("Press %s to fire and forget the explosion", Common_BtnStr(BTN_ACTION1));
        Common_Draw("Press %s to start the looping ambience", Common_BtnStr(BTN_ACTION2));
        Common_Draw("Press %s to stop the looping ambience", Common_BtnStr(BTN_ACTION3));
        Common_Draw("Press %s to start/restart the cancel sound", Common_BtnStr(BTN_ACTION4));
        Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));

        Common_Sleep(50);
    } while (!Common_BtnPress(BTN_QUIT));
    
    ERRCHECK( weaponsBank->unload() );
    ERRCHECK( menuBank->unload() );
    ERRCHECK( ambienceBank->unload() );
    ERRCHECK( stringsBank->unload() );
    ERRCHECK( masterBank->unload() );
	ERRCHECK( characterBank->unload() );

    ERRCHECK( system->release() );

    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;
}
Exemple #12
0
int FMOD_Main()
{
    void *extraDriverData = NULL;
    Common_Init(&extraDriverData);

    FMOD::Studio::System* system = NULL;
    ERRCHECK( FMOD::Studio::System::create(&system) );

    // The example Studio project is authored for 5.1 sound, so set up the system output mode to match
    FMOD::System* lowLevelSystem = NULL;
    ERRCHECK( system->getLowLevelSystem(&lowLevelSystem) );
    ERRCHECK( lowLevelSystem->setSoftwareFormat(0, FMOD_SPEAKERMODE_5POINT1, 0) );

    ERRCHECK( system->initialize(32, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, extraDriverData) );

    FMOD::Studio::Bank* masterBank = NULL;
    ERRCHECK( system->loadBankFile(Common_MediaPath("Master Bank.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &masterBank) );

    FMOD::Studio::Bank* stringsBank = NULL;
    ERRCHECK( system->loadBankFile(Common_MediaPath("Master Bank.strings.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &stringsBank) );

    FMOD::Studio::Bank* musicBank = NULL;
    FMOD_RESULT result = system->loadBankFile(Common_MediaPath("Music.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &musicBank);
    if (result != FMOD_OK)
    {
        // Music bank is not exported by default, you will have to export from the tool first
        Common_Fatal("Please export music.bank from the Studio tool to run this example");
    }

    FMOD::Studio::EventDescription* eventDescription = NULL;
    ERRCHECK( system->getEvent("event:/Music/Music", &eventDescription) );

    FMOD::Studio::EventInstance* eventInstance = NULL;
    ERRCHECK( eventDescription->createInstance(&eventInstance) );
    
    CallbackInfo info;
    Common_Mutex_Create(&info.mMutex);

    ERRCHECK( eventInstance->setUserData(&info) );
    ERRCHECK( eventInstance->setCallback(markerCallback, FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_MARKER | FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_BEAT) );
    ERRCHECK( eventInstance->start() );

    do
    {
        Common_Update();

        ERRCHECK( system->update() );

        int position;
        ERRCHECK( eventInstance->getTimelinePosition(&position) );

        Common_Draw("==================================================");
        Common_Draw("Music Callback Example.");
        Common_Draw("Copyright (c) Firelight Technologies 2015-2015.");
        Common_Draw("==================================================");
        Common_Draw("");
        Common_Draw("Timeline = %d", position);
        Common_Draw("");
        // Obtain lock and look at our strings
        Common_Mutex_Enter(&info.mMutex);
        for (size_t i=0; i<info.mEntries.size(); ++i)
        {
            Common_Draw("    %s\n", info.mEntries[i].c_str());
        }
        Common_Mutex_Leave(&info.mMutex);
        Common_Draw("");
        Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));

        Common_Sleep(50);
    } while (!Common_BtnPress(BTN_QUIT));

    ERRCHECK( system->release() );

    Common_Mutex_Destroy(&info.mMutex);
    Common_Close();

    return 0;
}
Exemple #13
0
int FMOD_Main()
{
    void *extraDriverData = 0;
    Common_Init(&extraDriverData);

    FMOD::Studio::System system;
    FMOD_RESULT result = FMOD::Studio::System::create(&system);
    ERRCHECK(result);

    result = system.initialize(32, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, extraDriverData);
    ERRCHECK(result);

    FMOD::Studio::Bank masterBank;
    ERRCHECK( system.loadBankFile(Common_MediaPath("Master Bank.bank"), &masterBank) );

    FMOD::Studio::Bank stringsBank;
    ERRCHECK( system.loadBankFile(Common_MediaPath("Master Bank.bank.strings"), &stringsBank) );

    FMOD::Studio::Bank vehiclesBank;
    ERRCHECK( system.loadBankFile(Common_MediaPath("Vehicles.bank"), &vehiclesBank) );
    
    FMOD::Studio::ID eventID = {0};
    ERRCHECK( system.lookupEventID("/Vehicles/Basic Engine", &eventID) );

    FMOD::Studio::EventDescription eventDescription;
    ERRCHECK( system.getEvent(&eventID, FMOD_STUDIO_LOAD_BEGIN_NOW, &eventDescription) );

    FMOD::Studio::EventInstance eventInstance;
    ERRCHECK( eventDescription.createInstance(&eventInstance) );

    FMOD::Studio::ParameterInstance rpm;
    ERRCHECK( eventInstance.getParameter("RPM", &rpm) );

    ERRCHECK( rpm.setValue(650) );

    ERRCHECK( eventInstance.start() );

    // Position the listener at the origin
    FMOD_3D_ATTRIBUTES attributes = { { 0 } };
    attributes.forward.z = 1.0f;
    attributes.up.y = 1.0f;
    ERRCHECK( system.setListenerAttributes(&attributes) );

    // Position the event 2 units in front of the listener
    attributes.position.z = 2.0f;
    ERRCHECK( eventInstance.set3DAttributes(&attributes) );
    
    initializeScreenBuffer();

    do
    {
        Common_Update();
        
        if (Common_BtnPress(BTN_LEFT))
        {
            attributes.position.x -= 1.0f;
            ERRCHECK( eventInstance.set3DAttributes(&attributes) );
        }
        
        if (Common_BtnPress(BTN_RIGHT))
        {
            attributes.position.x += 1.0f;
            ERRCHECK( eventInstance.set3DAttributes(&attributes) );
        }
        
        if (Common_BtnPress(BTN_UP))
        {
            attributes.position.z += 1.0f;
            ERRCHECK( eventInstance.set3DAttributes(&attributes) );
        }
        
        if (Common_BtnPress(BTN_DOWN))
        {
            attributes.position.z -= 1.0f;
            ERRCHECK( eventInstance.set3DAttributes(&attributes) );
        }

        result = system.update();
        ERRCHECK(result);
        
        updateScreenPosition(attributes.position);
        Common_Draw("==================================================");
        Common_Draw("Event 3D Example.");
        Common_Draw("Copyright (c) Firelight Technologies 2012-2013.");
        Common_Draw("==================================================");
        Common_Draw(screenBuffer);
        Common_Draw("Use the arrow keys (%s, %s, %s, %s) to control the event position", 
            Common_BtnStr(BTN_LEFT), Common_BtnStr(BTN_RIGHT), Common_BtnStr(BTN_UP), Common_BtnStr(BTN_DOWN));
        Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));

        Common_Sleep(50);
    } while (!Common_BtnPress(BTN_QUIT));

    result = system.release();
    ERRCHECK(result);

    Common_Close();

    return 0;
}
int FMOD_Main()
{
    FMOD::System        *system           = 0;
    FMOD_RESULT          result;
    unsigned int         version;
    void                *extradriverdata  = 0;
    unsigned int         pluginhandle;
    InspectorState       state            = PLUGIN_SELECTOR;
    PluginSelectorState  pluginselector   = { 0 };
    ParameterViewerState parameterviewer  = { 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->getNumPlugins(FMOD_PLUGINTYPE_DSP, &pluginselector.numplugins);
    ERRCHECK(result);

    pluginselector.system = system;

    do
    {
        Common_Update();

        if (state == PLUGIN_SELECTOR)
        {
            state = pluginSelectorDo(&pluginselector);

            if (state == PARAMETER_VIEWER)
            {
                result = pluginselector.system->getPluginHandle(FMOD_PLUGINTYPE_DSP, pluginselector.cursor, &pluginhandle);
                ERRCHECK(result);

                result = pluginselector.system->createDSPByPlugin(pluginhandle, &parameterviewer.dsp);
                ERRCHECK(result);

                FMOD_RESULT result = parameterviewer.dsp->getNumParameters(&parameterviewer.numparams);
                ERRCHECK(result);

                parameterviewer.scroll = 0;
            }
        }
        else if (state == PARAMETER_VIEWER)
        {
            state = parameterViewerDo(&parameterviewer);

            if (state == PLUGIN_SELECTOR)
            {
                result = parameterviewer.dsp->release();
                ERRCHECK(result);

                parameterviewer.dsp = 0;
            }
        }

        result = system->update();
        ERRCHECK(result);

        Common_Sleep(INTERFACE_UPDATETIME - 1);
    } while (!Common_BtnPress(BTN_QUIT));

    if (parameterviewer.dsp)
    {
        result = parameterviewer.dsp->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_RESULT      result = FMOD_OK;
    FMOD_OPENSTATE   openstate = FMOD_OPENSTATE_READY;
    unsigned int     version = 0;
    void            *extradriverdata = 0;
    const int        tagcount = 4;
    int              tagindex = 0;
    char             tagstring[tagcount][128] = { 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(1, FMOD_INIT_NORMAL, extradriverdata);
    ERRCHECK(result);

    /* Increase the file buffer size a little bit to account for Internet lag. */
    result = system->setStreamBufferSize(64*1024, FMOD_TIMEUNIT_RAWBYTES);
    ERRCHECK(result);

    result = system->createSound("http://shoutmedia.abc.net.au:10426", FMOD_CREATESTREAM | FMOD_NONBLOCKING, 0, &sound);
    ERRCHECK(result);

    /*
        Main loop
    */
    do
    {
        unsigned int    pos = 0;
        unsigned int    percent = 0;
        bool            playing = false;
        bool            paused = false;
        bool            starving = false;
        const char     *state = "Stopped";
        
        Common_Update();

        if (Common_BtnPress(BTN_ACTION1))
        {
            if (channel)
            {
                bool paused = false;
                
                result = channel->getPaused(&paused);
                ERRCHECK(result);
                result = channel->setPaused(!paused);
                ERRCHECK(result);
            }
        }
        
        result = system->update();
        ERRCHECK(result);
        
        result = sound->getOpenState(&openstate, &percent, &starving, 0);
        ERRCHECK(result);
        
        if (channel)
        {
            FMOD_TAG tag;
        
            /*
                Read any tags that have arrived, this could happen if a radio station switches
                to a new song.
            */
            while (sound->getTag(0, -1, &tag) == FMOD_OK)
            {
                if (tag.datatype == FMOD_TAGDATATYPE_STRING)
                {
                    sprintf(tagstring[tagindex], "%s = '%s' (%d bytes)", tag.name, (char *)tag.data, tag.datalen);
                    tagindex = (tagindex + 1) % tagcount;
                }
                else if (tag.type == FMOD_TAGTYPE_FMOD)
                {
                    /* When a song changes, the sample rate may also change, so compensate here. */
                    if (!strcmp(tag.name, "Sample Rate Change"))
                    {
                        float frequency = *((float *)tag.data);
                        
                        result = channel->setFrequency(frequency);
                        ERRCHECK(result);
                    }
                }
            }
            
            result = channel->getPaused(&paused);
            ERRCHECK(result);
            
            result = channel->isPlaying(&playing);
            ERRCHECK(result);
            
            result = channel->getPosition(&pos, FMOD_TIMEUNIT_MS);
            ERRCHECK(result);
            
            /* Silence the stream until we have sufficient data for smooth playback. */
            result = channel->setMute(starving);
            ERRCHECK(result);
        }
        else
        {
             /* This may fail if the stream isn't ready yet, so don't check the error code. */
            system->playSound(sound, 0, false, &channel);
        }
        
        if (openstate == FMOD_OPENSTATE_BUFFERING)
        {
            state = "Buffering...";
        }
        else if (openstate == FMOD_OPENSTATE_CONNECTING)
        {
            state = "Connecting...";
        }
        else if (paused)
        {
            state = "Paused";
        }
        else if (playing)
        {
            state = "Playing";
        }

        Common_Draw("==================================================");
        Common_Draw("Net Stream Example.");
        Common_Draw("Copyright (c) Firelight Technologies 2004-2014.");
        Common_Draw("==================================================");
        Common_Draw("");
        Common_Draw("Press %s to toggle pause", Common_BtnStr(BTN_ACTION1));
        Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));
        Common_Draw("");
        Common_Draw("Time = %02d:%02d:%02d", pos / 1000 / 60, pos / 1000 % 60, pos / 10 % 100);
        Common_Draw("State = %s %s", state, starving ? "(STARVING)" : "");
        Common_Draw("Buffer Percentage = %d", percent);
        Common_Draw("");
        Common_Draw("Tags:");
        for (int i = tagindex; i < (tagindex + tagcount); i++)
        {
            Common_Draw("%s", tagstring[i % tagcount]);
            Common_Draw("");
        }

        Common_Sleep(50);
    } while (!Common_BtnPress(BTN_QUIT));

    /*
        Stop the channel, then wait for it to finish opening before we release it.
    */    
    if (channel)
    {
        result = channel->stop();
        ERRCHECK(result);
    }

    do
    {
        Common_Update();
        Common_Draw("Waiting for sound to finish opening before trying to release it....", Common_BtnStr(BTN_ACTION1));
        Common_Sleep(50);
        
        result = system->update();
        ERRCHECK(result);

        result = sound->getOpenState(&openstate, 0, 0, 0);
        ERRCHECK(result);
    } while (openstate != FMOD_OPENSTATE_READY);

    /*
        Shut down
    */
    result = sound->release();
    ERRCHECK(result);
    result = system->close();
    ERRCHECK(result);
    result = system->release();
    ERRCHECK(result);

    Common_Close();
    
    return 0;
}
int FMOD_Main()
{
    FMOD::Channel    *channel[2] = { 0,0 };
    FMOD_RESULT       result;
    int               outputrate, slot = 0;
    unsigned int      version;
    void             *extradriverdata = 0;
    bool              paused = false;

    Common_Init(&extradriverdata);
    
    result = FMOD::System_Create(&gSystem);
    ERRCHECK(result);
    
    result = gSystem->getVersion(&version);
    ERRCHECK(result);

    if (version < FMOD_VERSION)
    {
        Common_Fatal("FMOD lib version %08x doesn't match header version %08x", version, FMOD_VERSION);
    }
    
    result = gSystem->init(100, FMOD_INIT_NORMAL, extradriverdata);
    ERRCHECK(result);
       
    result = gSystem->getSoftwareFormat(&outputrate, 0, 0);
    ERRCHECK(result);   
   
#if !defined(USE_STREAMS)
    for (unsigned int count = 0; count < NUMSOUNDS; count++)
    {
        result = gSystem->createSound(soundname[count], FMOD_IGNORETAGS, 0, &sound[count]);
        ERRCHECK(result);
    }
#endif

    /*
        Kick off the first 2 sounds.  First one is immediate, second one will be triggered to start after the first one.
    */
    channel[slot] = queue_next_sound(outputrate, channel[1-slot], rand()%NUMSOUNDS, slot);
    slot = 1-slot;  /* flip */
    channel[slot] = queue_next_sound(outputrate, channel[1-slot], rand()%NUMSOUNDS, slot);
    slot = 1-slot;  /* flip */

    do
    {
        bool isplaying = false;

        Common_Update();

        if (Common_BtnPress(BTN_ACTION1))
        {
            FMOD::ChannelGroup *mastergroup;

            paused = !paused;

            result = gSystem->getMasterChannelGroup(&mastergroup);
            ERRCHECK(result);
            result = mastergroup->setPaused(paused);
            ERRCHECK(result);
        }

        result = gSystem->update();
        ERRCHECK(result);

        /*
            Replace the sound that just finished with a new sound, to create endless seamless stitching!
        */
        result = channel[slot]->isPlaying(&isplaying);
        if (result != FMOD_ERR_INVALID_HANDLE)
        {
            ERRCHECK(result);
        }

        if (!isplaying && !paused)
        {
#ifdef USE_STREAMS
            /* 
                Release the sound that isn't playing any more. 
            */
            result = sound[slot]->release();       
            ERRCHECK(result);
            sound[slot] = 0;
#endif

            /*
                Replace sound that just ended with a new sound, queued up to trigger exactly after the other sound ends.
            */
            channel[slot] = queue_next_sound(outputrate, channel[1-slot], rand()%NUMSOUNDS, slot);
            slot = 1-slot;  /* flip */
        }

        Common_Draw("==================================================");
        Common_Draw("Granular Synthesis SetDelay Example.");
        Common_Draw("Copyright (c) Firelight Technologies 2004-2014.");
        Common_Draw("==================================================");
        Common_Draw("");
        Common_Draw("Toggle #define USE_STREAM on/off in code to switch between streams and static samples.");
        Common_Draw("");
        Common_Draw("Press %s to pause", Common_BtnStr(BTN_ACTION1));
        Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));
        Common_Draw("");
        Common_Draw("Channels are %s", paused ? "paused" : "playing");

        Common_Sleep(10);   /* If you wait too long, ie longer than the length of the shortest sound, you will get gaps. */
    } while (!Common_BtnPress(BTN_QUIT));

    /*
        Shut down
    */
    for (unsigned int count = 0; count < sizeof(sound) / sizeof(sound[0]); count++)
    {
        if (sound[count])
        {
            result = sound[count]->release();
            ERRCHECK(result);
        }
    }
    
    result = gSystem->release();
    ERRCHECK(result);

    Common_Close();

    return 0;
}
int FMOD_Main()
{
    FMOD::System     *system;
    FMOD::Sound      *sound, *sound_to_play;
    FMOD::Channel    *channel = 0;
    FMOD_RESULT       result;
    unsigned int      version;
    void             *extradriverdata = 0;
    int               numsubsounds;

    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);

    /*
        This example uses an FSB file, which is a preferred pack format for fmod containing multiple sounds.
        This could just as easily be exchanged with a wav/mp3/ogg file for example, but in this case you wouldnt need to call getSubSound.
        Because getNumSubSounds is called here the example would work with both types of sound file (packed vs single).
    */
    result = system->createSound(Common_MediaPath("wave_vorbis.fsb"), FMOD_LOOP_NORMAL | FMOD_2D, 0, &sound);
    ERRCHECK(result);

    result = sound->getNumSubSounds(&numsubsounds);
    ERRCHECK(result);

    if (numsubsounds)
    {
        sound->getSubSound(0, &sound_to_play);
        ERRCHECK(result);
    }
    else
    {
        sound_to_play = sound;
    }

    /*
        Play the sound.
    */
    result = system->playSound(sound_to_play, 0, false, &channel);
    ERRCHECK(result);

    /*
        Main loop.
    */
    do
    {
        Common_Update();

        if (Common_BtnPress(BTN_ACTION1))
        {
            bool paused;
            result = channel->getPaused(&paused);
            ERRCHECK(result);
            result = channel->setPaused(!paused);
            ERRCHECK(result);
        }

        result = system->update();
        ERRCHECK(result);

        {
            unsigned int ms = 0;
            unsigned int lenms = 0;
            bool         playing = false;
            bool         paused = false;

            if (channel)
            {
                result = channel->isPlaying(&playing);
                if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE))
                {
                    ERRCHECK(result);
                }

                result = channel->getPaused(&paused);
                if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE))
                {
                    ERRCHECK(result);
                }

                result = channel->getPosition(&ms, FMOD_TIMEUNIT_MS);
                if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE))
                {
                    ERRCHECK(result);
                }

                result = sound_to_play->getLength(&lenms, FMOD_TIMEUNIT_MS);
                if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE))
                {
                    ERRCHECK(result);
                }
            }

            Common_Draw("==================================================");
            Common_Draw("Play Stream Example.");
            Common_Draw("Copyright (c) Firelight Technologies 2004-2014.");
            Common_Draw("==================================================");
            Common_Draw("");
            Common_Draw("Press %s to toggle pause", Common_BtnStr(BTN_ACTION1));
            Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));
            Common_Draw("");
            Common_Draw("Time %02d:%02d:%02d/%02d:%02d:%02d : %s", ms / 1000 / 60, ms / 1000 % 60, ms / 10 % 100, lenms / 1000 / 60, lenms / 1000 % 60, lenms / 10 % 100, paused ? "Paused " : playing ? "Playing" : "Stopped");
        }

        Common_Sleep(50);
    } while (!Common_BtnPress(BTN_QUIT));

    /*
        Shut down
    */
    result = sound->release();  /* Release the parent, not the sound that was retrieved with getSubSound. */
    ERRCHECK(result);
    result = system->close();
    ERRCHECK(result);
    result = system->release();
    ERRCHECK(result);

    Common_Close();

    return 0;
}
Exemple #18
0
/*==============================================================================
Record example
Copyright (c), Firelight Technologies Pty, Ltd 2004-2014.

This example shows how to record continuously, and play back the same data as
closely to the record cursor as possible without stuttering.
==============================================================================*/
#include "fmod.hpp"
#include "common.h"

#define LATENCY_MS      (50) /* Some devices will require higher latency to avoid glitches */
int FMOD_Main()
{
    FMOD::System   *system = 0;
    FMOD::Sound    *sound = 0;
    FMOD::Channel  *channel = 0;
    FMOD_RESULT     result = FMOD_OK;
    unsigned int    version = 0;
    unsigned int    soundlength = 0;
    bool            dspenabled = false;
    void           *extradriverdata = 0;
    unsigned int    recordpos = 0;
    unsigned int    recorddelta = 0;
    unsigned int    minrecorddelta = (unsigned int)-1;
    unsigned int    lastrecordpos = 0;
    unsigned int    samplesrecorded = 0;
    unsigned int    playpos = 0;
    float           smootheddelta = 0;
    FMOD_CREATESOUNDEXINFO exinfo;
    
    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(100, FMOD_INIT_NORMAL, extradriverdata);
    ERRCHECK(result);


    int recordrate;
    int recordchannels;
    result = system->getRecordDriverInfo(0, NULL, NULL, 0, 0, &recordrate, 0, &recordchannels);
    ERRCHECK(result);

    unsigned int adjustedlatency = (recordrate * LATENCY_MS) / 1000;
    unsigned int driftthreshold =  adjustedlatency / 2;


    /*
        Create user sound to record into.
    */
    memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
    exinfo.cbsize           = sizeof(FMOD_CREATESOUNDEXINFO);
    exinfo.numchannels      = recordchannels;
    exinfo.format           = FMOD_SOUND_FORMAT_PCM16;
    exinfo.defaultfrequency = recordrate;
    exinfo.length           = exinfo.defaultfrequency * sizeof(short) * exinfo.numchannels * 5; /* 5 second buffer, doesnt really matter how big this is, but not too small of course. */
    
    result = system->createSound(0, FMOD_LOOP_NORMAL | FMOD_OPENUSER, &exinfo, &sound);
    ERRCHECK(result);

    result = system->recordStart(0, sound, true);
    ERRCHECK(result);

    result = sound->getLength(&soundlength, FMOD_TIMEUNIT_PCM);
    ERRCHECK(result);

    /*
        Main loop
    */
    do
    {
        Common_Update();

        if (Common_BtnPress(BTN_ACTION1))
        {
            FMOD_REVERB_PROPERTIES propon = FMOD_PRESET_CONCERTHALL;
            FMOD_REVERB_PROPERTIES propoff = FMOD_PRESET_OFF;

            dspenabled = !dspenabled;

            result = system->setReverbProperties(0, dspenabled ? &propon : &propoff);
            ERRCHECK(result);
        }

        result = system->update();
        ERRCHECK(result);
       
        system->getRecordPosition(0, &recordpos);
        ERRCHECK(result);

        recorddelta = (recordpos >= lastrecordpos) ? (recordpos - lastrecordpos) : (recordpos + soundlength - lastrecordpos);
        lastrecordpos = recordpos;
        
        samplesrecorded += recorddelta;
        if (samplesrecorded >= adjustedlatency && !channel)
        {
            result = system->playSound(sound, 0, false, &channel);
            ERRCHECK(result);
        }

        if (channel && recorddelta)
        {
            /*
                If the record driver steps the position of the record cursor in larger increments than the user
                defined latency value, then we should increase our latency value to match.
            */
            if (recorddelta < minrecorddelta)
            {
                minrecorddelta = recorddelta;
                if (adjustedlatency < recorddelta)
                {
                    adjustedlatency = recorddelta;
                }
            }

            result = channel->getPosition(&playpos, FMOD_TIMEUNIT_PCM);
            ERRCHECK(result);
            
	        /*
                Smooth total
            */
            {
                const float dampratio = 0.97f;
                static float total = 0;

                total *= dampratio;
                total += (recordpos >= playpos) ? (recordpos - playpos) : (recordpos + soundlength - playpos);
                smootheddelta = total * (1.0f - dampratio);
            }
           
            if (smootheddelta < (adjustedlatency - driftthreshold) || smootheddelta > soundlength / 2) /* If play cursor is catching up to record (or passed it), slow playback down */
            {
                channel->setFrequency(recordrate - (recordrate / 50)); /* Decrease speed by 2% */
            }
            else if (smootheddelta > (adjustedlatency + driftthreshold)) /* If play cursor is falling too far behind record, speed playback up */
            {
                channel->setFrequency(recordrate + (recordrate / 50)); /* Increase speed by 2% */
            }
            else
            {
                channel->setFrequency(recordrate); /* Otherwise set to normal rate */
            }
        }
       
        Common_Draw("==================================================");
        Common_Draw("Record Example.");
        Common_Draw("Copyright (c) Firelight Technologies 2004-2014.");
        Common_Draw("==================================================");
        Common_Draw("");
        Common_Draw("Adjust LATENCY define to compensate for stuttering");
        Common_Draw("");
        Common_Draw("Press %s to %s DSP effect", Common_BtnStr(BTN_ACTION1), dspenabled ? "disable" : "enable");
        Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));
        Common_Draw("");
        Common_Draw("Default playback latency: %4d (%dms)", (recordrate * LATENCY_MS) / 1000, LATENCY_MS);
        Common_Draw("Current playback latency: %4d (%dms)", (int)smootheddelta, (int)smootheddelta * 1000 / recordrate);
        Common_Draw("Record position: %6d", recordpos);
        Common_Draw("Play Position:   %6d", playpos);

        Common_Sleep(10);
    } while (!Common_BtnPress(BTN_QUIT));

    /*
        Shut down
    */
    result = sound->release();
    ERRCHECK(result);
    result = system->release();
    ERRCHECK(result);

    Common_Close();

    return 0;
}
int FMOD_Main()
{
    FMOD::System     *system;
    FMOD::Sound      *sound;
    FMOD::Channel    *channel = 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->createSound(Common_MediaPath("wave.mp3"), FMOD_HARDWARE | FMOD_LOOP_NORMAL | FMOD_2D, 0, &sound);
    ERRCHECK(result);

    /*
        Play the sound.
    */
    result = system->playSound(sound, 0, false, &channel);
    ERRCHECK(result);

    /*
        Main loop.
    */
    do
    {
        Common_Update();

        if (Common_BtnPress(BTN_ACTION1))
        {
            bool paused;
            result = channel->getPaused(&paused);
            ERRCHECK(result);
            result = channel->setPaused(!paused);
            ERRCHECK(result);
        }

        result = system->update();
        ERRCHECK(result);

        {
            unsigned int ms = 0;
            unsigned int lenms = 0;
            bool         playing = false;
            bool         paused = false;

            if (channel)
            {
                result = channel->isPlaying(&playing);
                if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE))
                {
                    ERRCHECK(result);
                }

                result = channel->getPaused(&paused);
                if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE))
                {
                    ERRCHECK(result);
                }

                result = channel->getPosition(&ms, FMOD_TIMEUNIT_MS);
                if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE))
                {
                    ERRCHECK(result);
                }
               
                result = sound->getLength(&lenms, FMOD_TIMEUNIT_MS);
                if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE))
                {
                    ERRCHECK(result);
                }
            }

            Common_Draw("==================================================");
            Common_Draw("Play Stream Example.");
            Common_Draw("Copyright (c) Firelight Technologies 2004-2013.");
            Common_Draw("==================================================");
            Common_Draw("");
            Common_Draw("Press %s to toggle pause", Common_BtnStr(BTN_ACTION1));
            Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));
            Common_Draw("");
            Common_Draw("Time %02d:%02d:%02d/%02d:%02d:%02d : %s", ms / 1000 / 60, ms / 1000 % 60, ms / 10 % 100, lenms / 1000 / 60, lenms / 1000 % 60, lenms / 10 % 100, paused ? "Paused " : playing ? "Playing" : "Stopped");
        }

        Common_Sleep(50);
    } while (!Common_BtnPress(BTN_QUIT));

    /*
        Shut down
    */
    result = sound->release();
    ERRCHECK(result);
    result = system->close();
    ERRCHECK(result);
    result = system->release();
    ERRCHECK(result);

    Common_Close();

    return 0;
}
int FMOD_Main()
{
    FMOD::System     *system;
    FMOD::Sound      *sound1, *sound2;
    FMOD::Channel    *channel = 0;
    FMOD_RESULT       result;
    unsigned int      version;
    int               selection = 0;
    void             *extradriverdata = 0;
    FMOD_SPEAKERMODE  speakermode = FMOD_SPEAKERMODE_STEREO;
    
    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->getSoftwareFormat(0, &speakermode, 0);
    ERRCHECK(result);

    result = system->createSound(Common_MediaPath("drumloop.wav"), FMOD_2D | FMOD_LOOP_OFF, 0, &sound1);
    ERRCHECK(result);

    result = system->createSound(Common_MediaPath("stereo.ogg"), FMOD_2D | FMOD_LOOP_OFF,  0, &sound2);
    ERRCHECK(result);

    /*
        Main loop.
    */
    do
    {
        Common_Update();

        if (Common_BtnPress(BTN_UP) && (selection != 0))
        {
            selection--;
        }
        
        if (Common_BtnPress(BTN_DOWN) && (selection != (SELECTION_COUNT - 1)))
        {
            selection++;
        }

        if (Common_BtnPress(BTN_ACTION1) && isSelectionAvailable(speakermode, selection))
        {
            if (selection == 0) /* Mono front left */
            {
                result = system->playSound(sound1, 0, true, &channel);
                ERRCHECK(result);

                result = channel->setMixLevelsOutput(1.0f, 0, 0, 0, 0, 0, 0, 0);
                ERRCHECK(result);

                result = channel->setPaused(false);
                ERRCHECK(result);
            }
            else if (selection == 1) /* Mono front right */
            {
                result = system->playSound(sound1, 0, true, &channel);
                ERRCHECK(result);

                result = channel->setMixLevelsOutput(0, 1.0f, 0, 0, 0, 0, 0, 0);
                ERRCHECK(result);

                result = channel->setPaused(false);
                ERRCHECK(result);
            }
            else if (selection == 2) /* Mono center */
            {
                result = system->playSound(sound1, 0, true, &channel);
                ERRCHECK(result);

                result = channel->setMixLevelsOutput(0, 0, 1.0f, 0, 0, 0, 0, 0);
                ERRCHECK(result);

                result = channel->setPaused(false);
                ERRCHECK(result);
            }
            else if (selection == 3) /* Mono surround left */
            {
                result = system->playSound(sound1, 0, true, &channel);
                ERRCHECK(result);

                result = channel->setMixLevelsOutput(0, 0, 0, 0, 1.0f, 0, 0, 0);
                ERRCHECK(result);

                result = channel->setPaused(false);
                ERRCHECK(result);
            }
            else if (selection == 4) /* Mono surround right */
            {
                result = system->playSound(sound1, 0, true, &channel);
                ERRCHECK(result);

                result = channel->setMixLevelsOutput(0, 0, 0, 0, 0, 1.0f, 0, 0);
                ERRCHECK(result);

                result = channel->setPaused(false);
                ERRCHECK(result);
            }
            else if (selection == 5) /* Mono rear left */
            {
                result = system->playSound(sound1, 0, true, &channel);
                ERRCHECK(result);

                result = channel->setMixLevelsOutput(0, 0, 0, 0, 0, 0, 1.0f, 0);
                ERRCHECK(result);

                result = channel->setPaused(false);
                ERRCHECK(result);
            }
            else if (selection == 6) /* Mono rear right */
            {
                result = system->playSound(sound1, 0, true, &channel);
                ERRCHECK(result);

                result = channel->setMixLevelsOutput(0, 0, 0, 0, 0, 0, 0, 1.0f);
                ERRCHECK(result);

                result = channel->setPaused(false);
                ERRCHECK(result);
            }
            else if (selection == 7) /* Stereo front */
            {
                result = system->playSound(sound2, 0, false, &channel);
                ERRCHECK(result);
            }
            else if (selection == 8) /* Stereo front channel swapped */
            {
                float matrix[] = { 0.0f, 1.0f,
                                   1.0f, 0.0f };

                result = system->playSound(sound2, 0, true, &channel);
                ERRCHECK(result);

                result = channel->setMixMatrix(matrix, 2, 2);
                ERRCHECK(result);

                result = channel->setPaused(false);
                ERRCHECK(result);
            }
            else if (selection == 9) /* Stereo (right only) center */
            {
                float matrix[] = { 0.0f, 0.0f,
                                   0.0f, 0.0f,
                                   0.0f, 1.0f };

                result = system->playSound(sound2, 0, true, &channel);
                ERRCHECK(result);

                result = channel->setMixMatrix(matrix, 3, 2);
                ERRCHECK(result);

                result = channel->setPaused(false);
                ERRCHECK(result);
            }
        }

        result = system->update();
        ERRCHECK(result);

        {
            unsigned int ms = 0;
            unsigned int lenms = 0;
            bool         playing = false;
            bool         paused = false;
            int          channelsplaying = 0;

            if (channel)
            {
                FMOD::Sound *currentsound = 0;

                result = channel->isPlaying(&playing);
                if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN))
                {
                    ERRCHECK(result);
                }

                result = channel->getPaused(&paused);
                if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN))
                {
                    ERRCHECK(result);
                }

                result = channel->getPosition(&ms, FMOD_TIMEUNIT_MS);
                if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN))
                {
                    ERRCHECK(result);
                }
               
                channel->getCurrentSound(&currentsound);
                if (currentsound)
                {
                    result = currentsound->getLength(&lenms, FMOD_TIMEUNIT_MS);
                    if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN))
                    {
                        ERRCHECK(result);
                    }
                }
            }

            result = system->getChannelsPlaying(&channelsplaying);
            ERRCHECK(result);

            Common_Draw("==================================================");
            Common_Draw("Multiple Speaker Example.");
            Common_Draw("Copyright (c) Firelight Technologies 2004-2015.");
            Common_Draw("==================================================");
            Common_Draw("");
            Common_Draw("Speaker mode is set to %s%s", SPEAKERMODE_STRING[speakermode], speakermode < FMOD_SPEAKERMODE_7POINT1 ? " causing some speaker options to be unavailable" : "");
            Common_Draw("");
            Common_Draw("Press %s or %s to select mode", Common_BtnStr(BTN_UP), Common_BtnStr(BTN_DOWN));
            Common_Draw("Press %s to play the sound", Common_BtnStr(BTN_ACTION1));
            for (int i = 0; i < SELECTION_COUNT; i++)
            {
                bool disabled = !isSelectionAvailable(speakermode, i);
                Common_Draw("[%c] %s%s", (selection == i) ? (disabled ? '-' : 'X') : ' ', disabled ? "[N/A] " : "", SELECTION_STRING[i]);
            }
            Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));
            Common_Draw("");
            Common_Draw("Time %02d:%02d:%02d/%02d:%02d:%02d : %s", ms / 1000 / 60, ms / 1000 % 60, ms / 10 % 100, lenms / 1000 / 60, lenms / 1000 % 60, lenms / 10 % 100, paused ? "Paused " : playing ? "Playing" : "Stopped");
            Common_Draw("Channels playing: %d", channelsplaying);
        }

        Common_Sleep(50);
    } while (!Common_BtnPress(BTN_QUIT));

    /*
        Shut down
    */
    result = sound1->release();
    ERRCHECK(result);
    result = sound2->release();
    ERRCHECK(result);
    result = system->close();
    ERRCHECK(result);
    result = system->release();
    ERRCHECK(result);

    Common_Close();

    return 0;
}
int FMOD_Main()
{
    void *extraDriverData = NULL;
    Common_Init(&extraDriverData);

    FMOD::Studio::System* system = NULL;
    ERRCHECK( FMOD::Studio::System::create(&system) );
    ERRCHECK( system->initialize(32, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, extraDriverData) );

    FMOD::Studio::Bank* masterBank = NULL;
    ERRCHECK( system->loadBankFile(Common_MediaPath("Master Bank.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &masterBank) );

    FMOD::Studio::Bank* stringsBank = NULL;
    ERRCHECK( system->loadBankFile(Common_MediaPath("Master Bank.strings.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &stringsBank) );

    FMOD::Studio::Bank* ambienceBank = NULL;
    ERRCHECK( system->loadBankFile(Common_MediaPath("Character.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &ambienceBank) );

    FMOD::Studio::EventDescription* eventDescription = NULL;
    ERRCHECK( system->getEvent("event:/Character/Footsteps/Footsteps", &eventDescription) );

    FMOD::Studio::EventInstance* eventInstance = NULL;
    ERRCHECK( eventDescription->createInstance(&eventInstance) );

    FMOD::Studio::ParameterInstance* surfaceParameter = NULL;
    ERRCHECK( eventInstance->getParameter("Surface", &surfaceParameter) );

    // Make the event audible to start with
    ERRCHECK( surfaceParameter->setValue(1.0f) );

    float surfaceParameterValue = 0;
    ERRCHECK( surfaceParameter->getValue(&surfaceParameterValue) );
    
    ERRCHECK( eventInstance->start() );

    do
    {
        Common_Update();

        if (Common_BtnPress(BTN_ACTION1))
        {
            surfaceParameterValue -= 1.0f;
            ERRCHECK( surfaceParameter->setValue(surfaceParameterValue) );
            ERRCHECK( surfaceParameter->getValue(&surfaceParameterValue) );
        }

        if (Common_BtnPress(BTN_ACTION2))
        {
            surfaceParameterValue += 1.0f;
            ERRCHECK( surfaceParameter->setValue(surfaceParameterValue) );
            ERRCHECK( surfaceParameter->getValue(&surfaceParameterValue) );
        }

        ERRCHECK( system->update() );

        Common_Draw("==================================================");
        Common_Draw("Event Parameter Example.");
        Common_Draw("Copyright (c) Firelight Technologies 2015-2015.");
        Common_Draw("==================================================");
        Common_Draw("");
        Common_Draw("Surface Parameter = %1.1f", surfaceParameterValue);
        Common_Draw("");
        Common_Draw("Surface Parameter:");
        Common_Draw("Press %s to decrease value", Common_BtnStr(BTN_ACTION1));
        Common_Draw("Press %s to increase value", Common_BtnStr(BTN_ACTION2));
        Common_Draw("");
        Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));

        Common_Sleep(50);
    } while (!Common_BtnPress(BTN_QUIT));

    ERRCHECK( system->release() );

    Common_Close();

    return 0;
}
int FMOD_Main()
{
    FMOD::System    *system;
    FMOD::Channel   *channel = 0;
    FMOD::DSP       *dsp;
    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);

    /*
        Create an oscillator DSP units for the tone.
    */
    result = system->createDSPByType(FMOD_DSP_TYPE_OSCILLATOR, &dsp);
    ERRCHECK(result);
    result = dsp->setParameterFloat(FMOD_DSP_OSCILLATOR_RATE, 440.0f); /* Musical note 'A' */
    ERRCHECK(result);

    /*
        Main loop
    */
    do
    {
        Common_Update();

        if (Common_BtnPress(BTN_ACTION1))
        {
            if (channel)
            {
                result = channel->stop();
                ERRCHECK(result);
            }

            result = system->playDSP(dsp, 0, true, &channel);
            ERRCHECK(result);
            result = channel->setVolume(0.5f);
            ERRCHECK(result);
            result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 0);
            ERRCHECK(result);
            result = channel->setPaused(false);
            ERRCHECK(result);
        }

        if (Common_BtnPress(BTN_ACTION2))
        {
            if (channel)
            {
                result = channel->stop();
                ERRCHECK(result);
            }

            result = system->playDSP(dsp, 0, true, &channel);
            ERRCHECK(result);
            result = channel->setVolume(0.125f);
            ERRCHECK(result);
            result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 1);
            ERRCHECK(result);
            result = channel->setPaused(false);
            ERRCHECK(result);
        }

        if (Common_BtnPress(BTN_ACTION3))
        {
            if (channel)
            {
                result = channel->stop();
                ERRCHECK(result);
            }

            result = system->playDSP(dsp, 0, true, &channel);
            ERRCHECK(result);
            result = channel->setVolume(0.125f);
            ERRCHECK(result);
            result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 2);
            ERRCHECK(result);
            result = channel->setPaused(false);
            ERRCHECK(result);
        }

        if (Common_BtnPress(BTN_ACTION4))
        {
            if (channel)
            {
                result = channel->stop();
                ERRCHECK(result);
            }

            result = system->playDSP(dsp, 0, true, &channel);
            ERRCHECK(result);
            result = channel->setVolume(0.5f);
            ERRCHECK(result);
            result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 4);
            ERRCHECK(result);
            result = channel->setPaused(false);
            ERRCHECK(result);
        }

        if (Common_BtnPress(BTN_MORE))
        {
            if (channel)
            {
                result = channel->stop();
                ERRCHECK(result);
                channel = 0;
            }
        }

        if (channel)
        {
            if (Common_BtnDown(BTN_UP) || Common_BtnDown(BTN_DOWN))
            {
                float volume;
            
                result = channel->getVolume(&volume);
                ERRCHECK(result);
            
                volume += (Common_BtnDown(BTN_UP) ? +0.1f : -0.1f);
                volume = (volume > 1.0f) ? 1.0f : volume;
                volume = (volume < 0.0f) ? 0.0f : volume;
           
                result = channel->setVolume(volume);
                ERRCHECK(result);
            }

            if (Common_BtnDown(BTN_LEFT) || Common_BtnDown(BTN_RIGHT))
            {
                float frequency;
            
                result = channel->getFrequency(&frequency);
                ERRCHECK(result);
            
                frequency += (Common_BtnDown(BTN_RIGHT) ? +500.0f : -500.0f);
            
                result = channel->setFrequency(frequency);
                ERRCHECK(result);
            }
        }

        result = system->update();
        ERRCHECK(result);

        {
            float frequency = 0.0f, volume = 0.0f;
            bool playing = false;

            if (channel)
            {
                result = channel->getFrequency(&frequency);
                ERRCHECK(result);
                result = channel->getVolume(&volume);
                ERRCHECK(result);
                result = channel->isPlaying(&playing);
                ERRCHECK(result);
            }

            Common_Draw("==================================================");
            Common_Draw("Generate Tone Example.");
            Common_Draw("Copyright (c) Firelight Technologies 2004-2015.");
            Common_Draw("==================================================");
            Common_Draw("");
            Common_Draw("Press %s to play a sine wave", Common_BtnStr(BTN_ACTION1));
            Common_Draw("Press %s to play a square wave", Common_BtnStr(BTN_ACTION2));
            Common_Draw("Press %s to play a saw wave", Common_BtnStr(BTN_ACTION3));
            Common_Draw("Press %s to play a triangle wave", Common_BtnStr(BTN_ACTION4));
            Common_Draw("Press %s to stop the channel", Common_BtnStr(BTN_MORE));
            Common_Draw("Press %s and %s to change volume", Common_BtnStr(BTN_UP), Common_BtnStr(BTN_DOWN));
            Common_Draw("Press %s and %s to change frequency", Common_BtnStr(BTN_LEFT), Common_BtnStr(BTN_RIGHT));
            Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));
            Common_Draw("");
            Common_Draw("Channel is %s", playing ? "playing" : "stopped");
            Common_Draw("Volume %0.2f", volume);
            Common_Draw("Frequency %0.2f", frequency);
        }

        Common_Sleep(50);
    } while (!Common_BtnPress(BTN_QUIT));

    /*
        Shut down
    */
    result = dsp->release();
    ERRCHECK(result);
    result = system->close();
    ERRCHECK(result);
    result = system->release();
    ERRCHECK(result);

    Common_Close();

    return 0;
}
int FMOD_Main()
{
    void *extraDriverData = NULL;
    Common_Init(&extraDriverData);

    FMOD::Studio::System* system = NULL;
    ERRCHECK( FMOD::Studio::System::create(&system) );

    // The example Studio project is authored for 5.1 sound, so set up the system output mode to match
    FMOD::System* lowLevelSystem = NULL;
    ERRCHECK( system->getLowLevelSystem(&lowLevelSystem) );
    ERRCHECK( lowLevelSystem->setSoftwareFormat(0, FMOD_SPEAKERMODE_5POINT1, 0) );

    ERRCHECK( system->initialize(1024, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, extraDriverData) );

    FMOD::Studio::Bank* masterBank = NULL;
    ERRCHECK( system->loadBankFile(Common_MediaPath("Master Bank.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &masterBank) );

    FMOD::Studio::Bank* stringsBank = NULL;
    ERRCHECK( system->loadBankFile(Common_MediaPath("Master Bank.strings.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &stringsBank) );

    FMOD::Studio::Bank* ambienceBank = NULL;
    ERRCHECK( system->loadBankFile(Common_MediaPath("Character.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &ambienceBank) );

    FMOD::Studio::EventDescription* eventDescription = NULL;
    ERRCHECK( system->getEvent("event:/Character/Radio/Command", &eventDescription) );

    FMOD::Studio::EventInstance* eventInstance = NULL;
    ERRCHECK( eventDescription->createInstance(&eventInstance) );
    
    ProgrammerSoundContext programmerSoundContext;
    ERRCHECK( system->getLowLevelSystem(&programmerSoundContext.system) );

    ERRCHECK( eventInstance->setUserData(&programmerSoundContext) );
    ERRCHECK( eventInstance->setCallback(programmerSoundCallback, FMOD_STUDIO_EVENT_CALLBACK_CREATE_PROGRAMMER_SOUND | FMOD_STUDIO_EVENT_CALLBACK_DESTROY_PROGRAMMER_SOUND) );

    ERRCHECK( eventInstance->setVolume(0.75f) );

    do
    {
        Common_Update();

        if (Common_BtnPress(BTN_ACTION1))
        {
            programmerSoundContext.soundName = Common_MediaPath("640166main_MECO.ogg");
            ERRCHECK( eventInstance->start() );
        }

        if (Common_BtnPress(BTN_ACTION2))
        {
            programmerSoundContext.soundName = Common_MediaPath("640169main_Press to ATO.ogg");
            ERRCHECK( eventInstance->start() );
        }

        if (Common_BtnPress(BTN_ACTION3))
        {
            programmerSoundContext.soundName = Common_MediaPath("640148main_APU Shutdown.ogg");
            ERRCHECK( eventInstance->start() );
        }

        if (Common_BtnPress(BTN_ACTION4))
        {
            programmerSoundContext.soundName = Common_MediaPath("640165main_Lookin At It.ogg");
            ERRCHECK( eventInstance->start() );
        }

        ERRCHECK( system->update() );

        Common_Draw("==================================================");
        Common_Draw("Programmer Sound Example.");
        Common_Draw("Copyright (c) Firelight Technologies 2016-2016.");
        Common_Draw("==================================================");
        Common_Draw("");
        Common_Draw("Press %s to play event with sound 1", Common_BtnStr(BTN_ACTION1));
        Common_Draw("Press %s to play event with sound 2", Common_BtnStr(BTN_ACTION2));
        Common_Draw("Press %s to play event with sound 3", Common_BtnStr(BTN_ACTION3));
        Common_Draw("Press %s to play event with sound 4", Common_BtnStr(BTN_ACTION4));
        Common_Draw("");
        Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));

        Common_Sleep(50);
    } while (!Common_BtnPress(BTN_QUIT));

    ERRCHECK( system->release() );

    Common_Close();

    return 0;
}