void SoundStream::Stream() { // Create the buffers ALCheck(alGenBuffers(BufferCount, myBuffers)); for (int i = 0; i < BufferCount; ++i) myEndBuffers[i] = false; // Fill the queue bool requestStop = FillQueue(); // Play the sound ALCheck(alSourcePlay(mySource)); while (myIsStreaming) { // The stream has been interrupted! if (SoundSource::GetStatus() == Stopped) { if (!requestStop) { // Just continue ALCheck(alSourcePlay(mySource)); } else { // End streaming myIsStreaming = false; } } // Get the number of buffers that have been processed (ie. ready for reuse) ALint nbProcessed = 0; ALCheck(alGetSourcei(mySource, AL_BUFFERS_PROCESSED, &nbProcessed)); while (nbProcessed--) { // Pop the first unused buffer from the queue ALuint buffer; ALCheck(alSourceUnqueueBuffers(mySource, 1, &buffer)); // Find its number unsigned int bufferNum = 0; for (int i = 0; i < BufferCount; ++i) if (myBuffers[i] == buffer) { bufferNum = i; break; } // Retrieve its size and add it to the samples count if (myEndBuffers[bufferNum]) { // This was the last buffer: reset the sample count mySamplesProcessed = 0; myEndBuffers[bufferNum] = false; } else { ALint size, bits; ALCheck(alGetBufferi(buffer, AL_SIZE, &size)); ALCheck(alGetBufferi(buffer, AL_BITS, &bits)); mySamplesProcessed += size / (bits / 8); } // Fill it and push it back into the playing queue if (!requestStop) { if (FillAndPushBuffer(bufferNum)) requestStop = true; } } // Leave some time for the other threads if the stream is still playing if (SoundSource::GetStatus() != Stopped) Sleep(10); } // Stop the playback ALCheck(alSourceStop(mySource)); // Unqueue any buffer left in the queue ClearQueue(); // Delete the buffers ALCheck(alSourcei(mySource, AL_BUFFER, 0)); ALCheck(alDeleteBuffers(BufferCount, myBuffers)); }
//////////////////////////////////////////////////////////// /// /see Thread::Run //////////////////////////////////////////////////////////// void SoundStream::threadedFunction() { // Create buffers ALCheck(alGenBuffers(BuffersCount, myBuffers)); unsigned int EndBuffer = 0xFFFF; // Fill the queue bool RequestStop = FillQueue(); if(myLoop) RequestStop = false; // Play the sound Sound::Play(); while (myIsStreaming) { // The stream has been interrupted ! if (Sound::GetStatus() == Stopped) { if (!RequestStop) { // Just continue Sound::Play(); } else { // End streaming myIsStreaming = false; } } // Get the number of buffers that have been processed (ie. ready for reuse) ALint NbProcessed; ALCheck(alGetSourcei(Sound::mySource, AL_BUFFERS_PROCESSED, &NbProcessed)); while (NbProcessed--) { // Pop the first unused buffer from the queue ALuint Buffer; ALCheck(alSourceUnqueueBuffers(Sound::mySource, 1, &Buffer)); // Retrieve its size and add it to the samples count if (Buffer == EndBuffer) { // This was the last buffer: reset the sample count mySamplesProcessed = 0; EndBuffer = 0xFFFF; } else { ALint Size; ALCheck(alGetBufferi(Buffer, AL_SIZE, &Size)); mySamplesProcessed += Size / sizeof(Int16); } // Fill it and push it back into the playing queue if (!RequestStop) { if (FillAndPushBuffer(Buffer)) { // User requested to stop: check if we must loop or really stop if (myLoop && OnStart()) { // Looping: mark the current buffer as the last one // (to know when to reset the sample count) EndBuffer = Buffer; } else { // Not looping or restart failed: request stop RequestStop = true; } } } } // Leave some time for the other threads if the stream is still playing if (Sound::GetStatus() != Stopped) ofSleepMillis(10); } // Stop the playback Sound::Stop(); // Unqueue any buffer left in the queue ofLog(OF_LOG_VERBOSE,"preparing to clear the queue"); ClearQueue(); // Delete the buffers ofLog(OF_LOG_VERBOSE,"preparing to delete the buffers"); ALCheck(alSourcei(Sound::mySource, AL_BUFFER, 0)); ALCheck(alDeleteBuffers(BuffersCount, myBuffers)); }