Drum Auto-Transcription

This project will record a rhythm played on a drum pad in tablature notation on a USB thumb drive and as serial to PC output by interfacing a Phidgets 1104 vibration sensor with an mbed microcontroller. An audible sound will be played and a visual LED will be shown as a hit confirmation for the user. Both sound and notation will vary with the strength of each drum hit.

/media/uploads/M_quettan/_scaled_20121011_132454.jpg

The image above shows the mbed processor connected to the vibration sensor and speaker. A driver is necessary for the proper amount of current to be supplied to the speaker from the mbed.

/media/uploads/M_quettan/_scaled_20121011_132446.jpg

This image shows the vibration sensor attached to the drum pad on which a rhythm will be played.

Connections:

mbed to vibration sensor

mbedSensor
p15Analog
GNDGround (0v)
VU (5v)Power (5v)

mbed to USB

mbedUSB
VIN (4.5v - 9v in)Vcc
p32D-
p31D+
gndgnd

mbed to driver to speaker

mbedMOSFET DriverSpeaker
gndgnd
VU (5v)JP2-1 RAW
P26JP2-3 Control
JP1-1Negative
JP2-2Positive

Toggle write and Toggle sound switch

mbedflip switch
p8out (write toggle)
p9out (sound toggle)
VOUT (3.3v)in (write toggle)
VOUT (3.3v)in (sound toggle)

Demo Code:

The demo code below will enable the mbed to receive an analog input from the vibration sensor and will record when the sensor is being vibrated enough to register as a “hit” on the drum pad. Once a hit is determined, the proper notation will be printed to the serial output of the USB as well as to a file named “tablature.txt” on your favorite USB memory drive in the following format:

/media/uploads/M_quettan/taboutput.jpg

This current implementation records 16th notes at 30 beats per minute. It is entirely possible for multiple hits to occur in between this count. If multiple hits occur between printing, the hardest hit is printed.

There is a switch implemented which will flag whether or not the device should enable sound and another for if the device should close the file which is being written on the USB and break the while loop, ending the program. These flags are labeled as variables within the code as "sound" and "write" respectively.

main.cpp

//****************************************************************************
// Zak Gamache and Marcus Quettan
//
//Drum Machine
//      - Write tablature based on input from user playing on a drum pad
//      - Playback sound relating to user input
//****************************************************************************

#include "mbed.h"
#include "MSCFileSystem.h"

#define FSNAME "msc"
MSCFileSystem msc(FSNAME);

// Unused AnalogIn inputs set as DigitalIn to reduce A/D noise
DigitalOut noise1(p16);
DigitalOut noise2(p17);
DigitalOut noise3(p18);
DigitalOut noise4(p19);
DigitalOut noise5(p20);

DigitalOut led1(LED1);      // Hit strength level 1
DigitalOut led2(LED2);      // Hit strength level 2
DigitalOut led3(LED3);      // Hit strength level 3
DigitalOut led4(LED4);      // Hit strength level 4

DigitalIn write(p8);        // USB Write Control: Push - Stop Write
DigitalIn sound(p9);        // Switch to enable playback of sound
PwmOut driver(p26);         // PWM to control sound volume
AnalogIn piezo(p15);        // Input from vibration sensor
Serial pc(USBTX, USBRX);    // mbed Serial over USB
Ticker PrintMe;             // Used to print tablature at a regular interval

int flag;                   // Hit tracker: 1 - Hit, 0 - No hit
int count = 0;              // Separates time frames
float voltage;              // Voltage from piezoelectric vibration sensor
int writeNow = 0;           // Write every so often


// File I/O for tablature
FILE *tabFile = fopen( "/" FSNAME "/tablature.txt", "w");

//****************************************************************************
// Keep (musical) time and tell program to write
//****************************************************************************
void printNote()
{
    // Tell the program to write
    writeNow = 1;
}

