miketeachman/micropython-i2s-examples

stereo on rp2040 using I2S PCM5102 Stereo DAC Decoder

Guustaaf opened this issue · 6 comments

Hi Mike,

Thanks for your work on the Micropython I2S class!

Playing mono wav files works fine but when I play a stereo file it sounds like it alternatingly fills the buffer with zeroes. So I hear one buffer full of sound and then for the same length silence.

Do you have any idea what could cause this? I am using code very similar to your example.

Thanks,
Guustaaf

Hi Guustaaf,
Thanks for reporting this issue. I can take a look, but I will need some additional background:

  • what stereo file are you using?
  • can you provide MicroPython code that shows the problem?
  • what PCM5102 hardware are you using?
  • what MicroPython version?
    Mike

Mike,
I tried two different DACs both with the same result. I tried wav files generated with Audacity as well as with Reaper.
Thanks for looking into this. Let me know if you need any more information.
Guustaaf
Code:
`from machine import Pin, SPI, I2S
import sdcard
import uos

cs = machine.Pin(17, machine.Pin.OUT,value=1)

spi = machine.SPI(0,
baudrate=1000000,
polarity=0,
phase=0,
bits=8,
firstbit=machine.SPI.MSB,
sck=machine.Pin(18),
mosi=machine.Pin(19),
miso=machine.Pin(16))

sd = sdcard.SDCard( spi, cs)

vfs = uos.VfsFat(sd)
uos.mount(vfs, "/sd")

files = uos.listdir("/sd")
for fi in files:
print(fi)

sck_pin = Pin(12)
ws_pin = Pin(13)
sdout_pin = Pin(10)

audio_out = I2S(
1,
sck=sck_pin,
ws=ws_pin,
sd=sdout_pin,
mode=I2S.TX,
bits=16,
format=I2S.MONO,
rate=44100,
ibuf=40000
)

samples = bytearray(44100)

with open("/sd/1khz-mono.wav", "rb") as file:
while True:
samples_read = file.readinto(samples)
if samples_read == 0:
break
else:
audio_out.write(samples[:samples_read])

audio_out.deinit()

file.close()
uos.umount("/sd")
spi.deinit()

`

Hi Guustaaf,
Good news. I was able to reproduce the exact problem you are hearing. The problem is caused by a SPI bus that is running at a slow BAUD rate of 1000000. With this SPI configuration, audio sample data comes out of the SD card at a low rate. The I2S driver runs out of samples and silence is heard.

There are two ways to correct this problem:

  1. initialize the SPI bus to a faster BAUD rate by calling sd.init_spi(25_000_000) as shown below.
sd = sdcard.SDCard( spi, cs)
sd.init_spi(25_000_000)  # increase SPI bus speed to SD card

OR

  1. If you are using the latest sdcard.py version you can change your code to:
    sd = sdcard.SDCard(spi, cs, baudrate=25_000_000)

Either of those fixes should allow audio samples to be read from the SD card at a fast enough rate to avoid audio gaps. In my testing I hear continuous audio at 44100 Hz Stereo.

Mike

Hi Mike,

Yes! That is the fix! Thanks so much Mike. I really appreciate it!

Guustaaf

Great !