void readSynthButtons() { readFnButton(); int diff; for(byte i=0;i<N_NOTE_BUTTONS;i++) { if (buttonPressedNew(i)) { if (!fnEnabled) { button[i].pitchReading = sampledAnalogRead(PITCH_POT); } button[i].noteIndex = doNoteOn(selectedSettings+1, button[i].midiVal, MAX_VELOCITY); note[button[i].noteIndex].trigger = i; } else { byte noteIndex = button[i].noteIndex; if ((noteIndex != UNSET) && (note[noteIndex].midiVal > NOTE_PENDING_OFF) && (note[noteIndex].trigger == i)) { if (buttonHeld(i)) { if (!fnEnabled) { int currentPitchReading = sampledAnalogRead(PITCH_POT); diff = abs(currentPitchReading - button[i].pitchReading); if (diff > 5) { // the pot has moved since the button was pressed button[i].midiVal = map(currentPitchReading, 0, 1024, POT_MIDI_LOW, POT_MIDI_HIGH+1); button[i].pitchReading = currentPitchReading; if (button[i].midiVal < MIDI_LOW) { button[i].midiVal = MIDI_LOW; } if (button[i].midiVal > MIDI_HIGH) { button[i].midiVal = MIDI_HIGH; } button[i].pitchReading = currentPitchReading; note[noteIndex].midiVal = button[i].midiVal; } } } else { if (note[noteIndex].envelopePhase != RELEASE) { // button released note[noteIndex].trigger = UNSET; button[i].noteIndex = UNSET; doNoteOff(selectedSettings+1, button[i].midiVal); } } } } } }
void grooveboxNoteOff(byte channelNum, byte midiNote, byte velocity) { if ((seqPreview) || (!seqRunning)) { if (channelNum == 10) { doDrumNoteOff(midiNote); } else { doNoteOff(selectedSettings+1, midiNote); } return; } seqLock = true; sequenceNote_t *sn; int noteEnd = pulseClock; sn = &seq[track[currentTrack].noteSeqIndex][currentTrack]; note_t *n = ¬e[sn->noteIndex]; byte midiVal = sn->midiVal & 0x7F; if ((midiVal == midiNote) && ((n->envelopePhase == OFF) || (n->envelopePhase == RELEASE)) && (!n->isSample)) { debugprint("WARNING: noteOff on track ", currentTrack); debugprintln(" : unexpected note envelope = ", n->envelopePhase); } if (midiVal == midiNote) { // Set the duration for the note we just turned off. unsigned int duration = noteEnd - sn->startPulse; if (duration == 0) { debugprintln("duration is 0, but setting to 1: ", midiNote); duration = 1; // rare, but avoid duration 0 to simplify logic } sn->duration = duration; if (n->trigger == currentTrack) { // It is possible that the note was a sample and already done/reused. releaseNote(¬e[sn->noteIndex]); } track[currentTrack].state = SEQ_PLAY; } else { debugprint("no match on ", midiVal); debugprint(", trigger ", n->trigger); debugprint(", noteSeqIndex ", track[currentTrack].noteSeqIndex); debugprintln(", noteIndex ", sn->noteIndex); } seqLock = false; }
void* MidiInput::run() { unsigned char tmp; unsigned char cmd = 0; unsigned char channel = 0; unsigned char data[2]; int inCommand = 0; char ctlName[ 10 ]; //format is "ctl00-000" while( running ) { read( midiFd, &tmp, 1 ); if ( tmp == 248 ) // throw away timing messages they mess us up! { //debug( DEBUG_STATUS, "." ); continue; } if ( tmp < 128 ) { data[0] = tmp; inCommand = 1; } else { cmd = tmp & 0xF0; channel = tmp & 0x0F; inCommand = 0; } switch( cmd ) { case MIDI_NOTEOFF: //0x80 READ2; doNoteOff( channel, data[0], data[1] ); break; case MIDI_NOTEON: //0x90 READ2; if ( data[1] == 0 ) { doNoteOff( channel, data[0], data[1] ); } else { doNoteOn( channel, data[0], data[1] ); } break; case MIDI_KEY_PRESSURE: //0xA0 READ2; debug( DEBUG_STATUS, "KEY PRESSURE ch=%d note=%d amount=%d\n", channel, cmd, data[ 0 ] ); break; case MIDI_CTL_CHANGE: //0xB0 READ2; debug( DEBUG_STATUS, "CTL_CHANGE %d %d %d\n", channel, data[ 0 ], data[ 1 ] ); sprintf( ctlName, "ctl%d-%d", channel, data[0] ); { Output* out; out = MoogObject::getOutput( ctlName ); if ( out != NULL ) out->setData(data[ 1 ] / 127.0); } break; case MIDI_PGM_CHANGE: //0xC0 READ1; debug( DEBUG_STATUS, "PGM_CHANGE %d %d\n", channel, data[ 0 ] ); break; case MIDI_CHN_PRESSURE: //0xD0 READ1; debug( DEBUG_STATUS, "CHN_PRESSURE %d %d\n", channel, data[ 0 ] ); break; case MIDI_PITCH_BEND: //0xE0 READ2; doPitchBend( (( data[ 1 ] << 7 ) & 0xFF00) | data[ 0 ] ); break; case MIDI_SYSTEM_PREFIX: //0xF0 switch( channel ) { case 0: break; } break; default: debug( DEBUG_STATUS, "[%d]\n", cmd ); } } pthread_exit(0); /* not reached */ return( NULL ); }