Archive for the ‘Random’ Category

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

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?).

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); = 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); = 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();"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.

Ikea-hacking a better workspace

What’s better than slightly improving your workspace? Not much! Inspired by this Ikea hack, I tore down my old Jerker desk and set upon building a new one.


Goodbye Jerker, hello Besta

The original hacker’s basic idea was to start with a Besta shelf unit, which has all kinds of add-ons. Saw your shelves down a little and mount them on rails from a matching drawer unit. I added a keyboard stand to mine, made out of a wall shelf and some Vika Kaj adjustable table legs. I also installed some Dioder multicolored LEDs, just cause they’re awesome.

The brilliant part is that, while you need to be able to reach all your controllers, you don’t need to reach them all at the same time. You can store them compactly tucked into the unit and just slide out the ones you want.  As awesome as my Jerker desk was, this setup has a significantly smaller footprint while keeping all my gadgets accessible.

If you are considering building this hack yourself, here are some tips:

  • Sawing the shelves down to size was surprisingly easy, although it takes a while and my arm got kind of tired. You can use the bottom of the drawer from which you took the rails as a sizing guide– it’s exactly the right width. Since the shelves are fiberboard, the side facing down as you saw is going to get a little ugly, so plan accordingly.
  • Mounting the rails on the shelves was slightly more difficult than I anticipated.  First, it’s easy to get confused about how to orient the rails.  Second, it’s a little tricky to drill holes in such a thin piece.
  • The most difficult part was installing the other half of the rails into the shelf– it’s really hard to operate a screwdriver around the rear holes. Ironically, this is the part actually sanctioned by Ikea.
  • Binder clips can keep your cables neat as you slide stuff in and out.

My latest band-crush

It’s Suz:

Information seems to be scarce and in Italian.  I’m not even sure if Suz is the name of the band or the singer.  But I’m quite enjoying this record.

Siouxsie vs New Order

Everyone loves a mashup:

In other news, I’m on SoundCloud now! Let’s be friends.

Pandora Potluck

For when you have guests.

1. Everyone writes down the name of one artist (in secret).

2. Create a new Pandora station from all the listed artists.

3. No song skips!  (Thumbs up are OK.)

Happy 909 Day

Last year Tom at Music Thing (RIP)1 had a nice bit for 808 day.  Those are big shoes to fill, but I couldn’t let 9.09.09 pass without a mention.

I tried to think of some quotes about the 909 but drew a blank.  The 808 was as common in hip-hop as in techno, while the 909 is exclusively a house and techno machine.  I enjoy listening to hip-hop, but I don’t really feel connected to hip-hop culture.  But I do feel like techno, and electronic music more generally, is part of me, not just something to consume but something to participate in.  Perhaps that why I am so fond of the 909.

Here’s Daft Punk:

Here’s Jeff Mills:

1. RIP to the blog, not to Tom.  As far as I know.

MS Paint MPC

Sorta hard to explain, so just check it out.

MS Paint Adventures is one part webcomic, one part crowd-sourced old school adventure game.  You probably should read/play the current story/game from the beginning.