コード例 #1
0
ファイル: AudioChannel.cpp プロジェクト: nixtux/spring
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);
}