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.
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.
“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.
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.
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.