-
Notifications
You must be signed in to change notification settings - Fork 262
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simultaneous read+write over I2S codec with DMA #545
Comments
Yes, this should already work. You have to specify |
Awesome! Thanks for the prompt reply. |
I have set this up and it worked smoothly! I am seeing ~100ms round trip latency (measured with a sound card sending the same signal back to itself and to the codec). Is that the expected latency? I have tried reducing the number of frames per read/write, but it doesn't seem to affect much the latency. |
OK, I was able to reduce it significantly decreasing the queue size. Is there any chance that the chunk size could be decreased below 32? |
If you want the smallest latency, you have to optimize the chunk size and
sound queue size on your own. I never tested a chunk size of 32, but
everything below 256 seems to be critical to me.
|
I have tested chunk size 32 and queue size of 500us (I have changed the code soundbasedevice.cpp). With this setting the roundtrip latency seems to be around 2ms. A chunk size of 32 amounts to 32 * 32 / 16 = 64 samples when working with 16 bits resolution, right? In general, what's the minimum latency I should be able to achieve? |
You can use CSoundBaseDevice::AllocateQueueFrames(), if you want to use a
sound queue smaller than 1 ms. You don't need to modify soundbasedevice.cpp
then.
A chunk size of 32 means 16 samples per Stereo channel. This is not influenced
by the sample size. I cannot say, what the minimum achievable latency is.
|
The chunk size is measured in samples then, not in words? ("nChunkSize is the size of the buffer in words." from https://circle-rpi.readthedocs.io/en/48.0/devices/audio-devices.html). With 16 samples I'd expect a latency that is much lower than ~2ms. I might be doing something wrong. |
Is there any chance that the other tasks (HDMI, USB keyboard, others?) are somewhat responsible for a large part of the latency when using a very small chunk size? |
Yes, but for the chunk size: one sample == one word.
You should use the system option REALTIME, otherwise the screen output can
delay IRQs. Add this to Config.mk and rebuild everything:
DEFINE += -DREALTIME
|
I thought I was using REALTIME already since I modified sysconfig.h. Tried recompiling everything after adding |
You are receiving audio on one side and gate it through to the output side of
the WM8960? Your chunk size is 32 and the size of both sound queues is 500 µs?
Please note that there are two sound queues and additional DMA buffers
involved. You read/write from/into the queues and the IRQ handler from the DMA
controller transfers this data into its own DMA buffers. There are two DMA
buffers with a size of chunk size for each direction. Then the DMA controller
transfers the samples from/to these DMA buffers to the DATA register of the I2S
controller.
That means the latency should be 2*500 µs + 2*333 µs, which is about 1.7 ms.
There may be a small additional latency in the I2S codec. So 2 ms is not far
away.
|
Yes, exactly.
I see. Thanks a lot for the detailed explanation. Will try to decrease both queue and chunk size to see if that decreases the latency. |
A correction: Because there are two concatenated DMA buffers on both sides: 2*500 µs + 2*2*333µs, about 2.3 ms. You are welcome. |
I am able to run with sound queues of 50us and a chunk size of 2, i.e., 2 * 50us + 2 * 2 * 41us = 264us, but the latency that I am measuring is still around 1.2ms. Is there any other hidden buffer that would justify this value? I have tried disabling HDMI and USB keyboard too. |
As I wrote, the WM8960 may add some latency. I cannot say, how big it is.
|
Is there any obvious way to measure the latency due to the codec in the setup associated with the application in test/sound-controller? |
I don't know one.
|
Alright, thanks - I'll keep investigating. |
I would have thought anything under 3ms would be pretty good for roundtrip on audio... |
Sure, but with sound queues of 50us and a chunk size of 2, we should have 2 * 50us + 2 * 2 * 41us = 264us. And "good" depends on the application. |
According to this document (section 7.2.) there is another 64 x 32 bit FIFO buffer in the TX and RX path of the I2S peripheral. It is probably not fully filled, when the device is in operation, otherwise the latency would be |
Thanks for this additional input. Very valuable. |
Hi, would it be possible to setup simultaneous read/write over an I2S codec (maybe this one? https://www.waveshare.com/wm8960-audio-hat.htm) using DMA on the Raspberry Pi 4?
The text was updated successfully, but these errors were encountered: