Tiny battery-powered 2×2 active mixer

This is the second in my series of tiny audio accessories: a pocket-sized two channel stereo mixer. It fits in an Altoids tin and lasts approximately forever on a pair of AA batteries.

There also two output jacks; I like to send one to speakers and the other to a recorder.

If you try to build this yourself, please let me know about it!



I am not a professional electrical engineer. Use these designs at your own risk. That said, I am pretty happy with this design and it more or less works exactly how I want it to.

The provided PCB is laid out for surface-mount components. I personally think soldering surface-mount components is no harder than through-hole, but the process is quite different and it was a little intimidating at first.




Get the .brd file or order boards from OSH Park.

Design notes

Power supply

I wanted to use AA batteries for a low profile, but the VCA requires a minimum 8V supply, so I used a boost converter. I selected the TI/National LMR62014 mainly because it’s cheap and readily available. The ratio of R16 to R17 sets the output voltage; I’m aiming for about 9.5V to provide a little headroom. The TLE2426 splits the boosted voltage to create a virtual ground, letting us simulate a bipolar power supply.


The core of this mixer is the COOLAUDIO 2164 quad VCA, and this circuit is pretty much straight out of the datasheet.

Recall the design of a simple summing inverting amplifier:


The current through R1 is I1 = V1/R1, and the current through R2 is I2 = V2/R2. The op amp input wants to sink zero current, so the only remaining path for the current I1 + I2 is through R3. That makes Vout = -1 * (I1 + I2) * R3; if we choose R1 = R2 = R3, then Vout = V1 + V2.

The 2164 is a current amplifier, so that means we can just drop in the middle of the summing amplifier design to add a gain control. Referring back to our mixer schematic, R1 controls the original input current, the VCA scales it according to the control voltage, and the op amp pulls it back through R9 to convert the signal back to a voltage.

The control voltage is -33 mV/dB, with ground giving unity gain. R14 – VOL1 – R15 sets up a voltage divider where the wiper on the pot can tap into the middle. Ideally the gain range would be something like -60 dB of cut and up to 6 dB of gain, but I also wanted to stick to common resistor values. The actual range ends up being something like -70dB to +3 dB, which is just fine for my purposes. We can apply the same control voltage to two channels to get a proper stereo gain control. No messy dual-gang pots required!

C14 smooths out gain changes a tiny bit; this prevents pot noise from turning into audio distortion.

You could add as many VCAs as you wanted to this circuit to make more channels.

Output stage

There are two output jacks and I just tied them together.

Of course, there are two unused op amps, so you could add an independent buffer for the second output. I ran into some trouble routing the board in that configuration, so I decided the lazy approach was probably good enough.

Parts list

You can get almost everything from Mouser. The VCA chip, however, is pretty difficult to find. The big distributors don’t carry it, so you have to hunt around specialist distributors.


4x battery clip Mouser
4x 1/8″ audio jack Mouser
Switch Mouser
16-pin DIP socket Jameco (or, if you want to get everything from Mouser try this one; I think the footprint is the same, but this is not exact one I used)


TLE2426 rail splitter Mouser
LMR62014 boost converter Mouser
COOLAUDIO 2164 VCA Small Bear
TLV2374 op amp Mouser


6x 30K resistors Mouser
4x 499Ω resistors Mouser
2x 10K resistors Mouser
3x 1.5K resistors Mouser
1x 88K resistor Mouser
1x 13.3K resistor Mouser
100μ capacitor Mouser
4x 1μ capacitors Mouser
2x 0.1μ capacitors Mouser
4x 560p capacitors Mouser
4.7μ capacitor Mouser
2.2μ capacitor Mouser
330p capacitor Mouser
10μ inductor Mouser
2x 10K linear pots Mouser


Indicator LED Mouser
Schottky diode Mouser

Portable battery-powered mic preamp

I am SUPER INTO the current trend of tiny musical instruments (OP-1, Volca series, Pocket Piano, etc). I’ve built a few accessories to complement my collection. Some people at the Operator-1 forum have expressed interest, so I thought I’d share the designs. I hope to provide enough information that you can make your own.

In this case, I wanted to use a pro microphone with the OP-1. So I designed a small, battery-powered mic preamp with an 1/8″ output.



I am not a professional electrical engineer. Use these designs at your own risk.

The design has no phantom power, and therefore will only work with dynamic microphones.

I had a bit of a brainfart when I designed the output stage, and the result is that it won’t work plugged into a balanced input. The preamp works great with the OP-1, but you might get funny results if you plug it into a pro mixer or such.

The provided PCB uses some surface-mount components, which require a different soldering technique from through-hole electronics. If you can do through-hole soldering, you can probably learn surface-mount, but it is different. I highly recommend using a hot air tool, but it is theoretically possible to do it with a plain old soldering iron as well.


