diff --git a/minimoog_mega_1/minimoog_mega_1.ino b/minimoog_mega_1/minimoog_mega_1.ino index 31c7f40..f11aaef 100644 --- a/minimoog_mega_1/minimoog_mega_1.ino +++ b/minimoog_mega_1/minimoog_mega_1.ino @@ -78,7 +78,7 @@ // Constants const uint8_t NUM_KEYS = 30; -const uint8_t MIDI_OFFSET = 47; // to be maybe modified +const uint8_t MIDI_OFFSET = 48; // to be maybe modified const uint8_t NUM_SWITCHES = 15; const uint8_t NUM_POTS = 16; diff --git a/minimoog_teensy/minimoog_teensy.ino b/minimoog_teensy/minimoog_teensy.ino index aa4833c..a498f08 100644 --- a/minimoog_teensy/minimoog_teensy.ino +++ b/minimoog_teensy/minimoog_teensy.ino @@ -113,7 +113,12 @@ uint8_t waveforms[6] = {WAVEFORM_SINE, WAVEFORM_TRIANGLE, WAVEFORM_SAWTOOTH, // keyTrack uint8_t keyTrackIndex = 0; -uint8_t keyTrack[KEYTRACK_MAX] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +struct { + uint8_t key; + uint8_t velocity; +} keyTrack[KEYTRACK_MAX]; + +int8_t nowPlaying = -1; // double CC track uint8_t ccTempValue[32]; @@ -125,7 +130,7 @@ enum keyMode_t{ KEY_UPPER, }; -keyMode_t keyMode = KEY_LAST; +keyMode_t keyMode = KEY_UPPER; struct midiSettings : public midi::DefaultSettings{ // static const bool UseRunningStatus = true; @@ -281,6 +286,11 @@ void loop() { } void noteOn(uint8_t note, uint8_t velocity, bool trigger = 1){ +/* + Serial.print("playing :"); + Serial.println(note); +*/ + nowPlaying = note; float duration = (float)glideEn * (float)glide * 3.75; float level = ((float)note + 12 * transpose) * HALFTONE_TO_DC; float filterLevel = (((float)note - FILTER_BASE_NOTE) + (12 * transpose)) * FILTER_HALFTONE_TO_DC; @@ -302,18 +312,63 @@ void noteOff(){ AudioInterrupts(); } -int8_t keyTrackAddNote(uint8_t note){ +int8_t keyTrackGetLower(uint8_t note){ + uint8_t lower = 127; + int8_t lowerIndex = keyTrackIndex - 1; + + for(uint8_t i = 0; i < keyTrackIndex; ++i){ + if(keyTrack[i].key < lower){ + lower = keyTrack[i].key; + lowerIndex = i; + } + } +/* + Serial.print("lower note : "); + Serial.print(lower); + Serial.print("\t index : "); + Serial.println(lowerIndex); +*/ + return lowerIndex; +} + +int8_t keyTrackGetUpper(uint8_t note){ + uint8_t upper = 0; + int8_t upperIndex = keyTrackIndex - 1; + + for(uint8_t i = 0; i < keyTrackIndex; ++i){ + if(keyTrack[i].key > upper){ + upper = keyTrack[i].key; + upperIndex = i; + } + } +/* + Serial.print("upper note : "); + Serial.print(upper); + Serial.print("\t index : "); + Serial.println(upperIndex); +*/ + return upperIndex; +} + +int8_t keyTrackAddNote(uint8_t note, uint8_t velocity){ // We only keep count of a limited quantity of notes ! if (keyTrackIndex >= KEYTRACK_MAX) return -1; +/* + Serial.print("note added : "); + Serial.print(note); + Serial.print("\t index : "); + Serial.println(keyTrackIndex); +*/ + keyTrack[keyTrackIndex].key = note; + keyTrack[keyTrackIndex].velocity = velocity; - keyTrack[keyTrackIndex] = note; return keyTrackIndex++; } int8_t keyTrackRemoveNote(uint8_t note){ int8_t update = -1; for(uint8_t i = 0; i < keyTrackIndex; ++i){ - if(keyTrack[i] == note){ + if(keyTrack[i].key == note){ update = i; keyTrackIndex--; break; @@ -321,6 +376,12 @@ int8_t keyTrackRemoveNote(uint8_t note){ } if(update >= 0){ +/* + Serial.print("note removed : "); + Serial.print(note); + Serial.print("\t index : "); + Serial.println(update); +*/ for(uint8_t i = update; i < keyTrackIndex; ++i){ keyTrack[i] = keyTrack[i + 1]; } @@ -335,28 +396,55 @@ void handleNoteOn(uint8_t channel, uint8_t note, uint8_t velocity){ Serial.print(note); Serial.println(" on"); */ + int8_t newIndex = -1; + int8_t lowerIndex = -1; + int8_t upperIndex = -1; switch(keyMode){ // When KEY_FIRST, we play the note only if there is not one already playing + // But we keep track of all notes depressed ! case KEY_FIRST: - if(keyTrackIndex != 0) return; - keyTrack[0] = note; - keyTrackIndex = 1; + if(keyTrackAddNote(note, velocity) == 0) noteOn(note, velocity); -// if(keyTrackAddNote(note) == 0) noteOn(note, velocity); break; // When KEY_LAST, we play the new note anyway. + // And keep track. Of course. case KEY_LAST: - keyTrack[0] = note; - if(keyTrackIndex != 0){ - noteOn(note, velocity, noteRetrigger); - } else { - noteOn(note, velocity); - } - keyTrackIndex = 1; -// if(keyTrackAddNote(note) == (keyTrackIndex - 1)) noteOn(note, velocity); + if(keyTrackAddNote(note, velocity) >= 0) noteOn(note, velocity); break; case KEY_LOWER: + // add note to the keytrack table. + // check if there is a lower one. + // if no, play the note. + // if yes, do nothing. +// Serial.println("handle note on"); + + newIndex = keyTrackAddNote(note, velocity); + lowerIndex = keyTrackGetLower(note); +/* + Serial.print("new : "); + Serial.print(newIndex); + Serial.print("\tlower : "); + Serial.println(lowerIndex); +*/ + if(newIndex >= 0){ + if(lowerIndex == (keyTrackIndex - 1)){ + noteOn(note, velocity); + } + } + break; case KEY_UPPER: + // add note to the keytrack table. + // check if there is an upper one. + // If no, play the note. + // If yes, do nothing. + newIndex = keyTrackAddNote(note, velocity); + upperIndex = keyTrackGetUpper(note); + if(newIndex >= 0){ + if(upperIndex == (keyTrackIndex - 1)){ + noteOn(note, velocity); + } + } + break; default: break; } @@ -369,23 +457,68 @@ void handleNoteOff(uint8_t channel, uint8_t note, uint8_t velocity){ Serial.print(note); Serial.println(" off"); */ + int8_t lowerIndex = -1; + int8_t upperIndex = -1; + int8_t newIndex = -1; switch(keyMode){ case KEY_FIRST: -/* if(keyTrackRemoveNote(note) == 0){ + if(keyTrackRemoveNote(note) == 0){ noteOff(); + if(keyTrackIndex > 0){ + noteOn(keyTrack[0].key, keyTrack[0].velocity, noteRetrigger); + } } break; -*/ case KEY_LAST: - if(keyTrack[0] == note){ - keyTrackIndex = 0; + case KEY_LAST: + if(keyTrackRemoveNote(note) == keyTrackIndex){ noteOff(); + if(keyTrackIndex > 0){ + noteOn(keyTrack[keyTrackIndex - 1].key, + keyTrack[keyTrackIndex - 1].velocity, noteRetrigger); + } } -/* if(keyTrackRemoveNote(note) == keyTrackIndex){ + break; + case KEY_LOWER: + // check the keytrack table and remove the note of it. + // compare it to other notes. + // if there is no, send note off. + // if there is a lower, do nothing. + // if there is an upper, play the new lower note. +// Serial.println("handle note off"); + + lowerIndex = keyTrackGetLower(note); + newIndex = keyTrackRemoveNote(note); +/* + Serial.print("new : "); + Serial.print(newIndex); + Serial.print("\tlower : "); + Serial.println(lowerIndex); +*/ + if(newIndex == lowerIndex){ noteOff(); } -*/ break; - case KEY_LOWER: + if(keyTrackIndex > 0){ + newIndex = keyTrackGetLower(note); + if(keyTrack[newIndex].key != nowPlaying){ + noteOn(keyTrack[newIndex].key, + keyTrack[newIndex].velocity, noteRetrigger); + } + } + break; case KEY_UPPER: + upperIndex = keyTrackGetUpper(note); + newIndex = keyTrackRemoveNote(note); + if(newIndex == upperIndex){ + noteOff(); + } + if(keyTrackIndex > 0){ + newIndex = keyTrackGetUpper(note); + if(keyTrack[newIndex].key != nowPlaying){ + noteOn(keyTrack[newIndex].key, + keyTrack[newIndex].velocity, noteRetrigger); + } + } + break; default: break; }