sfera-labs / arduino-pico-i2s-audio

I2S digital audio input Arduino library for the Raspberry Pi Pico RP2040
8 stars 2 forks source link

ringbuf_pop always returns false #4

Open biemster opened 1 year ago

biemster commented 1 year ago

This one's a doozy. I use your (great!) machine_i2s.c with the C-SDK like this:

#include "pico/stdlib.h"
#include "machine_i2s.c"

#define SCK 3
#define WS 4 // needs to be SCK +1
#define SD 29
#define BPS 32 // 24 is not valid in this implementation, but INMP441 outputs 24 bits samples
#define RATE 16000

int main() {
    stdio_init_all();
    machine_i2s_obj_t* i2s0 = machine_i2s_make_new(0, SCK, WS, SD, RX, BPS, STEREO, /*ringbuf_len*/SIZEOF_DMA_BUFFER_IN_BYTES, RATE);
    int32_t buffer[I2S_RX_FRAME_SIZE_IN_BYTES /4];
    while (true) {
        machine_i2s_stream_read(i2s0, (void*)&buffer[0], I2S_RX_FRAME_SIZE_IN_BYTES);
        printf("%.6x %.6x\n", buffer[0], buffer[1]);            
    }
}

but I don't get any samples out without the most peculiar change: if I add on https://github.com/sfera-labs/arduino-pico-i2s-audio/blob/master/src/machine_i2s.c#L232 the following:

printf("%d %d\n", rbuf->head,rbuf->tail);

it suddenly starts spewing out correct frames! So it seems to me that the printf statement somehow materializes the head and tail values, but my knowledge of the pico and or C is not nearly enough to start to understand this.

biemster commented 1 year ago

Maybe I hit something like this https://github.com/raspberrypi/pico-sdk/pull/971?

biemster commented 1 year ago

Printing some random stuff already fixes the issue, it does not have to involve head or tail.

biemster commented 1 year ago

I hacked my way around it by adding a stdio_flush() on line 971, but I'd love to find a better solution here..

giampiero7 commented 1 year ago

Hi @biemster , Things like this are usually caused by some timing issue. E.g. your call to printf() slows things down just enough to make the right thing happen at the right moment. Maybe a sleep call will produce the same effect.

This library is no longer updated, the efforts have been moved to the I2S library of the arduino-pico project: https://github.com/earlephilhower/arduino-pico/tree/master/libraries/I2S which starts from the same foundations and includes fixes and improvements.

So I'd strongly recommend to use that as your starting point.

Alternatively, you may want to have a look at the original MicroPython code to see if there's any update there: https://github.com/micropython/micropython/blob/master/ports/rp2/machine_i2s.c

Good luck!

biemster commented 1 year ago

Thanks @giampiero7 for your answer. I started of from the arduino-pico I2s library, but got stuck: https://github.com/biemster/pico-I2S, probably at the ping-pong DMA stuff (not my forte). I looked at the original MicroPython code as well indeed, but I don't see any relevant changes in that area, so that might have the bug as well..