thomas_lee
Posts: 2
Joined: Mon Sep 17, 2018 7:10 pm

Circle Audio Buffering

Mon Sep 17, 2018 7:26 pm

This is my first post in the forum, so first would just like to thank everyone who have been working on Circle. The process getting it to work was super simple and I've been able to cross-compile bundled examples without issues.

Anyway, I'm new to Circle and would like to understand better how the audio system works. I have modified the miniorgan example so support more advanced audio synthesis and things kind of work, but i have noticed that GetNextChunk() should return fairly quickly or there's corrupted output.

I'm using the default buffer size 2048 (which should translate to 23ms worth of audio stream?) and I thought it would be ok to spend up to 23ms in generating the buffer which should be plenty of time given the CPU speed on pi3 b+. However, If I add anything more complex than few sin(x) I start to get corrupted output so I was thinking is there some limit for processing time caused by the interrupts/DMA system that would require GetNextChunk() return much quicker than in 23ms max.

Any help or guidance would be appreciated. I'm new to Raspberry PI and Circle so bare with me if these should be obvious :)

rst
Posts: 311
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Circle Audio Buffering

Tue Sep 18, 2018 10:54 am

Supposing you are using the PWM sound device at 44.1 KHz sample rate, writing out one sound DMA buffer with 2048 samples (1024 per channel) should take about 23 ms, as you have noted. The CPWMSoundBaseDevice class uses two of these linked sound DMA buffers, so that while one buffer is written out, the other can be filled by the application in GetChunk().

If you have to do complex operations to prepare the sound data, 23 ms may be not much. Additionally there may be some overhead to handle the DMA interrupt at the end of the transmission of each sound buffer and to manage the data cache, which is required to ensure, the sound data can be written out using DMA. Unfortunately I cannot specify, how much overhead this will take, without doing complex measurements, but I guess it will be not more than a few milliseconds.

So what can you do? If possible, you could increase the nChunkSize parameter from 2048. This will reduce the influence of the overhead needed for the DMA interrupt and you will have more time to fill in the sound buffer (of course you have to produce more sound samples in this time then).

Another possibility is to use the multi-core capabilities of the RPi 3B+ to render the sound data. This is more complex, but very helpful. You may have a look at my MiniSynth Pi project, which is a virtual analog audio synthesizer based on Circle. The calculations needed for the VCF (filter) have been time consuming too. MiniSynth Pi can generate 24 simultaneous voices on the RPi 2, 3B and 3B+ using multi-core. On the RPi 1 it can generate only 4 simultaneous voices.

thomas_lee
Posts: 2
Joined: Mon Sep 17, 2018 7:10 pm

Re: Circle Audio Buffering

Tue Sep 18, 2018 7:22 pm

Thanks a lot for your good explanation and confirming that the double buffering should indeed work as expected so it's most likely just the overhead from DMA and non-optimized code on my side that's the issue (developed the synth originally for high-end PCs). The idea of using other cores of doing calculations makes lots of sense and your Minisynth PI project is super helpful in understanding how everything fits together and as a benchmark.

Thanks a lot!

rst
Posts: 311
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Circle Audio Buffering

Wed Sep 19, 2018 10:31 am

You are welcome. I did some measurements now and it comes out, that my guess was far too pessimistic. On a RPi 3B+ the overhead for DMA interrupt and cache management is safely below 30 microseconds per chunk. So the influence of this overhead on the available time for rendering the sound data is minimal.

Return to “Bare metal, Assembly language”

Who is online

Users browsing this forum: No registered users and 6 guests