void FFMODStudioOculusModule::OnInitialize()
{
	UE_LOG(LogFMODOculus, Verbose, TEXT("OnInitialize"));

#if FMOD_OSP_SUPPORTED
	const UFMODOculusSettings& Settings = *GetDefault<UFMODOculusSettings>();
	if (!Settings.bOculusEnabled)
	{
		UE_LOG(LogFMODOculus, Verbose, TEXT("bOculusEnabled is false - skipping init"));
		return;
	}

	FMOD::Studio::System* StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
	if (!StudioSystem)
	{
		UE_LOG(LogFMODOculus, Log, TEXT("StudioSystem is null - skipping init"));
		return;
	}

	if (!IFMODStudioModule::Get().LoadPlugin(TEXT("ovrfmod")))
	{
		UE_LOG(LogFMODOculus, Log, TEXT("ovrfmod failed to load - skipping init"));

		return;
	}

	UE_LOG(LogFMODOculus, Log, TEXT("Initialising OSP"));

	FMOD::System* LowLevelSystem = nullptr;
	verifyfmod(StudioSystem->getLowLevelSystem(&LowLevelSystem));
	if (LowLevelSystem)
	{
		int SampleRate = 0;
		unsigned int BufferSize = 0;
		verifyfmod(LowLevelSystem->getSoftwareFormat(&SampleRate, nullptr, nullptr));
		verifyfmod(LowLevelSystem->getDSPBufferSize(&BufferSize, nullptr));
		int returncode = OSP_FMOD_Initialize(SampleRate, BufferSize);
		if (returncode == 0)
		{
			bRunning = true;
			// Unreal units are per cm, but our plugin converts everything to metres when calling into Studio
			OSP_FMOD_SetGlobalScale(1.0f);
			UFMODOculusBlueprintStatics::SetEarlyReflectionsEnabled(Settings.bEarlyReflectionsEnabled);
			UFMODOculusBlueprintStatics::SetLateReverberationEnabled(Settings.bLateReverberationEnabled);
			UFMODOculusBlueprintStatics::SetRoomParameters(Settings.RoomParameters);
			UE_LOG(LogFMODOculus, Log, TEXT("OSP_FMOD_Initialize returned success - running with Oculus plugin enabled"));
		}
		else
		{
			UE_LOG(LogFMODOculus, Error, TEXT("OSP_FMOD_Initialize returned error %s"), returncode);
		}
	}
#else
	UE_LOG(LogFMODOculus, Log, TEXT("FMOD_OSP_SUPPORTED is not enabled"));
#endif
}
Exemplo n.º 2
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* 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;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
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;
}
int FMOD_Main()
{
	cout << "Tellale Music Extractor" << endl;
	cout << "FMOD Bank Extractor" << endl;
	cout << "Copyright (c) 2015 Bennyboy" << endl;
	cout << "Http://quickandeasysoftware.net" << endl << endl;

	//cout << "Dumping to " << argv[0] << endl << endl;
	cout << "Dumping will take some time, please be patient." << endl << endl;




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

	//Studio high level system
	FMOD::Studio::System* system = NULL;
	FMOD_RESULT result = FMOD::Studio::System::create(&system);
	ERRCHECK(result);

	//Low level system
	//FMOD::System* lowLevel;
	//system->getLowLevelSystem(&lowLevel);

	//Set output to wav file. NRT means we control the playback speed with update()
	//lowLevel->setOutput(FMOD_OUTPUTTYPE_WAVWRITER_NRT);    




	//Initialise the system. 
	result = system->initialize(32, FMOD_STUDIO_INIT_ALLOW_MISSING_PLUGINS, FMOD_INIT_NORMAL, extraDriverData);
	ERRCHECK(result);


	//Load all .bank files from dir into vector
	std::vector<std::string> FilesInDir;
	GetBankFilesInDirectory(FilesInDir, "C:/Program Files (x86)/FMOD SoundSystem/FMOD Studio API Windows/api/studio/examples/test/");


	//Create vector to hold all the bank instances
	std::vector<FMOD::Studio::Bank* > vbank_;
	int FileArraySize = FilesInDir.size();

	//Set size of the vector to the number of banks and initialise each bank to null 
	vbank_.resize(FileArraySize);
	for (int i = 0; i <= FileArraySize - 1; i++)
	{
		vbank_[i] = NULL; //initialise banks
	}

	//Loop through and load the banks from our bank instances
	for (int i = 0; i <= FileArraySize - 1; i++)
	{
		system->loadBankFile(FilesInDir[i].c_str(), FMOD_STUDIO_LOAD_BANK_NORMAL, &vbank_[i]);
		//Bank loading is asynchronous - so make sure its finished loading before we do operations on it. Easier just to wait here after we load each bank.
		FMOD_STUDIO_LOADING_STATE  bankloadingState = FMOD_STUDIO_LOADING_STATE_LOADING;
		while (bankloadingState != FMOD_STUDIO_LOADING_STATE_LOADED)
		{
			system->update();
			ERRCHECK(vbank_[i]->getLoadingState(&bankloadingState));
		}
	}


	//Preload all samples in all banks
	//for ( int i = 0 ; i <= FileArraySize-1 ; i++ )
	//{
	//	vbank_[i]->loadSampleData();
	//	FMOD_STUDIO_LOADING_STATE  loadingState = FMOD_STUDIO_LOADING_STATE_UNLOADED;
	//	while (loadingState !=FMOD_STUDIO_LOADING_STATE_LOADED)
	//	{
	//		if (vbank_[i]->getSampleLoadingState(&loadingState)  == FMOD_OK)
	//		{
	//			system->update();
	//		}
	//		else
	//		{}
	//	}
	//}


	//Create an array to hold all the Event ID's
	std::vector<std::string> idVector;

	//Get all the event ID's from the banks and store them in idVector
	for (int i = 0; i <= FileArraySize - 1; i++)
	{
		int eventCount = 0;
		int maxLen = 255;
		char buffer[255 + 1];

		vbank_[i]->getEventCount(&eventCount); //get the number of events in the bank

											   //Create an array to hold the eventdescriptions
		FMOD::Studio::EventDescription** eventArray = (FMOD::Studio::EventDescription**)malloc(eventCount * sizeof(void*));

		//Fill the array with the events from the bank
		result = vbank_[i]->getEventList(eventArray, eventCount, &eventCount);
		if (result == FMOD_OK)
		{
			for (int j = 0; j < eventCount; j++)
			{
				//Get the ID
				result = eventArray[j]->getPath(buffer, maxLen, 0);
				if (result == FMOD_OK)
				{
					//OutputDebugString(buffer); OutputDebugString("\n");
					if (strncmp(buffer, "event", 5) == 0) //only add "event" ID's
					{
						idVector.push_back(buffer); //add it as a new element at the end of the vector
					}
				}
				else
				{
					OutputDebugString("OI! couldnt get ID!");
				}
			}
		}

		free(eventArray);
	}


	//Free the system so we can create a new one and control the output filename
	result = system->release();
	ERRCHECK(result);


	//Loop through each ID
	for (int i = 0; i <= idVector.size() - 1; i++)
	{

		//Studio high level system
		FMOD::Studio::System* system = NULL;
		FMOD_RESULT result = FMOD::Studio::System::create(&system);
		ERRCHECK(result);

		//Low level system
		FMOD::System* lowLevel;
		system->getLowLevelSystem(&lowLevel);

		//Set output to wav file. NRT means we control the playback speed with update()
		lowLevel->setOutput(FMOD_OUTPUTTYPE_WAVWRITER_NRT);


		//Extract filename
		std::string tempString = idVector[i];//.c_str();
		std::string filename;
		unsigned found = tempString.find_last_of("/\\");
		filename = tempString.substr(found + 1);
		filename.append(".wav");



		//Initialise the system. 
		//Need STREAM_FROM_UPDATE as we're using WAVWRITER_NRT. Need the synchronous here?? Thread unsafe for low level - dunno
		result = system->initialize(32, FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE, FMOD_INIT_STREAM_FROM_UPDATE | FMOD_INIT_THREAD_UNSAFE, (char*)filename.c_str());
		ERRCHECK(result);


		//Loop through and load the banks from our bank instances (banks already stored in array earlier)
		for (int j = 0; j <= FileArraySize - 1; j++)
		{
			system->loadBankFile(FilesInDir[j].c_str(), FMOD_STUDIO_LOAD_BANK_NORMAL, &vbank_[j]);

			//Bank loading is asynchronous - so make sure its finished loading before we do operations on it. Easier just to wait here after we load each bank.
			system->update();
			FMOD_STUDIO_LOADING_STATE  bankloadingState = FMOD_STUDIO_LOADING_STATE_LOADING;
			ERRCHECK(vbank_[j]->getLoadingState(&bankloadingState));
			while (bankloadingState == FMOD_STUDIO_LOADING_STATE_LOADING)
			{

				ERRCHECK(vbank_[j]->getLoadingState(&bankloadingState));
			}
		}




		//Playback and save the file
		outputEventByID(system, idVector[i].c_str());


		//Free the system so we can create a new one and control the output filename
		result = system->release();
		ERRCHECK(result);
		lowLevel->release();
	}




	Common_Close();

	return 0;
}
Exemplo n.º 6
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;
}
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;
}