예제 #1
0
	/*/////////////////////////////////////////////////////////////////*/
	void OgreOggStreamSound::_updatePlayPosition()
	{
		if ( mSource==AL_NONE || !mSeekable ) 
			return;

		bool paused = isPaused();
		bool playing = isPlaying();

		// Seek...
		pause();
		ov_time_seek(&mOggStream, mPlayPos);

		// Unqueue all buffers
		_dequeue();

		// Fill buffers
		_prebuffer();

		// Reset state..
		if		( playing ) play();
		else if ( paused ) pause();

		// Set flag
		mStreamEOF=false;
		mPlayPosChanged = false;
		mLastOffset = mPlayPos;
	}			   
예제 #2
0
	/*/////////////////////////////////////////////////////////////////*/
	void OgreOggStreamSound::setSource(ALuint& src)
	{
		if (src!=AL_NONE)
		{
			// Set source
			mSource=src;

			// Fill data buffers
			_prebuffer();

			// Init source
			_initSource();
		}
		else
		{
			// Unqueue buffers
			_dequeue();

			// Set source
			mSource=src;

			// Cancel initialisation
			mInitialised = false;
		}
	}
예제 #3
0
	/*/////////////////////////////////////////////////////////////////*/
	void OgreOggStaticSound::setSource(ALuint& src)
	{
		if (src!=AL_NONE)
		{
			// Attach new source
			mSource=src;

			// Load audio data onto source
			_prebuffer();

			// Init source properties
			_initSource();
		}
		else
		{
			// Need to stop sound BEFORE unqueuing
			alSourceStop(mSource);

			// Unqueue buffer
			alSourcei(mSource, AL_BUFFER, 0);

			// Attach new source
			mSource=src;

			// Cancel initialisation
			mInitialised = false;
		}
	}
예제 #4
0
파일: player.c 프로젝트: jmerdich/cmus
void player_play_file(struct track_info *ti)
{
	player_lock();
	_producer_set_file(ti);
	if (producer_status == PS_UNLOADED) {
		_consumer_stop();
		goto out;
	}

	/* PS_STOPPED */
	_producer_play();

	/* PS_UNLOADED,PS_PLAYING */
	if (producer_status == PS_UNLOADED) {
		_consumer_stop();
		goto out;
	}

	/* PS_PLAYING */
	if (consumer_status == CS_STOPPED) {
		_consumer_play();
		if (consumer_status == CS_STOPPED)
			_producer_stop();
	} else {
		op_drop();
		change_sf(1);
	}
out:
	_player_status_changed();
	if (producer_status == PS_PLAYING)
		_prebuffer();
	player_unlock();
}
예제 #5
0
파일: player.c 프로젝트: jmerdich/cmus
void player_pause(void)
{
	if (ip && ip_is_remote(ip) && consumer_status == CS_PLAYING) {
		/* pausing not allowed */
		player_stop();
		return;
	}
	player_lock();

	if (consumer_status == CS_STOPPED) {
		_producer_play();
		if (producer_status == PS_PLAYING) {
			_consumer_play();
			if (consumer_status != CS_PLAYING)
				_producer_stop();
		}
		_player_status_changed();
		if (consumer_status == CS_PLAYING)
			_prebuffer();
		player_unlock();
		return;
	}

	_producer_pause();
	_consumer_pause();
	_player_status_changed();
	player_unlock();
}
예제 #6
0
파일: player.c 프로젝트: jmerdich/cmus
static void _consumer_handle_eof(void)
{
	struct track_info *ti;

	if (ip_is_remote(ip)) {
		_producer_stop();
		_consumer_drain_and_stop();
		player_error("lost connection");
		return;
	}

	if (player_info.ti)
		player_info.ti->play_count++;

	if (player_repeat_current) {
		if (player_cont) {
			ip_seek(ip, 0);
			reset_buffer();
		} else {
			_producer_stop();
			_consumer_drain_and_stop();
			_player_status_changed();
		}
		return;
	}

	if (get_next(&ti) == 0) {
		_producer_unload();
		ip = ip_new(ti->filename);
		_producer_status_update(PS_STOPPED);
		/* PS_STOPPED, CS_PLAYING */
		if (player_cont) {
			_producer_play();
			if (producer_status == PS_UNLOADED) {
				_consumer_stop();
				track_info_unref(ti);
				file_changed(NULL);
			} else {
				/* PS_PLAYING */
				file_changed(ti);
				if (!change_sf(0))
					_prebuffer();
			}
		} else {
			_consumer_drain_and_stop();
			file_changed(ti);
		}
	} else {
		_producer_unload();
		_consumer_drain_and_stop();
		file_changed(NULL);
	}
	_player_status_changed();
}
예제 #7
0
	/*/////////////////////////////////////////////////////////////////*/
	void OgreOggStreamSound::_stopImpl()
	{
		if(mSource != AL_NONE)
		{
			// Remove audio data from source
			_dequeue();

			// Stop playback
			mState = SS_STOPPED;

			if (mTemporary)
			{
				OgreOggSoundManager::getSingletonPtr()->_destroyTemporarySound(this);
				return;
			}

			// Jump to beginning if seeking available
			if ( mSeekable ) 
			{
				ov_time_seek(&mOggStream,0);
				mLastOffset=0;
				mStreamEOF=false;
			}
			// Non-seekable - close/reopen
			else
			{
				// Close
				_release();

				// Reopen
				_openImpl(mAudioStream);
			}

			// If marked for auto-destruction request destroy()
			if (mTemporary)
			{
				mAwaitingDestruction=true;
			}
			else
			{
				// Reload data
				_prebuffer();

				// Give up source immediately if specfied
				if (mGiveUpSource) OgreOggSoundManager::getSingleton()._releaseSoundSource(this);
			}
		
			// Notify listener
			if ( mSoundListener ) mSoundListener->soundStopped(this);
		}
	}
