Touch MIDI Controller

Aluminum sheets -> Pro Trinket -> MIDI OUT

Generates MIDI notes based on skin contact between people and skin contact on the aluminum sheets. Responds well to squeezes and varies over different parts of the body.

More video and photos coming soon.

Composer Tony Marasco experiments with the Touch MIDI Controller at Signal Culture in Owego, New York. ---->


Sewing Machine Inductor Synth

MIDI Controller -> Teensy 2.0 -> ST-M5045 Microstep Driver -> Nema 34 Stepper -> Bass pickup -> FX pedals/Amp

The code we used was a very slightly modified version of Randolph Voorhies' midimotor code available here.


SquIDI USB MIDI Controller

USB MIDI CC controller

(4) HC-SR04 distance sensors -> Pro Micro. Github link. Code requires Ralf Kistner's Arcore available here. Each HC-SR04 sends MIDI CC data on its own channel for a total of 4 channels (102-105, MIDI CC channels that are typically unused). 

Check the shop to buy a fully assembled SquIDI with 3-D printed enclosure or a kit (does not include enclosure).


Drum Pad MIDI Station

Piezo transducers with 5.1v zener diode, 1Mohm resistor in parallel with a 330ohm resistor in series from positive to Teensy 3.1 analog input  (10 pads, one set per pad).  21" diameter circle split into 10 pads, two pads have FSRs (force sensitive resistors) on their supporting feet so that you can press down on the pad and simulate pressing down on a drum skin to obtain a different note than what the drum is tuned to. There are also (4) HR-S04 ultrasonic distance sensors mounted on a standard mic stand attachment to generate MIDI CC data based on hand motions and stick motions. Paul wrote a program in SuperCollider to play grains and samples with this MIDI controller. More photos, schematics, code and video coming soon.

Super Collider code from the demo- uses only four pads  (sample list should be adjusted accordingly):

MIDIIn.connect(0, 3);

~sampleList = [
    "/home/paul/Music/samples/Take\ Me\ In\ The\ Back.wav",

~audioBuffers = ~sampleList.collect { |samp|
        channels: [0]);

SynthDef(\grainSynth, { |audioBuffer, trigBus, rate=1|
    var trig =;
    var grain =
        numChannels: 2,
        trigger: trig,
        dur: 1/2,
        sndbuf: audioBuffer,
        rate: rate * 0.5,
        pos: ( * 0.05) + ( / 750)
    // grain =, 0.01, 0.1) + grain;[0, 1], grain);

~trigBusses = ~audioBuffers.collect { Bus.control(s, 1) };
~grainSynths = ~audioBuffers.collect { |buf, index|
    Synth(\grainSynth, [
        \audioBuffer, buf,
        \trigBus, ~trigBusses[index]

NoteOnResponder.removeAll; { |src, chan, num, value|
    var index = num.switch(
        36, { 0 },
        37, { 1 },
        41, { 2 },
        42, { 3 }
    ~grainSynths[index].set(\rate, 1);


Kegelsynth Kegel controlled Teensy Synthesizer

Flex sensors ->  Teensy 3.1 -> Audio shield

This was based on Konkasynth by Bharat Bushan Konka but modified to use a flex sensor instead of the HC-SR04 ultrasonic distance sensor. The flex sensor is mounted inside the controller and has a standard unbalanced 1/4" jack soldered on to make it easier to remove and clean. The Konkasynth is great you can read about it and find Fritzing files/links to code here


MIDI Umbrella

Converts signals generated by raindrops into MIDI data. Harder drops make lower notes. 

6 piezo transducers -> Adafruit Pro Trinket -> MIDI Out

More photos, code and video coming soon.


Analog Light Theremin

Standard 555 IC  square wave photo-resistor theremin

Audio, video and schematic coming soon.


MIDI Vibrator Inductor Synth

MIDI input circuit -> Arduino -> Orgasmatronics Hack Off -> Standard 3v vibrator.


Click on images to enlarge.



Rhythm bones with conductive copper strips. This video uses Teensy 3.1 into Super Collider.

More photos and video to come.



Code for Teensy 3.1:

#define bonePin 20
#define accPinX 5
#define accPinY 17
#define ON LOW

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>

// GUItool: begin automatically generated code
AudioSynthNoiseWhite     noise1;         //xy=146,384
AudioFilterBiquad        biquad1;        //xy=292,389
AudioEffectEnvelope      envelope1;      //xy=501,421
AudioOutputI2S           i2s1;           //xy=700,408
AudioConnection          patchCord1(noise1, biquad1);
AudioConnection          patchCord2(biquad1, envelope1);
AudioConnection          patchCord3(envelope1, 0, i2s1, 0);
AudioConnection          patchCord4(envelope1, 0, i2s1, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=647,611
// GUItool: end automatically generated code

volatile int state = 0;  // 1 = playing, 0 = off

// maps a delay from the accelerometer to a frequency in Hz
int mapFilterFreq(int val) {
  static const int minv = 3600;
  static const int maxv = 6600;
  return constrain(map(val, minv, maxv, 80, 8000),
                   40, 16000);

// An interrupt handler that runs when the bones start and stop touching each
// other.
void bonesISR() {
  int sensorVal = digitalReadFast(bonePin) == ON;
  if (state == 0 && sensorVal == 1) {
    state = 1;
  } else if (state == 1 && sensorVal == 0) {
    state = 0;

void setup() {
  pinMode(bonePin, INPUT_PULLUP);
  pinMode(accPinY, INPUT);
  pinMode(accPinX, INPUT);
  // Serial.begin(9600);
  // run ISR once whenever bones circuit opens or closes.
  attachInterrupt(digitalPinToPort(bonePin), bonesISR, CHANGE);

  biquad1.setLowpass(0, 500, 1);

void loop() {
  // set filter frequency based on accelerometer tilt.
  // Serial.println(pulseIn(accPinX, HIGH));
                     mapFilterFreq(pulseIn(accPinX, HIGH)),



Dental impression trays with transducers and audio

jacks. The harder you bite, the louder it is

(especially lower frequencies).