#I2S Audio

1 messages · Page 1 of 1 (latest)

steep pollen
#

So I tried to shorten your code so that I could just test its functionality. The audio is still blasting at full strength, and it appears to only output one voice. If the voice level is set to 0 it turns it off, but otherwise, it's on full blast, and it appears that 0 supersedes 1 when both are on:

# audiomixer_demo_i2s.py -- show how to fade up and down playing loops
# 30 Nov 2022 - @todbot / Tod Kurt

import time
import board
import audiocore
import audiomixer
import audiobusio
import audiomp3

i2s_bclk = board.GP0   # BCK on PCM5102 I2S DAC (SCK pin to Gnd)
i2s_wsel = board.GP1  # LCLK on PCM5102
i2s_data = board.GP2  # DIN on PCM5102
num_voices = 2

audio = audiobusio.I2SOut(bit_clock=i2s_bclk, word_select=i2s_wsel, data=i2s_data)

mixer = audiomixer.Mixer(voice_count=num_voices, sample_rate=16000, channel_count=1,
                         bits_per_sample=16, samples_signed=True)
audio.play(mixer) # attach mixer to audio playback

print("audio is now playing")

# set some initial levels
mixer.voice[0].level = 0.1  # drums on
mixer.voice[1].level = 0.1  # synth off

# load wav and start drum loop playing
wave0 = audiocore.WaveFile(open("StreetChicken1600.wav","rb"))
mixer.voice[0].play( wave0, loop=True )

# load wav and start synth loop playing
wave1 = audiocore.WaveFile(open("test1600-low-volume.wav","rb"))
mixer.voice[1].play( wave1, loop=True )

time.sleep(1.0)  # let drums play a bit

while True:
    print("voice 0 level=%1.2f" % mixer.voice[0].level)
    print("voice 1 level=%1.2f" % mixer.voice[1].level)
    time.sleep(0.1)

What's even more curious/frustrating is that the voice levels display as they should in the shell.

#

One clue though is that I'm using an Adafruit MAX98357A amplifier breakout: https://www.adafruit.com/product/3006 which is set up to a 9dB gain, and can be set to lower with a resistor. I'll have to try putting a resistor in to change the behavior, but I'm surprised that the I2C volume control seems to have no effect.

#

@lilac sedge LMK what you think about that code, perhaps I've omitted something important.

lilac sedge
#

code looks okay to me. perhaps that I2S amp is doing something funky with its stereo->mono conversion. Try setting its "SD" pin to 3.3V. That should set it to Left channel only

#

do you have another I2S board to try?

obsidian galleon
#

is the wav file mono or stereo?

lilac sedge
#

good point. @steep pollen try using the WAVs (and sample rate settings) I've prepared to see if you can at least recreate my sketch

steep pollen
steep pollen
#

@lilac sedge Got your code to run, thanks so much! The SD jumper to 3.3V seems to improve the sound.
One small note, on your Gist I believe you have a typo on line 46 - "incq" = "inc"?

lilac sedge
lilac sedge
#

Oh and yes that button in the video is on the RESET pin since Pico’s don’t have a reset button

steep pollen
#

@lilac sedge Looking at this again with a PAM302 amp from Adafruit - https://www.adafruit.com/product/2130 I tried putting in a max_audio_level as shown to your code: https://github.com/todbot/circuitpython-tricks/blob/main/larger-tricks/audiomixer_demo.py. Seems to kind of work, but hisses a bit and not nearly as quiet as I would suspect for .05.

# Write your code here :-)
# audiomixer_demo.py -- show how to fade up and down playing loops
# note this causes glitches and crashes on RP2040
# 9 Feb 2022 - @todbot / Tod Kurt
c
import time
import board
import audiocore
import audiomixer
from audiopwmio import PWMAudioOut as AudioOut  # for RP2040 etc
#from audioio import AudioOut as AudioOut  # for SAMD51/M4 etc

num_voices = 2
max_audio_level = .05

