예제 #1
0
void RestartVorbisPlayer(VorbisPlayer *self)
{
	stb_vorbis_seek_start(self->vorbis);
	self->currentframe=NULL;
	self->framepos=0;
	self->framelength=0;
}
예제 #2
0
파일: AEAudio.c 프로젝트: Oddity007/AE
bool AEAudioStreamUpdate(AEAudioStream* self){
	ALint processed=0;
	
    alGetSourcei(self->source, AL_BUFFERS_PROCESSED, &processed);

    while(processed--){
        ALuint buffer=0;
        
        alSourceUnqueueBuffers(self->source, 1, &buffer);
		
		if(not AEAudioStreamStream(self, buffer)){
			bool shouldExit=true;
			
			if(self->shouldLoop){
				stb_vorbis_seek_start(self->stream);
				self->totalSamplesLeft=stb_vorbis_stream_length_in_samples(self->stream) * self->info.channels;
				shouldExit=not AEAudioStreamStream(self, buffer);
			}
			
			if(shouldExit) return false;
		}
		alSourceQueueBuffers(self->source, 1, &buffer);
	}
	
	return true;
}
예제 #3
0
void snd_PlayStreaming( int streamID, float volume, float pan ) // todo: fade in?
{
	assert( ( streamID >= 0 ) && ( streamID < MAX_STREAMING_SOUNDS ) );
	SDL_LockAudioDevice( devID ); {
		if( ( streamingSounds[streamID].access != NULL ) && !streamingSounds[streamID].playing ) {

			streamingSounds[streamID].sdlStream = SDL_NewAudioStream( AUDIO_S16,
				(Uint8)( streamingSounds[streamID].access->channels ), streamingSounds[streamID].access->sample_rate,
				WORKING_FORMAT, streamingSounds[streamID].channels, WORKING_RATE );

			if( streamingSounds[streamID].sdlStream == NULL ) {
				llog( LOG_ERROR, "Unable to create SDL_AudioStream for streaming sound." );
				return;
			}

			streamingSounds[streamID].playing = true;
			streamingSounds[streamID].volume = volume;
			streamingSounds[streamID].pan = pan;

			stb_vorbis_seek_start( streamingSounds[streamID].access );

			streamingSounds[streamID].readDone = false;
		}
	} SDL_UnlockAudioDevice( devID );
}
예제 #4
0
			virtual void pull(AudioChunk &chunk)
			{
				if (!chunk.length())   return;
				if (!valid || finished) {chunk.silence(); return;}

				int samples, have = 0, need = chunk.length();

				//Create pointers to 16-bit data
				short *d16[PG_MAX_CHANNELS];
				for (Uint32 i = 0; i < chunk.format().channels; ++i)
					d16[i] = (short*) chunk.start(i);

				while (true)
				{
					samples = stb_vorbis_get_samples_short(ogg,
						chunk.format().channels, d16, (need-have));

					if (samples < 0)
					{
						finished = true;
						//cout << " VORBIS ERROR" << endl;
						break;
					}
					if (samples == 0)
					{
						//File's end
						if (loop)
						{
							stb_vorbis_seek_start(ogg);
							continue;
						}
						else
						{
							finished = true;
							break;
						}
					}

					for (Uint32 i=0; i < chunk.format().channels; ++i)
						d16[i] += samples;
					have += samples;
					//if (have > need) cout << "VORBIS OVERDRAW" << endl;

					//std::cout << "OGG pull: " << have << "/" << need << std::endl;

					if (have >= need) break;
				}

				//Cutoff marker if necessary
				if (have < need) chunk.cutoff(have);

				//Upsample data to 24-bit Sint32s
				for (Uint32 i=0; i < chunk.format().channels; ++i)
				{
					Sint32 *start = chunk.start(i), *op = start + have;
					short *ip = d16[i];
					while (op!=start) {*(--op) = 256 * Sint32(*(--ip));}
				}
			}
