void CBackgroundSource::play() { if (_Playing) stop(); CAudioMixerUser *mixer = CAudioMixerUser::instance(); const vector<CBackgroundSound::TSoundInfo> &sounds = _BackgroundSound->getSounds(); vector<CBackgroundSound::TSoundInfo>::const_iterator first(sounds.begin()), last(sounds.end()); for (; first != last; ++first) { TSubSource subSource; subSource.Source = mixer->createSource(first->SoundName, false, 0, 0, _Cluster, 0); if (subSource.Source != NULL) subSource.Source->setPriority(_Priority); subSource.Filter = first->Filter; subSource.Status = SUB_STATUS_STOP; _Sources.push_back(subSource); } updateFilterValues(mixer->getBackgroundSoundManager()->getFilterValues()); CSourceCommon::play(); }
void CBackgroundSound::getSubSoundList(std::vector<std::pair<std::string, CSound*> > &subsounds) const { CAudioMixerUser *mixer = CAudioMixerUser::instance(); std::vector<TSoundInfo>::const_iterator first(_Sounds.begin()), last(_Sounds.end()); for (; first != last; ++first) { CSound *sound = mixer->getSoundId(first->SoundName); subsounds.push_back(make_pair(CStringMapper::unmap(first->SoundName), sound)); } }
void CSimpleSource::initPhysicalSource() { CAudioMixerUser *mixer = CAudioMixerUser::instance(); CTrack *track = mixer->getFreeTrack(this); if (track != NULL) { nlassert(track->hasPhysicalSource()); _Track = track; } }
void CStreamSource::initPhysicalSource() { CAudioMixerUser *mixer = CAudioMixerUser::instance(); CTrack *track = mixer->getFreeTrack(this); if (track != NULL) { nlassert(track->hasPhysicalSource()); m_Track = track; getPhysicalSource()->setStreaming(true); } }
/* * Return the sample buffer of this sound */ IBuffer* CSimpleSound::getBuffer() { if (_Buffer == 0) { // try to find the sample buffer in the sample bank. CAudioMixerUser *audioMixer = CAudioMixerUser::instance(); _Buffer = audioMixer->getSampleBankManager()->get(_Buffername); audioMixer->getSoundBank()->registerBufferAssoc(this, _Buffer); _Registered = true; } return _Buffer; }
void CStreamSource::releasePhysicalSource() { if (hasPhysicalSource()) { CAudioMixerUser *mixer = CAudioMixerUser::instance(); ISource *pSource = getPhysicalSource(); nlassert(pSource != NULL); // free the track pSource->stop(); pSource->setStreaming(false); mixer->freeTrack(m_Track); m_Track = NULL; } }
void CSimpleSource::releasePhysicalSource() { if (hasPhysicalSource()) { CAudioMixerUser *mixer = CAudioMixerUser::instance(); ISource *pSource = getPhysicalSource(); nlassert(pSource != NULL); // free the track pSource->stop(); pSource->setStaticBuffer(NULL); mixer->freeTrack(_Track); _Track = NULL; } }
float CBackgroundSound::getMaxDistance() const { CAudioMixerUser *mixer = CAudioMixerUser::instance(); float ret = 0.0f; std::vector<TSoundInfo>::const_iterator first(_Sounds.begin()), last(_Sounds.end()); for (; first != last; ++first) { CSound *sound = mixer->getSoundId(first->SoundName); if (sound != 0) { ret = max(ret, sound->getMaxDistance()); } } if (ret == 0) ret = 1; return ret; }
bool CSampleBank::unload() { vector<IBuffer*> vec; TSampleTable::iterator it; if (!_Loaded) { nlwarning("Trying to unload an already unloaded bank : %s", CStringMapper::unmap(_Name).c_str ()); return true; } // need to wait end of load ? if (!_LoadingDone) return false; //nlinfo("Unloading sample bank %s", CStringMapper::unmap(_Name).c_str()); for (it = _Samples.begin(); it != _Samples.end(); ++it) { IBuffer *buffer = it->second; if (buffer) { const NLMISC::TStringId & bufferName = buffer->getName(); CAudioMixerUser *audioMixer = _SampleBankManager->m_AudioMixer; // Warn the mixer to stop any track playing this buffer. audioMixer->bufferUnloaded(buffer); // Warn the sound banks about this buffer. audioMixer->getSoundBank()->bufferUnloaded(bufferName); // delete it->second = NULL; delete buffer; } } _Loaded = false; _SampleBankManager->m_LoadedSize -= _ByteSize; _ByteSize = 0; return true; }
uint32 CBackgroundSound::getDuration() { if (_DurationValid) return _Duration; vector<sint32> durations; CAudioMixerUser *mixer = CAudioMixerUser::instance(); std::vector<TSoundInfo>::const_iterator first(_Sounds.begin()), last(_Sounds.end()); for (; first != last; ++first) { CSound *sound = mixer->getSoundId(first->SoundName); if (sound != NULL) durations.push_back(sound->getDuration()); } if (durations.empty()) return 0; _Duration = *(std::max_element(durations.begin(), durations.end())); _DurationValid = true; return _Duration; }
CStreamSource::CStreamSource(CStreamSound *streamSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster) : CSourceCommon(streamSound, spawn, cb, cbUserParam, cluster), m_StreamSound(streamSound), m_Alpha(0.0f), m_Track(NULL), m_FreeBuffers(3), m_NextBuffer(0), m_LastSize(0), m_BytesPerSecond(0) { nlassert(m_StreamSound != 0); // get a local copy of the stream sound parameter m_Alpha = m_StreamSound->getAlpha();//m_Buffers // create the three buffer objects CAudioMixerUser *mixer = CAudioMixerUser::instance(); ISoundDriver *driver = mixer->getSoundDriver(); m_Buffers[0] = driver->createBuffer(); m_Buffers[1] = driver->createBuffer(); m_Buffers[2] = driver->createBuffer(); }
/// Stop playing void CSimpleSource::stop() { // nldebug("CSimpleSource %p : stop", (CAudioMixerUser::IMixerEvent*)this); // nlassert(_Playing); if (_WaitingForPlay) { nlassert(!_Playing); // cannot already be playing if waiting for play CAudioMixerUser *mixer = CAudioMixerUser::instance(); mixer->removeSourceWaitingForPlay(this); } if (!_Playing) return; if (hasPhysicalSource()) { releasePhysicalSource(); } else if (_PlayMuted) { CAudioMixerUser *mixer = CAudioMixerUser::instance(); // clear the registered event because of a stop before normal end of play mixer->decPlayingSourceMuted(); mixer->removeEvents(this); } CSourceCommon::stop(); if (_Spawn) { if (_SpawnEndCb != NULL) { _SpawnEndCb(this, _CbUserParam); } delete this; } }
void CStreamSource::play() { nlassert(!_Playing); bool play = false; CAudioMixerUser *mixer = CAudioMixerUser::instance(); { CAutoMutex<CMutex> autoMutex(m_BufferMutex); //if ((mixer->getListenPosVector() - _Position).sqrnorm() > m_StreamSound->getMaxDistance() * m_StreamSound->getMaxDistance()) if ((_RelativeMode ? getPos().sqrnorm() : (mixer->getListenPosVector() - getPos()).sqrnorm()) > m_StreamSound->getMaxDistance() * m_StreamSound->getMaxDistance()) { // Source is too far to play if (_Spawn) { if (_SpawnEndCb != NULL) _SpawnEndCb(this, _CbUserParam); delete this; } // nldebug("CStreamSource %p : play FAILED !", (CAudioMixerUser::IMixerEvent*)this); return; } CAudioMixerUser *mixer = CAudioMixerUser::instance(); if (!hasPhysicalSource()) initPhysicalSource(); if (hasPhysicalSource()) { ISource *pSource = getPhysicalSource(); nlassert(pSource != NULL); for (uint i = 0; i < m_NextBuffer; ++i) pSource->submitStreamingBuffer(m_Buffers[i]); // pSource->setPos( _Position, false); pSource->setPos(getVirtualPos(), false); if (!m_Buffers[0]->isStereo()) { pSource->setMinMaxDistances(m_StreamSound->getMinDistance(), m_StreamSound->getMaxDistance(), false); setDirection(_Direction); // because there is a workaround inside pSource->setVelocity(_Velocity); } pSource->setGain(_Gain); pSource->setSourceRelativeMode(_RelativeMode); // pSource->setLooping(_Looping); pSource->setPitch(_Pitch); pSource->setAlpha(m_Alpha); // and play the sound play = pSource->play(); // nldebug("CStreamSource %p : REAL play done", (CAudioMixerUser::IMixerEvent*)this); } else { if (_Priority == HighestPri) { // This sound is not discardable, add it in waiting playlist mixer->addSourceWaitingForPlay(this); return; } else { // No source available, kill. if (_Spawn) { if (_SpawnEndCb != NULL) _SpawnEndCb(this, _CbUserParam); delete this; } return; } } if (play) CSourceCommon::play(); } nlassert(play); }
/// Play void CSimpleSource::play() { // nldebug("CSimpleSource %p : play", this); CAudioMixerUser *mixer = CAudioMixerUser::instance(); // -- Some test to check if we can play the source // Check if sample buffer is available and if the sound source is not too far if (_SimpleSound->getBuffer() == 0 || !_SimpleSound->getBuffer()->isBufferLoaded() //|| (mixer->getListenPosVector() - _Position).sqrnorm() > _SimpleSound->getMaxDistance() * _SimpleSound->getMaxDistance()) || (_RelativeMode ? getPos().sqrnorm() : (mixer->getListenPosVector() - getPos()).sqrnorm()) > _SimpleSound->getMaxDistance() * _SimpleSound->getMaxDistance()) { // The sample buffer is not available, don't play (we don't know the length) _WaitingForPlay = false; if (_Spawn) { if (_SpawnEndCb != 0) _SpawnEndCb(this, _CbUserParam); delete this; } // nldebug("CSimpleSource %p : play FAILED !", (CAudioMixerUser::IMixerEvent*)this); return; } // -- Here we can play the source, either in a real track or as a muted source. // Try to obtain a track if (!hasPhysicalSource()) initPhysicalSource(); if (hasPhysicalSource()) { ISource *pSource = getPhysicalSource(); nlassert(pSource != NULL); // ok, we have a track to realy play, fill the data into the track pSource->setStaticBuffer(_SimpleSound->getBuffer()); // pSource->setPos( _Position, false); pSource->setPos(getVirtualPos(), false); if (!_SimpleSound->getBuffer()->isStereo()) { pSource->setMinMaxDistances(_SimpleSound->getMinDistance(), _SimpleSound->getMaxDistance(), false); setDirection(_Direction); // because there is a workaround inside pSource->setVelocity(_Velocity); } pSource->setGain(getFinalGain()); pSource->setSourceRelativeMode(_RelativeMode); pSource->setLooping(_Looping); pSource->setPitch(_Pitch); pSource->setAlpha(_Alpha); // and play the sound bool play = pSource->play(); #ifdef NL_DEBUG nlassert(play); #else if (!play) nlwarning("Failed to play physical sound source. This is a serious error"); #endif // nldebug("CSimpleSource %p : REAL play done", (CAudioMixerUser::IMixerEvent*)this); } else { if (_Priority == HighestPri) { // This sound is not discardable, add it in waiting playlist mixer->addSourceWaitingForPlay(this); _WaitingForPlay = true; return; } // there is no available track, just do a 'muted' play mixer->addEvent(this, CTime::getLocalTime() + _SimpleSound->getDuration()); _PlayMuted = true; mixer->incPlayingSourceMuted(); // nldebug("CSimpleSource %p : MUTED play done", (CAudioMixerUser::IMixerEvent*)this); } CSourceCommon::play(); _WaitingForPlay = false; }