Showing posts with label taiko arduino midi. Show all posts
Showing posts with label taiko arduino midi. Show all posts

Tuesday, August 2, 2011

Taiko Synth - Phase 9 - Waveforms

Until now, the taiko drum pad was a simple piece of masonite on a stack of packing foam with some mouse mats on top. A single strike resulted in multiple signals and I suspected it was because of either the masonite resonating, or all the pieces bouncing up and down. I needed some instrumentation.

The first step was to tie the drum pad together in an attempt to hold all the pieces together. I cut a circular base from plywood, then used a hacksaw to cut the foam to match. The foam looks terribly jagged - I think it needed some kind of hot-wire cutter for that. I got some 1/4" shock-cord (at REI, this is what they call this bungee cord) and cord-stoppers (clips used to close up back-packs, etc), then I cut holes in the drum head, foam, and base through which to thread the shock-cord. The hardest part was punching holes in the foam and threading the cord through it. The drill won't cut; the foam just got all wrapped around the bit! Forcing a 1/4" rod through the foam worked pretty well, although it was sill nearly impossible to thread the shock cord through the foam. Once the shock cord was threaded and cinched up, I glued some 2x2s to the base so it didn't rock back and forth on the shock-cord and cord-stoppers underneath. I used Gorilla Glue, which is really strange stuff, attach the 2x2s. As it hardens it foams up like polyurethane and can be a big mess if you use too much. The last step was to attach the mouse mats to the top surface of the masonite with silicone rubber glue.

After all that, it was time to hook it up. I connected a mini stereo plug to the drum and plugged that into the input jack of a laptop running XOscope. This is a pretty neat program. The controls are pretty intuitive, but I'm not going to be able to get any useful amplitude data until I figure out some kind of calibration work-flow. The other thing I didn't do which I should have done was to put some protection on the inputs - I could have damaged the PC's audio circuit - or worse. Note to self: next time be more careful!


Here's a trace of a hard DON strike. Right click and open the graph a new tab to enbiggen it sufficiently. The green trace it the drum head and the blue trace is the rim. You can see that the green trace is clipped, but what I was looking for was how long it resonated for. This way I could know when to start listening for the next strike. The graph shows that the signal took about 75 mS to settle down.

The other thing we can determine is that the resonant frequency is 4/0.02125, or 188 Hz

What I see there is that the drum head needs more damping. I want a single bounce - like when you push down on the fender of your car to see if the shocks are shot.


Below is a plot of a softer strike; one that 's not clipped. From it we can obtain the damping coefficient Tau, or the time it takes for the sine wave component to decay to 0.27 times its origin amplitude. It looks like Tau is about 0.017 Seconds.

The other thing I see in this plot is cross-talk. Striking the center of the drum results in a signal on the rim sensors. Cross talk's roughly (0.25/3.5)*100% or 7% and that's not too bad.


Tapping on the rim shows a quite different crosstalk story. Here the cross talk is (0.5/1.2)*100% or 42%. Something will need to be done to improve this. I think I many need to cut a slot in the foam to separate the rim from the drum pad center, but I'm concerned that the remaining foam will be too thin to support the rim. Maybe the foam will need to be replaced by a stiffer elastomer.


From this base-line data, I'll be able to see if changes I make to the construction of the drum pad improve or worsen its performance.

Friday, July 15, 2011

Sunday, June 26, 2011

Taiko Synth - Phase 8 - Two Channels


On a taiko drum, in addition to striking the head (ドン) you need to be able to play rim shots (カラ). To make a rim, I cut a gap into the masonite. The rim needed to be as wide as a piezo sensor. I used GE silicone adhesive to fasten the piezo sensors to the drum head and rim, then wired each set in parallel (observing polarity) and then to a connector on the rim. I had to change the Arduino/nunchuck interface a little to handle two channels efficiently. That may be the subject of a later post.

In this new configuration, I seem to have trouble with single hits being detected as multiple. Reducing the number of sensors on the head helped. Also increasing the padding on the head of the drum helped. I bought a bunch of mouse mats for that purpose. Still, I think either the masonite board is resonating, or, more likely the board is bouncing up and down on the foam. The best fix I can think of for this is to glue them together, but if I do that, I will no longer have access to the underside of the head, so making changes is going to be difficult.

Anyway, here's the result:

Saturday, April 9, 2011

Taiko Synth - Phase 7 - Basic Improvements

