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