예제 #5
0
파일: Sound.cpp 프로젝트: CarloMaker/Urho3D
void Sound::RewindDecoder(void* decoder)
{
    if (!decoder)
        return;
    
    stb_vorbis* vorbis = static_cast<stb_vorbis*>(decoder);
    stb_vorbis_seek_start(vorbis);
}
예제 #6
0
static inline void LoadNextFrameIfNeeded(VorbisPlayer *self)
{
	if(self->framepos>=self->framelength)
	{
		self->framepos=0;
		self->framelength=stb_vorbis_get_frame_float(self->vorbis,NULL,&self->currentframe);
		if(!self->framelength)
		{
			stb_vorbis_seek_start(self->vorbis);
			self->framelength=stb_vorbis_get_frame_float(self->vorbis,NULL,&self->currentframe);
		}
	}
}
예제 #7
0
	result WavStreamInstance::rewind()
	{
		if (mOgg)
		{
			stb_vorbis_seek_start(mOgg);
		}
		else
		if (mFile)
		{
			mFile->seek(mParent->mDataOffset);
		}
		mOffset = 0;
		mStreamTime = 0;
		return 0;
	}
예제 #8
0
	int WavStreamInstance::rewind()
	{
		if (mOgg)
		{
			stb_vorbis_seek_start(mOgg);
		}
		else
		if (mFile)
		{
			fseek(mFile, mParent->mDataOffset, SEEK_SET);
		}
		mOffset = 0;
		mStreamTime = 0;
		return 1;
	}