예제 #8
0
파일: player.c 프로젝트: jmerdich/cmus
void player_play(void)
{
	int prebuffer;

	player_lock();
	if (producer_status == PS_PLAYING && ip_is_remote(ip)) {
		/* seeking not allowed */
		player_unlock();
		return;
	}
	prebuffer = consumer_status == CS_STOPPED;
	_producer_play();
	if (producer_status == PS_PLAYING) {
		_consumer_play();
		if (consumer_status != CS_PLAYING)
			_producer_stop();
	} else {
		_consumer_stop();
	}
	_player_status_changed();
	if (consumer_status == CS_PLAYING && prebuffer)
		_prebuffer();
	player_unlock();
}
예제 #9
0
	/*/////////////////////////////////////////////////////////////////*/
	void OgreOggStreamSound::_updateAudioBuffers()
	{
		if (!isPlaying()) return;

		ALenum state;
		alGetSourcei(mSource, AL_SOURCE_STATE, &state);

		if (state == AL_PAUSED) return;

		// Ran out of buffer data?
		if (state == AL_STOPPED)
		{
			if(mStreamEOF)
			{
				stop();
				
				// Finished callback
				if ( mSoundListener ) 
					mSoundListener->soundFinished(this);
				
				return;
			}
			else
			{
				// Clear audio data already played...
				_dequeue();

				// Fill with next chunk of audio...
				_prebuffer();

				// Play...
				alSourcePlay(mSource);
			}
		}

		int processed;

		alGetSourcei(mSource, AL_BUFFERS_PROCESSED, &processed);

		while(processed--)
		{
			ALuint buffer;
			ALint size, bits, channels, freq;

			alSourceUnqueueBuffers(mSource, 1, &buffer);

			// Get buffer details
			alGetBufferi(buffer, AL_SIZE, &size);
			alGetBufferi(buffer, AL_BITS, &bits);
			alGetBufferi(buffer, AL_CHANNELS, &channels);
			alGetBufferi(buffer, AL_FREQUENCY, &freq);    

			// Update offset (in seconds)
			mLastOffset += ((ALuint)size/channels/(bits/8)) / (ALfloat)freq;
			if ( mLastOffset>=mPlayTime )
			{
				mLastOffset = mLastOffset-mPlayTime;
				
				/**	This is the closest we can get to a loop trigger.
				@remarks 
					If played data size exceeds audio data size trigger callback.
				*/
				if ( mSoundListener ) mSoundListener->soundLooping(this);
			}

			if ( _stream(buffer) ) alSourceQueueBuffers(mSource, 1, &buffer);
		}

		// handle play position change 
		if ( mPlayPosChanged ) 
		{
			_updatePlayPosition();
		}
	}