Raspberry Pi Zero audio recording with the AudioInjector hat

Just when I thought the remote Olympus recorder is the way to go here, along comes a promising new Pi solution for remote recording – this looks to be low cost and small. What more could a fellow want?

Decent instructions and specs, for a start 😉 Australia seems to have a vibrant electronics tinkering community, and Matt Flax of audio-injector has come up with a dinky little recording sound card suitable for the Pi Zero, without the sort of stupendous kernel-compiling hurt associated with the now discontinued, Wolfson/Cirrus sound card. Matt even used Cirrus tech under the hood, kudos to him for making it work in the Pi environment- I guess the Pi has advanced in standardising add-on gizmos too.

You can buy the AudioInjector Zero from Australia, only to discover postage is about as much as the sound card, so Google helped me discover that you can get it in the UK from Amazon, who drop-ship it at a much more acceptable price of £12.50 delivered free if the total order is > £20. So I go get one.

The Pi Zero sound card – tiny. Look ma, zero connectors!

Nice. No GPIO connectors, though you get a nice bunch of extra audio connectors to make this connect to phono jacks. How does that work, then?

The Pi Zero has the same problem of no GPIO, but at least there’s some rationale, you can use a Pi Zero without the GPIO, but the Zero sound card is as much use as a chocolate teapot without GPIO connector. Ebay was my friend, for some reason CPC don’t do the 40-way header and male pins. So far so good. I then spark up the Pi Zero I had to play with, great, hello world. Howsabout some audio, then?

Unlike the Wolfson, you have a delightfully small amount of choice here, it’s mic or line input. I initially assumed the side marked input was the input, so mic and line were setting the gain and sensitivity, and perhaps the mic bias voltage. But it was not to be, like so many of these audio chips, they assume you only ever want to record mono mics, and the mic input is the mono pads for the electret insert supplied. The chip is the WM8731S, which is from Cirrus/Wolfson, so hat tip to our Australian friends for making this workable in a Pi. However, the block diagram shows there’s only one mic channel, allocated to both sides

so I am SOL on stereo mic capability. In theory I could pick off the mic bias voltage and inject that onto the line inputs with an isolating capacitor, but this seems to be switched with recording, and intelligently – when recording from line it’s not on.

You have two provided scripts, to use mic or line. Alsamixer is reasonably friendly

56 on capture is about right for a 0dBu input level on line, which records in stereo.

Specs – what specs?

Cirrus quote a line level of 1Vrms for 0dBFS as 0dB gain, and I don’t see anything I recognise as an op-amp on the board, so I presume AudioInjector present the line input of the chip straight to the board inputs, they are sketchy on signal levels and all that jazz. Let’s try and get some science into this subject.

You always have to run

alsactl –file /usr/share/doc/audioInjector/asound.state.RCA.thru.test restore

after powering up, else you’re not seeing anything, it doesn’t persist across power cycles. I used a Tek 2245A scope bridged across the signal generator & input.  I ran this for the test

arecord -c 2 -f S16_LE -d 10 -V stereo -r 48000 /run/shm/test.wav

using the temporary RAMdisk to save the SD card. On line in, I get where shown and dBvalue from the alsamixer display, VPPmax is the total peak to peak measured, dBu is calculated from VPPmax

shown db value vPPmax dBu
100 12 0.7 -10.0
93 10.5 0.8 -8.4
87 9 1.0 -7.2
81 7.5 1.2 -5.6
75 6 1.3 -4.3
70 4.5 1.6 -2.7
65 3 1.9 -1.3
60 1.5 2.2 0.2
56 0 2.8 2.0
51 -1.5 3.2 3.3
47 -3 3.8 4.8
44 -4.5 4.5 6.3
40 -6 clip

Below 44 I can’t reach 0dBFS without clipping the input signal, presumably into the input protection diodes. So I didn’t go any further.

Taking the gain=100 I then term the input with a 50 ohm term and record silence. Audition tells me the rms noise is at -84dBFS. If I A-weight it I would probably get down to Cirrus’s -85dBFS in the spec.

Does what it says on the tin, there. The lowest two or three bits are noise. I’m not going to get 0.7V p-p from an electret mic in ambient noise, unless I’m bootlegging a rock concert. I need a mic preamp.

