void AudioChannel::FindSourceAndPlay(size_t id, const float3& pos, const float3& velocity, float volume, bool relative) { if (!enabled) return; if (volume <= 0.0f) return; boost::recursive_mutex::scoped_lock slck(soundMutex); SoundItem* sndItem = sound->GetSoundItem(id); if (!sndItem) { sound->numEmptyPlayRequests++; return; } if (pos.distance(sound->GetListenerPos()) > sndItem->MaxDistance()) { if (!relative) return; else LogObject(LOG_SOUND) << "CSound::PlaySample: maxdist ignored for relative payback: " << sndItem->Name(); } if (emmitsThisFrame >= emmitsPerFrame) return; emmitsThisFrame++; CSoundSource* sndSource = sound->GetNextBestSource(); if (!sndSource) return; if (sndSource->GetCurrentPriority() < sndItem->GetPriority()) { if (sndSource->IsPlaying()) sound->numAbortedPlays++; sndSource->Play(this, sndItem, pos, velocity, volume, relative); CheckError("CSound::FindSourceAndPlay"); boost::recursive_mutex::scoped_lock lck(chanMutex); cur_sources[sndSource] = true; } }
CSoundSource* CSound::GetNextBestSource(bool lock) { boost::recursive_mutex::scoped_lock lck(soundMutex, boost::defer_lock); if (lock) lck.lock(); if (sources.empty()) return NULL; CSoundSource* bestPos = NULL; for (sourceVecT::iterator it = sources.begin(); it != sources.end(); ++it) { if (!it->IsPlaying()) { return &(*it); } else if (it->GetCurrentPriority() <= (bestPos ? bestPos->GetCurrentPriority() : INT_MAX)) { bestPos = &(*it); } } return bestPos; }
void AudioChannel::FindSourceAndPlay(size_t id, const float3& pos, const float3& velocity, float volume, bool relative) { boost::recursive_mutex::scoped_lock lck(soundMutex); if (!enabled) return; if (volume <= 0.0f) return; SoundItem* sndItem = sound->GetSoundItem(id); if (!sndItem) { sound->numEmptyPlayRequests++; return; } if (pos.distance(sound->GetListenerPos()) > sndItem->MaxDistance()) { if (!relative) { return; } else { LOG("CSound::PlaySample: maxdist ignored for relative playback: %s", sndItem->Name().c_str()); } } if (emmitsThisFrame >= emmitsPerFrame) return; emmitsThisFrame++; if (cur_sources.size() >= maxConcurrentSources) { CSoundSource* src = NULL; int prio = INT_MAX; for (std::map<CSoundSource*, bool>::iterator it = cur_sources.begin(); it != cur_sources.end(); ++it) { if (it->first->GetCurrentPriority() < prio) { src = it->first; prio = it->first->GetCurrentPriority(); } } if (src && prio <= sndItem->GetPriority()) { src->Stop(); } else { LOG_L(L_DEBUG, "CSound::PlaySample: Max concurrent sounds in channel reached! Dropping playback!"); return; } } CSoundSource* sndSource = sound->GetNextBestSource(); if (!sndSource) { LOG_L(L_DEBUG, "CSound::PlaySample: Max sounds reached! Dropping playback!"); return; } if (sndSource->GetCurrentPriority() < sndItem->GetPriority()) { if (sndSource->IsPlaying()) sound->numAbortedPlays++; sndSource->Play(this, sndItem, pos, velocity, volume, relative); CheckError("CSound::FindSourceAndPlay"); cur_sources[sndSource] = true; } }
void AudioChannel::FindSourceAndPlay(size_t id, const float3& pos, const float3& velocity, float volume, bool relative) { std::lock_guard<spring::recursive_mutex> lck(soundMutex); if (!enabled) return; if (volume <= 0.0f) return; // generate the sound item SoundItem* sndItem = sound->GetSoundItem(id); if (sndItem == nullptr) { sound->numEmptyPlayRequests++; return; } // check distance to listener if (pos.distance(sound->GetListenerPos()) > sndItem->MaxDistance()) { if (!relative) return; LOG("CSound::PlaySample: maxdist ignored for relative playback: %s", sndItem->Name().c_str()); } // don't spam to many sounds per frame if (emitsThisFrame >= emitsPerFrame) return; emitsThisFrame++; // check if the sound item is already played if (curSources.size() >= maxConcurrentSources) { CSoundSource* src = nullptr; int prio = INT_MAX; for (auto it = curSources.begin(); it != curSources.end(); ++it) { if ((*it)->GetCurrentPriority() < prio) { src = *it; prio = src->GetCurrentPriority(); } } if (src == nullptr || prio > sndItem->GetPriority()) { LOG_L(L_DEBUG, "CSound::PlaySample: Max concurrent sounds in channel reached! Dropping playback!"); return; } src->Stop(); } // find a sound source to play the item in CSoundSource* sndSource = sound->GetNextBestSource(); if (sndSource == nullptr || (sndSource->GetCurrentPriority() >= sndItem->GetPriority())) { LOG_L(L_DEBUG, "CSound::PlaySample: Max sounds reached! Dropping playback!"); return; } if (sndSource->IsPlaying()) sound->numAbortedPlays++; // play the sound item sndSource->PlayAsync(this, sndItem, pos, velocity, volume, relative); curSources.insert(sndSource); }