Posted on 1 Comment

DIY 26 Speaker Ambisonic Dome – Part 3

Software

Back in the 70’s you could buy hardware Ambsonic decoders, such as the Integrex. They were niche, and usually available as a kit you built yourself. Reportedly, they did not perform very well though I’d love the opportunity to hear one to judge for myself. The largest drawback of a hardware solution is that you are tied down to one configuration of speakers. Personal computers have become so inexpensive and powerful that it is easier and far more flexible to drive the dome from a software solution.

The ideal software for cost effectiveness is Pure Data, also known as PD. It’s hard to beat free software for price. This is an open-source solution and comes with all of the benefits and drawbacks of an open product. There is a lot of support and a real community around PD, but if it breaks, you get to keep both pieces and there may be no-one interested enough help you. This is also a good way to describe the current state of Ambisonics in PD, specifically the HOA toolset.

HOA tools from the PD patch repository.

It looks great – it also doesn’t work anymore with the current version of PD and hasn’t worked for years. You could try running it in a version of PD from when it was released, but then you will discover that other parts of PD will not work because they are too old. To borrow a phrase from the Linux community, you are now in ‘dependency hell’ where there is no combination of software versions that will work for everything you want to do.

I’ve run into this problem a lot when developing for Arduino, where it is particularly bad. I often wonder if anyone in the Arduino community actually gets any real-world work done with the products they write about on their webpages. A popular library for processing the output of gyroscopes has an axis completely reversed for some hardware. None of the popular Youtube channels or blogs even noticed and the main library remains unfixed.

With PD reluctantly excluded, we must turn to MAX/MSP and MAX for Live. The HOA tools from PD are also available in MAX, but why make life difficult when the excellent ICST Ambisonics package is available for free in the package manager.

ICST Ambisonics in MAX/MSP

ICST Ambisonics makes a complex job easy. If you know where your speakers are and you know where your sources should be (or you have audio already recorded in a surround format), you can have audio coming out of the array in just a few minutes. My own software stores lists of speaker configurations to suit different rooms. You can select 4, 5, 10, 20, or 25 channels (plus the subs channel).

A simple decoder for playing prerecorded sound through the dome. The speaker array selector buttons are on the right.
My own MAX patch for an Ambisonic mixer/instrument and DMX lighting controller
This one is an interface for an Ambisonic computerised version of Laurie Anderson’s tape bow.
The Ambisonic decoder plugs right into the outputs from your computer. Two FireWire Focusrite Liquid 56s are twin-linked together to create this output set. It all fits within the bandwidth of one single FireWire 400 connection.

Unfortunately, MAX/MSP is NOT an open source product and it is not cheap. I still hope to replace MAX with PD when I have enough time to return to programming for fun, but that time may be never.

Waves NX

Although the dome is portable, transporting it requires several large boxes and about 6 hours of swearing to set it up (if you are on your own). There are some clever tools available to bring something approaching surround sound to your headphones.

Let’s first talk about mix room simulation.

Room simulation tools have been around for a long time. I used to use Focusrite’s VRM (Virtual Room Modelling) until an Apple OSX update made it inoperable. These tools were very polarizing when they were released, many engineers hated they way they sounded. One friend who disliked the effect flipped through the presets, turned it off and on a few times, complaining about how fake and smeared the sound was. If you have the desire to try one of these tools, this is exactly how not to audition one. By turning it off and on and jumping from one room model to another you are concentrating on the differences between the emulation and the reality – you are creating a condition where the emulation cannot win.

At first, I didn’t like the VRM much either, but I left the headphones on and set to work mixing. About fifteen minutes later there was a knock at the studio door and I leapt to the room controls to turn the monitors down. I had been fooled and completely forgot that I wasn’t listening to speakers. The same approach works with Waves NX – don’t dismiss this technology before giving it a fair listen.

Waves NX is step above a static room emulator. It is capable of tracking the movement of your head, either through your laptop’s camera or by using a special bluetooth sender that attaches to the band of your headphones. Some popular headphones have frequency compensation curves built into the plugin. Measure the circumference of you head and the distance between your ears around the back of your head (the inter-aural arc) and waves with use a HRTF (head related transfer function) to calculate what each ear should be hearing as you move your head.

The Waves NX interface. Note the area for entering your head measurements in the lower left.

Waves NX is not kind to your processor if you use webcam tracking, and the positional lag as the camera system chases your face wrecks the effect a little (in a similar way to visual lag ruining Virtual Reality visuals). It does work though, and a slew of competitors are releasing similar products.

DIY 26 Speaker Ambisonic Dome – Part 1, The Dome Structure

DIY 26 Speaker Ambisonic Dome – Part 2, The Audio

Next installment: The Audio Controllers

Posted on

Nichrome wire as a controller input for Max Msp

The bow hair has been replaced with strands of nichrome wire. When the wires are connected by contact with a violin string or another piece of metal they form a conductive loop. The aim is to reliably measure the length of that loop and deduce the position of the bow. The electronics packages also contain gyros and bluetooth modules.

