Beispiel #1
0
bool SoundStream::FillQueue()
{
    // Fill and enqueue all the available buffers
    bool requestStop = false;
    for (int i = 0; (i < BufferCount) && !requestStop; ++i)
    {
        if (FillAndPushBuffer(i))
            requestStop = true;
    }

    return requestStop;
}
Beispiel #2
0
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)
        {
            // Return to the beginning of the stream source
            OnSeek(0);

            // If we previously had no data, try to fill the buffer once again
            if (!data.Samples || (data.SampleCount == 0))
            {
                return FillAndPushBuffer(bufferNum);
            }
        }
        else
        {
            // Not looping: request stop
            requestStop = true;
        }
    }

    // Fill the buffer if some data was returned
    if (data.Samples && data.SampleCount)
    {
        unsigned int buffer = myBuffers[bufferNum];

        // Fill the buffer
        ALsizei size = static_cast<ALsizei>(data.SampleCount) * sizeof(Int16);
        ALCheck(alBufferData(buffer, myFormat, data.Samples, size, mySampleRate));

        // Push it into the sound queue
        ALCheck(alSourceQueueBuffers(mySource, 1, &buffer));
    }

    return requestStop;
}
Beispiel #3
0
////////////////////////////////////////////////////////////
/// 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;
}
Beispiel #4
0
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));
}
Beispiel #5
0
////////////////////////////////////////////////////////////
/// /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));
}