예제 #9
0
파일: audio.c 프로젝트: Danlestal/raylib
// Update (re-fill) music buffers if data already processed
extern void UpdateMusicStream()
{
    ALuint buffer = 0;
    ALint processed = 0;
    bool active = true;
    
    if (musicEnabled)
    {
        // Get the number of already processed buffers (if any)
        alGetSourcei(currentMusic.source, AL_BUFFERS_PROCESSED, &processed);
        
        while (processed > 0)
        {
            // Recover processed buffer for refill
            alSourceUnqueueBuffers(currentMusic.source, 1, &buffer);

            // Refill buffer
            active = BufferMusicStream(buffer);
            
            // If no more data to stream, restart music (if loop)
            if ((!active) && (currentMusic.loop))   
            {
                if (currentMusic.loop)
                {
                    stb_vorbis_seek_start(currentMusic.stream);
                    currentMusic.totalSamplesLeft = stb_vorbis_stream_length_in_samples(currentMusic.stream) * currentMusic.channels;
                    
                    active = BufferMusicStream(buffer);
                }
            }
            
            // Add refilled buffer to queue again... don't let the music stop!
            alSourceQueueBuffers(currentMusic.source, 1, &buffer);
            
            if(alGetError() != AL_NO_ERROR) TraceLog(WARNING, "Ogg playing, error buffering data...");
            
            processed--;
        }
        
        ALenum state;
        alGetSourcei(currentMusic.source, AL_SOURCE_STATE, &state);
        
        if ((state != AL_PLAYING) && active) alSourcePlay(currentMusic.source);
        
        if (!active) StopMusicStream();
    }
}
예제 #10
0
void AudioStream::Update()
{	//Hacer con variable auxiliar
	ALint buffersProcessed;
	alGetSourcei(source->GetID(), AL_BUFFERS_PROCESSED, &buffersProcessed);
	while (buffersProcessed--) {
		uint32 buffer;
		alSourceUnqueueBuffers(source->GetID(), 1, &buffer);
		if (Stream(buffer)) {
			alSourceQueueBuffers(source->GetID(), 1, &buffer);
		}
		else if (shouldLoop) {
			stb_vorbis_seek_start(stream);
			samplesLeft = stb_vorbis_stream_length_in_samples(stream) * info.channels;
			if (Stream(buffer)) alSourceQueueBuffers(source->GetID(), 1, &buffer);
		}
	}
}
예제 #11
0
unsigned OggVorbisSoundStream::GetData(signed char* dest, unsigned numBytes)
{
    if (!decoder_)
        return 0;
    
    stb_vorbis* vorbis = static_cast<stb_vorbis*>(decoder_);
    
    unsigned channels = stereo_ ? 2 : 1;
    unsigned outSamples = stb_vorbis_get_samples_short_interleaved(vorbis, channels, (short*)dest, numBytes >> 1);
    unsigned outBytes = (outSamples * channels) << 1;
    
    // Rewind and retry if is looping and produced less output than should have
    if (outBytes < numBytes && !stopAtEnd_)
    {
        numBytes -= outBytes;
        stb_vorbis_seek_start(vorbis);
        outSamples = stb_vorbis_get_samples_short_interleaved(vorbis, channels, (short*)(dest + outBytes), numBytes >> 1);
        outBytes += (outSamples * channels) << 1;
    }
예제 #12
0
파일: MusicOGG.cpp 프로젝트: Daivuk/onut
 void MusicOGG::run()
 {
     while (m_isPlaying)
     {
         if (m_bufferCount < MUSIC_BUFFER_COUNT)
         {
             m_mutex.lock();
             auto pBuffer = m_buffers.back();
             m_buffers.pop_back();
             m_mutex.unlock();
             pBuffer->count = stb_vorbis_get_samples_float_interleaved(m_pStream, m_engineChannelCount, pBuffer->data.data(), m_bufferMax) * m_engineChannelCount;
             pBuffer->offset = 0;
             if (pBuffer->count)
             {
                 m_mutex.lock();
                 m_buffers.insert(m_buffers.begin() + m_bufferCount, pBuffer);
                 ++m_bufferCount;
                 m_mutex.unlock();
             }
             else
             {
                 if (m_loop)
                 {
                     stb_vorbis_seek_start(m_pStream);
                     m_mutex.lock();
                     m_buffers.push_back(pBuffer);
                     m_mutex.unlock();
                     continue;
                 }
                 else
                 {
                     // Done playing!
                     stb_vorbis_close(m_pStream);
                     m_pStream = nullptr;
                     m_done = true;
                     break;
                 }
             }
         }
         std::this_thread::sleep_for(std::chrono::milliseconds(10));
     }
 }
예제 #13
0
int MusicPlayer::pullAudio(AUDIO_SAMPLE_TYPE *target, int sampleCount)
	{
	memset(target, 0, sampleCount * sizeof(AUDIO_SAMPLE_TYPE));
#ifdef USE_OGG
	if(v && error==0)
		{
		int samples = stb_vorbis_get_samples_short_interleaved(v, channels, target, sampleCount);
		if(samples==0)
			{
			stb_vorbis_seek_start(v);
			stb_vorbis_get_samples_short_interleaved(v, channels, target, sampleCount);
			// error=-1;
			}
		}
#endif

#ifdef USE_MP3
	if (!error)
		{
		size_t done;
		error = mpg123_read(mh, (unsigned char *) target, sampleCount
				* sizeof(AUDIO_SAMPLE_TYPE), &done);
		// read will return MPG123_DONE eventually...

		if (error == MPG123_DONE)
			{

			mpg123_seek(mh, 0, SEEK_SET);
			error = mpg123_read(mh, (unsigned char *) target, sampleCount
					* sizeof(AUDIO_SAMPLE_TYPE), &done);
			}

		// ignore format change
		if (error == MPG123_NEW_FORMAT)
			error = MPG123_OK;

		}
#endif
	return sampleCount;
	}
예제 #14
0
파일: Audio.c 프로젝트: Doy-lee/Dengine
const i32 audio_updateAndPlay(MemoryArena_ *arena, AudioManager *audioManager,
                              AudioRenderer *audioRenderer)
{
	AudioVorbis *audio = audioRenderer->audio;
	if (!audio) return 0;

	u32 alSourceId = getSourceId(audioManager, audioRenderer);
	if (alIsSource(alSourceId) == AL_FALSE)
	{
		DEBUG_LOG("audio_updateAndPlay(): Update failed on invalid source id");
		return -1;
	}

	ALint audioState;
	alGetSourcei(alSourceId, AL_SOURCE_STATE, &audioState);
	AL_CHECK_ERROR();
	if (audioState == AL_STOPPED || audioState == AL_INITIAL)
	{
		if (audioState == AL_STOPPED)
		{
			if (audioRenderer->numPlays != AUDIO_REPEAT_INFINITE)
				audioRenderer->numPlays--;

			if (audioRenderer->numPlays == AUDIO_REPEAT_INFINITE ||
			    audioRenderer->numPlays > 0)
			{
				// TODO(doyle): Delete and recreate fixes clicking when reusing
				// buffers
				alDeleteBuffers(ARRAY_COUNT(audioRenderer->bufferId),
				                audioRenderer->bufferId);
				AL_CHECK_ERROR();

				alGenBuffers(ARRAY_COUNT(audioRenderer->bufferId),
				             audioRenderer->bufferId);
				AL_CHECK_ERROR();
			}
			else
			{
				i32 result =
				    rendererRelease(arena, audioManager, audioRenderer);
				return result;
			}
		}

		if (audioRenderer->isStreaming)
		{
			stb_vorbis_seek_start(audio->file);
			for (i32 i = 0; i < ARRAY_COUNT(audioRenderer->bufferId); i++)
			{
				i16 audioChunk[AUDIO_CHUNK_SIZE_] = {0};
				stb_vorbis_get_samples_short_interleaved(
				    audio->file, audio->info.channels, audioChunk,
				    AUDIO_CHUNK_SIZE_);

				alBufferData(audioRenderer->bufferId[i], audioRenderer->format,
				             audioChunk, AUDIO_CHUNK_SIZE_ * sizeof(i16),
				             audio->info.sample_rate);
				AL_CHECK_ERROR();
			}

			alSourceQueueBuffers(alSourceId,
			                     ARRAY_COUNT(audioRenderer->bufferId),
			                     audioRenderer->bufferId);
		}
		else
		{
			alSourceQueueBuffers(alSourceId, 1, audioRenderer->bufferId);
		}

		AL_CHECK_ERROR();
		alSourcePlay(alSourceId);
		AL_CHECK_ERROR();
	}
	else if (audioState == AL_PLAYING)
	{
		ALint numProcessedBuffers;
		alGetSourcei(alSourceId, AL_BUFFERS_PROCESSED,
		             &numProcessedBuffers);
		AL_CHECK_ERROR();
		if (numProcessedBuffers > 0)
		{
			// TODO(doyle): Possibly wrong, we should pass in all processed buffers?
			ALint numBuffersToUnqueue = 1;
			ALuint emptyBufferId;
			alSourceUnqueueBuffers(alSourceId, numBuffersToUnqueue,
			                       &emptyBufferId);
			AL_CHECK_ERROR();

			i16 audioChunk[AUDIO_CHUNK_SIZE_] = {0};
			i32 sampleCount = stb_vorbis_get_samples_short_interleaved(
			    audio->file, audio->info.channels, audioChunk,
			    AUDIO_CHUNK_SIZE_);

			/* There are still samples to play */
			if (sampleCount > 0)
			{
				alBufferData(emptyBufferId, audioRenderer->format, audioChunk,
				             sampleCount * audio->info.channels * sizeof(i16),
				             audio->info.sample_rate);
				AL_CHECK_ERROR();
				alSourceQueueBuffers(alSourceId, 1, &emptyBufferId);
				AL_CHECK_ERROR();
			}
		}
	}

	return 0;
}
예제 #15
0
	void WavStreamInstance::getAudio(float *aBuffer, unsigned int aSamples)
	{			
		unsigned int channels = mChannels;

		if (mFile == NULL)
			return;

		if (mOgg)
		{
			unsigned int offset = 0;			
			if (mOggFrameOffset < mOggFrameSize)
			{
				int b = getOggData(mOggOutputs, aBuffer, aSamples, aSamples, mOggFrameSize, mOggFrameOffset, channels);
				mOffset += b;
				offset += b;
				mOggFrameOffset += b;
			}

			while (offset < aSamples)
			{
				mOggFrameSize = stb_vorbis_get_frame_float(mOgg, NULL, &mOggOutputs);
				mOggFrameOffset = 0;
				int b;
				b = getOggData(mOggOutputs, aBuffer + offset, aSamples - offset, aSamples, mOggFrameSize, mOggFrameOffset, channels);
				mOffset += b;
				offset += b;
				mOggFrameOffset += b;
				if (mOffset >= mParent->mSampleCount)
				{
					if (mFlags & AudioSourceInstance::LOOPING)
					{
						stb_vorbis_seek_start(mOgg);
						mOffset = aSamples - offset;
						mLoopCount++;
					}
					else
					{
						unsigned int i;
						for (i = 0; i < channels; i++)
							memset(aBuffer + offset + i * aSamples, 0, sizeof(float) * (aSamples - offset));
						mOffset += aSamples - offset;
						offset = aSamples;
					}
				}
			}
		}
		else
		{
			unsigned int copysize = aSamples;
			if (copysize + mOffset > mParent->mSampleCount)
			{
				copysize = mParent->mSampleCount - mOffset;
			}

			getWavData(mFile, aBuffer, copysize, aSamples, channels, mParent->mChannels, mParent->mBits);
		
			if (copysize != aSamples)
			{
				if (mFlags & AudioSourceInstance::LOOPING)
				{
					mFile->seek(mParent->mDataOffset);
					getWavData(mFile, aBuffer + copysize, aSamples - copysize, aSamples, channels, mParent->mChannels, mParent->mBits);
					mOffset = aSamples - copysize;
					mLoopCount++;
				}
				else
				{					
					unsigned int i;
					for (i = 0; i < channels; i++)
						memset(aBuffer + copysize + i * aSamples, 0, sizeof(float) * (aSamples - copysize));
						
					mOffset += aSamples;
				}
			}
			else
			{
				mOffset += aSamples;
			}
		}
	}
예제 #16
0
// stereo LRLRLR order
void mixerCallback( void* userdata, Uint8* streamData, int len )
{
	memset( streamData, len, workingSilence );
	memset( workingBuffer, 0, workingBufferSize );
	if( workingBuffer == NULL ) {
		return;
	}

	int numSamples = ( len / WORKING_CHANNELS ) / ( ( SDL_AUDIO_MASK_BITSIZE & WORKING_FORMAT ) / 8 );

#if 0
	int soundFreq = 440; // wave length
	float step = 1.0f / WORKING_RATE;
	// for testing audio output
	for( int s = 0; s < numSamples; ++s ) {
		int streamIdx = ( s * WORKING_CHANNELS );
		testTimePassed += 1.0f / WORKING_RATE;
		float v = sinf( testTimePassed * soundFreq * M_TWO_PI_F );
		workingBuffer[streamIdx] = v * 0.1f;
		workingBuffer[streamIdx+1] = v * 0.1f;
	}
#else
	// advance each playing sound
	for( EntityID id = idSet_GetFirstValidID( &playingIDSet ); id != INVALID_ENTITY_ID; id = idSet_GetNextValidID( &playingIDSet, id ) ) {
		int i = idSet_GetIndex( id );
		Sound* snd = &( playingSounds[i] );
		Sample* sample = &( samples[snd->sample] );
		
		// for right now lets assume the pitch will stay the same, when we get it working it'll just involve
		//  changing the speed at which we move through the array
		bool soundDone = false;
		float volume = snd->volume * sbSoundGroups[snd->group].volume * masterVolume;
		for( int s = 0; ( s < numSamples ) && !soundDone; ++s ) {

			int streamIdx = ( s * WORKING_CHANNELS );

			// we're assuming stereo output here
			if( sample->numChannels == 1 ) {
				float data = sample->data[(int)snd->pos] * volume;
/* left */		workingBuffer[streamIdx] += data * inverseLerp( 1.0f, 0.0f, snd->pan );
/* right */		workingBuffer[streamIdx+1] += data * inverseLerp( -1.0f, 0.0f, snd->pan );
				snd->pos += snd->pitch;
			} else {
				// if the sample is stereo then we ignore panning
				//  NOTE: Pitch change doesn't work with stereo samples yet
				workingBuffer[streamIdx] += sample->data[(int)snd->pos] * volume;
				workingBuffer[streamIdx+1] += sample->data[(int)snd->pos+1] * volume;
				snd->pos += 2.0f;
			}

			if( snd->pos >= sample->numSamples ) {
				if( sample->loops ) {
					snd->pos -= (float)sample->numSamples;
				} else {
					soundDone = true;
				}
			}
		}

		if( soundDone ) {
			idSet_ReleaseID( &playingIDSet, id ); // this doesn't invalidate the id for the loop
		}
	}

	for( int i = 0; i < MAX_STREAMING_SOUNDS; ++i ) {
		if( !streamingSounds[i].playing ) continue;

		StreamingSound* stream = &( streamingSounds[i] );
		bool soundDone = false;
		float volume = stream->volume * sbSoundGroups[stream->group].volume * masterVolume;

		// if the next buffer fill would be past what we have loaded then load some more
		//  note: the SDL_AudioStreamAvailable return value is in bytes
		while( ( SDL_AudioStreamAvailable( stream->sdlStream ) < len ) && !( stream->readDone ) ) {
			int read = 0;
			int request = STREAM_READ_BUFFER_SIZE / sizeof( short );
			size_t test = ARRAY_SIZE( streamReadBuffer );
			// returns the number of samples stored per channel
			int samplesPerChannel = stb_vorbis_get_samples_short_interleaved(
				stream->access, stream->access->channels, streamReadBuffer, request );
			read = samplesPerChannel * sizeof( short );

			SDL_AudioStreamPut( stream->sdlStream, streamReadBuffer, samplesPerChannel * stream->channels * sizeof( short ) );

			// reached the end of the file, are we looping?
			if( read != request ) {
				if( stream->loops ) {
					stb_vorbis_seek_start( stream->access );
				} else {
					stream->readDone = true;
					SDL_AudioStreamFlush( stream->sdlStream );
				}
			}
		}

		// read data from the audio stream until there is no more left or the end of the buffer to fill
		int bytesToStream = numSamples * stream->channels * sizeof( sbStreamWorkingBuffer[0] );
		sb_Reserve( sbStreamWorkingBuffer, (size_t)bytesToStream );
		int gotten = SDL_AudioStreamGet( stream->sdlStream, sbStreamWorkingBuffer, bytesToStream );
		if( gotten < 0 ) {
			llog( LOG_ERROR, "Error reading from sdlStream: %s", SDL_GetError( ) );
			stream->playing = false;
			continue;
		} else if( gotten == 0 ) {
			// end of stream
			stream->playing = false;
		}

		int samplesGotten = gotten / ( stream->channels * sizeof( sbStreamWorkingBuffer[0] ) );
		for( int s = 0; s < samplesGotten; ++s ) {
			// then just mix those samples
			int streamIdx = ( s * WORKING_CHANNELS );
			int workingIdx = ( s * stream->channels );
			
			// we're assuming stereo output here
			if( stream->access->channels == 1 ) {
				float data = sbStreamWorkingBuffer[workingIdx] * volume;
				workingBuffer[streamIdx] += data * inverseLerp( 1.0f, 0.0f, stream->pan );		// left
				workingBuffer[streamIdx+1] += data * inverseLerp( -1.0f, 0.0f, stream->pan );   // right
			} else {
				// if the sample is stereo then we ignore panning
				workingBuffer[streamIdx] += sbStreamWorkingBuffer[workingIdx] * volume;
				workingBuffer[streamIdx+1] += sbStreamWorkingBuffer[workingIdx + 1] * volume;
			}
		}
	}
#endif

	memcpy( streamData, workingBuffer, len );
}
void nVorbisStream::rewind()
{
    stb_vorbis_seek_start(_vorbis);
}