The volume is now proportional to the hit - although I do need to scale it for better dynamic range. Initially I did the scaling like I would in any software application:
outputValue = inputValue * maxOutput / maxInput
The problem is that Arduino only deals with 16 bit integer math. Anything over 32767 is a negative number. By multiplying first, it went over that value so I was seeing negative volume values when I hit the drum hard. Since maxOutput and maxInput are constants with a ratio of about 5, I re-wrote the formula as follows:
outputValue = inputValue / 5
More work needs to be done on scaling; the detection threshold needs to be lower, a peak indicator LED is needed, and I want to be able to use the nunchuck to adjust the sensitivity. The nunchuck is running out of controls, so I'll try to use the accelerometers.


I'm now running the synthesizer software on an HP 1000 mini running Ubuntu 10.04 LTS off of a bootable flash drive.The latency isn't as bad as before. The little netbook works pretty well. I read that there's a low-latency Linux kernel, so I may try that for fun some day.

I changed the synthesizer software is to FluidSynth (http://sourceforge.net/projects/fluidsynth/). FluidSynth needs a soundfont. It can use the General MIDI instruments which include Taiko (channel 117) and a bird (channel 123 - not so useful, but fun).

Here's where I got the sound font: http://packages.debian.org/search?keywords=fluid-soundfont-gm

Once installed, here's how to start everything.
./ttymidi -s /dev/ttyUSB0&
aconnect -i
aconnect -o
aconnect 129:0 a28:0
fluidsynth -c0 -r0 -r22050 -l -a alsa -o audio.alsa.device=plughw:0 FluidR3_GM.sf2

If you are troubleshooting, there's a -v parameter for verbose, that's helpful.



I installed Jack, a GUI device connector, and experimented with that, but I think it's easier to use Aconnect.

Here's a demo of the results:

Saturday, March 12, 2011

Taiko Synth - Phase 6 - Sensing the Bachi

I began with this simple code to detect the strikes, assuming that the start of the first negative slope signal the strongest part of the strikes.
void loop()
{
//polarity - white positive
amp = 0;
ampNew = 0;
don = false;
peak = false;
while(!don)
{
ampNew = analogRead(0);
if (ampNew > 25)
{
don = true;
while(!peak)
{
amp = ampNew;
ampNew = analogRead(0);
if ((ampNew + 1) < amp) // plus 10 for noise compensation
{
peak = true;
printSettings();
}
}
}
}



In the above code, I've had to replace all the "greater than" and "less than" symbols with equivalent HTML entity names, and that seems to work fine. I thought anything with in a code block shouldn't have needed that.

Anyway...

This "don detect" algorithm gave some strange results. The first strike didn't seem to even register. Later strikes weren't proportional to the intensity of the hit. To investigate, wrote new code to capture as much data as possible and send it to Putty via USB serial at 115200 bps.
void setup() {
Serial.begin(115200);
}

void loop() {
Serial.println(analogRead(0));
}



Here are 5 strikes growing in amplitude:







Here's a close-up of the 5th strike:









Some interesting observations can be made. I'm not quite sure of the frequency, because I'm not sure of the sample rate, but you can see that the wave form is a truncated decaying sine wave. That's what one might expect from striking a board with a stick. What's a little surprising is that the first peak is not necessarily the greatest. There is also some dc offset at the end of the strike. From this, the lesson is that I need to change the "don detect" algorithm take the first 15 or so points after a strike is detected. Then, use the greatest of those to determine the peak amplitude. This method may trade latency for accuracy so I may need to tweak the final code a little. It may be a good idea to write more test code to capture these points from within the taiko app to make sure sufficient data is gathered to determine the true peak amplitude. This is because the taiko app surely has a different sample rate than the app above. To address the DC offset, I think I need to make sure that the foam is cut away from beneath the piezo sensor.

Saturday, February 26, 2011

Taiko Synth - Phase 5 - Drum Pad

The first drum pad attempt used 24" diameter, 1/8 thick Masonite with four inches of foam below, and mouse pads on top. I tried a good hard hit, and cracked the board! Second try used two layers of Masonite, 18" in diameter, joined with Gorilla Glue.







A length of 26 GA stranded wire was soldered to a 1" piezo disc. You can get an idea of the polarity and a rough idea of the amplitude by using a DC voltmeter and simply squeezing the sensor. The silver part of the sensor is positive, although that doesn't really matter. The cable and the sensor were glued to the drum pad with GE silicone glue. The other end of the cable was connected to the Arduino input(0) with a 1 megaohm resistor and a 4.7 V zener diode in parallel to protect the Arduino inputs.

Taiko Synth - Phase 4

Lots of folks are talking about multiple nunchucks:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1230499241

I like the idea of using a couple i2c accelerometers from sparkfun the best, I think.
I could attach them to dowels, Y-axis could detect ドン and X-axis could detect カラ. The question is, what is the frequency response of i2c accelerometers? A spongy mount could be used to trade amplitude for frequency. Detecting the a soft note from a loud note may be a challenge, too. I think I'd keep the nunchuck as a controller.


Now that I can select MIDI channel, voice, and note, I've been able to explore timidity. One change I would like to make to my UI is that the setting should change when the joystick passes the threshold, rather than when it it released from the de-bounce routine. Because if this I find I don't know how far to push the joystick to affect a change.

On channel 0, each voice is a different instrument and note changes the frequency. In this way one could change the size of the drum sound.

Taiko related sounds on channel 0,
0,47 Drum
0,73-76, various flutes.
0,78 Shakuhachi - not there!
0,115 Drum
0,117 Taiko - not there!
0,122 Water

Channel 9 is a set of percussive sounds. Changing voice does nothing. Changing note selects various percussion instruments. So far 64 sounds like the best taiko drum. For the first phase, I just need a center hit and a rim shot. Later a shinofue, suzu, and shime would be good. I'd like to run the accompaniment on the PC while playing drums on Arduino.

Too bad a lot of the sounds I want are missing from Timidiy. Oh well, there are other soft synths to try. I think there are .PAT files that Timidity can use, but the web sites that supply these look a little scary.

Here's a video demonstrating what works so far.

Taiko Synth - Phase 3

We need to see the MIDI settings so they can be matched to the sounds from the Timidiy soft synth.

I used a serial LCD display from sparkfun:

http://www.sparkfun.com/products/9393

This is a great unit, and as a bonus, it can display katakana! Check the datasheet:

http://www.sparkfun.com/datasheets/LCD/st7066.pdf

Use the Arduino softserial library to talk to the display, because the main serial port is being used for MIDI. Lady Ada also has a softserial library, but I just used the one that came with Arduino.

Connect the display to power and to data on digital pin 3.

Explore the syth as follows.


C button: Toggle channel 0/9
Joy stick: up/down: change voice (instrument)
Joy Stick: left/right: change note
Z button: play note


I had considered using the nunchuck's built in accelerometer to trigger the note when playing "air drum" style, however that would encourage weaker hitting of the taiko, as you don't want to hold back when playing. Another option: mount the nunchuck and the stick and trigger on detecting the hits. I like this except I would need two nunchucks, and they both operate on the same i2c channel. This solution might need either two arduinos, figuring out to use the i2c library with two data channels, or changing the nunchuck channel.

Here's the code.



/*
* WiiMIDI --
* a06 display change in value as soon as joystick crosses threshold.
*
*
*
*/

#include
#include
#include
#include "nunchuck_funcs.h"

#define rxPin 2
#define txPin 3

int loop_cnt=0;
byte accx,accy,accz,zbut,cbut,joyx,joyy;
int ledPin = 13;
int note_on = 0;
int voice = 47;
int note = 60;
int channel = 9;

SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);

int debounce;

void setup()
{
Serial.begin(115200);
pinMode(ledPin, OUTPUT);
midi_program_change(0, voice);

pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
// set the data rate for the SoftwareSerial port
mySerial.begin(9600);

nunchuck_setpowerpins();
nunchuck_init(); // send the initilization handshake
printSettings();
midi_program_change(0, voice);
}

void loop()
{
delay(1);
nunchuck_get_data();

//accx = nunchuck_accelx(); // ranges from approx 70 - 182
//accy = nunchuck_accely(); // ranges from approx 65 - 173
//accz = nunchuck_accelz();
zbut = nunchuck_zbutton();
cbut = nunchuck_cbutton();
joyx = nunchuck_joyx(); //33L - 133C - 225R
joyy = nunchuck_joyy(); //25B - 128C - 224B

if(cbut == 1)
{
if(channel == 9)
{
channel=0;
//printMsg((char*)"nine");
//printSettings();
}
else
{
channel = 9;
//printMsg((char*)"zero");
//printSettings();
}
while(cbut == 1)
{
delay(100);
nunchuck_get_data();
cbut = nunchuck_cbutton();
//printMsg((char*)"release button");
}
printSettings();
}

if(joyy > 175)
{
voice++;
printSettings();
while(joyy > 150)
{
delay(100); //why does this delay prevent the app from getting hung up?
nunchuck_get_data();
joyy = nunchuck_joyy(); //25B - 128C - 224B
//printMsg((char*)"inc v");
}
midi_program_change(0, voice);
}

if(joyy < joyy =" nunchuck_joyy();"> 175)
{
note++;
printSettings();
while(joyx > 150)
{
delay(100); //why does this delay prevent the app from getting hung up?
nunchuck_get_data();
joyx = nunchuck_joyx(); //33L - 133C - 225R
//printMsg((char*)"inc n");
}
}

if(joyx < joyx =" nunchuck_joyx();" zbut ="="" zbut ="="" zbut =" nunchuck_zbutton();" joyx =" 125;" joyy =" 125;"> 100 )
// { // every 100 msecs get new data
// loop_cnt = 0;
// }
// loop_cnt++;
// delay(100);
}

void printSettings()
{
mySerial.print(0xFE, BYTE);
mySerial.print(0x01, BYTE);
mySerial.print("c:");
mySerial.print(channel);
mySerial.print(" v:");
mySerial.print(voice);
mySerial.print(" n:");
mySerial.print(note);
//delay(1000);
}

void printMsg(char* msg)
{
mySerial.print(0xFE, BYTE);
mySerial.print(0x01, BYTE);
mySerial.print(msg);
delay(1000);
}

Taiko Synth - Phase 2

The sythesizer produces lots of different sounds. I need and easy way to select a sound an listen to it.

There are 127 voices, 127 notes, and 2 different channels.


A Nintendo Wii nunchuck is used to select voices, notes, and channels. It also is used to play the selected sound. An adapter is needed to connect to Arduino.

http://www.sparkfun.com/products/9281

Solder a header to the adapter and plug it into analog inputs 2-5. The "Wire" library will use the use analaog inputs 2 and 3 for power and inputs 4 and 5 as digital i2c I/O.

For a nunchuck libary that makes the interface really easy, here's a link to Todd Kurt's blog.

http://todbot.com/blog/2008/02/18/wiichuck-wii-nunchuck-adapter-available/

Download the Wiichuckdemo. Put the example program and nunchuck_funcs.h in the same sketchbook folder and open them together with the Arduino IDE.

Compile and upload to the Arduino to make sure everything works.

Taiko Synth - Phase I

Taiko drums are quite expensive. I only get to play them in class, but I want to practice at home. Some people just use a large bucket strapped with duct tape, but of course that's not going to sound quite right.

I'm making a variant of the bucket idea, but on top of the bucket with be a soft surface with some kind of piezo or resistive sensor to detect strikes to the head of the drum. Around the edge will be soft plastic tubing (like Tygon), capped at one end and with a small microphone or pressure transducer inserted into the other end. This will be used to detect the カラ hits. An Arduino will detect the hits, and convert them to the appropriate MIDI messages and send them to a PC running a synthesizer application.


The first step is to install the synthesizer onto the PC. I'm running Ubuntu, so I added Timidity from the software archive.

The Arduino is going to need to talk to Timidity through USB serial. Timidity doesn't know about USB serial - it usually receives data from a MIDI controller. Fortunately, Thiago Teixeira has written a excellent tool called ttymidi. It can be downloaded here.

http://www.varal.org/ttymidi/

Grab the whole package. The ardumidi libraray in the package will be useful on for the Arduino part of the system. Extract the ttymidi code and compile it. It's a good idea to read the source code first, just to make sure it's safe. More or less follow the instructions in the readme file.

Copy the ardumidi library folder to the Arduino /libraries folder. Copy the example program to the sketchbook and compile.

Running the Arduino IDE and ttymidi on the same box doesn't seem to work real well because I think they both want to use the same port. It kind of a hassle working on two boxes. I need to look into how to switch back and forth easily.

Now disconnect from you IDE box and connect to the box running Timidity. On my system, Timidity was started automatically so I was able to omit that step.

Start ttymidi.

./ttymidi -s /dev/ttyUSB0 &

It's not always clear what port the Arduino is on, especially if you are disconnecting and reconnecting it. Look in the /dev directory and see how many USB devices there are and try each one if you have to. Also remember process number so you can kill ttymidi when you need to reconnect the Arduino and restart ttymidi.

Now connect ttymidi to Timidity.


aconnect -i
aconnect -o
aconnect 129:0 128:0
or whatever input and output ports are reported respectively.

Restart Arduino and it should start playing notes.