//****************************************************************************
// Main Program
//      - Continuously read vibration sensor and scale to a hit strength
//      - Call ticker actions at a regular interval
//****************************************************************************
int main()
{
    // Flash lights and print error if file not opened
    if ( tabFile == NULL ) {
        error("Could not open file for write\n");
    }

    // Setup pullup resistor for sound switch
    sound.mode(PullUp);
    write.mode(PullUp);
    wait(0.01);

    // Print to the tablature every half second (slow quarter note)
    PrintMe.attach(&printNote, 0.50);

    // Run forever
    while(1) {
        // On switch toggle
        if (!write) {
            fclose(tabFile);        // Close file
            tabFile = NULL;         // Set file pointer to null
            pc.printf("Exit");      // Alert user to exit
            break;
        }
        voltage = piezo;

        // 1 - Softest Hit
        if ((voltage >= 0.495 && voltage < 0.515)) {
            if(flag < 2) {
                flag = 1;
            }
            led1 = 1;
        }
        // 2 - Soft Hit
        else if ((voltage >= 0.515 && voltage < 0.530)) {
            if (flag < 3) {
                flag = 2;
            }
            led2 = 1;
        }
        // 3 - Hard Hit
        else if ((voltage >= 0.530 && voltage < 0.550)) {
            if(flag < 4) {
                flag = 3;
            }
            led3 = 1;
        }
        // 4 - Hardest Hit
        else if ((voltage >= 0.550)) {
            flag = 4;
            led4 = 1;
        }
        // 0 - No Hit
        else {
            led1 = 0;
            led2 = 0;
            led3 = 0;
            led4 = 0;
        }

        if (writeNow) {
            if (tabFile) {
                if (count == 0) {
                    pc.printf("\n\n"
                              "1 e & a 2 e & a 3 e & a 4 e & a || 1 e & a 2 e & a 3 e & a 4 e & a"
                              "\n");
                    fprintf(tabFile, "\n\n"
                            "1 e & a 2 e & a 3 e & a 4 e & a || 1 e & a 2 e & a 3 e & a 4 e & a"
                            "\n", flag);
                }

                // If a hit has occurred
                if (flag > 0) {
                    // Print the strength value of the hit to the tablature
                    if (count == 16) {
                        pc.printf("|| %i ", flag);
                        fprintf(tabFile, "|| %i ", flag);
                    } else {
                        pc.printf("%i ", flag);
                        fprintf(tabFile, "%i ", flag);
                    }

                    // Changes sound output pitch based on strenght of hit
                    if (flag == 1) {
                        driver.period(0.005);
                    } else if (flag == 2) {
                        driver.period(0.0075);
                    } else if (flag == 3) {
                        driver.period(0.01);
                    } else {
                        driver.period(0.015);
                    }

                    // If sound is enabled, set the volume
                    if (sound) {
                        driver = 0.005;
                    } else {
                        driver = 0.0;
                    }

                    // Reset hit tracker and time keeper
                    flag = 0;
                    count += 1;
                    // If no hit has occurred
                } else {
                    // Print an empty note to tablature
                    if (count == 16) {
                        pc.printf("|| - ", flag);
                        fprintf(tabFile, "|| - ", flag);
                    } else {
                        pc.printf("- ", flag);
                        fprintf(tabFile, "- ", flag);
                    }

                    // Make sure the volume is 0 and increment the time keeper
                    driver = 0.0;
                    count += 1;
                }

                // Separates tablature time frames
                if (count == 32) {
                    count = 0;
                }
            } else {
                pc.printf("File Not Open\n");
            }

            // Don't write until next tick
            writeNow = 0;
        }
    }
}

Warning!

Do not power off or unplug your USB drive without first flipping the switch to close the tablature file!

Import programDrumAuto-Transcription

ECE4180 Drum Auto-Transcription Project

Below is a demo video of the device. As can be seen in the video, even when the drum pad is not being hit, a few erroneous hits are being registered and written. These erroneous hits are also played as sound.

Problems:

The vibration sensor used is very sensitive and registers vibration from the environment. The drum pad and vibration sensor must be placed on a surface with minimal vibration that is isolated from the mbed and speaker. Your computer causes a lot of vibration! Unless this sensor is in a vacuum, you will observe a generous amount of erroneous “hits” due to the vibration sensor’s sensitivity; so expect some erroneous hits. Rapid changes in air pressure, the rattling of your table, and footsteps of nearby people are all possible causes for erroneous hits.

Improvements:

With more time and resources, the biggest improvement would have been to re-build the vibration sensor in such a way that it is built to be placed onto a flat surface. The build design of the piezoelectric sensor for this implementation requires us to tape it down so that it will not move, it would be ideal if we could place it on the surface like a quarter.

Also, as opposed to only outputting a simple PWM signal to the speaker, a .wav sound of an actual drum hit could be used instead. This would provide the ability to create an electronic drum pad out of any drum pad! Also, a play-back feature would add additional functionality to our device.

To enhance both the sound and tablature output, writing to the MIDI format would be beneficial. This would provide a more standardized sound and tablature notation.


Please log in to post comments.