Audio with PIO PWM

I have been playing around with the audio capabilities of the PicoCalc and I found a disappointing limitation.

The left channel is on GP26 and the right channel is on GP27. The problem is that these pins share the same PWM slice which forces a single PWM frequency on both pins (channels). You cannot implement stereo playback using a simple technique of PWM-based audio. The only way to get stereo sound is through wavetable synthesis, that I can think of.

Managing the pushing out sound data with very tight tolerances with other background processing is very tough.

Does anyone have any other ideas?

Luckily it’s pretty trivial to implement PWM generation in the PIO’s, and there’s no pin restrictions with such an approach.

1 Like

Indeed ,I would have preferred a I2S audio implementation but this would require more pins

Not sure if the chosen PICO range actually have enough free pins.

My current core board is the Luckfox Lyra and I will soon connecting up the Luckfox Lyra Zero W.

1 Like

Thank you so much, @pelrun!

I will that a go!

You can control the duty cycle of each channel independently.

Pitch is controlled by frequency, not duty cycle.

1 Like

Yes, you can change the frequency – the pitch, and the duty-cycle – the volume/tone on each channel independently using PIO. You also can use the duty-cycle to apply an envelope to the note (sine, sawtooth, ADSR). Once again, thanks to @pelrun for directing me down this path of learning the wonderful capabilities of PIO.

However, since the PicoCalc has a hardware volume control, I am keeping it simple with a square wave of 50% duty-cycle (full-volume/balanced tone) and a single note per channel. This is what I want to get working right now.

I need to keep in mind that what I want to achieve is a simple stereo audio driver, a single component of a larger project, and I am not trying to create a music synthesizer, which would definitely be a project on its own for a single developer.

Why are you shying away from wavetable synthesis? It really is trivial to implement and the overhead is just a regular interrupt that adds a phase shift to a counter that is used to reference a table of amplitudes/duty cycle values.

Well, this is my first go at producing audio, so I want to walk before I run. This is also my first use of PIO as well. If I am going to understand with the depth that I require of myself, I need to get the basics down.

To start, I needed to learn how I can recreate music and the components of pitch, volume, tone and envelopes digitally. Next I need to get a very solid grasp of PIO programming. The more interesting things (envelopes!) can come later, but I will need to move on to other parts of the project before that.

I am not a cut & paste developer or one that just plugs blackbox libraries together, and saying that is no way implying that you are! What I am trying to say is that I desire to understand what I am doing and how it works fundamentally which has served me well in my career.

Has anyone noticed crosstalk when the volume dial is set low?

Output modulation of PWM is done by having a fixed very high PWM frequency and varying the duty cycle to match the desired analog output level at each sample time period

See the schematic, because PicoCalc has the all required components for high freq sound PWM especially the low pass RC filter

  • RC low-pass filter per channel (R501+C502, R503+C504) with additional smoothing (C504, R505).

PS More info from original PI devices how it works

In section 3.4.1 PWM Audio

https://datasheets.raspberrypi.com/rp2040/hardware-design-with-rp2040.pdf#page=24

Also keep in mind that rp2350 has 16 bit resolution instead of 10 bit PWM output of rp2040 allowing higher quality output

1 Like

As for PIO, PIO used for i2s communication with DAC chips like PCM5102


For the PicoCalc PWM is enough to produce sound on internal and headphone outputs.

That is one way to generate audio, but it is not the only way.