Click for full size:



I shared the project on OSH Park, where you can download the .brd file or order PCBs.

Design notes

I can’t really take any credit for this design as it’s more or less straight out of the INA217 datasheet.

Power supply

The TLE2426 is a nifty IC for converting a single voltage into a bipolar power supply. It finds the midpoint voltage of its two inputs, and then you can pretend that’s ground. Your 9V battery then looks like a +/- 4.5V bipolar supply.

D1 is for reverse protection. D2 is a power indicator. If you use the same LED I did, it’s SUPER bright, so feel free to replace R5 with a slightly bigger resistor. You can swap in your favorite color of LED instead, just adjust R5 to match. C5 is for smoothing the power supply. This circuit is not very power hungry, so you don’t need much; 47μ is probably plenty. I happen to have a giant bag of small 100μ caps so that’s what I use.


This is a totally standard application of the INA217 preamp.

R6 is the gain potentiometer; it should have a reverse-log (also called reverse audio) taper for smooth control. Unfortunately, it’s backward: fully clockwise is minimum gain, fully counterclockwise is maximum gain. I could not find a suitable arrangement that gave me both a nice gain curve and conventional operation, so I chose the gain curve.

R2 sets the maximum gain at about 60 dB.

Output stage

There’s a 1/4″ and 1/8″ output, each of which has its own op-amp buffer. Even though the schematic says 4227, you should use a rail-to-rail op amp like the TI 2374 instead. (This is a case where I didn’t really know how to use Eagle yet.)

It was kinda dumb of me to give the tip and ring of the 1/4″ output independent buffers with the same signal. This is really confusing to a balanced input. I never bothered to fix this, because I mainly just connect the 1/8″ output to a stereo line input and that works great.

Parts list

You can get almost everything from Mouser. There are a couple random things that I got from other suppliers, mainly because they matched the parts that happened to be in my Eagle library. Feel free to substitute, just check the data sheets carefully.


9V battery clip Digi-Key
8-pin DIP socket Jameco
Neutrik XLR/TRS combo jack Mouser
1/4″ output jack Sparkfun
1/8″ output jack Mouser
Switch Mouser


TLE2426 rail splitter Mouser
TLV2374 op amp Mouser
INA217 instrumentation amplifier Mouser


10K reverse log pot Mouser
2x 2.2K 0603 resistors Mouser
10 ohm 0603 resistor Mouser
1.5K 0603 resistor Mouser
4x 1μ capacitors Mouser
100μ capacitor Mouser


Indicator LED Mouser
1N4148 diode Mouser

Paranoid Android by Radiohead for solo piano

Trying to sharpen my piano skills a little bit.

How to set up 16-bit PWM with an Arduino Uno / Atmega328

No fuss working example:

