Cirrus Logic audio card for the Raspberry Pi revisited

Cirrus Logic Audio card for Raspberry Pi

There is more green space and trees around me where I am now, with many more garden birds, though no sparrows1, and occasionally some tawny owls in the night.

Tawny owls, recorded ME66 handheld

So thoughts turn to a garden recording gizmo again. I have enough power, and a network connection to a shed, a oddly wind-sheltered location and many trees nearby. For short term recordings in the field I am still in favour of the timed field recorder approach, but for the garden where I have power and data the Pi still scores. You don’t have to fiddle with it, it’s entirely remote controlled. Many years ago I had a PC in the garage which was the music server, I used a piece of software called loop recorder on that. This cat fight is one of my favourite urban recordings from that time.

although I was really trying to record a hedge full of sparrows. A loop recorder lets you go back and catch things like that, and the microphone would be much closer to the area where the owls are.

So I thought I’d revisit this Cirrus Logic audio card, particularly as a case for a Pi with this mounted was being sold off cheap for £5

The Cirrus is the only audio card for the Raspberry Pi that lets you record sound with it, as opposed to the legion of DAC cards for the Pi. You can, of course, use a USB sound card instead, though that precludes using a Model A if you want to use wifi and have the lowest power.

The good news is that a hero hacker, Matthias Reichl, has sorted out the drivers, it’s now a RPI-update rather than patching kernels and esoteric crap.

The bad news is that the manufacturer discontinued the card 🙁 Having said that, it still seems to be available for about £60 if you work hard enough, GIYF. That’s dear – a Behringer UCA202 is a good Pi compatible USB sound card for about £24, line level input. The Cirrus Logic card offers a bit more sensitivity and on board mic bias.

Installation process

It’s not absolutely futz-free, though it’s far better than it used to be. I’ve never managed to blow a Raspberry Pi board, so I have a fine collection of old boards from my Pi history, the very first one is still in service collecting sensor data.

For this job I will select a Raspberry Pi B+ with Ethernet, the first model with the 40-pin GPIO and the HAT physical format, because that’s what the Cirrus wants. I could use an A+, but I want Ethernet, because paradoxically trunking WiFi to the shed with some patch antennas works fine but doesn’t give me WiFi at the shed, and I want lots of USB connectors spare, because I will probably be recording using real spinning HDD, because – well SD cards burn out whereas spinning metal seems to last. Plus the latter is fast, although recording audio really shouldn’t be an I/O challenge even for SD these days.

  1. Get new raspi-stretch lite, load without card attached
  2. works, enable ssh, enable key, test key login
  3. sudo apt-get update, sudo apt-get upgrade
  4. Now visit http://www.horus.com/~hias/cirrus-driver.html and do as the man says
  5. sudo nano /boot/config.txt, can the internal audio and add the line as instructed
  6. sudo nano /etc/modprobe.d/cirrus.conf, add line
  7. wget http://www.horus.com/~hias/tmp/cirrus/cirrus-ng-scripts.tgz, make bin directory, do it
  8. sudo shutdown -h now, wait for green blinkenlights, pull power and attach card
  9. Restart Pi, log in
  10. execute the bin/Record_from_Linein_Micbias.sh file, which terminated silently

Now I run alsamixer, knowing that I have killed off the internal sound card. I’m only interested in record, if I wanted just play I’d go buy myself a cheap DAC HAT and save myself a ton of trouble. Don’t even think of using the F4 button to switch to Capture, use the arrow key to get to the relevant section and then the tab key to select in section, because alsamixer is ratty and will crash if you press F4. You get this

This baffling mixer setup ain’t the half of it

but in fact what you actually want is all the way to the right, so make with the right arrow key, past all that equaliser crap

all the way to the right is the interesting stuff

The implication is that I am looking at IN3L and IN3R, because IN1L,R and IN2 L,R are set to 0, and hopefully nobody’s tossing anything in on DIG 1,2,3, although in a perfect world it would be nice to see them set to 0 too. Nice that the noise generator is set to 0, though the noise gate is worrying, apparently that means

Noise Gate Threshold: [dB Gain: -90.00]

What that means in real life, well, your guess is as good as mine, but I’ll leave it well alone for now.

To get to record from the card you need to know what you’re recording from, so I set 1kHz tone going in and do this

arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: RPiCirrus [RPi-Cirrus], device 0: WM5102 AiFi wm5102-aif1-0 []
 Subdevices: 1/1
 Subdevice #0: subdevice #0

It’s either RPiCirrus or it’s RPi-Cirrus, I’ll save you the experimentation, it’s the former

arecord -Dhw:RPiCirrus -r 48000 -c 2 -f S16_LE -d 5 testy.wav
Recording WAVE 'testy.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo

when I FTP the result off the Pi and look at it I get

Recorded 1kHz tone

Which looks OK – there’s a slight phase difference and the usual DC bump at the start – try and start recording at least a quarter second of deadspace to let that die off.

So it does basically work, with a stock Pi with a minimum of fiddling about. Win.

Adjusting levels

