HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Ring buffer in C tail pointer issue (for audio streaming)

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
issuepointeraudiotailstreamingforringbuffer

Problem

I am currently writing an embedded application for audio streaming purposes. The embedded app will receive audio packets being sent over WiFi, buffer the packets, then send the audio data over to a decoder chip. I have a ring buffer implementation written, but am getting some weird behavior sometimes. In terms of audio, I am hearing some parts of the song repeat during playback. I found out that this is due to the tail pointer being set to the beginning of the buffer twice.

(In my implementation, the head pointer marks the end of valid data whereas the tail pointer marks the beginning of valid data)

For example, I see:

  • Head pointer reset to start of buffer



  • Tail pointer reset to start of buffer



  • Tail pointer reset to start of buffer



  • Head pointer reset to start of buffer



Here is the ring buffer implementation:

```
typedef struct ring_buffer
{
UINT8 buffer; / data buffer */
UINT8 buffer_end; / end of data buffer */
size_t capacity; / maximum number of mp3Bytes in the buffer /
size_t count; / number of mp3Bytes in the buffer /
size_t typesize; / size of each mp3Byte in the buffer /
UINT8 head; / ring buffer head pointer */
UINT8 tail; / ring buffer tail pointer */
} ring_buffer;

PUBLIC UINT8
AppAudioStream_RingBufInit(ring_buffer *rb, size_t capacity, size_t typesize)
{
/ alloc buffer of size capacity typesize */
rb->buffer = malloc(capacity * typesize);
if(rb->buffer == NULL)
{
printf("ring buffer init fail\r\n");
return RING_BUF_INIT_FAIL;
}

/ init rb buffer to 0 /
memset(rb->buffer, 0, capacity * typesize);

/ rb struct element init /
rb->capacity = capacity;
rb->buffer_end = rb->buffer + capacity * typesize;
rb->count = 0;
rb->typesize = typesize;
rb->head = rb->buffer;
rb->tail = rb->buffer;

return RING_BUF_INIT_DONE;
}

PUBLIC VOID
AppAudioStream_RingBufWrite(ring_buffer rb, UINT8 mp3By

Solution

If I'm right you need some synchronization/locking to make visible every data change properly for every thread since two threads use the ring buffer at the same time: AppAudioStream_BufRecv and AppAudioStream_DecoderCb.

Two posts from SO which look useful:

  • Mutex example / tutorial?



  • Is changing a pointer considered an atomic action in C?

Context

StackExchange Code Review Q#11774, answer score: 3

Revisions (0)

No revisions yet.