The Tooba
 All Data Structures Namespaces Files Functions Variables Macros Pages
The Tooba Documentation

The Tooba is an electronic musical instrument built into a piece of PVC tubing (hence the name). It borrows principles from the Moog-style analog music synthesizers of past decades.

![Video demo of the instrument](http://img.youtube.com/vi/QGhZ0tecp60/0.jpg)

Way back when, one of my friends in high school was a guy named Dave Wilson whose father got him into 1970s-era Moog-style analog electronic music synthesizers. Dave created a museum of historical synthesizers in his home in Nashua, New Hampshire. Throughout our high school and college years, we exchanged ideas and circuits and bits of lore for various synthesizer hacks.

Music synthesizers of that era were actually special-purpose analog computers, performing arithmetic operations with integrators, summers, and other such circuits. These computations can be performed digitally by a microprocessor or special-purpose digital circuit (e.g. FPGA). So Dave and I both at various points and in various contexts wrote code to do that.

Sound generation in the Tooba (and keyboard scanning and voice assignment) is done in C++ running on a 32-bit ARM microcontroller.

Status, plans, etc

The first PVC prototype, the one shown at Providence on Aug 8th 2015, did all sound generation in the interrupt handler. More recently, the interrupt handler only transfers audio samples from a queue to the microcontroller's on-chip 12-bit DAC, and sound generation occurs in the loop() function.

Teensy 3.1 info

Earlier prototype

I want to read the GPIO in assembly to accurately measure the period of the oscillator. This code ran on the June prototype and measured the capacitance of the touch sensitive keyboard. The capacitance was used in the RC time constant of a free-running oscillator and the idea here is to get a measurement roughly proportional to the period.

  1. Set counter to zero.
  2. If input is LOW, go to step 7.
  3. Wait for a falling edge. Proceed when input is LOW.
  4. Increment counter while waiting for rising edge. Proceed when input is HIGH.
  5. Increment counter while waiting for falling edge. Proceed when input is LOW.
  6. Go to step 10.
  7. Wait for a rising edge. Proceed when input is HIGH.
  8. Increment counter while waiting for falling edge. Proceed when input is LOW.
  9. Increment counter while waiting for rising edge. Proceed when input is HIGH.
  10. Return counter.

So that piece is assembly, and then in C you choose a touch contact and call that function. That should ensure that you read the keyboard about as fast as it can be read. The code for this is buried in the sandbox directory.

1 static int measurePeriod(void)
2 {
3  // Step 1, set up registers
4  int count = 0, x = 0, mask = 1 << 17, addr = 0x400ff050;
5 # define READ_INPUT "ldr %1, [%3]\n" "ands %1, %1, %2\n"
6 # define INC_COUNT "add %0, %0, #1\n"
7  asm volatile(
8  // Step 2, if input is low go to step 7
9  READ_INPUT
10  "beq step7" "\n"
11  // Step 3, wait for falling edge
12  "step3:" "\n"
13 
14  ... lots more code ...
15 
16  "step10:" "\n"
17  : "+r" (count), "+r" (x), "+r" (mask), "+r" (addr)
18  );
19  return count;
20 }

This works well in both the Arduino/Teensy IDE and in the online ARM C++ compiler.