A 5V supply mic preamp isn’t as easy as it looks…

It’s surprisingly tough to come up with a 5V electret mic amp using normal opamps, the LM358 would do but is noisy and notable for crossover distortion. Many decent audio opamps just need more than 5V to do their stuff, I don’t want to put in an inverter for the front-end, although I suppose I could use the control PIC to generate a square wave and use a Cockroft-Walton multiplier, once you get past about 8V the opamp selection opens up widely. Messy.

Then there’s the vexed question of the microphone bias supply – there’s no PSRR at all, because the mic is a sort of audio variable current source working into the drain resistance. You don’t want to be running this off 3.3V running a Pi, perhaps with 100 ohms in series and a 100uF to ground, it ain’t gonna cut enough of the hash out, BTDT.

Fortunately those nice fellows at Maxim have applied themselves to this conundrum with the MAX9812L, and there is an army of industrious folk in Shenzen saving me the faff of laying out my own boards and sourcing the MAX chip, £1.60 a throw from ebay. I need two for stereo, I probably couldn’t start to lay out the board for three times that much. I had hoped the MAX9813 would give me two channels, but no, it lets me select one of two mics. Oh well. If I ever do lay out my own boards then it’s not too much of a hardship to drop in two of these tiny SC70 packages, though hand-soldering them might make me swear.

Maxim spec noise en as 40nV/√Hz which is not stellar, a NE5534A is good for 5nV/√Hz  so the MAX chip is about 18dB worse, not one for dynamic mics then. A fixed 20dB plus the internal 12dB is enough to get a mic up to line level on ambient sounds. The WM8731 measured about -84dB noise on 0.25Vrms in at full gain, so about 14μV rms. The MAX9812’s 5μV across the audio band is a worthwhile reduction of ~9dB in noise, less in practice because of the modest gain.

I could wish for more gain, as it appears the WM8731 noise will still contribute. I am almost tempted in the direction of a single transistor amplifier, which could give me more gain, but the low noise mic bias voltage is a headache, so I’ll only go that way if the MAX9812 is too noisy. The single transistor tends to have a low input impedance of around 2-5k, which will needlessly shunt the electret mic more than the bias resistor, reducing signal levels which is bad for noise performance. Messy in a different way.

This rig needs powering, and I am thinking of using the Pimoroni Zero LiPo for that. This interfaces with the battery and the pi to provide a shutdown on low battery function. This is a way of wiring that to still use the GPIO. This is where I need to hope the AudioInjector doesn’t use GPIO4. It’s likely to use GPIO 2 and 3 with are I2C SDA and SCL to control the WM8731, the sketchy description doesn’t really say much else.

Trials and tribulations of installation

First off, this is nowhere near the amount of grief that the Wolfson and Cirrus were. You’re not installing custom kernels or compiling code from scratch. You have a good chance of getting there, but information is sketchy, IMO. Dunno what it is about recording-capable sound cards for the Pi, but they all seem to assume you are experienced and the documentation  is to that level. Let’s take a look at audioinjector forums. First they say you can get support on github, well perhaps you can, but I am too dense to see how that works. No problem, back to the forums, how to setup and test. Actually the first place I fell was how to solder the audio connectors, which way round should the PCB connectors go? It doesn’t strictly matter as GND is the middle of three pins, but one way the colours won’t match the channels.

Anyway, Matt nonchalantly says download

audio.injector.scripts_0.1-1_all.deb.tar.gz

file, extract and run it. I don’t know how to run a deb file on a Pi, I’ve only used apt-get upgrade and apt-get update. Google is my friend here, fine. So here is where I see guru-dom and a lack of kindness to noobs –

I go tar -xzf audio.injector.scripts_0.1-1_all.deb.tar.gz, to find

-rw-r--r-- 1 pi pi 3864 Jul 24 2016  audio.injector.scripts_0.1-1_all.deb
-rw-r--r-- 1 pi pi 3990 Jul 24 2016 audio.injector.scripts_0.1-1_all.deb.tar.gz

the original is a teeny bit smaller than the tar.gz, so why have that initial step at all?

