GNU Radio project simplifies building DSP systems, even if they’re not Software Defined Radios. This month, Ed interfaces a pair of microphones with a GNU Radio flowgraph and shows how to aim the mic response around a meeting room.
We recently bought a new car sporting an audio system with a USB jack and a built-in MP3 player. I dumped an assortment of traveling music onto a USB drive, plugged it in, and discovered that the system’s Treble control had absolutely no effect on what I heard, even while sitting in a quiet garage. Unfortunately, the problem was all in my head, not the audio system: these days, my world has no treble and very little midrange.
That’s a continuation of the situation I described in my August and October 2007 columns: the pure-analog treble boost amplifier I built improved several years of concerts, even though the bulky package wasn’t practical for daily use and, alas, became less useful as my treble response continued to drop.
One member of the local hackerspace, who works on weapons-grade RF signal analysis equipment using GNU Radio as part of his day job, suggested that GNU Radio could produce an audio-frequency DSP “circuit” that would run on low-end hardware. Based on that, I decided to see what stock x86-based hardware and DSP software could accomplish, rather than build another pure analog “hearing aid.”
In this column, I’ll describe how I characterized a USB microphone and produced a simple audio beamsteering application with the GNU Radio’s DSP blocks, defining the flowgraphs with the GNU Radio Companion GUI. Even though the hardware is much less portable than my old analog amplifier, some early tests at the local Linux User Group meetings (where deploying strange tech produces interest, not suspicion) produced promising results.
SYNCHRONIZED AUDIO INPUTS
DSP circuits built with GNU Radio normally use radio frequency hardware for the initial RF amplification and downconversion to a practical intermediate frequency. Quadrature-sampling ADCs produce streams of digital data that the PC receives through a USB, PCI, or PCIe interface capable of the required data rate, with increasingly desperate techniques required for high-bandwidth signals. Compared to that, the audio-frequency data processing I need poses no bandwidth challenge at all.
I decided to use the Sound Tech USB-based tabletop conference microphones shown in Photo 1, rather than a pair of analog mics plugged into the laptop, to put the digitization as close to the mic elements as possible. The CM-1000 USB microphone on the left contains the ADC and USB circuitry, with the CM-1000 analog mic on its right plugged into a jack on its rear panel. Both units will produce stereo signals when used separately, but combining them produces a super-stereo USB microphone: each unit acts as a monaural mic, with the USB mic as the Left channel and the analog mic as the Right channel. Placing them along the length of a conference-room table would provide good sound quality, albeit with an unnaturally wide stereo image.
The USB unit samples the analog sound signal from both mics at 44.1 kHz and sends pairs of 16 bit values to the PC. The mics lack a datasheet with a frequency specification, but, even if they’re not audiophile grade, they’re certainly good enough for my purposes.
The GNU Radio flowgraph in Figure 1 amplifies the USB microphone data values from ALSA Card 1 by a factor of 20, then displays the resulting values on an oscilloscope. If you were testing analog mics on your workbench, you’d breadboard a similar circuit from a pair of op amps, with the additional hassle of setting up power supplies and quelling the usual oscillations and noise.
Photo 2 shows the mic responses to an impulse sound produced by rapping a plastic box with a mechanical pencil. Because the initial peak goes negative, I think the analog microphone amplifier in front of the ADC inverts the sign of the audio signal: given the simplicity of an inverting op amp circuit, I can almost see the hardware without dismantling the microphone case. If that matters, you can flip the sign with a negative amplifier gain, which is certainly easier than rewiring an analog breadboard.
Sound waves travel at 344 m/s = 1,130 ft/s in ordinary room air, which means the same sound produces a signal in each microphone at a time depending on the distance from the sound to the microphone. With the center of the mics 300 mm apart, a sound wave requires 870 µs to travel from one to the other:
The traces in Photo 2 came from the same impulse sound produced 2 m to the left of the mics. The 900 µs delay from the blue Left mic to the green Right mic corresponds to a distance of 310 mm:
An impulse sound to the right produced a different delay between the two responses, suggesting that a simple time-of-flight delay wasn’t the only thing going on.
Photo 3 shows the mic responses to an impulse from 1.6 m directly in front, with equal distances to the mic centers. For whatever reason, the Right channel produces a response about 100 µs before the Left channel to a sound that arrives at the same time, which corresponds to a distance of 34 mm. Even if the microphone capsules are at different positions inside the USB and analog units, there’s simply not enough offset to account for that much timing difference. I can’t think of any reason to insert an analog delay, particularly in a cheap microphone intended for a conference table.
However, the delay might indicate something about the microphone’s internal structure. Digitizing the audio data at a 44.1 kHz rate means successive samples occur at 22.7 µs intervals. If the microcontroller has a single ADC input and the firmware must switch an external analog multiplexer between the analog sources for each sample, that delay corresponds to four samples. Allowing the audio signal to stabilize after each switch might account for that much delay.
Compensating for that delay would be a real nuisance on an analog breadboard (ignoring the obvious fact that it’s a digital delay), but requires only a few additional GNU Radio DSP blocks, as shown in Figure 2, to produce the neatly aligned result in Photo 4.
The GUI slider control in the upper left of Photo 4 sets the delay of the Left channel with respect to the Right channel. The default –100 µs delay means that the Left channel should be advanced by 100 µs: you must look ahead to data that might not have arrived.
Because the current version of GNU Radio doesn’t support precognition, the two Delay blocks convert the signed delay into a positive delay for the appropriate channel. A value of –100 µs doesn’t advance the Left channel into the future, it pushes the Right channel into the past by +100 µs. A +100 µs value delays the Left channel, which I won’t need but you might. In each case, the other channel delay becomes 0 µs.
However, the Delay blocks contain queues of samples and require an integer delay value specifying a number of samples, rather than a time delay in (micro)seconds. The snippets of Python code in Listing 1 decide which channel must be delayed, then convert the delay from microseconds into the corresponding number of samples; the top line calculates the Left delay and the bottom line handles the Right delay.
The nearly exact alignment of the two traces in Photo 4 show that a 100 µs delay, which becomes 90.7 µs when expressed as four 44.1 kHz samples at 22.7 µs each, compensates for the offset between the two channels. We’ll never know what actually happens inside that USB microphone, but the evidence so far certainly suggests a monaural ADC alternating between incoming analog audio signals.
Figure 3 shows the geometry behind a simple beamsteering receiver. If the distant source (sketched as a small speaker) was directly ahead, its sound would arrive simultaneously at both microphones. As you’ve just seen, the “circuit” in Figure 2 produces that result, even for microphones with slightly misaligned temporal responses.
However, when the speaker sits at an angle θ to the left of the microphone midline, the additional distance to the right-side mic introduces an additional delay. You saw the limiting case of this situation in Photo 2, with the source at θ = 90° on the far left on the axis between the microphones. In the general case, a simple trig formula relates the additional distance ∆ to the angle q and the distance between the microphones:
The accuracy of that formula depends on the sound source sitting far enough away to produce a nearly planar wavefront at the microphones, which is at least roughly true for practical setups in lecture halls and meeting rooms.
As you saw earlier, the additional distance ∆ produces a time delay between the microphone responses for sounds from that source:
Combine that with the distance equation:
Delaying the signal from the near-side microphone by that amount will synchronize the two signals and cause the sound to appear to come from directly ahead at θ = 0°.
The GNU Radio flowgraph in Figure 4 implements that logic, with one GUI slider setting the Pointing Angle and another controlling the microphone spacing; I’ll discuss the Band Pass Filter blocks later. A test layout with the source at –45° produced the results in Photo 5: nearly perfect alignment for an impulse wavefront.
Although the standard trigonometric convention measures positive angles counter-clockwise from the reference, that makes the GUI slider work backwards: sources to the right of the midline have negative angles that required sliding the control to the left of center. After using that setup for a few minutes, I flipped the sign of the angle so the slider in Photo 5 matches the physical layout: negative angles now correspond to sound sources on the left of the microphone array.
The layout in Figure 3 has an obvious symmetry at q + 90°, with the beam aimed to the left rear of the microphones. One additional mic could resolve this ambiguity by providing another delayed version of the source signal.
Pop quiz: Draw a layout and define the equations.
Photo 6 shows the signals from an impulse sound at –45° with the beam steered to +45°. The equation predicts a 617 µs delay for that layout, but with the wrong sign due to the incorrect beam angle. The physical and computed delays add, so the waveforms have a 1,200 µs offset and don’t combine to form a proper signal.
The Audio Sink block in parallel with the Scope Sink Block routes the output data to the laptop’s built-in sound card, into which I plugged a pair of Bose QC-20 active noise-cancelling earphones to suppress direct sound from the room and put the combined signal in the proper place.
Sitting in the back of the local LUG meeting and guesstimating the Pointing Angle, beamsteering let me focus on the Q&A discussions following the presentation. Separating the mics by 450 mm produced a super-stereo effect that helped emphasize the on-beam source and somewhat suppressed off-beam sounds. Of course, this could be entirely due to the Placebo Effect, where any change must be an improvement, but I had less trouble following the discussions.
The gain of 20 shown in the Multiply Const blocks in Figures 1 and 2 worked well for tests in my relatively quiet home office, but was far too high for a meeting. I added a GUI slider to set the microphone gain in dB, then used this Python expression to produce the linear gain required by the Multiply Const blocks:
The default 10 dB gain corresponds to a linear factor of 3, so the audio starts out much quieter. I limited the maximum gain to 40 dB, a linear factor of 100, because that produces audible clipping on moderately loud sounds. GNU Radio includes several Automatic Gain Control blocks that could eliminate the need for manual adjustments.
SUPPRESSED BACKGROUND SOUND
Many rooms, particularly public meeting rooms, have a fairly high bass noise level from common mechanical and electrical sources: 60 Hz rumble from 3,600 rpm air-handler motors, 120 Hz buzz and 240 Hz hum from magnetic fluorescent ballasts, and so forth. My reduced treble and midrange response makes those low-frequency sources relatively louder in comparison to the high-frequency sounds of speech and music.
The flowgraph in Figure 4 includes a pair of Band Pass Filter blocks and a pair of GUI sliders to set their lower and upper rolloff frequencies. The default 200 Hz and 4 kHz values provide slightly more audio bandwidth than the “communications grade” audio from VHF- and UHF-band amateur radio transceivers.
Using several narrow band-reject filters to eliminate the first few 60 Hz harmonics might produce less audio distortion than simply chopping out the entire bass spectrum, but that’s certainly in the nature of fine tuning.
I find that increasing the high-frequency rolloff doesn’t make much difference in what I hear, which, alas, confirms the evidence provided by our car’s audio system.
Unfortunately, if you think you won’t suffer from hearing loss, you’re probably wrong, so invest a few minutes at any of the Web-based frequency tests to get a baseline measurement for future comparison.
As of right now, a tiny Intel Edison can’t quite run GNU Radio without heroic interventions. I expect that another year or two of tech improvements will produce a “wearable” solution that will certainly be more interesting and useful than a closed-source hearing aid!
GNU Radio, www.gnuradio.org
E. Nisley, “Hearing Clearly,” Circuit Cellar 205 and 207, 2007.
———, “SoundTech CM-1000 USB Channel Layout,” SoftSolder.com, 2016, https://softsolder.com/2016/05/03/soundtech-cm-1000-usb-channel-layout/.
Sound Tech CM-1000 USB and analog microphone set
AAAPrice.com | www.amazon.com/CM-1000USB-CM-1000-Conference-Microphone-Extension/dp/B00U1TOKH4
QC-20 Noise-cancelling earphones:
Bose Corp. | www.bose.com/en_us/products/headphones/earphones.html
Intel Corp. | www-ssl.intel.com/content/www/us/en/do-it-yourself/edison.html
The GNU Radio Foundation | http://gnuradio.org/
PUBLISHED IN CIRCUIT CELLAR MAGAZINE • SEPTEMBER 2016 #314 – Get a PDF of the issueSponsor this Article