9 years, 9 months ago.  This question has been closed. Reason: Too broad - no single answer

Audio Buffer

Hey guys, I'm working on a project with realtime audio, and I'm looking for some advise on how to create an audio buffer. Here's how my solution looks so far:

  • The audio sample rate is 50kHz
  • An RtosTimer running at 1kHz generates the next N samples, and enqueues them in an audio buffer
  • A Ticker running at 50kHz dequeues one sample from the audio buffer, and updates a DAC

The way I see it, an audio buffer of 100 samples will accommodate any jitter in the update timer. When the update timer runs, it will check the available space in the audio buffer once (since the Ticker will continue to empty it), and generate enough samples to fill that space. I think a ring buffer would probably be best for this, but I'm not sure how to avoid the potential concurrency issues with having two sections of code modifying the same buffer at the same time. Does anyone smarter than me have any suggestions? Will I have to write a ring buffer implementation in assembly in order to use atomic operations? Thanks!

2 Answers

9 years, 9 months ago.

I think one of your timers is going to have to be the master timer that the other one follows, otherwise small differences will accumulate and in the end give errors. If the ticker is running as master clock for example you could always make it update a piece of the (ring)buffer ahead of the ticker timer, and also look at how much space is between him and the current ticker pointer, if that is less than a threshold it should calculate more samples during the next run. If the RTOS timer is the master timer you would need to modify the ticker timer tick rate, but I would guess you need a custom timer implementation since I doubt 1us is then enough resolution.

Hmm... My thought was that using a 2ms buffer would prevent small timing differences from adding up. The buffer would be initialized with 100 samples, and ideally there would be 50 samples remaining, and therefore space for 50 new samples each time the RtosTimer ran. In practice however, jitter will affect this so there might only be 30 or 40 samples available, and the RtosTimer will need to generate 60 or 70 samples respectively. In either case, the buffer should always have enough samples available for at least one RtosTimer interval.

posted by Neil Thiessen 04 Aug 2014
9 years, 9 months ago.

The alternative to a ring buffer would be ping-pong buffers. The ticker would just need to indicate when it switches buffers to tell the other task to re-fill the empty buffer.

Thanks for the suggestion, I'll keep it in mind. However, a crazy thought just occurred to me... Why not use an RTOS queue? In the RtosTimer I can run a 100 iteration for loop, and break if the queue is full.

posted by Neil Thiessen 05 Aug 2014