Looking for music data or a way to convert music (makes sense if you read it)

Hi all,

I'm experimenting with Timer 1 on my MEGA2560 R3 and want to either download or generate simple music note data. For example, here's one I put together (to explain what I'm talking about):

const uint16_t notes[] = {
    NOTE_C4, NOTE_C4, NOTE_D4, NOTE_E4, NOTE_C4, NOTE_E4, NOTE_D4, NOTE_G3,
    NOTE_C4, NOTE_C4, NOTE_D4, NOTE_E4, NOTE_C4, NOTE_B3, NOTE_C4, NOTE_C4,
    NOTE_D4, NOTE_E4, NOTE_F4, NOTE_E4, NOTE_D4, NOTE_C4, NOTE_B3, NOTE_G3,
    NOTE_A3, NOTE_B3, NOTE_C4, NOTE_C4, NOTE_A4, NOTE_B4, NOTE_A4, NOTE_G4,
    NOTE_A4, NOTE_B4, NOTE_C5, NOTE_G4, NOTE_A4, NOTE_G4, NOTE_F4, NOTE_E4,
    NOTE_G4, NOTE_A4, NOTE_B4, NOTE_A4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5,
    NOTE_A4, NOTE_G4, NOTE_C5, NOTE_B4, NOTE_D5, NOTE_C5, NOTE_C5,
};

const uint8_t duration[] = {
    2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 4, 4, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 4, 4, 3, 1, 2, 2,
    2, 2, 4, 3, 1, 2, 2, 4,
    4, 3, 1, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 4, 4,
};

The notes are frequency defines (i.e. NOTE_A4 is 440, etc..) and the duration is based on note timing multiplied by a constant to determine music speed. (The song is, by the way, "Yankee Doodle" (or the "Barney" song or if you're old enough to remember, the "Roger Ramjet" song) :slight_smile:

Anyway, I made the above data from sheet music, laboriously figuring it out note by note (because I don't read music).

I've tried searching for "convert notes to frequencies" and "convert midi to raw data" and all other kinds of things and came up with nothing.

If anyone can point me in a direction to easily obtain a few larger test files like this, I would appreciate it.

The format doesn't have to be exact... I can convert it as long as I have note and timing info.

Thanks!

(p.s. here's the whole thing for anyone who wants to play with it):

// note defines stolen from "Tone.h"

#define NOTE_C3  131
#define NOTE_CS3 139
#define NOTE_D3  147
#define NOTE_DS3 156
#define NOTE_E3  165
#define NOTE_F3  175
#define NOTE_FS3 185
#define NOTE_G3  196
#define NOTE_GS3 208
#define NOTE_A3  220
#define NOTE_AS3 233
#define NOTE_B3  247
#define NOTE_C4  262
#define NOTE_CS4 277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4 370
#define NOTE_G4  392
#define NOTE_GS4 415
#define NOTE_A4  440
#define NOTE_AS4 466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5 554
#define NOTE_D5  587
#define NOTE_DS5 622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5 740
#define NOTE_G5  784
#define NOTE_GS5 831
#define NOTE_A5  880
#define NOTE_AS5 932
#define NOTE_B5  988

#define PIEZO_A 2 // pins for the beeper/speaker
#define PIEZO_B 3

// bigger songs should be in PROGMEM!
const uint16_t notes[] = {
    NOTE_C4, NOTE_C4, NOTE_D4, NOTE_E4, NOTE_C4, NOTE_E4, NOTE_D4, NOTE_G3,
    NOTE_C4, NOTE_C4, NOTE_D4, NOTE_E4, NOTE_C4, NOTE_B3, NOTE_C4, NOTE_C4,
    NOTE_D4, NOTE_E4, NOTE_F4, NOTE_E4, NOTE_D4, NOTE_C4, NOTE_B3, NOTE_G3,
    NOTE_A3, NOTE_B3, NOTE_C4, NOTE_C4, NOTE_A4, NOTE_B4, NOTE_A4, NOTE_G4,
    NOTE_A4, NOTE_B4, NOTE_C5, NOTE_G4, NOTE_A4, NOTE_G4, NOTE_F4, NOTE_E4,
    NOTE_G4, NOTE_A4, NOTE_B4, NOTE_A4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5,
    NOTE_A4, NOTE_G4, NOTE_C5, NOTE_B4, NOTE_D5, NOTE_C5, NOTE_C5,
};

const uint8_t duration[] = {
    2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 4, 4, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 4, 4, 3, 1, 2, 2,
    2, 2, 4, 3, 1, 2, 2, 4,
    4, 3, 1, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 4, 4,
};

uint8_t BUZ_BIT1;
uint8_t BUZ_BIT2;
volatile uint8_t *BUZ_PORT1;
volatile uint8_t *BUZ_PORT2;
volatile uint8_t *BUZ_DDR1;
volatile uint8_t *BUZ_DDR2;
volatile uint8_t state;

ISR (TIMER1_COMPA_vect)
{
    // toggle piezo pins alternately
    //           __    __    __    __
    // PIEZO_A _|  |__|  |__|  |__|
    //         _    __    __    __
    // PIEZO_B  |__|  |__|  |__|  |__
    //
    (state % 2)   ? *BUZ_PORT1 |= BUZ_BIT1 : *BUZ_PORT1 &= ~BUZ_BIT1;
    (state++ % 2) ? *BUZ_PORT2 &= ~BUZ_BIT2 : *BUZ_PORT2 |= BUZ_BIT2;
}

void playnote (uint32_t freq)
{
    uint8_t ps = 0;
    if (freq) { // freq==0 turns off timer
        ps++;
        freq = (F_CPU / (freq * 2));
        while (freq > 0xFFFF) { // calculate divider
            freq /= 8;
            ps++;
        }
    }
    // set timer 1 (16 bit)
    TCCR1A = 0;
    TCCR1B = _BV (WGM12) | ps; // mode 4 (CTC) | prescaler
    OCR1A = freq;
    TIMSK1 = _BV (OCIE1A); // enable interrupt on OCA match
}

int main (void)
{
#define SPD 100 // arbitrary delay

    init ();
    Serial.begin (115200);

    BUZ_BIT1 = digitalPinToBitMask (PIEZO_A);
    BUZ_BIT2 = digitalPinToBitMask (PIEZO_B);

    BUZ_PORT1 = portOutputRegister (digitalPinToPort (PIEZO_A));
    BUZ_PORT2 = portOutputRegister (digitalPinToPort (PIEZO_B));

    BUZ_DDR1 = portModeRegister (digitalPinToPort (PIEZO_A));
    BUZ_DDR2 = portModeRegister (digitalPinToPort (PIEZO_B));

    *BUZ_DDR1 |= BUZ_BIT1; // set DDR to output
    *BUZ_DDR2 |= BUZ_BIT2;

    uint8_t n, x;
    n = sizeof (notes) / sizeof (*notes);
    for (x = 0; x < n; x++) {
        playnote (notes[x]);
        _delay_ms (SPD * duration[x]); // 60 is an arbitrary delay
        playnote (0);
        _delay_ms (SPD);
    }

    while (1);
}

Have you seen my program for a 13-note simultaneous note generator using a '1284P?
That has all the frequencies generated using micros() and which match a piano.

piano13keyBurstFix.ino (11.2 KB)

There's also the tone().