Reading MIDI, converting to polyphonic square wave with Tone library

HI guys,

I've made a few changes and thought I'd post here.

I have decided to go the route of Bresenham accumulators and use the timer directly. Here is what I have to go on:

#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>
#include <TimerOne.h>
#include <avr/pgmspace.h>

#define TIMER_OVF_PERIOD 51  //period in uS before Timer1 triggers the interrupt
#define MAX_ON_TIME 1       //10 to give ~510uS per pulse, 1 for 51uS
#define MODE_NUM 3           //number of modes

/* Output Tone Pins */
int tone1pin = 3;
int tone2pin = 5;
int tone3pin = 6;

volatile int mode;

/* Note Status (On/Off) */
boolean note1on = false;
boolean note2on = false;
boolean note3on = false;

/* 32-bit Bresenham Accumulators */
unsigned long bres1 = 0; 
unsigned long bres2 = 0;
unsigned long bres3 = 0;

/* 32-bit Note Frequencies */
unsigned long note1freq;
unsigned long note2freq;
unsigned long note3freq;

/* Note On-Time Counters */
int note1_on_time = MAX_ON_TIME;
int note2_on_time = MAX_ON_TIME;
int note3_on_time = MAX_ON_TIME;

/* MIDI Data Information */
volatile double note;
volatile int type, velocity, channel, d1, d2;

void setup() {
  pinMode(tone1pin, OUTPUT);          // tone output pins
  pinMode(tone2pin, OUTPUT);
  pinMode(tone3pin, OUTPUT);

  MIDI.begin(MIDI_CHANNEL_OMNI);
  
  Timer1.initialize(TIMER_OVF_PERIOD);    //trigger the interrupt at specified number of uS
  Timer1.attachInterrupt(noteISR);        //attach interrupt service routine to Timer1
  Serial.begin(57600);
}

void loop() {
    
    if (MIDI.read()) {
      byte type = MIDI.getType();
      switch (type) {
        case NoteOn:
          note = 440.0 * pow(2.0, ((double)(MIDI.getData1()-69.0)/12.0));  //get note frequency
          velocity = MIDI.getData2();
          channel = MIDI.getChannel();
          if (velocity > 0) {
            if (!note1on) {
              note1freq = note;
              note1on = true;
            } else if (!note2on) {
              note2freq = note;
              note2on = true;
            } else if (!note3on) {
              note3freq = note;
              note3on = true;
            }
          } else {
            if (note1freq == note) note1on = false;
            else if (note2freq == note) note2on = false;
            else if (note3freq == note) note3on = false;
          }
          break;
        case NoteOff:
          note = 440.0 * pow(2.0, ((double)(MIDI.getData1()-69.0)/12.0));  //get note frequency
          //determine which pin is playing the note and turn it off
          if (note1freq == note) note1on = false;
          else if (note2freq == note) note2on = false;
          else if (note3freq == note) note3on = false;
          break;
        default:
          break;
      }
    }
  }
}

/*****************************
 * Interrupt Service Routine *
 *****************************/
 
void noteISR() {
  
  /* Note 1 */
  if (note1on) {
    bres1 += note1freq * 64;
    if (bres1 >= (19531.25 * 64)) {
      bres1 -= (19531.25 * 64);
      note1_on_time = MAX_ON_TIME;
    }
  }
  if (note1_on_time > 0) {
    note1_on_time--;
    //Serial.println(note_on_time);
    digitalWrite(tone1pin, HIGH);
  } else {
    digitalWrite(tone1pin, LOW);
  }
  
  /* Note 2 */
  if (note2on) {
    bres2 += note2freq * 64;
    if (bres2 >= (19531.25 * 64)) {
      bres2 -= (19531.25 * 64);
      note2_on_time = MAX_ON_TIME;
    }
  }
  if (note2_on_time > 0) {
    note2_on_time--;
    //Serial.println(note_on_time);
    digitalWrite(tone2pin, HIGH);
  } else {
    digitalWrite(tone2pin, LOW);
  }
  
  /* Note 3 */
  if (note3on) {
    bres3 += note3freq * 64;
    if (bres3 >= (19531.25 * 64)) {
      bres3 -= (19531.25 * 64);
      note3_on_time = MAX_ON_TIME;
    }
  }
  if (note3_on_time > 0) {
    note3_on_time--;
    //Serial.println(note_on_time);
    digitalWrite(tone3pin, HIGH);
  } else {
    digitalWrite(tone3pin, LOW);
  }
}

Unfortunately, I constantly get stuck notes and can't seem to figure out why. I was hoping someone could look over the code for me.

The specifications have changed a bit. I need each note frequency to have a duty cycle with an on-time that stays at around 50uS. That's what TIMER_OVF_PERIOD and MAX_ON_TIME do. I am using the MIDI library found here: MIDI Library, For Communication With Musical Instruments

I'm afraid there's not much more info I can give you right now. I'm stumped.

Thanks for any insight you can offer.
Regards,
Matt