void CStreamSource::updateAvailableBuffers() { if (hasPhysicalSource()) { m_FreeBuffers = 3 - getPhysicalSource()->countStreamingBuffers(); } }
uint32 CSimpleSource::getTime() { if (hasPhysicalSource()) return getPhysicalSource()->getTime(); else return 0; }
/* * Set the direction vector (3D mode only, ignored in stereo mode) (default: (0,0,0) as non-directional) */ void CStreamSource::setDirection(const NLMISC::CVector& dir) { CAutoMutex<CMutex> autoMutex(m_BufferMutex); CSourceCommon::setDirection(dir); // Set the direction if (hasPhysicalSource()) { if (!m_Buffers[0]->isStereo()) { static bool coneset = false; if (dir.isNull()) // workaround // For what? { getPhysicalSource()->setCone(float(Pi * 2), float(Pi * 2), 1.0f); // because the direction with 0 is not enough for a non-directional source! getPhysicalSource()->setDirection(CVector::I); // Don't send a 0 vector, DSound will complain. Send (1,0,0), it's omnidirectional anyway. coneset = false; } else { // if (!coneset) { getPhysicalSource()->setCone(m_StreamSound->getConeInnerAngle(), m_StreamSound->getConeOuterAngle(), m_StreamSound->getConeOuterGain()); coneset = true; } getPhysicalSource()->setDirection(dir); } } } }
/// Stop playing void CStreamSource::stop() { CAutoMutex<CMutex> autoMutex(m_BufferMutex); // nldebug("CStreamSource %p : stop", (CAudioMixerUser::IMixerEvent*)this); // nlassert(_Playing); if (!_Playing) return; if (hasPhysicalSource()) releasePhysicalSource(); CSourceCommon::stop(); m_FreeBuffers = 3; m_NextBuffer = 0; if (_Spawn) { if (_SpawnEndCb != NULL) _SpawnEndCb(this, _CbUserParam); delete this; } }
void CStreamSource::setVelocity(const NLMISC::CVector& vel) { CAutoMutex<CMutex> autoMutex(m_BufferMutex); CSourceCommon::setVelocity(vel); if (hasPhysicalSource()) getPhysicalSource()->setVelocity(vel); }
void CStreamSource::setRelativeGain(float gain) { CAutoMutex<CMutex> autoMutex(m_BufferMutex); CSourceCommon::setRelativeGain(gain); if (hasPhysicalSource()) getPhysicalSource()->setGain(_Gain); }
void CStreamSource::setPitch(float pitch) { CAutoMutex<CMutex> autoMutex(m_BufferMutex); CSourceCommon::setPitch(pitch); if (hasPhysicalSource()) getPhysicalSource()->setPitch(pitch); }
void CStreamSource::setSourceRelativeMode(bool mode) { CAutoMutex<CMutex> autoMutex(m_BufferMutex); CSourceCommon::setSourceRelativeMode(mode); if (hasPhysicalSource()) getPhysicalSource()->setSourceRelativeMode(mode); }
void CStreamSource::setPos(const NLMISC::CVector& pos) { CAutoMutex<CMutex> autoMutex(m_BufferMutex); CSourceCommon::setPos(pos); if (hasPhysicalSource()) getPhysicalSource()->setPos(getVirtualPos()); }
uint32 CStreamSource::getTime() { CAutoMutex<CMutex> autoMutex(m_BufferMutex); if (hasPhysicalSource()) return getPhysicalSource()->getTime(); else return 0; }
/* Shift the frequency. 1.0f equals identity, each reduction of 50% equals a pitch shift * of one octave. 0 is not a legal value. */ void CSimpleSource::setPitch(float pitch) { CSourceCommon::setPitch(pitch); // Set the pitch if (hasPhysicalSource()) { getPhysicalSource()->setPitch( pitch ); } }
/* * Set the source relative mode. If true, positions are interpreted relative to the listener position (default: false) */ void CSimpleSource::setSourceRelativeMode(bool mode) { CSourceCommon::setSourceRelativeMode(mode); // Set the relative mode if (hasPhysicalSource()) { getPhysicalSource()->setSourceRelativeMode( mode ); } }
/* Set the position vector (default: (0,0,0)). * 3D mode -> 3D position * st mode -> x is the pan value (from left (-1) to right (1)), set y and z to 0 */ void CSimpleSource::setPos(const NLMISC::CVector& pos) { CSourceCommon::setPos(pos); // Set the position if (hasPhysicalSource()) { // getPhysicalSource()->setPos(pos); getPhysicalSource()->setPos(getVirtualPos()); } }
/* * Set the velocity vector (3D mode only, ignored in stereo mode) (default: (0,0,0)) */ void CSimpleSource::setVelocity(const NLMISC::CVector& vel) { CSourceCommon::setVelocity(vel); // Set the velocity if (hasPhysicalSource()) { // TODO : uncomment, test only getPhysicalSource()->setVelocity(vel); } }
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; } }
/// Notify that you are done writing to the locked buffer, so it can be copied over to hardware if needed. Set size to the number of bytes actually written to the buffer. Returns true if ok. bool CStreamSource::unlock(uint size) { nlassert(m_FreeBuffers > 0); CAutoMutex<CMutex> autoMutex(m_BufferMutex); IBuffer *buffer = m_Buffers[m_NextBuffer]; bool result = buffer->unlock(size); if (size > 0) { ++m_NextBuffer; m_NextBuffer %= 3; --m_FreeBuffers; if (hasPhysicalSource()) getPhysicalSource()->submitStreamingBuffer(buffer); m_LastSize = size; } return result; }
/// 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; } }
/// 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; }
void CSimpleSource::updateFinalGain() { // Set the gain if (hasPhysicalSource()) getPhysicalSource()->setGain(getFinalGain()); }
/// Set looping on/off for future playbacks (default: off) void CSimpleSource::setLooping(bool l) { CSourceCommon::setLooping(l); if (hasPhysicalSource()) getPhysicalSource()->setLooping( l ); }
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); }