then I run

sudo apt install ./audio.injector.scripts_0.1-1_all.deb

and it works fine

Reading package lists... Done
Building dependency tree
Reading state information... Done
Note, selecting 'audio.injector.scripts' instead of './audio.injector.scripts_0.1-1_all.deb'
The following NEW packages will be installed:
audio.injector.scripts
0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
Need to get 0 B/3,864 B of archives.
After this operation, 22.5 kB of additional disk space will be used.
Get:1 /home/pi/audio.injector.scripts_0.1-1_all.deb audio.injector.scripts all 0.1-1 [3,864 B]
Selecting previously unselected package audio.injector.scripts.
(Reading database ... 34322 files and directories currently installed.)
Preparing to unpack .../audio.injector.scripts_0.1-1_all.deb ...
Unpacking audio.injector.scripts (0.1-1) ...
Setting up audio.injector.scripts (0.1-1) ...

I kind of figure a reboot wouldn’t do any harm here. Well, it might brick the whole thing, but here goes. He then recommends to run audioInjector-setup.sh, buggered if I can see it anywhere but I try it anyway-

audioInjector-setup.sh
updating the kernel
*** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS and Dom
*** Performing self-update
*** Relaunching after update
*** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS and Dom
*** Your firmware is already up to date

The audio injector sound card is now setup.
Please reboot to enable the correct device tree.

grand. I reboot, then I run the next recommended commands

pi@piZero:~ $ audioInjector-test.sh
couldn't find the sox command please install the sox pacakge
pi@piZero:~ $ sudo apt-get install sox

and get a load of hurt about sox being missing. Some screenfuls of cruft later I get to try again

pi@piZero:~ $ audioInjector-test.sh
play: no process found
arecord: no process found
gpicview: no process found
Recording WAVE '/tmp/test.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo

Encoding: n/a
Channels: 2 @ 16-bit
Samplerate: 48000Hz
Replaygain: off
Duration: unknown

In:0.00% 00:00:03.07 [00:00:00.00] Out:144k [ =====|===== ] Hd:5.9 Clip:0
Done.
/usr/bin/audioInjector-test.sh: line 43: xdg-open: command not found
Recording WAVE '/tmp/test.mic.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo

Encoding: n/a
Channels: 2 @ 16-bit
Samplerate: 48000Hz
Replaygain: off
Duration: unknown

In:0.00% 00:00:03.07 [00:00:00.00] Out:144k [ | ] Hd:5.9 Clip:0
Done.
/usr/bin/audioInjector-test.sh: line 53: xdg-open: command not found
press enter to test again, any other key then enter to exit

I think most of that aggravation is because I am running headless, after a while I get to hear a ghastly noise coming out of the headphones, some sort of pulsed 10k. Now I can still hear 10kHz but I presume audioinjector is in his 20s to have chosen that frequency – what’s wrong with the time-honoured 1kHz, FFS… But it works. And with a lot less hurt than for the Wolfson sound card, but not exactly noob-friendly.

3 thoughts on “Raspberry Pi Zero audio recording with the AudioInjector hat”

  1. “The Pi Zero has the same problem of no GPIO, but at least there’s some rationale, you can use a Pi Zero without the GPIO, but the Zero sound card is as much use as a chocolate teapot without GPIO connector. ”

    There are no GPIO pins on either the zero or the audioinjector zero but the GPIO is present on the zero and used by the AI board. The user must install the connector but several configurations and connector styles are possible so it is not included, except that recently the RPi zero is offered with a pre-installed connector. As either or both can be used by soldering wire connections, your comment is incorrect.

    1. Well colour me unadventurous but the thought of soldering 40 wire connections rather than use the headers really isn’t my idea of fun at all. Sure, the AI may only need power, ground and I2C but there’s still enough opportunity to screw up. Which is why in practice the purchaser has to go out and buy what is an essential component to make this work.

      1. I believe Adafruit has “press-in” type 40 pin headers for the solder-adverse as the RPi zero also ships with no GPIO connectors. There are so many types of headers out there that it would be a problem to choose which one to put into production. Even at that, it isn’t that bad of a job unless you suffer from tremor or loss of vision.

Leave a Reply

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