void setup() {
  // Set PB1/2 as outputs.
  DDRB |= (1 << DDB1) | (1 << DDB2);

  TCCR1A =
      (1 << COM1A1) | (1 << COM1B1) |
      // Fast PWM mode.
      (1 << WGM11);
  TCCR1B =
      // Fast PWM mode.
      (1 << WGM12) | (1 << WGM13) |
      // No clock prescaling (fastest possible
      // freq).
      (1 << CS10);
  OCR1A = 0;
  // Set the counter value that corresponds to
  // full duty cycle. For 15-bit PWM use
  // 0x7fff, etc. A lower value for ICR1 will
  // allow a faster PWM frequency.
  ICR1 = 0xffff;

void loop() {
  // Use OCR1A and OCR1B to control the PWM
  // duty cycle. Duty cycle = OCR1A / ICR1.
  // OCR1A controls PWM on pin 9 (PORTB1).
  // OCR1B controls PWM on pin 10 (PORTB2).
  OCR1A = 0x0000;
  OCR1A = 0x8000;
  OCR1A = 0xffff;

PWM will be on pin 9 running around 250 Hz (16MHz / 2 ^ 16 = 244 Hz). This assumes you don't care about correct phase, etc. If you do, hit up the data sheet.

This will break any Arduino library functions that depend on TIMER1 (the servo library, and maybe some other stuff?).

OP-1 + Volca Keys

Lady got me a Volca Keys for Christmas. Just playing around.

I have a new look

This blog has had the same theme for about 8 years, and it looked pretty dated. Thus I made this new one. This theme is “responsive,” which means it looks good even if you have a really tiny screen, which, I’m told, is what the kids are into these days.

What do you think?

I haven’t quite polished all the bits so some things still look weird. I’ll fix them when I get to them!

Some credit

The color scheme is “OceanSandBeachParty” by Suzana_K. Thanks for putting a bunch of rad color palettes on the internet for free, Suzana_K! I owe you one.

If you want to be “responsive” too, you should read this handy book.

Livid Alias 8 remote script for Ableton Live 9

I found myself in need of a basic mixer-type control surface. I’m quite fond of my Ohm64, so I picked up an Alias 8 from Livid.

Livid Alias 8

This is my Alias 8.

Oddly, they don’t seem to have an official Live 9 remote script. So naturally I wrote my own.

What does it do?

Each channel strip is set up like so:

  • Top knob is unassigned– MIDI map to whatever you like.
  • Bottom knob is pan.
  • Fader is level.
  • Top button is solo/cue.
  • Bottom button is arm.

The big fader is master volume. The encoder, when in CC mode, scrolls through the tracks.

That’s it! If you want to do straightforward record-and-mix type work, this is the map for you.

How does one get it?

It’s on github!

If github ain’t your thang, download here: Alias8.zip

To install on Mac:

  • Unzip the Alias8.zip file.
  • Find and open your Live app bundle. (Right-click and choose “Show Package Contents”)
  • Go to Contents -> App-Resources -> MIDI Remote Scripts.
  • Drop the “Alias8” directory there.

The script should also work on Windows, but I don’t know how to find your MIDI Remote Scripts directory.

NOTE: This script assumes the encoder above the master fader is in relative (infinite) mode. Out of the box, it’s configured in absolute mode, so you’ll need to change it. The easiest way to do so is with Livid’s web editor.


Mooradian custom keyboard bags are wonderful

If you have an oddly-sized instrument, and you take it out of your house more than rarely, you should get a custom bag from Mooradian.

Way back in January or so my faithful microKorg died and I replaced it with a Waldorf Blofeld. I picked up a generic 49-key keyboard bag to go with it. This bag was crap. First, the bag was way too big for the Blofeld, making it floppy and awkward to carry. Second, the flimsy hardware on the strap broke within a couple weeks.

Long story short, a couple months ago I stumbled across Mooradian, who will make a variety of bags to order. I ordered a bag for the Blofeld. It came to under $200 delivered and arrived in about 4 weeks.

Mooradian custom keyboard bag for Waldorf Blofeld Keyboard

The Blofeld in its nest

The hardware and craftsmanship are top quality. Most importantly, the difference from the ill-fitting bag to the properly-fitting bag is shocking. My instrument feels ten pounds lighter, probably just because it doesn’t shift around when I carry it.

Mooradian custom keyboard bag for Waldorf Blofeld Keyboard

All zipped up

I recommend them highly.

A JavaScript spectrum analyzer

My friend asked me if I could make a music player with a spectrum analyzer for his web page. I’m like, I dunno? Can I?

I can make a spectrum analyzer in my sleep, and browsers can do some audio stuff these days, right? So, maybe?

I can make a spectrum analyzer in my sleep

Here’s how you make a spectrum analyzer. First, run your original signal through a few parallel bandpass filters. The range of human hearing spans about 10 octaves, from 20 Hz to 20k. If we want a 5-band display, we’ll place our bandpass filters at 2-octave intervals. This gives us centers at 40 Hz, 160 Hz, 640 Hz, 2.5k, and 10k.

Filter design is super interesting and fairly complex, but implementing a basic bandpass filter is shockingly simple.

Now we’ve got five (or whatever) new audio signals. We compute the power of each band and draw a bar for each one. There are some details around how you compute the actual size of the bars to make them look good, but that’s the main idea.

Easy! NEXT

Browsers can do some audio stuff these days, right?

Yes, but with difficulty. Dropping in an audio player is straightforward with the audio tag. Codecs are a bit muddled– Firefox won’t play MP3; Safari won’t play Vorbis. But in the grand scheme of browser quirks, this one is charmingly easy to deal with.

Here’s how you implement it:

<audio controls preload="auto">
<source src="/spectest/metal_star.ogg">
<source src="/spectest/metal_star.mp3">

We specify both sources so that all browsers can play at least one. And presto:

This is cute, but to add a spectrum analyzer to our player, we need access to the raw PCM stream. The problem is thorny.

In Firefox

Firefox’s Audio Data API makes it easy. Your audio element will fire a MozAudioAvailable event for each little chunk of sound it plays. Create an event listener, and your callback can process the stream however you like. Like this (I use Cobra cause I like it):

var Biquad = new Cobra.Class({
  __init__: function(self, freq, q) {
    var omega = 2*Math.PI*freq/44100.0;
    var alpha = Math.sin(omega)*(2*q);

    self.b0 = alpha;
    self.b1 = 0.0;
    self.b2 = -alpha;
    self.a0 = 1 + alpha;
    self.a1 = -2*Math.cos(omega);
    self.a2 = 1 - alpha;

    self.y1 = self.y2 = self.x1 = self.x2 = 0.0;

  next: function(self, x) {
    var y = (self.b0 / self.a0)*x +
      (self.b1 / self.a0)*self.x1 +
      (self.b2 / self.a0)*self.x2 -
      (self.a1 / self.a0)*self.y1 -
      (self.a2 / self.a0)*self.y2;
    self.y2 = self.y1;
    self.y1 = y;
    self.x2 = self.x1;
    self.x1 = x;
    return y;

var bands = [
  new Biquad(40.0, 1.0),
  new Biquad(160.0, 1.0),
  new Biquad(640.0, 1.0),
  new Biquad(2560.0, 1.0),
  new Biquad(10240.0, 1.0)

function updateSpectrum(ev) {
  var fb = ev.frameBuffer;
  var sumsq = [0.0, 0.0, 0.0, 0.0, 0.0];

  for (var i = 0; i < fb.length/2; ++i) {
    /* average to get mono channel */
    var center = (fb[2*i] + fb[2*i+1])/2.0;

    /* feed to bp filters */
    for (var j = 0; j < 5; ++j) {
      var out = bands[j].next(center);
      sumsq[j] += out*out;

  for (var i = 0; i < 5; ++i) {
    /* calculate rms power */
    var rms = Math.sqrt(2.0 * sumsq[i] / fb.length);

    /* update bar */
    var db = 6.0 * Math.log(rms) / Math.log(2.0);
    var length = 450 + 10.0*db;
    if (length < 1) {
      length = 1;
    var bar = document.getElementById("bar" + i);
    bar.style.width = length + "px";

var audio = document.getElementById("player");
audio.addEventListener("MozAudioAvailable", updateSpectrum, false);

You can see it in action here.

Brilliant! Hopefully WebKit provides an equally easy solution.

In WebKit

Nope! WebKit is implementing the Web Audio API. This API sorta works like a modular. You create chains of AudioNode objects which act as sound sources or processors. There are a bunch of prefab AudioNodes, or you can write your own.

Chrome implements at least part of the Web Audio API. So do Safari nightlies, and I presume Safari 6 will as well.

My plan was to connect an audio element to a custom AudioNode, which would use the same spectrum analyzer code from the Firefox example. This plan was foiled when I discovered that the MediaElementAudioSourceNode, designed to provide integration with the audio and video tags, is silently unimplemented in Chrome. You can create one, but it will just feed you a steady stream of zeroes.

For now, it appears that the preferred solution is to re-implement the audio tag yourself using an XHR and an AudioBufferSource. Which is insane.

Our updateSpectrum only changes slightly:

function updateSpectrum(ev) {
  var fb = ev.inputBuffer;
  var outb = ev.outputBuffer;
  var sumsq = [0.0, 0.0, 0.0, 0.0, 0.0];
  var inputL = fb.getChannelData(0);
  var inputR = fb.getChannelData(1);
  var outputL = outb.getChannelData(0);
  var outputR = outb.getChannelData(1);

  for (var i = 0; i < inputL.length; ++i) {
    /* average to get mono channel */
    var center = (inputL[i] + inputR[i])/2.0;

    /* copy to output */
    outputL[i] = inputL[i];
    outputR[i] = outputR[i];

    /* feed to bp filters */
    for (var j = 0; j < 5; ++j) {
      var out = bands[j].next(center);
      sumsq[j] += out*out;

  for (var i = 0; i < 5; ++i) {
    /* calculate rms amplitude */
    var rms = Math.sqrt(sumsq[i] / inputL.length);

    /* update bar */
    var db = 6.0 * Math.log(rms) / Math.log(2.0);
    var length = 450 + 10.0*db;
    if (length < 1) {
      length = 1;
    var bar = document.getElementById("bar" + i);
    bar.style.width = length + "px";

But we need a bunch of new rigmarole to wire up the sound:

var context = new webkitAudioContext();

var processor = context.createJavaScriptNode(512, 1, 1);
processor.onaudioprocess = updateSpectrum;

/* get the sound via http */
var req = new XMLHttpRequest();
req.open("GET", "/spectest/metal_star.mp3", true);
req.responseType = "arraybuffer";
req.onload = function() {
  var audio = context.createBuffer(req.response, false);
  var source = context.createBufferSource();
  source.buffer = audio;

And here’s the Chrome edition of the demo (warning: autoplays).


I quite like the Mozilla Audio Data API. The Web Audio API strikes me as overdesigned.

I hate Flash with the fury of a thousand suns scorned, but given this Byzantine thicket, I understand why developers use it.


If you like the song in the demos, download it here.

The oxygen’s too heavy

in your lungs to be let out:

Of Recordings is proudly powered by WordPress
Entries (RSS) and Comments (RSS).
Color palette by Suzana_K.