void mainloopalgorithms(void) { // 1. check to see if we are in a new measure and update the // metronome accordingly. If in 4/4, then the metronome will // be guarenteed to be between 0 and 3.99999 after the following // code is run. The update will make sure that the metronome remains // synced exactly in time with the absolute beat. (Useful for // polyphony, not really necessary in monophonic cases). if (metronome.expired() >= meter) { metronome.update(meter); } // 2. Determine the current beat of the meter. // We will want to play automated chords on beats one and three. beatfraction = metronome.getPeriodCount(); beat = (int)beatfraction + 1; beatfraction -= beat - 1; // 3. Process the incoming MIDI note messages (if any), keeping track // of the last note, and whether it is currently on or off. while (synth.getNoteCount() > 0) { notemessage = synth.extractNote(); if (notemessage.getP2() != 0) { note = notemessage.getP1(); notestates[note] = 1; } else { notestates[notemessage.getP1()] = 0; } } // 4. Determine the position in time in the current beat. // There are two beat-parts which are called states: // state == 0: we are at the start of the beat and may need to // choose a new chord. // state == 1: we are past the maximum wait time for a chord decision // Also, check to see if the state has changed from 0 to 1 or 1 to 0. oldstate = state; state = beatfraction < maxwait ? 0 : 1; stateChange = (state != oldstate); // 5. Check to see if a chord needs to be played. if (stateChange && state == 0) { playMetronome(beat); if (chordBeat(beat, meter)) { notescan = 1; } else { playChord(currentnote, OFF); } } if (notescan && notestates[note]) { // if note played in beat window currentnote = note; playChord(currentnote, ON); notescan = 0; } else if (notescan && state == 1) { // if too late for a new note playChord(currentnote, ON); notescan = 0; } }
void mainloopalgorithms(void) { if (comparestate && notetimer.expired()) { if (notetimer.expired() > 2) { notetimer.reset(); } else { notetimer.update(); } notestate = !notestate; if (notestate == 1 || notestate == -1) { synth.play(0, note, 64); data = 0x90; sentout.insert(data); data = note; sentout.insert(data); data = 64; sentout.insert(data); } else { synth.play(0, note, 0); data = 0x90; sentout.insert(data); data = note; sentout.insert(data); data = 0; sentout.insert(data); note += step * direction; if (note > highestnote) { note = lowestnote; } if (note < lowestnote) { note = highestnote; } } } if (midiinput.getCount() > 0) { message = midiinput.extract(); receivedin.insert(message.p0()); receivedin.insert(message.p1()); receivedin.insert(message.p2()); // check that the messages are identical if (receivedin.getCount() < 3) { cout << "Error: not enough received data" << endl; } else { checkin[0] = receivedin.extract(); checkin[1] = receivedin.extract(); checkin[2] = receivedin.extract(); } if (sentout.getCount() < 3) { cout << "Error: not enough sent data" << endl; } else { checkout[0] = sentout.extract(); checkout[1] = sentout.extract(); checkout[2] = sentout.extract(); } if ((checkout[0] != checkin[0]) || (checkout[1] != checkin[1]) || (checkout[2] != checkin[2])) { synth.rawsend(0xaa, 0x7f, 0x00); cout << "Error " << "output was = (" << hex << (int)checkout[0] << ") " << dec << (int)checkout[1] << " " << dec << (int)checkout[2] << "\tbut input is = (" << hex << (int)checkin[0] << ") " << dec << (int)checkin[1] << " " << dec << (int)checkin[2] << " " << endl; // assume that a note message was missed. if (sentout.getCount() < 3) { cout << "Error: not enough sent data during error" << endl; } else { checkout[0] = sentout.extract(); checkout[1] = sentout.extract(); checkout[2] = sentout.extract(); } stop(); cout << "Press space to restart testing, " "or press 'S' to silence synth" << endl; } } }