# audio pin is almost any pin on RP2040, let's do A0 (RP2040 GPIO226) or RX (RP2040 GPIO1)
# audio pin is A0 on SAMD51 (Trelllis M4, Itsy M4, etc)
audio = AudioOut(board.A0)
mixer = audiomixer.Mixer(voice_count=num_voices, sample_rate=22050, channel_count=1,
                         bits_per_sample=16, samples_signed=True)
# attach mixer to audio playback
audio.play(mixer)

mixer.voice[0].level = max_audio_level
mixer.voice[1].level = 0.0

# start drum loop playing
wave0 = audiocore.WaveFile(open("wav/drumsacuff_22k_s16.wav","rb"))
mixer.voice[0].play( wave0, loop=True )

# start synth loop playing
wave1 = audiocore.WaveFile(open("wav/snowpeaks_22k_s16.wav","rb"))
mixer.voice[1].play( wave1, loop=True )

time.sleep(1.0)  # let drums play a bit

# fade each channel up and down
up_down_inc = 0.01
while True:
    mixer.voice[1].level = min(max(mixer.voice[1].level + up_down_inc, 0), max_audio_level)
    mixer.voice[0].level = min(max(mixer.voice[0].level - up_down_inc, 0), max_audio_level)
    if mixer.voice[0].level == 0 or mixer.voice[1].level == 0:
        up_down_inc = -up_down_inc
    time.sleep(0.1)
#

Is this simply a result of the fact that it's doing a PWM out and not actually an ADC? Better to simply use a variable resistor? The I2S board seems to give me much better results in testing, which would make sense if my assumptions here are correct. Thx!

#

Also, I tied the SD to 3.3V, though I'm not sure what, if anything, that will do.

#

Actually, more experimentation here, and it seems to hiss at any volume.

lilac sedge
#

With the audio level so low, you're fighting inherent noise in the entire system. I was expecting you to only need to reduce it a few percent. Seems like you need to lower the gain on the amp so you can increase that max_audio_level

steep pollen
#

Turned the pot a bit, and hissing either way. Ah, OK, that makes sense... The rabbit hole never ends it seems! Thx!

lilac sedge
#

yes. audio stuff is always kind of a nightmare

#

but if you can swing it, I2S seems to be the better way to go (but I prefer the ones that do stereo line out (then use a separate amp)

steep pollen
#

Ah, makes sense. Well I appreciate it!

steep pollen
#

As I2S is digital, why does it matter what the PWM output is? Or is it still related somehow?

obsidian galleon
#

thanks for noting!

steep pollen
lilac sedge
#

ahah I thought it was just shade against PWM 😀

steep pollen
#

@lilac sedge I made a couple more examples modified on your code here: https://github.com/JeremySCook/circuitpython-tricks/tree/main/larger-tricks - I'm not exactly a GitHub aficionado, but once I have things cleaned up you're welcome to integrate it (or not to) to yours in any way you see fit.

I'll likely link it in an article at some point, so I'd be happy for it to reside in one place - whether that's my account or yours!

GitHub

Some CircuitPython tricks, mostly reminders to myself - circuitpython-tricks/larger-tricks at main · JeremySCook/circuitpython-tricks

lilac sedge
#

awesome! I wanted to merge them in but that link seems to be gone now

steep pollen
# lilac sedge awesome! I wanted to merge them in but that link seems to be gone now

I really need to get better with GitHub.

Anyway, I hadn't heard back for a few days, so as you noticed I decided to start from scratch on my own experiments repository. I suppose I didn't have to delete the other one, but wanted to keep things clean.

You are welcome to link or even copy my code/files relating to this I2S audio experimentation into your repository as you see fit. Thanks for your help!

#

BTW, I wrote up this article on the subject, and made sure to credit you there: https://embeddedcomputing.com/technology/open-source/i2s-volume-control-with-raspberry-pi-pico-and-circuitpython

Embedded Computing Design

In a recent article, I outlined how to play MP3 files on the Raspberry Pi Pico with no extra components, just a small speaker. I also talked about doing this with the addition of an amplifier. While either is fine for many applications, the Pico does not have a true ADC, meaning it instead uses less-than-perfect PWM to simulate an analog output....

lilac sedge
#

Nice! Thanks for the reference! I gotta get me some of those I2S amps to play with