Can't get rid of audio PWM noise

I'm developping a synth based on bytebeat and now I'm trying to get a clean audio.

I'm working with a Pico

The PWM is running 22050Hz in order to avoid switching noise

I found a circuit in "Hardware Design with rp2040" that looks like this

I tried with and without but on scope, results look pretty the sames

without filter

with filter

But the more surprising is when I connect a jack for listening to the audio the waveform transform like that

When listening to the audio with earbuds, I got a very unpleasant buzzing in the background

For information, the jack is the only peripherical connected to AGND for avoid noise from a SPI screen

I don't know if the PWM rate is not enough (I can't really increase it because both cores a running near their limits)

Is the filter from the book is really effective ?

Why the waveform collapse when I'm connecting earbuds ?

Should I switch directly to a DAC to avoid working on a cheap solution ?

In the book they're talking about a clean audio supply formed with a voltage regulator, could it be the solution ?

That is a first order bandpass filter, with a high frequency roll-off at about 20 kHz, which means it reduces the "buzz" by only 3 dB at 20 kHz.

As you have noticed, that isn't much reduction. A 3rd or 4th order filter with a significantly lower rolloff frequency would do a better job. There are plenty of design guides on the web.

In any case, PWM audio sampled at 22 kHz cannot reproduce audio signals with frequency > 11 kHz, and should not be expected to. It is fine for voice audio, limited to about 8 kHz.

LTSpice simulation:

The "buzz" might be something different, but a real DAC should work better.

The Raspberry Pi MIGHT run at a higher frequency.

Class-D amplifiers are "similar" to PWM but they usually run at hundreds of kHz (sometimes 1MHz) and the good ones have L-C filters.

I've read about amplifier chips getting hot and not putting any sound (or very weak sound) and I would NEVER feed into my home theater amplifier, or any high-power amp, or any amp that I cared about. Even when putting-out "silence" it's full-voltage PWM (before filtering)

Thank you !
I didn't know it was a bandpass.
In the case of "classic" bytebeat running at 8Khz, the maximum frequency rate is 4Khz, so I don't know if I should improve this filter.

@DVDdoug
Yeah, i'm thinking more and more about a DAC. I wonder if using a DAC is more CPU consuming than the hardware PWM of the pico.

Because I thinking more and more that this "buzz" is some audio artifact caused by too large consumption of CPU ressources.

Are they ways to know if the CPU is too slow for handling all the functionnalities ? (parsing of bytebeat formule, display, audio, buttons & potentiometers, MIDI, webusb ?)

The problem is the hash produced by the 22 kHz PWM, not by the audio signal. You need a much better filter to remove the 22 kHz hash.

Understood !
But isn't that the official filter used on the raspberry pi ? Maybe it is because like DVDDoug said, it's running way more faster.

What do you mean by "hash produced by the 22 kHz PWM" ?
It is possible to calculate that and adapt the filter for my case ?

The noise produce by the 22 kHz PWM.

I think you are already very close to the truth of the problem.

Background noise is often related to the design of the power supply.

So in our audio Bluetooth product manual, we always remind users to pay attention to power supply when designing in this way:

“Power supply requirements matter. lf audio is involved, a clean power supply affectsaudio noise. The dirtier the power, the more troublesome the audio processing. A phonecharger's 5V output is typically very clean and usually doesn't cause significantbackground noise. lf audio isn't used, a slightly less clean power supply is fine.”

I tried several things and I'm little disappointed...

  1. The complete circuit provided by the rp2040 book is for a line level. For me it's not helpful, I would like to listen to the synth with headphones

  2. Also tried a 2nd order filter with R=1k and C=10nF, works pretty great but the volume is too attenuated

  3. I put a LM358 in follower configuration just for giving more power to the signal with a capacitor in serie just in front of the audio jack and I think it's better. The problem ? The LM358 is powered by the 3V3 or 5V of the pico and parasited by the other periphericals around (I think)

  1. I tried to add a MCP1700 33 in order to provide a clean power to the LM358, but the little boy started getting hot and smoking

I believe too much current is pulled from the pico supply, I'm not really sure

That is a very poor filter design. It is not a second order filter at all. It is just two RC filters one after the other. This is not a second order filter because the impedances interfere with each other. That op amp is not doing very much for you either.

Look up how to design active filters.

Noise from the PWM is mainly due to the impedance matching between the signal and the input to any amplifier.

The input impedance of the amplifier is normally high, and it needs to be low so it does not pick up noise. Make it low by putting a low resistor, like 2K2 across it’s imput.

I tried other things

I put a sallen key filter that take the PWM input, the filter output pass trough a 100u capacitor with a 10k pot followed by the audio jack

The sound is a little better but I always have this unpleasant sound when the AOP is wired to the VSYS(5V) of the pico and the potentiometer full open
So I place a 2.2k in serie with the pot input and it help a little

After that I unplugged my SSD1309 screen and it improved a lot the background noise so maybe provide a clean supply to the AOP will help ?

I tried to add a voltage regulator (MCP1700 33) with two 1u cap for supply the AOP, but it doesn't seems to improve much (this time it doesn't get hot)

I decided to scope the PWM output directly (with screen plugged) and remark something, when I stop the dutycycle update with a button (works like a looper) if the pwm looks like this
PWM direct output


PWM filtered output

I haven't much noise

But when it's looks like this
PWM direct output


PWM filtered output

I got the unpleasant noise
So in the software I tried to set the dutycycle to 0 and stop the PWM but it doesn't work

inside the setup1 while(1) loop of the pico

// mode == 1 is the looper, loopPlayStatus [0,1,2] are stop, pause, play
        if (mode == 1 && (formulaCore1.loopPlayStatus == 0 ||
                          formulaCore1.loopPlayStatus == 1)) {
          audioCore1.updateDutyCycle(0);
          pwm_set_enabled(audioCore1.slice, false);

        } else if (mode == 1 && formulaCore1.loopPlayStatus == 2) {
          pwm_set_enabled(audioCore1.slice, true);
        }

Thanks for that.

This is the circuit I have used a lot to greatly reduce the noise I get from a signal in a noisy environment.

Note there are two parts to this, first is the way the way I apply the signal to the input, and second is the way I filter the power supply to the amplifier. Note the use of a small inductor in the filter.