Sound::~Sound() { SafeDeleteArray(soundData); FMOD_VERIFY(fmodInstanceGroup->release()); FMOD_VERIFY(fmodSound->release()); }
SoundSystem::SoundSystem(int32 maxChannels) { FMOD_VERIFY(FMOD::EventSystem_Create(&fmodEventSystem)); FMOD_VERIFY(fmodEventSystem->getSystemObject(&fmodSystem)); FMOD_VERIFY(fmodEventSystem->init(maxChannels, FMOD_INIT_NORMAL, 0)); FMOD_VERIFY(fmodSystem->set3DSettings(1.f, 1.f, 0.4f)); }
void FMODSoundEvent::SetParameterValue(const FastName & paramName, float32 value) { paramsValues[paramName] = value; Vector<FMOD::Event *> instancesCopy(fmodEventInstances); int32 instancesCount = instancesCopy.size(); for(int32 i = 0; i < instancesCount; ++i) { FMOD::EventParameter * param = 0; FMOD_VERIFY(instancesCopy[i]->getParameter(paramName.c_str(), ¶m)); if(param) FMOD_VERIFY(param->setValue(value)); } }
void Sound::UpdateInstancesPosition() { if(is3d) { FMOD_VECTOR pos = {position.x, position.y, position.z}; int32 instancesCount = 0; FMOD_VERIFY(fmodInstanceGroup->getNumChannels(&instancesCount)); for(int32 i = 0; i < instancesCount; i++) { FMOD::Channel * inst = 0; FMOD_VERIFY(fmodInstanceGroup->getChannel(i, &inst)); FMOD_VERIFY(inst->set3DAttributes(&pos, 0)); } } }
void FMODSoundEvent::Stop(bool force /* = false */) { SoundSystem * soundSystem = SoundSystem::Instance(); Vector<FMOD::Event *> instancesCopy(fmodEventInstances); int32 instancesCount = instancesCopy.size(); for(int32 i = 0; i < instancesCount; ++i) { FMOD::Event * fEvent = instancesCopy[i]; FMOD_VERIFY(fEvent->setCallback(0, 0)); FMOD_VERIFY(fEvent->stop(force)); PerformEvent(SoundEvent::EVENT_END); soundSystem->ReleaseOnUpdate(this); } fmodEventInstances.clear(); }
void Sound::SetSoundGroup(const FastName & groupName) { SoundGroup * soundGroup = SoundSystem::Instance()->CreateSoundGroup(groupName); if(soundGroup) { FMOD_VERIFY(fmodSound->setSoundGroup(soundGroup->fmodSoundGroup)); } }
bool FMODSoundEvent::Trigger() { SoundSystem * soundSystem = SoundSystem::Instance(); FMOD::EventSystem * fmodEventSystem = soundSystem->fmodEventSystem; if(is3D) { FMOD::Event * fmodEventInfo = 0; FMOD_VERIFY(fmodEventSystem->getEvent(eventName.c_str(), FMOD_EVENT_INFOONLY, &fmodEventInfo)); if(fmodEventInfo) { FMOD_VERIFY(fmodEventInfo->set3DAttributes((FMOD_VECTOR*)&position, 0, isDirectional ? (FMOD_VECTOR*)&direction : NULL)); FMOD_VERIFY(fmodEventInfo->setVolume(volume)); ApplyParamsToEvent(fmodEventInfo); } } FMOD::Event * fmodEvent = 0; FMOD_RESULT result = fmodEventSystem->getEvent(eventName.c_str(), FMOD_EVENT_DEFAULT, &fmodEvent); if(result == FMOD_OK) { ApplyParamsToEvent(fmodEvent); FMOD_VERIFY(fmodEvent->setVolume(volume)); FMOD_RESULT startResult = fmodEvent->start(); if(startResult == FMOD_OK) { FMOD_VERIFY(fmodEvent->setCallback(FMODEventCallback, this)); fmodEventInstances.push_back(fmodEvent); Retain(); } else if(startResult != FMOD_ERR_EVENT_FAILED) //'just fail' max playbacks behavior { Logger::Error("[FMODSoundEvent::Trigger()] Failed to start event by %d on eventID: %s", startResult, eventName.c_str()); } } else if(result != FMOD_ERR_EVENT_FAILED) //'just fail' max playbacks behavior { Logger::Error("[FMODSoundEvent::Trigger()] Failed to retrieve event by %d on eventID: %s", result, eventName.c_str()); } PerformEvent(EVENT_TRIGGERED); return fmodEvent != 0; }
void FMODSoundEvent::ApplyParamsToEvent(FMOD::Event *event) { FastNameMap<float32>::iterator it = paramsValues.begin(); FastNameMap<float32>::iterator itEnd = paramsValues.end(); for(;it != itEnd; ++it) { FMOD::EventParameter * param = 0; FMOD_VERIFY(event->getParameter(it->first.c_str(), ¶m)); if(param) { FMOD_VERIFY(param->setValue(it->second)); } else { Logger::Error("Event: %s, Param: %s", eventName.c_str(), it->first.c_str()); } } }
SoundEvent * SoundSystem::CreateSoundEvent(const String & eventPath) { FMOD::Event * fmodEvent = 0; FMOD_VERIFY(fmodEventSystem->getEvent(eventPath.c_str(), FMOD_EVENT_DEFAULT, &fmodEvent)); if(fmodEvent) return new SoundEvent(fmodEvent); else return 0; }
ScopedPtr<SoundEventCategory> SoundSystem::GetSoundEventCategory(const String & category) { FMOD::EventCategory * fmodCategory = 0; FMOD_VERIFY(fmodEventSystem->getCategory(category.c_str(), &fmodCategory)); if(fmodCategory) return ScopedPtr<SoundEventCategory>(new SoundEventCategory(fmodCategory)); else return ScopedPtr<SoundEventCategory>(0); }
SoundSystem::~SoundSystem() { for(FastNameMap<SoundGroup*>::Iterator it = soundGroups.Begin(); it != soundGroups.End(); ++it) { SoundGroup * soundGroup = it.GetValue(); SafeRelease(soundGroup); } soundGroups.Clear(); FMOD_VERIFY(fmodSystem->release()); }
void SoundSystem::SetListenerOrientation(const Vector3 & at, const Vector3 & left) { Vector3 atNorm = at; atNorm.Normalize(); Vector3 upNorm = at.CrossProduct(left); upNorm.Normalize(); FMOD_VECTOR fmodAt = {atNorm.x, atNorm.y, atNorm.z}; FMOD_VECTOR fmodUp = {upNorm.x, upNorm.y, upNorm.z}; FMOD_VERIFY(fmodEventSystem->set3DListenerAttributes(0, 0, 0, &fmodAt, &fmodUp)); }
FMOD_RESULT F_CALLBACK SoundInstanceEndPlaying(FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACKTYPE type, void *commanddata1, void *commanddata2) { if(type == FMOD_CHANNEL_CALLBACKTYPE_END) { FMOD::Channel *cppchannel = (FMOD::Channel *)channel; Sound * sound = 0; FMOD_VERIFY(cppchannel->getUserData((void**)&sound)); SoundSystem::Instance()->SendCallbackOnUpdate(sound); } return FMOD_OK; }
void FMODSoundEvent::SetVelocity(const Vector3 & velocity) { if(is3D && fmodEventInstances.size()) { Vector<FMOD::Event *> instancesCopy(fmodEventInstances); int32 instancesCount = instancesCopy.size(); for(int32 i = 0; i < instancesCount; ++i) { FMOD_VERIFY(instancesCopy[i]->set3DAttributes(0, (FMOD_VECTOR*)&velocity, 0)); } } }
void FMODSoundEvent::UpdateInstancesPosition() { if(is3D) { Vector<FMOD::Event *> instancesCopy(fmodEventInstances); int32 instancesCount = instancesCopy.size(); for(int32 i = 0; i < instancesCount; ++i) { FMOD_VERIFY(instancesCopy[i]->set3DAttributes((FMOD_VECTOR*)&position, 0, isDirectional ? (FMOD_VECTOR*)&direction : NULL)); } } }
Sound * Sound::CreateWithFlags(const FilePath & fileName, eType type, const FastName & groupName, int32 flags, int32 priority) { Sound * sound = new Sound(fileName, type, priority); if(flags & FMOD_3D) sound->is3d = true; File * file = File::Create(fileName, File::OPEN | File::READ); int32 fileSize = file->GetSize(); sound->soundData = new uint8[fileSize]; file->Read(sound->soundData, fileSize); SafeRelease(file); FMOD_CREATESOUNDEXINFO exInfo; memset(&exInfo, 0, sizeof(FMOD_CREATESOUNDEXINFO)); exInfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); exInfo.length = fileSize; switch (type) { case TYPE_STATIC: FMOD_VERIFY(SoundSystem::Instance()->fmodSystem->createSound((char *)sound->soundData, FMOD_LOOP_NORMAL | FMOD_OPENMEMORY | flags, &exInfo, &sound->fmodSound)); SafeDelete(sound->soundData); break; case TYPE_STREAMED: FMOD_VERIFY(SoundSystem::Instance()->fmodSystem->createStream((char *)sound->soundData, FMOD_LOOP_NORMAL | FMOD_OPENMEMORY | flags, &exInfo, &sound->fmodSound)); break; } #if !defined DONT_USE_DEFAULT_3D_SOUND_SETTINGS if( sound->is3d && sound->fmodSound ) FMOD_VERIFY( sound->fmodSound->set3DMinMaxDistance(5.0f, 100.0f) ); #endif sound->SetSoundGroup(groupName); sound->SetLoopCount(0); FMOD_VERIFY(SoundSystem::Instance()->fmodSystem->createChannelGroup(0, &sound->fmodInstanceGroup)); return sound; }
void FMODSoundEvent::GetEventParametersInfo(Vector<SoundEventParameterInfo> & paramsInfo) const { paramsInfo.clear(); FMOD::Event * event = 0; if(fmodEventInstances.size()) { event = fmodEventInstances[0]; } else { FMOD::EventSystem * fmodEventSystem = SoundSystem::Instance()->fmodEventSystem; fmodEventSystem->getEvent(eventName.c_str(), FMOD_EVENT_INFOONLY, &event); } if(!event) return; int32 paramsCount = 0; FMOD_VERIFY(event->getNumParameters(¶msCount)); paramsInfo.reserve(paramsCount); for(int32 i = 0; i < paramsCount; i++) { FMOD::EventParameter * param = 0; FMOD_VERIFY(event->getParameterByIndex(i, ¶m)); if(!param) continue; char * paramName = 0; FMOD_VERIFY(param->getInfo(0, ¶mName)); SoundEventParameterInfo pInfo; pInfo.name = String(paramName); FMOD_VERIFY(param->getRange(&pInfo.minValue, &pInfo.maxValue)); paramsInfo.push_back(pInfo); } }
void FMODSoundEvent::SetVolume(float32 _volume) { if(volume != _volume) { volume = _volume; Vector<FMOD::Event *> instancesCopy(fmodEventInstances); int32 instancesCount = instancesCopy.size(); for(int32 i = 0; i < instancesCount; ++i) { FMOD_VERIFY(instancesCopy[i]->setVolume(volume)); } } }
FMOD_RESULT F_CALLBACK FMODSoundEvent::FMODEventCallback(FMOD_EVENT *event, FMOD_EVENT_CALLBACKTYPE type, void *param1, void *param2, void *userdata) { if(type == FMOD_EVENT_CALLBACKTYPE_STOLEN || type == FMOD_EVENT_CALLBACKTYPE_EVENTFINISHED) { DVASSERT_MSG(Thread::IsMainThread(), DAVA::Format("FMOD Callback type %d", type).c_str()); FMOD::Event * fEvent = (FMOD::Event *)event; FMODSoundEvent * sEvent = (FMODSoundEvent *)userdata; if(sEvent && fEvent) { FMOD_VERIFY(fEvent->setCallback(0, 0)); sEvent->PerformCallback(fEvent); } } return FMOD_OK; }
void Sound::Play() { FMOD::Channel * fmodInstance = 0; FMOD_VERIFY(SoundSystem::Instance()->fmodSystem->playSound(FMOD_CHANNEL_FREE, fmodSound, true, &fmodInstance)); //start sound paused FMOD_VECTOR pos = {position.x, position.y, position.z}; FMOD_VERIFY(fmodInstance->setPriority(priority)); FMOD_VERIFY(fmodInstance->setCallback(SoundInstanceEndPlaying)); FMOD_VERIFY(fmodInstance->setUserData(this)); FMOD_VERIFY(fmodInstance->setChannelGroup(fmodInstanceGroup)); if(is3d) FMOD_VERIFY(fmodInstance->set3DAttributes(&pos, 0)); FMOD_VERIFY(fmodInstance->setPaused(false)); Retain(); }
void Sound::Pause(bool isPaused) { FMOD_VERIFY(fmodInstanceGroup->setPaused(isPaused)); }
void SoundEventCategory::Stop() { FMOD_VERIFY(fmodEventCategory->stopAllEvents()); }
bool SoundEventCategory::GetPaused() { bool isPaused = false; FMOD_VERIFY(fmodEventCategory->getPaused(&isPaused)); return isPaused; }
int32 Sound::GetLoopCount() const { int32 loopCount; FMOD_VERIFY(fmodSound->getLoopCount(&loopCount)); return loopCount; }
void Sound::SetLoopCount(int32 loopCount) { FMOD_VERIFY(fmodSound->setLoopCount(loopCount)); }
void Sound::Stop() { FMOD_VERIFY(fmodInstanceGroup->stop()); }
bool Sound::IsPaused() { bool isPaused = false; FMOD_VERIFY(fmodInstanceGroup->getPaused(&isPaused)); return isPaused; }
void SoundEventCategory::Pause(bool isPaused) { FMOD_VERIFY(fmodEventCategory->setPaused(isPaused)); }
float32 Sound::GetVolume() { float32 volume = 0; FMOD_VERIFY(fmodInstanceGroup->getVolume(&volume)); return volume; }
void Sound::SetVolume(float32 volume) { FMOD_VERIFY(fmodInstanceGroup->setVolume(volume)); }