The nominal gain of IN3 is 8dB (displayed as 16). If I crank it all the way I can get up to 31dB, displayed as 100. So I will try that on IN3R.

Looks good, about 23dB difference

This confirms IN3 is the input I am dealing with. I wasn’t really able to convince myself the mic bias ever came on. I could have had this information easier if I’d used the Source, because in the file rpi-cirrus-functions.sh is the section

# input base names
headset_in="IN1"
dmic_in="IN2"
line_in="IN3"

but where’s the fun in that, eh? You can find the original of the scripts on Github. Apparently Matthias’ sterling work is all to do with LibreELEC which is designed to be just enough OS to run KODI, so the fact that recording is looked at at all is impressive, since you don’t normally record anything with a media server.

buffer overruns
arecord -Dhw:RPiCirrus -r 48000 -c 2 -f S16_LE -d 600 testy.wav
Recording WAVE 'testy.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
overrun!!! (at least 80.227 ms long)
overrun!!! (at least 250.903 ms long)
overrun!!! (at least 372.018 ms long)
overrun!!! (at least 388.525 ms long)
overrun!!! (at least 1433.851 ms long)
overrun!!! (at least 186.375 ms long)
overrun!!! (at least 25.032 ms long)
overrun!!! (at least 970.541 ms long)

Everyone and his dog starts off recording to the same SD card that the OS is on, and you get buffer overruns. There are all sorts of reasons why you shouldn’t record audio to the OS SD card, but overruns seems to be the obvious one. This thread seems to confirm this, the OS is busy with the SD card at times so it can’t write your audio.

So I mounted a USB stick. You get to run as sudo because you’re writing to a device, there’s probably a way to fix that but for now I’ll run with it

sudo arecord -Dhw:RPiCirrus -r 48000 -c 2 -f S16_LE -d 300 testy.wav
Recording WAVE 'testy.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
overrun!!! (at least 268.754 ms long)
overrun!!! (at least 373.587 ms long)
overrun!!! (at least 48.686 ms long)
overrun!!! (at least 273.932 ms long)

Nice try but no cigar. How about using FLAC? It reduces the IO, but it also offers the possibility of using jstsch’s massive interpass buffer trick.

arecord -c 2 -f S16_LE -d 130 -r 44100 | flac -o test1.flac - -f

flac 1.3.2
Copyright (C) 2000-2009 Josh Coalson, 2011-2016 Xiph.Org Foundation
flac comes with ABSOLUTELY NO WARRANTY. This is free software, and you are
welcome to redistribute it under certain conditions. Type `flac' for details.

Recording WAVE 'stdin' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo -: wrote 3680289 bytes, ratio=0.160

Hmm, looks OK2 without the buffer on the USB drive for 5 mins (set to 48k to be the same as previous ones where it barfed). Flac gets the sudo this time because it has the job of writing to the USB stick.

arecord -c 2 -f S16_LE -d 600 -r 48000 | sudo flac -o test1.flac - -f
Recording WAVE 'stdin' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo

flac 1.3.2
Copyright (C) 2000-2009 Josh Coalson, 2011-2016 Xiph.Org Foundation
flac comes with ABSOLUTELY NO WARRANTY. This is free software, and you are
welcome to redistribute it under certain conditions. Type `flac' for details.

-: wrote 41235318 bytes, ratio=0.358

input buffer trick (onto the normal disk)

arecord -c 2 -f S16_LE -d 5 -r 44100 --buffer-size=192000 -f dat -t raw | dd bs=480000 | flac -o test1.flac - -f --endian=little --channels=2 --sample-rate=44100 --sign=signed --bps=16

which seemed to go OK for the 5 sec duration, so if it turns out I need it I have the command line. It’s a lot of faff to go to if it’s not needed.

Analogue issues

There are three problems with using this for an electret mike:

  1. The mic bias doesn’t work
  2. sensitivity is low, it is a line input after all. OTOH I can boost it by 23dB
  3. I tested it playing from a Behringer 302 sound card main mix output (phono unbalanced) in parallel with the input to an amplifier. I hear a distinct change in tone and level for the duration of the recording, not huge, but implying the input impedance of this is low. Behringer claim these outputs are 470Ω

It occurred to me that if the circuit conditions change such that I can hear a difference with it bridged across a 470Ω bus, perhaps the mic bias also only comes on on record. Measurement confirmed this, an open-loop voltage of 2.7V appears if I execute Record_from_Linein_Micbias.sh, but only for the duration of the recording. It seems I need a deeper understanding of the analogue performance of this board.

At maximum gain (100) I applied 133mV p-p (~47mV rms) which when replayed was -2.8dBFS, so 0dBFS ~ 64mVrms

That’s low sensitivity for a mic input, typical electrets will give 25mV/Pa @1kHz. Trouble is 1Pa is pretty damn loud, a diesel truck at 10m. Conversational speech at 1m is 2% of that, about 34dB down. You’ll get some signal if you holler at at electret mic with mic bias on, but the birds won’t shift the needle on the dial. I am probably about 40dB off. Sure, it’s a digital system and you want 12-20dB of headroom to 0dBFS, but that’s still a shortfall of 30dB, I want a mic gain of about 30 times.

