Skip to content

Instantly share code, notes, and snippets.

@rfielding
Created January 5, 2012 22:17
Show Gist options
  • Save rfielding/1567625 to your computer and use it in GitHub Desktop.
Save rfielding/1567625 to your computer and use it in GitHub Desktop.
Fixing a huge omission in MIDI, note-ties
if(fingerTurningOff != NOBODY)
{
struct Fretless_fingerState* turningOffPtr = &ctxp->fingers[fingerTurningOff];
if(turningOffPtr->isOn == FALSE)
{
ctxp->fail("turningOffPtr->isOn should be on\n");
}
if(turningOffPtr->isSupressed == FALSE)
{
ctxp->fail("turningOffPtr->isSupressed should be supressed\n");
}
if(legato == 2)
{
Fretless_noteTie(ctxp,turningOffPtr);
}
ctxp->midiPutch(MIDI_ON + turningOffPtr->channel);
ctxp->midiPutch(turningOffPtr->note);
ctxp->midiPutch(0);
//if( ctxp->noteChannelDownRawBalance[turningOffPtr->note][turningOffPtr->channel] > 0 )
{
ctxp->noteChannelDownRawBalance[turningOffPtr->note][turningOffPtr->channel]--;
}
}
ctxp->midiPutch(MIDI_ON + fsPtr->channel);
ctxp->midiPutch(fsPtr->note);
ctxp->midiPutch(fsPtr->velocity);
ctxp->noteChannelDownRawBalance[fsPtr->note][fsPtr->channel]++;
//
// Given note ties, you don't have to mess with bend width, and can leave that at its
// default value and be able to bend from midi 0 smoothly to midi 127 at full resolution
// and microtones. Because it has the effect of continuing the next note on/off pair
// with the sound in its same state (ie: no re-attack on note down), it also works
// perfectly fine as a legato message.
//
// It's critical to making polyphonic microtonality work correctly in
// the context of MIDI, because:
// 1) small bends can jump boundaries from one base note to another
// (ie: A+2Semitones versus B)
// 2) every note can bend any distance up or down in the future.
// this is fundamentally why tuning tables and limited bend distances don't work.
//
// Call this just before you turn off one note and turn on the note that it is to
// be tied together with.
//
void Fretless_noteTie(struct Fretless_context* ctxp,struct Fretless_fingerState* fsPtr)
{
int lsb;
int msb;
Fretless_numTo7BitNums(1223,&lsb,&msb);
int channel = fsPtr->channel;
int note = fsPtr->note;
ctxp->midiPutch(0xB0 + channel);
ctxp->midiPutch(0x63);
ctxp->midiPutch(msb);
ctxp->midiPutch(0xB0 + channel);
ctxp->midiPutch(0x62);
ctxp->midiPutch(lsb);
ctxp->midiPutch(0xB0 + channel);
ctxp->midiPutch(0x06);
ctxp->midiPutch(note);
///* I am told that the reset is bad for some synths
ctxp->midiPutch(0xB0 + channel);
ctxp->midiPutch(0x63);
ctxp->midiPutch(0x7f);
ctxp->midiPutch(0xB0 + channel);
ctxp->midiPutch(0x62);
ctxp->midiPutch(0x7f);
//*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment