Behind The Pin: How The Raspberry Pi Gets Its Audio

Single board computers have provided us with a revolution in the way we approach computing as hardware creators. We have grown accustomed to a world in which an entire microcomputer has become a component in its own right rather than a complex system, and we interface to them as amorphous entities through their exposed interfaces. But every pin or socket on a single board computer has something behind it, so following up on a recent news-inspired item in which we took a look at what lies behind the Ethernet jack on a Raspberry Pi, we’d like to continue that theme by looking behind more pins and interfaces. So today we’ll stay with the Raspberry Pi, and start with an easy target by taking a look down its audio jack.

All the main Raspberry Pi board releases since 2012 with the exception of the Pi Zero series, have featured a 3.5mm jack carrying line-level audio. The circuits are readily accessible via the Raspberry Pi website, and are easy enough to understand because of course all the really hard work is done within the silicon of the Broadcom system-on-chip. Looking at the audio circuitry, we’ll start by going back to the original Pi Model B from 2012 (PDF) because though more recent models have seen a few changes, this holds the essence of the circuitry.

The audio circuitry from the first Raspberry Pi.
The audio circuitry from the first Raspberry Pi.

The schematic above shows the audio circuitry from the first Raspberry Pi. On the left are inputs from a pair of BCM2385 PWM lines, and on the right is the audio jack. What is in the middle might seem quite surprising, this circuit uses only discrete components. Even that splits neatly into two sections, the diodes perform the function of protecting the input from harmful voltages that might come in through the jack, and the RC network is a filter. This last section is the interesting part, and deserves a more in-depth explanation.

PWM, which stands for Pulse Width Modulation, is an entirely digital way of representing an analogue value as a chain of pulses whose width is proportional to the analogue value being expressed. In itself it is not an analogue signal, though it is simple to convert to one by passing through a low-pass filter whose cut-off frequency is the maximum frequency of the analogue signal. So if we take a look again at the right hand side of the circuit, we see using the numbers from the right channel in the top circuit that R21 and C20 form a low-pass filter. The values of 270R and 33nF can be calculated to give a cut-off frequency of just below 18kHz, which is a sensible sounding value for an audio output.

The next two components are a high-pass filter, R20 and C48. This takes away any extremely low frequencies which might cause uncomfortable rumbling or damage to speakers. The values of 150R and 10uF can be calculated as having a cut-off of about 100Hz, yet again a sensible-sounding figure. The output from this pair of filters should be an acceptable audio signal, and goes straight to the 3.5mm jack.

Newer Pi, Better Audio

The more recent Raspberry Pi models have had a few changes in the audio department. The early boards had a low-ish audio level, and their frequency response could have been better. The newer version of the circuit adds a high-speed buffer chip to provide a lower-impedance source, and tweaks the filter values somewhat.

The audio circuitry from the Raspberry Pi 3.
The audio circuitry from the Raspberry Pi 3.

The low-pass filter’s 220R and 100nF now give it a cut-off of just over 7kHz, and the high-pass filter’s 100R and 47uF give it 33Hz. Both these values sound way off the mark, after all 7kHz is hardly hi-fi. But to imagine that the calculated cut-off frequency is a brick wall is to make a grave error. In fact that is better termed as a roll-off frequency, at which the response starts to decline. These revised values will give a rounded frequency response that still lets through plenty of high frequencies and stops plenty of low ones, but has an end result that doesn’t stretch too high above the audio range.

Thanks to some maths that torment electronic engineering students, the response of the low-pass filter should end at  half the sampling frequency (at least) of the audio being played, to avoid unwanted distortion in the result. These values provide a better approximation to that figure, and thus make for a better quality audio output from more recent Pi versions.

This is a circuit that seems simple enough, yet there lurks a surprising complexity. It has plenty of uses beyond the Pi, because wherever you may use a PWM audio signal from a microcontroller or SoC you will need to replicate its functionality.

46 thoughts on “Behind The Pin: How The Raspberry Pi Gets Its Audio

  1. Does anyone know (or have a o-scope screenshot) of the “PWM” out is truly a PWM signal or a (much better) PRN (noise) modulation signal?Not complaining, but I am surprised at how shitty the audio quality is from the RPI. You can hear the aliasing plain as day – especially if the volume is low.

      1. HI Gordon, thanks for the tip. But since you probably are the Director of Engineering of the Raspberry Pi, and this article is specifically about explanation of the RPi’s analog audio output circuitry, as there are several conflicting advices in the comments, please could you bring some more definitive answer and actual facts about this electronic circuit design ?

  2. Great article! I had to study the topic while working on ZeroPhone and adding audio to it – especially given that I use my ZP for music a lot, and I’m now working on adding out-of-the-box audio streaming sink support to it (AirPlay-receiver like). Some remarks:

    – The 1.8K resistor on the output is not addressed – I personally would love to know about what it’s for. Loading the output somehow? Working as a high-pass filter as well?
    – The 270/150 and 220/100 resistors also work as a voltage divider, dividing 3.3V output (either after a buffer or before it) into a ~1V signal, which was originally meant to produce “line-level” audio. I can’t really explain it well because I don’t know much about line levels, but here’s what Adafruit says: “R21 and R20 are voltage dividers to get the 3.3V signal down to about 1.1V max (that’s the max peak-to-peak voltage you want for audio line level.”
    – The large output capacitor also works as the DC blocking capacitor – so that your line-ins/headphones only get AC and not DC waveforms they tend to dislike. Again, referring to the Adafruit guide ( https://learn.adafruit.com/adding-basic-audio-ouput-to-raspberry-pi-zero )
    – The buffer not only provides a lower-impedance source – which is necessary after all, since even though Pi audio was never advertised for headphone output, people keep plugging headphones into it. The main problem is that 3.3V line is noisy because of CPU and peripherals’ activity. As a result of this, each time the CPU is doing something – like loading a new MP3 file from the SD card and parsing it – you hear noise in the headphones (unless there’s no active application doing anything with audio, then the snd_bcm2835 driver sets the audio output GPIOs low). To combat that, the filter is actually powered from a separate low-noise LDO (with 2.5V output on A+/B+/2B and 3.3V on 3B/3B+) – you can see it listed on the last schematic as AUD_3V3.
    (Note that I personally like listening to the CPU noise – it’s kinda interesting to hear when your device’s doing something, like processing an SSH login. However, I assume that people building more consumer-facing devices don’t feel that way ;-P )

    Hope this comment helps further explain the topic. One small point – I’m quite sad I can’t plug a Tindie link to my recently developed Pi analog audio experimentation breakout – yet =) While it’s likely inferior to an I2S DAC in terms of sound quality, it does allow you to add clean audio at the expense of 2 GPIO pins and minimal software problems. I’d publish it on Tindie by now, but I haven’t yet got one assembled (as I only recently got some 47uF capacitors from China). But mainly, I can’t wait to see if there are audible differences in frequency responses with different schematics – especially given that audio output is quite important for ZeroPhone.

    1. 1.8K resistor provides a DC path to ground on the output side of the capacitor. This gives an effective DC bias of 0 volts. The 1.8K is not critical, as it just needs to be >> the source impedance driving the output at signal frequencies, which it is.

    1. Ethernet being already on the USB bus, any heavy network transfer will degrade your audio. . If one wants any decent audio output on the Pi, one have to use I2S, ideally with DMA (if you have some channels left).

    2. Try telling mobile phone owners this. They are in uproar because they don’t understand bthe limitations on onboard audio stage. The inline DAC on the phones without jack sockets bring music alive, but they won’t ever get as far as hearing that, their preconceptions stop them.

  3. Has anyone tried using the PWM to control some half bridge drivers for directly driving speakers? That should theoretically work, just limited in quality since the Pi’s PWM output is not particularly high resolution.

    1. Speaker is not a motor, don’t treat it like one. Speakers have complex impedances and really, really hate square waves. However H-bridge configuration is done by bridging two class D amplifiers with proper output low-pass filters.

      1. Many class D amps use a H-bridge configuration. And in “filterless” class D amp chips the speakers get the square waves, they are not asked if they like it. :-)

    2. If you enable the SDM audio (other people have mentioned in the comments), it runs the PWMs with a ~780 kHz carrier and 7 bit resolution. This could go straight into an off-the-shelf H bridge driver.

      Noise shaping pushes the quantisation noise up out of the audio band. The quantisation noise floor ends up around -95 dB, which is more or less CD quality. I remember reading about this in a thread on the Pi forums.

      Wrt filtering, you can get away without it (speakers only have a finite bandwidth anyway), but if you are really looking to gild the lily, you could build a simple passive filter like an LC Butterworth. Speakers are complex loads, you will want to do some LTSpice when you design this circuit.

  4. ” high-pass filter’s 100R and 47uF give it 33Hz.”
    Errrm. No! The HP filter is the 4.7uF together with the 1.8K in parallel with the load (more exact, there is some source impedance over there as well, but will be well below the 1.8K, so that should be dominant). So the corner should frequency be much smaller in case you use active speakers.

    1. Electrobob, you’re right. Just imagine a case of infinite load impedance (at the older Pi scheme) – the “highpass” corner frequency limits to zero! The circuit analysis idea is principially bad. The right analysis says, that there’s a PWM smoothing and level adjusting first order lowpass in a form of a resistor divider R21 and R20, together with a C20 – and a simple DC decoupling capacitor C48. No highpass at all.

      At the “PI3” there is somethig looking like a highpass, made of C58 and R61 – but its corner frequency is out of the audible band. Thus, the correct view is the DC decoupling capacitor again – and a “DC zeroing” resistor at the output to eliminate the “plug in” pops.

    1. Not just a 1-bit DAC, but the second-simplest to explain and second-worst-sounding kind of 1-bit DAC.

      Delta-Sigma converters are also 1-bit DAC, and you can get really nice results out of a 5th order one.

      1. You can enable SDM audio on Pi by putting audio_pwm_mode=2 in your config.txt

        This runs a sigma-delta controller with noise-shaping error feedback on the VPU (i.e. in software!). You get about 15 1/2 bits of resolution by enabling this.

  5. I’m kind of a noob to electronics (teaching myself), but I really don’t think the Nyquist rate applies here (unless the output is intended to go into something that is sampling at ~14khz). Every class D amplifier schematic I’ve seen has a low pass filter with the cutoff frequency well above 20khz so that the frequency response is flat throughout the audio band.

    The lowpass filter here seems terribly low. I’m guessing it’s because the PWM can’t switch at a proper high frequency?

  6. For a couple of bucks (and I am being generous here), I can get a USB sound card delivered to my door, that also includes the USB connector, a couple of female jacks, and an LED, all inside of a plastic case.

    I wonder how much does Adafruit save on each RPi by using a PWM instead of a dedicated chip.

    1. 1) Adafruit doesn’t produce RPis, you might be thinking about Raspberry Pi Foundation 2) those USB cards don’t have good sound, as I’ve found out 3) it’s probably a whole bunch cheaper – especially initially, with Pi 1A/1B, when it only cost the same as adding 5 items to the BOM 4) there’s only one USB host port, so audio would require a USB hub on a Pi A, as opposed to simply employing two by-default-unused PWM channels.

      1. 1) I stand corrected, thanks.

        2) On the other hand, I’m completely satisfied with mine: I can play MP3 files (using a TA2030 amplifier and a couple of speakers) and not distinguish them from a CD.

        3) It can’t believe it’s “a whole bunch cheaper” when the full item (plus other parts you would not need) does not cost more than a couple of bucks (literary).

        4) It does not have to be USB-based, I’m sure there are other methods to connect a DAC.

  7. Unfortunately the explanation of the filters is not correct. The low pass filter has the impedance of the voltage divider (parallel connection of the 2 resistors, 96 Ohm) as working resistance. This gives a corner frequency of 96kHz.
    The 10µ cap is only for DC blocking, it’s working resistance as a filter is the input impedance of the following stage (e.g. 47kOhm) or headphone (e.g. 32 Ohm). So it is no well defined filter.

    1. Also, a 32 Ω headphone voice coil is not interchangeable with a 32 Ω resistor. It’s electrically inductive, and mechanically resonant.

      However, when you consider the board space and BoM cost of one of these boards, it’s a pretty good solution.

      Look at the price of a 3.3V rail-rail input-output dual op amp on your favourite distributor. Then ask what you would have to sacrifice on a *computer* where parts, board manufacture, board assembly, testing and margin all add up to $35 plus tax.

      Also ask: is it worth it, when most use cases are covered by HDMI audio?

  8. Pete’s original design was only meant to be a line-out and suffered noise due to the fact the IO bank driving the PWM signals was noisy (as others have pointed out).

    My goal for the B+ was to reduce the output impedance so that headphones were usable (so had to drive 32R ‘phones at acceptable volume) and to cure the switching noise.

    For the record the correct analysis is (looking at the AUDIO_L channel of the Pi3):
    – The buffer is driven from a low-noise supply (LDO) to avoid coupling general GPIO bank noise into the audio.
    – R16 (220R) in parallel with R17 (100R) drops the 3V3 output to ~1V and provides an output impedance of R16//R17=68.75R which forms a low pass filter with 3dB point at ~23kHz with the 100n cap.
    – C58 (47u) is sized to give adequate bass response when driving low impedance (32R) loads (and was the largest already-used cap value).
    – Each buffer can source/sink up to 25mA but at that level dissipates quite a bit of power – max DC output current was set at ~10mA (3.3V/(220R+100R)).
    – R61 (1.8K) is simply to make sure the line-end of the output cap is biased to 0V so avoid clicks/pops when plugging in an audio sink. As has been pointed out this just has to be significantly larger than the output impedance of 68.75R – 1.8K was just a convenient already-used value.

    As others have mentioned headphones both change the response of the filter and provide a complex load and therefore can’t be simply equated to a 32R resistor – however in practice it works well (and of course it was tested with various sets of headphones to make sure human ears approved!).

    A side note – I removed the BAV99 protection diodes as these are not really necessary – the energy of an ESD strike will easily be buffered by the R and absorbed by the large Cs in the signal path well before it can do any damage to the upstream silicon.

    I would definitely suggest adding:
    audio_pwm_mode=2
    to config.txt to enable the Sigma-Delta modulation mode which gives near CD quality output.

    1. James, thank you and Gordon for having responded to the call, it’s excellent to have those insights direct from RPi engineers in the discussion !

      The Sigma-Delta modulation mode is nice to have. I’ve found this topic where it is detailed : https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=195178
      I was looking forward to study the software implementation in the driver (like the noise shapping) but couldn’t find it, looks like it’s in the firmware which is closed source… Still, your developper [jdb] gave some hints : https://www.raspberrypi.org/forums/viewtopic.php?t=171588

    2. Gosh. It doesn’t get much closer to the horse’s mouth than that! Thank you very much, I really appreciate your coming back with the inside story on what I tried to describe from the outside.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.