Skip to content
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

Open
zanellia opened this issue Feb 25, 2025 · 23 comments
Open

Simultaneous read+write over I2S codec with DMA #545

zanellia opened this issue Feb 25, 2025 · 23 comments

Comments

@zanellia
Copy link

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?

@rsta2
Copy link
Owner

rsta2 commented Feb 25, 2025

Yes, this should already work. You have to specify DeviceModeTXRX for the parameter DeviceMode in the constructor of the class CI2SSoundBaseDevice. You can test this mode using the test/sound-controller.

@zanellia
Copy link
Author

Awesome! Thanks for the prompt reply.

@zanellia zanellia changed the title Simulataneous read+write over I2S codec with DMA Simultaneous read+write over I2S codec with DMA Feb 25, 2025
@zanellia
Copy link
Author

zanellia commented Mar 9, 2025

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.

@zanellia
Copy link
Author

zanellia commented Mar 9, 2025

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?

@rsta2
Copy link
Owner

rsta2 commented Mar 10, 2025 via email

@zanellia
Copy link
Author

zanellia commented Mar 10, 2025

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?

@rsta2
Copy link
Owner

rsta2 commented Mar 10, 2025 via email

@zanellia
Copy link
Author

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.

@zanellia
Copy link
Author

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?

@rsta2
Copy link
Owner

rsta2 commented Mar 10, 2025 via email

@zanellia
Copy link
Author

zanellia commented Mar 10, 2025

I thought I was using REALTIME already since I modified sysconfig.h. Tried recompiling everything after adding DEFINE += -DREALTIME to Config.mk, but I still see 2ms of latency.I still don't understand if that's even possible at all, since a chunk size of 32 corresponds to 16 stereo samples and, at 48kHz, 16 new samples are provided every ~333us. How are samples not being lost if I see a latency of 2ms?

@rsta2
Copy link
Owner

rsta2 commented Mar 10, 2025 via email

@zanellia
Copy link
Author

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?

Yes, exactly.

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 2500 µs + 2333 µ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.

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.

@rsta2
Copy link
Owner

rsta2 commented Mar 10, 2025

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.

@zanellia
Copy link
Author

zanellia commented Mar 10, 2025

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.

@rsta2
Copy link
Owner

rsta2 commented Mar 11, 2025 via email

@zanellia
Copy link
Author

Is there any obvious way to measure the latency due to the codec in the setup associated with the application in test/sound-controller?

@rsta2
Copy link
Owner

rsta2 commented Mar 11, 2025 via email

@zanellia
Copy link
Author

Alright, thanks - I'll keep investigating.

@ellisgl
Copy link

ellisgl commented Mar 11, 2025

I would have thought anything under 3ms would be pretty good for roundtrip on audio...

@zanellia
Copy link
Author

zanellia commented Mar 11, 2025

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.

@rsta2
Copy link
Owner

rsta2 commented Mar 12, 2025

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 2*50µs + 2*2*41µs + 2*64/2/48000 ~ 1.6ms. The FIFOs are used for both Stereo channels, that's why the divider by 2.

@zanellia
Copy link
Author

zanellia commented Mar 12, 2025

Thanks for this additional input. Very valuable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants