float SoundManager::getSoundTimelinePosition(void * soundHandle)
{
    int milliseconds = 0;
#ifdef FMOD_ACTIVE
    FMOD::Studio::EventInstance * instance = static_cast<FMOD::Studio::EventInstance *>(soundHandle);
    if ( nullptr != instance && instance->isValid() )
    {
        ERRCHECK(instance->getTimelinePosition(&milliseconds));
    }
#endif
    return (float)milliseconds/1000.0f;
}
void outputEventByID(FMOD::Studio::System* system, const char* ID)
{
	FMOD_RESULT result;

	FMOD::Studio::ID eventID = { 0 };
	ERRCHECK(system->lookupID(ID, &eventID));  //Lookup the ID string from the banks

											   //Use the ID to get the event
	FMOD::Studio::EventDescription* eventDescription = NULL;
	ERRCHECK(system->getEventByID(&eventID, &eventDescription));

	// Create an instance of the event
	FMOD::Studio::EventInstance* eventInstance = NULL;
	ERRCHECK(eventDescription->createInstance(&eventInstance));
	
	//Preload sample data - otherwise some sounds just dont play
	//eventDescription->loadSampleData(); Done need this -  docs say it starts loading sample as soon as eventinstance created
	FMOD_STUDIO_LOADING_STATE  loadingState = FMOD_STUDIO_LOADING_STATE_LOADING;
	system->update();
	ERRCHECK(eventDescription->getSampleLoadingState(&loadingState));
	while (loadingState != FMOD_STUDIO_LOADING_STATE_LOADED)
	{
		//if (eventDescription->getSampleLoadingState(&loadingState)  == FMOD_OK)
		//{
		//	system->update();
		//}
		//else
		//{}
		//Sleep(1);
		ERRCHECK(eventDescription->getSampleLoadingState(&loadingState));
		system->update();
	}

	//Try and stop looping :~ failed
	//FMOD::ChannelGroup* Channels = NULL;
	//eventInstance->getChannelGroup(&Channels);
	//Channels->setMode(FMOD_LOOP_OFF);


	cout << "Dumping " << ID << endl;

	//TODO - delete file if length is 0 - no point having empty files around
	int length = 0;
	result = eventDescription->getLength(&length);
	if (length == 0)
	{
		return;
	}
	float rate = 1024.0f / 48000.0f;
	float newlength = (float)length / 1000; //turn length into seconds
	float totalCalls = (newlength) / rate; // calculate how many calls of our loop we need till the sound has been played
	float totalTime = 0.0f;
	//bool played = false;
	//OutputDebugString(ID); OutputDebugString("\n");

	//Start playback
	ERRCHECK(eventInstance->start()); //starting here seems to work ok
	
	FMOD_STUDIO_PLAYBACK_STATE playbackState = FMOD_STUDIO_PLAYBACK_STOPPED;
	//system->update();
	eventInstance->getPlaybackState(&playbackState);
	while (playbackState != FMOD_STUDIO_PLAYBACK_PLAYING)
	{
		eventInstance->getPlaybackState(&playbackState);
		system->update();
	}

	int TimelinePos = 0;
	int LastPos = -1;
	//for (int i = 0; i < totalCalls; i++)
	while (TimelinePos < length)
	{
		// if(1000 <= totalTime && !played)
		// {
		//// play sound just once
		//  //ERRCHECK( eventInstance->start() );
		//played = true;
		// }


		eventInstance->getTimelinePosition(&TimelinePos);
		char buffer[255 + 1];
		sprintf(buffer, "Timeline Position is %d\n", TimelinePos);
		OutputDebugString(buffer);

		if (LastPos > TimelinePos) //Looping sounds repeat it seems eg mus_loop_tense never reaches timelinepos then starts again
		{
			break;
		}
		LastPos = TimelinePos;
		system->update();
		Sleep(1);
		//Sleep(1.5); //Crucial! Slows it down enough so that sounds start and end at correct time
					//Big hack but still cant fix it. Tried with callbacks and other methods - this
					//Is the only way that 'reliably' works
		//totalTime += (rate * 1000);
		//sprintf(buffer, "TotalTime Position is %f\n", totalTime);
		//OutputDebugString(buffer);
	}

	eventInstance->stop(FMOD_STUDIO_STOP_ALLOWFADEOUT); //FMOD_STUDIO_STOP_ALLOWFADEOUT 

	playbackState = FMOD_STUDIO_PLAYBACK_STOPPING;
	while (playbackState != FMOD_STUDIO_PLAYBACK_STOPPED)
	{
		eventInstance->getPlaybackState(&playbackState);
		system->update();
	}

	eventInstance->release(); //necessary?????
	eventDescription->unloadSampleData();

	system->update();
	loadingState = FMOD_STUDIO_LOADING_STATE_LOADED;
	while (loadingState != FMOD_STUDIO_LOADING_STATE_UNLOADED)
	{
		if (eventDescription->getSampleLoadingState(&loadingState) == FMOD_OK)
		{
			//system->update();
		}
		else
		{
		}
	}

	//eventDescription->releaseAllInstances;
}
bool outputEventByID(FMOD::Studio::System* system, const char* ID)
{
	FMOD_RESULT result;

	FMOD::Studio::ID eventID = { 0 };
	ERRCHECK(system->lookupID(ID, &eventID));  //Lookup the ID string from the banks

	//Use the ID to get the event
	FMOD::Studio::EventDescription* eventDescription = NULL;
	ERRCHECK(system->getEventByID(&eventID, &eventDescription));

	// Create an instance of the event
	FMOD::Studio::EventInstance* eventInstance = NULL;
	ERRCHECK(eventDescription->createInstance(&eventInstance));
	
	//Preload sample data - otherwise some sounds just dont play
	//eventDescription->loadSampleData(); Done need this -  docs say it starts loading sample as soon as eventinstance created
	FMOD_STUDIO_LOADING_STATE  loadingState = FMOD_STUDIO_LOADING_STATE_LOADING;
	system->update();
	ERRCHECK(eventDescription->getSampleLoadingState(&loadingState));
	while (loadingState != FMOD_STUDIO_LOADING_STATE_LOADED)
	{
		ERRCHECK(eventDescription->getSampleLoadingState(&loadingState));
		system->update();
	}

	
	int length = 0;
	result = eventDescription->getLength(&length);
	if (length == 0)
	{
		return false; 
	}


	cout << "Dumping " << ID << endl;

	int TimelinePos = 0;
	int LastPos = -1;
	bool played = false;

	while (TimelinePos < length)
	{
		if (!played)
		{
			ERRCHECK(eventInstance->start()); //Start playback
			played = true;
		}
		
		eventInstance->getTimelinePosition(&TimelinePos);
		//char buffer[255 + 1];
		//sprintf(buffer, "Timeline Position is %d\n", TimelinePos);
		//OutputDebugString(buffer);

		if (LastPos > TimelinePos) //Looping sounds repeat and have wrong getlength value eg mus_loop_tense never reaches timelinepos 
		{						   //Seems to report a longer length than reality. So if we dont manually stop it, the track loops forever
			break;
		}
		LastPos = TimelinePos;
		system->update();
		Sleep(1);   //Crucial! Slows it down enough so that sounds start and end at correct time
					//Big hack but still cant fix it. Tried with callbacks and other methods - this
					//Is the only way that 'reliably' works
	}

	eventInstance->stop(FMOD_STUDIO_STOP_IMMEDIATE); //FMOD_STUDIO_STOP_ALLOWFADEOUT 
	FMOD_STUDIO_PLAYBACK_STATE playbackState = FMOD_STUDIO_PLAYBACK_STOPPING;
	while (playbackState != FMOD_STUDIO_PLAYBACK_STOPPED)
	{
		eventInstance->getPlaybackState(&playbackState);
		system->update();
	}

	eventInstance->release(); //necessary?????
	eventDescription->unloadSampleData();

	system->update();
	loadingState = FMOD_STUDIO_LOADING_STATE_LOADED;
	while (loadingState != FMOD_STUDIO_LOADING_STATE_UNLOADED)
	{
		if (eventDescription->getSampleLoadingState(&loadingState) == FMOD_OK)
		{
			//system->update();
		}
		else
		{
		}
	}

	//eventDescription->releaseAllInstances;
	return true;
}
Beispiel #4
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;
}