My microphone is going to be about 20 yards from the Pi. I had fondly thought it would be as simple as running a coax cable with mic bias out to the mic from an input more sensitive than this. If I need to amplify, I may as well run the Pi at the lowest sensitivity and make the head amplifier work for its living.

Which would also work for running the Pi with a standard USB sound card like the Behringer UCA202, which is a line level sensitivity one… This project has metamorphosed from a Pi project to a remote mic preamp project. I am ok with the Pi side of things now, once I get the case, time to box the sucker up, and think about a gizmo to sort out the mic interface. If I take a typical audio coax cable I get a capacitance of 340pf/m, so 20m of that will be 6.8nF.

Your typical electret is a audio variable current source developing a voltage across the plug-in-power bias resistor of about 6k8 in parallel with the input impedance of the amplifier input. Let’s guess about 5k.

Across that is the cable capacitance. The impedance of that 6.8nF is about 1.2k at 20kHz, so it will clobber high frequencies. At least I can feel better about the Cirrus Logic not being sensitive enough to run an electret mic barefoot – things like robins will get rolled off, although the tawny will probably make it OK. I need to do better here.

Interestingly enough, Frank the binaural head guy has used the Cirrus Logic and the UCA202 barefoot with electret capsules, and is doing well. I don’t feel happy with the gain distribution running such a low signal into these cards, but he is out there and doing it… Perhaps I am missing something here, but the sound recordist in me just can’t relate to running a rig normalised to 40dB down on 0dBFS.

He seems to advocate listening at a low level, but somehow I feel it’s good to get the gain up early to capture with a higher SNR and attenuate later if the desire is low SPL. His feed is here, and in fairness ambient noise swamps mic and input stage hiss, which speaks for his technique in Ormskirk anyway.


  1. there are sparrows a few houses down from me, which pleases me. 
  2. There is a possibility in the back of my mind that perhaps piping the output of arecord into flac is masking the error messages to stdout. I don’t know enough about linux to say if that is the case, or how to test it. 

5 thoughts on “Cirrus Logic audio card for the Raspberry Pi revisited”

    1. Inspired by your comment, I tried the verbose version of arecord with the -vv flag. There were overruns because this was ont othe SD card, but not only did I get record level control and a load of useful guff and flag-ups of the overrun, but the flac was fine (other than a glitch audible on the second overrun). Which confirms that errors are displayed, and that they don’t get piped into the flac as garbage.

      For mics in the garden as a loop record the trouble with bluetooth is powering the remote mics. Oddly enough for actual recording manually an issue with BT is the slight delay, which makes monitoring a challenge.

      $ arecord -c 2 -f S16_LE -d 60 -r 48000 -vv | sudo flac -o test
      1.flac - -f
      Recording WAVE 'stdin' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
      
      flac 1.3.2
      Copyright (C) 2000-2009  Josh Coalson, 2011-2016  Xiph.Org Foundation
      flac comes with ABSOLUTELY NO WARRANTY.  This is free software, and you are
      welcome to redistribute it under certain conditions.  Type `flac' for details.
      
      Plug PCM: Hardware PCM card 0 'RPi-Cirrus' device 0 subdevice 0
      Its setup is:
        stream       : CAPTURE
        access       : RW_INTERLEAVED
        format       : S16_LE
        subformat    : STD
        channels     : 2
        rate         : 48000
        exact rate   : 48000 (48000/1)
        msbits       : 16
        buffer_size  : 24000
        period_size  : 6000
        period_time  : 125000
        tstamp_mode  : NONE
        tstamp_type  : MONOTONIC
        period_step  : 1
        avail_min    : 6000
        period_event : 0
        start_threshold  : 1
        stop_threshold   : 24000
        silence_threshold: 0
        silence_size : 0
        boundary     : 1572864000
        appl_ptr     : 0
        hw_ptr       : 0
      ##################################################+| 98%overrun!!! (at least 299.147 ms long)
      Status:
        state       : XRUN
        trigger_time: 392.781707728
        tstamp      : 0.000000
        delay       : 0
        avail       : 24000
        avail_max   : 24000
      ##################################################+| 98%-: 36% complete, ratio=0##################################################+| 98%overrun!!! (at least 1030.215 ms long)
      Status:
        state       : XRUN
        trigger_time: 417.839336910
        tstamp      : 0.000000
        delay       : 0
        avail       : 24000
        avail_max   : 24000
      ###############################wrote 4445088 bytes, ratio=0.386
      
    1. Interesting mod – hat tip for perseverance and ingenuity! The guy using the stacking header makes this less tough. The whole thing has been overtaken IMO by the audioinjector zero which doesn’t need all that microsurgery and is more or less the same price from Amazon. The audioinjector has the same problem of a lack of sensitivity on line in but is otherwise easier to use and a whole lot smaller. Doesn’t have the SPDIF I/O, however.

Leave a Reply

Your email address will not be published. Required fields are marked *