示例#1
0
IFrame* AudioFrameBuffer::getFrame(const size_t size)
{
    LOG_DEBUG("Get a " << size << " bytes frame from a " << _totalDataSize << " bytes frame buffer");
    IFrame* next = _frameQueue.front();
    const size_t nextFrameSize = next->getDataSize();

    // If no expected size, or if the expected size equals the front frame of the queue (with no offset)
    if(size == 0 || (size == nextFrameSize && _positionInFrontFrame == 0))
    {
        // Directly return the front frame of the queue
        _totalDataSize -= nextFrameSize;
        popFrame();
        return next;
    }

    // Create a new frame
    AudioFrame* newAudioFrame = new AudioFrame(_audioFrameDesc, false);
    const size_t expectedNbSamples = size / (newAudioFrame->getNbChannels() * newAudioFrame->getBytesPerSample());
    newAudioFrame->setNbSamplesPerChannel(expectedNbSamples);
    newAudioFrame->allocateData();

    // Concatenate frames data
    size_t extractedDataSize = 0;
    unsigned char* outputData = new unsigned char[size];
    while(extractedDataSize != size && _frameQueue.size() != 0)
    {
        // Get the front frame from queue
        next = _frameQueue.front();
        size_t remainingDataInFrontFrame = next->getDataSize() - _positionInFrontFrame;

        // Compute the data size to get from the frame
        size_t dataToGet = size - extractedDataSize;
        if(dataToGet > remainingDataInFrontFrame)
            dataToGet = remainingDataInFrontFrame;

        // Copy the data from the frame to temporal buffer
        for(size_t i = 0; i < dataToGet; i++)
            outputData[extractedDataSize++] = next->getData()[0][_positionInFrontFrame + i];

        if(dataToGet < remainingDataInFrontFrame)
        {
            // Set new position into front frame
            _positionInFrontFrame += dataToGet;
        }
        else
        {
            // The whole front frame has been read, so pop it from queue
            popFrame();
            _positionInFrontFrame = 0;
        }
    }

    _totalDataSize -= extractedDataSize;
    newAudioFrame->assignBuffer(outputData);
    return newAudioFrame;
}