void CStreamSource::updateAvailableBuffers()
{
	if (hasPhysicalSource())
	{
		m_FreeBuffers = 3 - getPhysicalSource()->countStreamingBuffers();
	}
}
Пример #2
0
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;
}
Пример #11
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 );
	}
}
Пример #12
0
/*
 * 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 );
	}
}
Пример #13
0
/* 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());
	}
}
Пример #14
0
/*
 * 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;
	}
}
Пример #16
0
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;
}
Пример #18
0
/// 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;
	}
}
Пример #19
0
/// 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;
}
Пример #20
0
void CSimpleSource::updateFinalGain()
{
	// Set the gain
	if (hasPhysicalSource())
		getPhysicalSource()->setGain(getFinalGain());
}
Пример #21
0
/// 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);
}