Recently I attempted to create a violin controller that used lengths of nichrome wire to replace the horsehair in the bow. The theory was that I could use the predicable resistance of the nichrome to detect where the bow was contacting a conductive element on the violin bridge. It turned out to be a little more complicated than I anticipated.

28 gauge (0.3mm) nichrome wire (Jaycar). 13.77 Ω/m resistance.

What is nichrome?

Nichrome in an alloy of nickel, chromium and (often) iron. It has high resistivity and is used to construct heating elements. DIY types would know it as the hot wire in a home-made foam cutter. The resistance increases linearly with length – a property I thought would make it ideal for constructing my own sensor.

Turning nicrome into a length sensor

Arduinos, and their clones, make measuring resistances very simple. The usual method is to construct a voltage divider using 5v or 3.3v sourced from the Arduino (or a power supply) and a known resistance (usually something in the order of a few kΩ). There are two reasons why this method will not work with the length of nichrome I am using in my project:

The usual way to measure a resistance with an Arduino. Ideally, the known and unknown resistances need to be similar, but that is not possible with my project due to current concerns.

The sensitivity and voltage range of the Arduino

The change in resistance over the length of nichrome I am using is small – only ~16Ω, and I need to measure that small resistance with the highest accuracy I can get.

Using the voltage divider equation, a divider using, for example, a 1k resistor as the known value will give me a tiny range of 5V to 4.92V on my 5V powered Arduino Pro.

The standard Arduino only has a 10 bit resolution for measuring that input voltage – that’s a 0 – 1023 range, of which I can use ~80 with that tiny change in voltage. To make matters worse, in the real world you sacrifice some of that range to ensure that the values you are measuring are all relevant and all captured. A system set up to use all of the input range has no room for values to slip, components to change, or for just the random behavior that seems to creep into home-built hardware. It is possible, however, to tell the Arduino to use a different measure for comparing voltages.

Input voltages are usually measured against a reference voltage that matches the voltage used to power the Arduino. This is convenient, as the Arduino is commonly the voltage source for sensing attached switches and potentiometers. It is possible to set a different reference voltage inside the Arduino, using AnalogReference(). This approach has some limitations, not the least of which is the lack of uniformity across the range of Arduinos and clones. This project began on an Arduino Mega clone, was installed on genuine Arduino Pro units for the final product and was moved to a Duinotech Nano for one of the interfaces. The second round of hardware has spent some time installed on 3.3v Duinotech ESP32s and a 3.3v Arduino Nano 33 BLE Sense (the sense has an optional 12 bit resolution but uses 10 bits for compatibility).

Lets’s look at the available reference voltages for the family of boards that I have used for the first round. Setting anaglogReference(INTERNAL) gives different results on different boards, some values are only available on Mega boards and the standard value differs between 5v and 3.3v versions of the same boards.

Arduino AVR style internal reference voltages: 
5V (5V power supply) or 3.3V (3.3V power supply)
INTERNAL: 1.1 volts on the ATmega168 or ATmega328P and 2.56 volts on the ATmega32U4 and ATmega8 (not available on the Arduino Mega)
INTERNAL1V1: a built-in 1.1V reference (Arduino Mega only)
INTERNAL2V56: a built-in 2.56V reference (Arduino Mega only)

So why not maximise the voltage available for measurement by using a known resistance similar in value to my length of nichrome? Because that would be very dangerous for my Arduino. The nichrome in the bow forms a loop when the two strands are bridged by a metal contact, so the total resistance would be < ~14Ω when in use (you won’t usually use the very ends of the bow, so you won’t see the full 16Ω). Even if we double that and use a 25Ω resistor, with a 5v source that is is ~200mA (1W @ 5v!). I’ve looked through the specifications for a few models of Arduino, and they have all had a 40mA maximum for IO pins. So how do we do it safely?

Safe sensing

Connecting a constant current source to the Arduino.

We can measure low resistances safely using an external constant current source. R = V / I, so with a known voltage and current we can measure resistance without presenting a risk to the Arduino. The LM317 regulator shown in the diagram provides a known 104mA. We can round this down to 100mA (0.01A) and see that R = 10V. My 14Ω usable resistance range is now a manageable voltage range of 0 – 1.4V of 1.6V total range measured against 5V. That immediately improves the 5V Arduinos measurement resolution to ~287 of ~328. The hardware will be re re-implemented on newer 3.3V modules which improves the Arduinos performance to ~434 of ~496. The 3.3V Nano 33 BLE SENSE has an optional 12 bit mode (0 – 4095) that improves the bow reading accuracy again to ~1736 of ~1984.

Making it Better

There are some easy ways to make the hardware better – the most obvious being altering the current source, but these modules are already built and I’d like them to be useful for other low resistance tasks, so they’ll stay at 100mA for now. There is, however, a simple way of drastically improving the apparent resolution of a hardware sampling system without touching the hardware at all:

Next installment: oversampling

LM317 modules in action:

Bow electronics package. The LM317 is visible on the bottom right.
Another electronics package for the body of the violin, to sense a nichrome replacement for one of the violin strings. The LM317 and 12Ω resistor are visible on the middle right.