// pop the processed buffers from the queue, // refill them, and push them back in line bool COggStream::UpdateBuffers() { int buffersProcessed = 0; bool active = true; alGetSourcei(source, AL_BUFFERS_PROCESSED, &buffersProcessed); while (buffersProcessed-- > 0) { ALuint buffer; alSourceUnqueueBuffers(source, 1, &buffer); CheckError("COggStream::UpdateBuffers"); // false if we've reached end of stream active = DecodeStream(buffer); if (active) alSourceQueueBuffers(source, 1, &buffer); CheckError("COggStream::UpdateBuffers"); } return active; }
bool cOggStream::update() { int processed; alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); bool active = true; while (processed--) { ALuint buffer; alSourceUnqueueBuffers(source, 1, &buffer); ReportError(); active = RefillBuffer(buffer); alSourceQueueBuffers(source, 1, &buffer); ReportError(); } return active; }
void WavReader::onInit(const int& posInFile, const int& posInBuffer) { InternalMessage("Sound","enter wavreader Init") ; // Open the file SF_INFO fileInfos; m_file = sf_open(m_fileName.c_str(), SFM_READ, &fileInfos); if (!m_file) { //TODO paufiner erreur sur location ou format non reconnu ErrorMessage("[OpenAL::WavReader] Can't read the file: " + m_fileName); return ; } //Get file information m_sampleRate = fileInfos.samplerate; m_samplesByBuffer = (ALsizei)(fileInfos.channels * fileInfos.samplerate * m_updateTime) ; switch (fileInfos.channels) { case 1 : m_format = AL_FORMAT_MONO16; break; case 2 : m_format = AL_FORMAT_STEREO16; break; default : ErrorMessage("[OpenAL::WavReader] Audio Format audio not supported (more than 2 channel)"); return ; } int pos = 0 ; if(posInFile > 0) { pos = posInFile - m_samplesByBuffer + posInBuffer + 1; } sf_seek(m_file, pos, SEEK_SET); //Load the buffers and link with the source loadBuffer(m_buffers[0]); loadBuffer(m_buffers[1]); alSourceQueueBuffers(m_source, 2, m_buffers); if (alGetError() != AL_NO_ERROR) { ErrorMessage("[OpenAL::WavReader] Impossible to queue the buffers"); return ; } InternalMessage("Sound","leave wavreader Init") ; }
//----------------------------------------------------------------------------- bool MusicOggStream::playMusic() { if(isPlaying()) return true; if(!streamIntoBuffer(m_soundBuffers[0])) return false; if(!streamIntoBuffer(m_soundBuffers[1])) return false; alSourceQueueBuffers(m_soundSource, 2, m_soundBuffers); alSourcePlay(m_soundSource); m_pausedMusic = false; m_playing = true; check("playMusic"); return true; } // playMusic
bool OpenALMusicPlayer::startPlayback() { if(isPlaying()) { return true; } if(!streamBuffer(buffers[0])) { return false; } if(!streamBuffer(buffers[1])) { return false; } alSourceQueueBuffers(source, 2, buffers); alSourcePlay(source); return true; }
void CBufferItem::Attach(CSoundData* itemData) { if ( m_ALSource == 0 ) return; AL_CHECK; if (m_SoundData != NULL) { CSoundData::ReleaseSoundData(m_SoundData); m_SoundData = 0; } AL_CHECK; if (itemData != NULL) { m_SoundData = itemData->IncrementCount(); alSourceQueueBuffers(m_ALSource, m_SoundData->GetBufferCount(),(const ALuint *) m_SoundData->GetBufferPtr()); AL_CHECK; } }
inline__ DeviceError write_out(uint32_t device_idx, const int16_t* data, uint32_t length, uint8_t channels) { if (device_idx >= MAX_DEVICES) return de_InvalidSelection; Device* device = running[output][device_idx]; if (!device) fprintf(stderr, "DEVICE IS NULL SILLY\n"); if (!device || device->muted) return de_DeviceNotActive; pthread_mutex_lock(device->mutex); ALuint bufid; ALint processed, queued; alGetSourcei(device->source, AL_BUFFERS_PROCESSED, &processed); alGetSourcei(device->source, AL_BUFFERS_QUEUED, &queued); if(processed) { ALuint bufids[processed]; alSourceUnqueueBuffers(device->source, processed, bufids); alDeleteBuffers(processed - 1, bufids + 1); bufid = bufids[0]; } else if(queued < 16) alGenBuffers(1, &bufid); else { pthread_mutex_unlock(device->mutex); return de_Busy; } alBufferData(bufid, device->sound_mode, data, length * 2 * channels, device->sample_rate); alSourceQueueBuffers(device->source, 1, &bufid); ALint state; alGetSourcei(device->source, AL_SOURCE_STATE, &state); if(state != AL_PLAYING) alSourcePlay(device->source); pthread_mutex_unlock(device->mutex); return de_None; }
// This function's logic was shamelessly stolen from uTox void Core::playAudioBuffer(int callId, int16_t *data, int samples, unsigned channels, int sampleRate) { if(!channels || channels > 2) { qWarning() << "Core::playAudioBuffer: trying to play on "<<channels<<" channels! Giving up."; return; } ALuint bufid; ALint processed, queued; alGetSourcei(calls[callId].alSource, AL_BUFFERS_PROCESSED, &processed); alGetSourcei(calls[callId].alSource, AL_BUFFERS_QUEUED, &queued); alSourcei(calls[callId].alSource, AL_LOOPING, AL_FALSE); if(processed) { ALuint bufids[processed]; alSourceUnqueueBuffers(calls[callId].alSource, processed, bufids); alDeleteBuffers(processed - 1, bufids + 1); bufid = bufids[0]; } else if(queued < 16) { alGenBuffers(1, &bufid); } else { qDebug() << "Core: Dropped audio frame"; return; } alBufferData(bufid, (channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, data, samples * 2 * channels, sampleRate); alSourceQueueBuffers(calls[callId].alSource, 1, &bufid); ALint state; alGetSourcei(calls[callId].alSource, AL_SOURCE_STATE, &state); if(state != AL_PLAYING) { alSourcePlay(calls[callId].alSource); qDebug() << "Core: Starting audio source of call " << callId; } }
static int group_audio_write(int peernum, int groupnum, const int16_t *pcm, unsigned int samples, uint8_t channels, unsigned int sample_rate) { if (!pcm) return -1; if (channels == 0 || channels > 2) return -2; ALuint source = groupchats[groupnum].audio.sources[peernum]; ALuint bufid; ALint processed = 0; ALint queued = 0; alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); fprintf(stderr, "%d, %d\n", source, processed); if (processed) { ALuint bufids[processed]; alSourceUnqueueBuffers(source, processed, bufids); alDeleteBuffers(processed - 1, bufids + 1); bufid = bufids[0]; } else if (queued < 16) { alGenBuffers(1, &bufid); } else { return -3; } int length = samples * channels * sizeof(int16_t); alBufferData(bufid, (channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, pcm, length, sample_rate); alSourceQueueBuffers(source, 1, &bufid); ALint state; alGetSourcei(source, AL_SOURCE_STATE, &state); if (state != AL_PLAYING) alSourcePlay(source); return 0; }
//This function will update our streams bool DIZ_OGGSTREAM::update() { //Declare a conductor variable set our first target item DIZ_LISTITEM<DIZ_OGGSTREAMTARGET> *cdtr = targets.rootItem(); //Declare a storage variable for no. of processed buffers in each source int processedBuffers; //Declare a buffer-ID storage variable ALuint buf; //Declare a result-tracking variable bool results = true; //Loop while we still have items to move through while (cdtr) { //First retrieve our no. of processed buffers in our current source alGetSourcei(cdtr->item.source, AL_BUFFERS_PROCESSED, &processedBuffers); //Loop until we've replaced all the buffers while (processedBuffers > 0) { //Pop our finished buffers of the source queue alSourceUnqueueBuffers(cdtr->item.source, 1, &buf); //Then fill it up with new data, with a quick error check if (!streamToBuffer(buf, &cdtr->item.location)) { results = false; } //Then put it back on the end of the queue alSourceQueueBuffers(cdtr->item.source, 1, &buf); //Then decrement our counter processedBuffers--; } //Check that we have a next item to move onto, otherwise exit our loop cdtr = cdtr->nextItem(); } //Finally, check for any OpenAL errors if (alGetError() != AL_NO_ERROR) { results = false; } //And return our result- false means one or more streams failed return results; }
void OpenALStream::nextStreamStep() { if (mFinished) return; ALint processedBuffers = 0; ALuint tempBufferId; // Get the numbers of buffers that are already processed. alGetSourcei(mSourceId, AL_BUFFERS_PROCESSED, &processedBuffers); alErrorHandler("OpenALStream::nextStreamStep", "Error occured calling alGetSourcei."); // If all buffers are processed the stream is finished. if (processedBuffers >= mNUM_BUFFER) { dbglog << "Stream '"+mAudioFile->toString()+"' finished."; alSourceUnqueueBuffers(mSourceId, mNUM_BUFFER, mBufferIds.get()); alErrorHandler("OpenALStream::nextStreamStep", "Error occured calling alSourceUnqueueBuffers."); // Calling callback. mOnStreamFinished(); mFinished = true; return; } // Filling the processed buffers with fresh audio data. while (processedBuffers > 0) { alSourceUnqueueBuffers(mSourceId, 1, &tempBufferId); alErrorHandler("OpenALStream::nextStreamStep", "Error occured calling alSourceUnqueueBuffers."); mAudioFile->read(tempBufferId); alSourceQueueBuffers(mSourceId, 1, &tempBufferId); alErrorHandler("OpenALStream::nextStreamStep", "Error occured calling alSourceQueueBuffers."); alGetSourcei(mSourceId, AL_BUFFERS_PROCESSED, &processedBuffers); alErrorHandler("OpenALStream::nextStreamStep", "Error occured calling alGetSourcei."); } }
//================================================================================================= void Sounds::update() { if (!file) return; if (flag & STREAM) { ALint processed; alGetSourcei( source, AL_BUFFERS_PROCESSED, &processed ); if (processed == 1) { alSourceUnqueueBuffers( source, 1, &buffers[ current_buffer ] ); int size = file->read( buffer, BUFFER_SIZE ); if (size > 0 || (size == 0 && flag & LOOP)) { alBufferData( buffers[ current_buffer ], format, buffer, size, file->freq ); alSourceQueueBuffers( source, 1, &buffers[ current_buffer ] ); if (size != BUFFER_SIZE && flag & LOOP) file->seek( 0.0 ); } else { int queued; alGetSourcei( source, AL_BUFFERS_QUEUED, &queued ); if (queued == 0) file->seek( 0.0 ); } current_buffer = 1 - current_buffer; } else if (processed == 2) { alSourceUnqueueBuffers( source, 2, buffers ); current_buffer = 0; play(); } } }
void audio_updateStreams(void) { for(int i = 0; i < moduleData.playingStreamCount;) { audio_StreamSource const* source = moduleData.playingStreams[i]; int loaded = source->decoder->preloadSamples(source->decoderData, 8000); if(loaded == 0) { if(source->looping) { source->decoder->rewind(source->decoderData); } else { } } ALuint src = source->common.source; ALint count; ALint queued; ALint state; alGetSourcei(src, AL_BUFFERS_PROCESSED, &count); alGetSourcei(src, AL_BUFFERS_QUEUED, &queued); alGetSourcei(src, AL_SOURCE_STATE, &state); // printf("%d buffers free, %d queued, state=%d\n", count, queued, state); for(int j = 0; j < count; ++j) { ALuint buf; alSourceUnqueueBuffers(src, 1, &buf); // This may cause preloading two full frames int uploaded = source->decoder->uploadPreloadedSamples(source->decoderData, buf); if(uploaded) { alSourceQueueBuffers(src, 1, &buf); } } alGetSourcei(src, AL_BUFFERS_QUEUED, &queued); if(state == AL_STOPPED && queued == 0) { --moduleData.playingStreamCount; moduleData.playingStreams[i] = moduleData.playingStreams[moduleData.playingStreamCount]; } else { ++i; } } }
void AudioDescriptor::_PrepareStreamingBuffers() { if(_stream == NULL) { IF_PRINT_WARNING(AUDIO_DEBUG) << "_stream pointer was NULL, meaning this function should never have been called" << std::endl; return; } if(_source == NULL) { IF_PRINT_WARNING(AUDIO_DEBUG) << "failed because no source was available for this object to utilize" << std::endl; return; } bool was_playing = false; if(AudioManager->CheckALError()) { IF_PRINT_WARNING(AUDIO_DEBUG) << "OpenAL error detected: " << AudioManager->CreateALErrorString() << std::endl; } // Stop the audio if it is playing and detatch the buffer from the source if(_state == AUDIO_STATE_PLAYING) { was_playing = true; Stop(); } alSourcei(_source->source, AL_BUFFER, 0); // Fill each buffer with audio data for(uint32 i = 0; i < NUMBER_STREAMING_BUFFERS; i++) { uint32 read = _stream->FillBuffer(_data, _stream_buffer_size); if(read > 0) { _buffer[i].FillBuffer(_data, _format, read * _input->GetSampleSize(), _input->GetSamplesPerSecond()); if(_source != NULL) alSourceQueueBuffers(_source->source, 1, &_buffer[i].buffer); } } if(AudioManager->CheckALError()) { IF_PRINT_WARNING(AUDIO_DEBUG) << "failed to fill all buffers: " << AudioManager->CreateALErrorString() << std::endl; } if(was_playing) { Play(); } }
//////////////////////////////////////////////////////////// /// Fill a new buffer with audio data, and push it to the /// playing queue //////////////////////////////////////////////////////////// bool SoundStream::FillAndPushBuffer(unsigned int BufferNum) { bool RequestStop = false; // Acquire audio data Chunk Data = {NULL, 0}; if (!OnGetData(Data)) { // Mark the buffer as the last one (so that we know when to reset the playing position) myEndBuffers[BufferNum] = true; // Check if the stream must loop or stop if (myLoop && OnStart()) { // If we succeeded to restart and we previously had no data, try to fill the buffer once again if (!Data.Samples || (Data.NbSamples == 0)) { return FillAndPushBuffer(BufferNum); } } else { // Not looping or restart failed: request stop RequestStop = true; } } // Fill the buffer if some data was returned if (Data.Samples && Data.NbSamples) { unsigned int Buffer = myBuffers[BufferNum]; // Fill the buffer ALsizei Size = static_cast<ALsizei>(Data.NbSamples) * sizeof(Int16); ALCheck(alBufferData(Buffer, myFormat, Data.Samples, Size, mySampleRate)); // Push it into the sound queue ALCheck(alSourceQueueBuffers(Sound::mySource, 1, &Buffer)); } return RequestStop; }
void StreamedSound::update() { // once it's all been streamed, it's just a matter of waiting for the // buffers to be finished off... if(!mDone) { int processed = 0; alGetSourcei(mSource, AL_BUFFERS_PROCESSED, &processed); // unqueue, stream to and requeue any processed buffers while(processed--) { ALuint buffer; alSourceUnqueueBuffers(mSource, 1, &buffer); if(updateBuffer(buffer)) alSourceQueueBuffers(mSource, 1, &buffer); } } }
void lime_al_source_queue_buffers (int source, int nb, value buffers) { if (val_is_null (buffers) == false) { int size = val_array_size (buffers); ALuint* data = new ALuint[size]; for (int i = 0; i < size; ++i) { data[i] = (ALuint)val_int( val_array_i (buffers, i) ); } alSourceQueueBuffers (source, nb, data); delete[] data; } }
void audio_play_golpe_inicio(void) { if (audio_deactivated) return; //alSourceStop(audio_source[AUDIO_SRC_GOLPES]); //alSourcei(audio_source[AUDIO_SRC_GOLPES],AL_BUFFER,audio_snd_buffer[AUDIO_SND_GOLPE]); audio_pre_hit=1; ALint state; alGetSourcei(audio_source[AUDIO_SRC_GOLPES], AL_SOURCE_STATE, &state); // if (state==AL_PLAYING) { // printf("golpe source still playing !!\n"); // } //printf("queuing buffer init at source %d\n",audio_source[AUDIO_SRC_GOLPES]); alSourceStop(audio_source[AUDIO_SRC_GOLPES]); alSourcei(audio_source[AUDIO_SRC_GOLPES],AL_BUFFER,0); alSourceQueueBuffers(audio_source[AUDIO_SRC_GOLPES],1,&(audio_snd_buffer[AUDIO_SND_GOLPE])); alSourcePlay(audio_source[AUDIO_SRC_GOLPES]); }
/** * \brief write data into buffer and reset underrun flag */ static int play(struct ao *ao, void **data, int samples, int flags) { struct priv *p = ao->priv; ALint state; int num = samples / CHUNK_SAMPLES; for (int i = 0; i < num; i++) { for (int ch = 0; ch < ao->channels.num; ch++) { char *d = data[ch]; d += i * p->chunk_size; alBufferData(buffers[ch][cur_buf[ch]], p->al_format, d, p->chunk_size, ao->samplerate); alSourceQueueBuffers(sources[ch], 1, &buffers[ch][cur_buf[ch]]); cur_buf[ch] = (cur_buf[ch] + 1) % NUM_BUF; } } alGetSourcei(sources[0], AL_SOURCE_STATE, &state); if (state != AL_PLAYING) // checked here in case of an underrun alSourcePlayv(ao->channels.num, sources); return num * CHUNK_SAMPLES; }
bool OggStream::play(bool l) { if(isPlaying()) return true; if(!stream(buffers[0])) return false; if(!stream(buffers[1])) return false; loop=l; alSourceQueueBuffers(source, 2, buffers); alSourcePlay(source); return true; }
void run() { for (;;) { if (end_flag_.load(std::memory_order_seq_cst)) { break; } ALint state; alGetSourcei(*source_, AL_SOURCE_STATE, &state); if (state == AL_PLAYING) { int processed; alGetSourcei(*source_, AL_BUFFERS_PROCESSED, &processed); while(processed--) { ALuint buffer; alSourceUnqueueBuffers(*source_, 1, &buffer); read(buffer); alSourceQueueBuffers(*source_, 1, &buffer); } } sleep(1); } }
void openal_stream_update(audio_stream *stream) { openal_stream *local = stream_get_userdata(stream); // See if we have any empty buffers to fill int val; alGetSourcei(local->source, AL_BUFFERS_PROCESSED, &val); if(val <= 0) { return; } // Handle buffer filling and loading char buf[AUDIO_BUFFER_SIZE]; ALuint n; while(val--) { // Fill buffer & re-queue int ret = source_update(stream->src, buf, AUDIO_BUFFER_SIZE); if(ret > 0) { alSourceUnqueueBuffers(local->source, 1, &n); alBufferData(n, local->format, buf, ret, source_get_frequency(stream->src)); alSourceQueueBuffers(local->source, 1, &n); // Check for any errors int err = alGetError(); if(err != AL_NO_ERROR) { PERROR("OpenAL Stream: Error %d while buffering!", err); } } else { stream_set_finished(stream); break; } } // Make sure we are playing stream if(stream_get_status(stream) == STREAM_STATUS_PLAYING) { ALenum state; alGetSourcei(local->source, AL_SOURCE_STATE, &state); if(state != AL_PLAYING) { alSourcePlay(local->source); } } }
void clAudioSource::Play() { if ( IsPlaying() ) { return; } if ( !FWaveDataProvider ) { return; } int State; alGetSourcei( FSourceID, AL_SOURCE_STATE, &State ); if ( State != AL_PAUSED && FWaveDataProvider->IsStreaming() ) { UnqueueAll(); StreamBuffer( FBufferID[0], BUFFER_SIZE ); StreamBuffer( FBufferID[1], BUFFER_SIZE ); alSourceQueueBuffers( FSourceID, 2, &FBufferID[0] ); } alSourcePlay( FSourceID ); }
void OpenALPlayer::FillBuffers(ALsizei count) { // Do the actual filling/queueing for (count = mid(1, count, buffers_free); count > 0; --count) { ALsizei fill_len = mid<ALsizei>(0, decode_buffer.size() / bpf, end_frame - cur_frame); if (fill_len > 0) // Get fill_len frames of audio provider->GetAudioWithVolume(&decode_buffer[0], cur_frame, fill_len, volume); if ((size_t)fill_len * bpf < decode_buffer.size()) // And zerofill the rest memset(&decode_buffer[fill_len * bpf], 0, decode_buffer.size() - fill_len * bpf); cur_frame += fill_len; alBufferData(buffers[buf_first_free], AL_FORMAT_MONO16, &decode_buffer[0], decode_buffer.size(), samplerate); alSourceQueueBuffers(source, 1, &buffers[buf_first_free]); // FIXME: collect buffer handles and queue all at once instead of one at a time? buf_first_free = (buf_first_free + 1) % num_buffers; --buffers_free; } }
bool AudioStream_Ogg::update() { if (openal_is_shutdown) return false; if (mSuspend) return true; if (!mIsValid) return false; int processed = 0; bool active = true; alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); while(processed--) { ALuint buffer; alSourceUnqueueBuffers(source, 1, &buffer); alGetError(); if (buffer) { active = stream(buffer); alSourceQueueBuffers(source, 1, &buffer); check(); } } if (active && !playing()) alSourcePlay(source); /*if (!active && mLoops > 0) { mLoops --; double seek = mStartTime * 0.001; ov_time_seek(oggStream, seek); return update(); }*/ return active; } //update
/** * \brief Updates this music when it is playing. * * This function handles the double buffering. */ void Music::update_playing() { // get the empty buffers ALint nb_empty; alGetSourcei(source, AL_BUFFERS_PROCESSED, &nb_empty); // refill them for (int i = 0; i < nb_empty; i++) { ALuint buffer; alSourceUnqueueBuffers(source, 1, &buffer); // unqueue the buffer // fill it by decoding more data switch (format) { case SPC: decode_spc(buffer, 4096); break; case IT: decode_it(buffer, 4096); break; case OGG: decode_ogg(buffer, 4096); break; case NO_FORMAT: Debug::die("Invalid music format"); break; } alSourceQueueBuffers(source, 1, &buffer); // queue it again } ALint status; alGetSourcei(source, AL_SOURCE_STATE, &status); if (status != AL_PLAYING) { alSourcePlay(source); } }
void OpenAL_AudioInterface::insertData(float** data,int nSamples) { //Deactivated output //printf("got %d bytes, %d buffers queued\n",nSamples,(int)mBufferQueue.size()); for (int i=0;i<nSamples;i++) { if (mBuffSize < mMaxBuffSize) { //mTempBuffer[mBuffSize++]=rand(); debug mTempBuffer[mBuffSize++]=float2short(data[0][i]); if (mNumChannels == 2) mTempBuffer[mBuffSize++]=float2short(data[1][i]); } if (mBuffSize == mFreq*mNumChannels/4) { OpenAL_Buffer buff; alGenBuffers(1,&buff.id); ALuint format = (mNumChannels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; alBufferData(buff.id,format,mTempBuffer,mBuffSize*2,mFreq); alSourceQueueBuffers(mSource, 1, &buff.id); buff.nSamples=mBuffSize/mNumChannels; mNumProcessedSamples+=mBuffSize/mNumChannels; mBufferQueue.push(buff); mBuffSize=0; int state; alGetSourcei(mSource,AL_SOURCE_STATE,&state); if (state != AL_PLAYING) { //alSourcef(mSource,AL_PITCH,0.5); // debug alSourcef(mSource,AL_SAMPLE_OFFSET,(float) mNumProcessedSamples-mFreq/4); alSourcePlay(mSource); } } } }
void SoundFeedStreamData(unsigned char *pData, long lBytes) { ALint processed; ALint state; ALuint buffer; int needed; int i; //printf("[SPU] SoundFeedStreamData: %i\n", lBytes); needed = (lBytes + (BUFFER_SIZE - 1)) / BUFFER_SIZE; // Expect free buffer. alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); while(processed < needed) { usleep(1); alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); } // Add buffers to queue. for(i = 0; i < needed; ++i) { alSourceUnqueueBuffers(source, 1, &buffer); alBufferData(buffer, format, pData, lBytes > BUFFER_SIZE ? BUFFER_SIZE : lBytes, sampleRate); alSourceQueueBuffers(source, 1, &buffer); lBytes -= BUFFER_SIZE; pData += BUFFER_SIZE; } // Restart playing. alGetSourcei(source, AL_SOURCE_STATE, &state); if(state != AL_PLAYING) { //fprintf(stderr, "[SPU] AL_SOURCE_STATE != AL_PLAYING: %x\n", state); alSourcePlay(source); checkALError(); } }
void Sound::DoFrame() { ALint state; int num_buffers_processed; if ((alcGetCurrentContext() != 0) && (m_music_name.size() > 0)) { alGetSourcei(m_sources[0],AL_BUFFERS_PROCESSED,&num_buffers_processed); while (num_buffers_processed > 0) { ALuint buffer_name_yay; alSourceUnqueueBuffers (m_sources[0], 1, &buffer_name_yay); if (RefillBuffer(&m_ogg_file, m_ogg_format, m_ogg_freq, buffer_name_yay, BUFFER_SIZE, m_music_loops)) { m_music_name.clear(); // m_music_name.clear() must always be called before ov_clear. Otherwise break; /// this happens if RefillBuffer returns 1, meaning it encountered EOF and the file shouldn't be repeated } alSourceQueueBuffers(m_sources[0],1,&buffer_name_yay); num_buffers_processed--; } alGetSourcei(m_sources[0], AL_SOURCE_STATE, &state); if (state == AL_STOPPED) /// this may happen if the source plays all its buffers before we manage to refill them alSourcePlay(m_sources[0]); } }
void OpenALThread::Open(const void* src, ALsizei size) { alGenSources(1, &m_source); checkForAlError("alGenSources"); alGenBuffers(g_al_buffers_count, m_buffers); checkForAlError("alGenBuffers"); alSourcei(m_source, AL_LOOPING, AL_FALSE); checkForAlError("OpenALThread::Open ->alSourcei"); m_buffer_size = size; for(uint i=0; i<g_al_buffers_count; ++i) { AddBlock(m_buffers[i], m_buffer_size, src); } alSourceQueueBuffers(m_source, g_al_buffers_count, m_buffers); checkForAlError("alSourceQueueBuffers"); Play(); }