0

The Arduino I2S reference describes the I2S standard and functions available with the standard I2S library, (Bizarrely it doesn't reference the existing read() function which is used in the examples but that is beside the point). There also exists an ArduinoSound library, however I have the same issue with this.

I would like to record audio from WM8731 connected up to Arduino. I am using an SAMD arduino part.

But, I have a tremendous issue with the I2S.read() function. The I2S.read() function only returns a singular value, however the I2S standard is intrinsically stereo.

This is particularly important for my project as I am only interested in the LEFT channel as the RIGHT channel is muted.

I would expect this to either:

  • return a pair of values (i.e left /right) samples for that particular point in time , OR
  • return a singular sample with extra information telling me which channel that is was retrieved from.

However it seems this is not the case. (Github)

I also assume that the I2S is buffered making it impossible to simply read the WS pin state, as I will probably be popping a sample from the buffer that was push into the buffer at some point in the past.

So, is it possible to know which channel the sample was returned from the I2S.read() function or does this mean that the library needs to be modified?

I am more interested in using the samd library as other libraries such as AudioLibrary is limited to 16-bit - I need 32-bit resolution.

1 Answer 1

0

From my understanding it's just retrieving subsequent samples from the DMA buffer, which means you will alternately get left and right samples from each read. It would be more normal to use the read(buffer, len) variant to read two (or more) samples at once.

int16_t pair[2]; // change to int32_t for 32 bit samples
I2S.read(pair, sizeof(pair));
5
  • Thanks. It helps, however using this method would there not still be a possibility that the channels may be swapped? Will this ensure that the first member of the pair is always the LEFT or RIGHT (e.g.)? I find that the Arduino documentation, library and examples are extremely lacking with this regard and to my astonishment does not seem to concern most folk in the community
    – pm101
    May 19, 2021 at 11:13
  • Your always dealing with an entire dma buffer, so should always be the same.
    – Majenko
    May 19, 2021 at 11:35
  • Thanks, I have tested this however occasionally I am getting all LEFT and sometimes all RIGHT on pair[0] depending when I start reading. which is my main problem
    – pm101
    May 19, 2021 at 12:08
  • 1
    I think part of the problem is that the whole library's methodology is flawed. You hjave DMA driven ping-pong buffers which receive the data constantly, and you must deal with an entire buffer in less time that it takes to fill the other buffer. You may be better off using the onReceive() callback to run a function at the moment the buffers swap, at which point you must read the entirety of the buffer, otherwise it will stall (by the looks of things).
    – Majenko
    May 19, 2021 at 12:14
  • thanks for the help - you've certainly understood the problem and it is worth recording (no pun intended) for others to know about. For now as my project only requires one channel I can simply put split the one channel into both left and right so that in this case it doesn't matter and I will always read the same channel regardless, however that's just a sticking plaster.
    – pm101
    May 19, 2021 at 12:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.