private void WriteUserBuffersToAudioTrack()
        {
            // Here we need to fill the subBuffers of size 'subBufferSize' with the buffers provided by the user.
            // There are three cases:
            //  (1) the provided buffer is smaller than our subBuffer size. In this case we need to concat the buffers.
            //  (2) the provided buffer is bigger than our subBuffer size. In this case we need to cut the buffer.
            //  (3) the buffer has exaclty the size of our subBuffer size. In this case we submit the buffer as is.

            while (internalPendingBufferCount < NbOfSubBuffers)
            {
                if (pendingUserBuffers.Count == 0) // no user buffers available anymore
                {
                    return;
                }

                var userBuffer = pendingUserBuffers.Peek();

                if (userBuffer.ByteCount > dataNeededToFillCurSubBuffer) // (case 2: cut the buffers)
                {
                    AudioTrackWrite(userBuffer.Buffer, userBuffer.Offset, dataNeededToFillCurSubBuffer);

                    Interlocked.Increment(ref internalPendingBufferCount);
                    submittedBufferHandles.Enqueue(currentSubBufferHandles); // submit the handles (note: current buffer handle is added only in case (1))

                    userBuffer.Offset           += dataNeededToFillCurSubBuffer;
                    userBuffer.ByteCount        -= dataNeededToFillCurSubBuffer;
                    dataNeededToFillCurSubBuffer = SubBufferSize;
                    currentSubBufferHandles      = new SubBufferDataHandles();
                }
                else
                {
                    // case 1: concat the buffers
                    AudioTrackWrite(userBuffer.Buffer, userBuffer.Offset, userBuffer.ByteCount);

                    currentSubBufferHandles.AddHandle();
                    dataNeededToFillCurSubBuffer -= userBuffer.ByteCount;

                    if (dataNeededToFillCurSubBuffer == 0) // case 3: the user buffer fit perfectly the size of our subbuffer
                    {
                        Interlocked.Increment(ref internalPendingBufferCount);
                        submittedBufferHandles.Enqueue(currentSubBufferHandles); // submit the handles (note: current buffer handle is added only in case (1))

                        dataNeededToFillCurSubBuffer = SubBufferSize;
                        currentSubBufferHandles      = new SubBufferDataHandles();
                    }

                    // remove this buffer from the pending list because consumed
                    pendingUserBuffers.Dequeue();
                }
            }
        }
 private void ResetBufferInfo()
 {
     currentSubBufferHandles      = new SubBufferDataHandles();
     dataNeededToFillCurSubBuffer = SubBufferSize;
     nbOfAudioFrameAvailable      = 0;
 }
 private void ResetBufferInfo()
 {
     currentSubBufferHandles = new SubBufferDataHandles();
     dataNeededToFillCurSubBuffer = SubBufferSize;
     nbOfAudioFrameAvailable = 0;
 }
        private void WriteUserBuffersToAudioTrack()
        {
            // Here we need to fill the subBuffers of size 'subBufferSize' with the buffers provided by the user.
            // There are three cases:
            //  (1) the provided buffer is smaller than our subBuffer size. In this case we need to concat the buffers.
            //  (2) the provided buffer is bigger than our subBuffer size. In this case we need to cut the buffer.
            //  (3) the buffer has exaclty the size of our subBuffer size. In this case we submit the buffer as is.

            while (internalPendingBufferCount < NbOfSubBuffers)
            {
                if (pendingUserBuffers.Count == 0) // no user buffers available anymore
                    return;

                var userBuffer = pendingUserBuffers.Peek();

                if (userBuffer.ByteCount > dataNeededToFillCurSubBuffer) // (case 2: cut the buffers)
                {
                    AudioTrackWrite(userBuffer.Buffer, userBuffer.Offset, dataNeededToFillCurSubBuffer);

                    Interlocked.Increment(ref internalPendingBufferCount);
                    submittedBufferHandles.Enqueue(currentSubBufferHandles); // submit the handles (note: current buffer handle is added only in case (1))

                    userBuffer.Offset += dataNeededToFillCurSubBuffer;
                    userBuffer.ByteCount -= dataNeededToFillCurSubBuffer;
                    dataNeededToFillCurSubBuffer = SubBufferSize;
                    currentSubBufferHandles = new SubBufferDataHandles();
                }
                else
                {
                    // case 1: concat the buffers
                    AudioTrackWrite(userBuffer.Buffer, userBuffer.Offset, userBuffer.ByteCount);

                    currentSubBufferHandles.AddHandle();
                    dataNeededToFillCurSubBuffer -= userBuffer.ByteCount;

                    if (dataNeededToFillCurSubBuffer == 0) // case 3: the user buffer fit perfectly the size of our subbuffer
                    {
                        Interlocked.Increment(ref internalPendingBufferCount);
                        submittedBufferHandles.Enqueue(currentSubBufferHandles); // submit the handles (note: current buffer handle is added only in case (1))

                        dataNeededToFillCurSubBuffer = SubBufferSize;
                        currentSubBufferHandles = new SubBufferDataHandles();
                    }

                    // remove this buffer from the pending list because consumed
                    pendingUserBuffers.Dequeue();
                }
            }
        }