Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // MIDI MACHINE by Gabriel Maria
- // More info at gabrielmaria.com
- // This code is for a Teensy 3.5
- // What this code does:
- // Takes USB midi notes AND midi CC values and applys them to 4 different types of devices
- // Solonoids, Servos, Stepper Motors and Floppy Drives.
- // Solonoids and Servos are on MIDI channel 10.
- // Stepper Motors 0,1,2,3 are collectivly on MIDI channel 1, and are polyphonic.
- // The Floppy Drive (Stepper Motor 4) is on MIDI channel 2.
- // each Solonoid has a pulse width setting via MIDI CC.
- // each Servo has a start-angle and end-angle, both can be set via MIDI CC.
- // Stepper Motors collectivly have one octive shift setting via MIDI CC.
- // Every so often the current midi CC values are saved to EEPROM
- #include <PWMServo.h>
- #include <IntervalTimer.h>
- #include <MIDI.h>
- #include <EEPROM.h>
- MIDI_CREATE_DEFAULT_INSTANCE();
- #define p Serial.print
- #define pl Serial.println
- #define debugGraphing 1
- //--pinMux-------------------
- #define ledR 28
- #define ledG 3
- uint32_t deviceOnTime = 0;
- volatile uint32_t TIMEmicros = 0;
- struct solenoidStruct{
- bool en = 0;
- uint8_t pin = 100;
- uint8_t midiNote = 255;
- uint8_t midiCC = 255;
- bool polarity = 1; //1 normal
- bool bidirectional = 0;
- //
- bool gate = 0;
- bool stayOnMode = 0; //set by baseOnTime midi knob being 0
- bool forceStayOnMode = 0; //set by midi velocity being 0
- uint32_t trigTime = 0;
- uint32_t releaseTime = 0;
- uint32_t baseOnTime = 10000; // set by midi knobs
- float velocityMultiplyer = 1; //(1)midi = 1%, (100)midi = 100%, (127)midi = 200%, (0)midi = 9999999%
- uint32_t onTimeSet = 10000; // result
- };
- volatile struct solenoidStruct sol[30];
- volatile uint32_t numberOfSols = 30;
- struct stepperStruct{
- bool en = 0;
- uint8_t enPin = 100;
- uint8_t stepPin = 100;
- uint8_t directionPin = 100;
- uint32_t stepsBeforeReverse = 0;
- //
- bool gate = 0;
- uint32_t stepCount = 0;
- float speedSet = 0;
- uint32_t periodSet = 0;
- bool dir = 0;
- bool stepPinState = 0;
- float freqOut = 0;
- uint32_t fCount = 0;
- uint32_t fFlip = 0;
- };
- volatile struct stepperStruct stepp[6];
- volatile uint32_t numberOfSteppers = 6;
- uint8_t voices[4];
- uint8_t numVoices = 4;
- uint8_t floppyVoice[1];
- uint8_t notes[2][129];
- uint8_t numNotes[2];
- struct servoStruct{
- bool en = 0;
- uint8_t pwmPin = 100;
- uint8_t midiNote = 0;
- uint8_t midiCC1 = 0;
- uint8_t midiCC2 = 0;
- uint8_t position1 = 0; //home position, also can be modulated for analog control
- uint8_t position2 = 180; //second position when the MIDI note is enaged
- bool gate = 0;
- };
- volatile struct servoStruct serv[10];
- volatile uint32_t numberOfServos = 10;
- volatile bool updateEEPROMflag = 0;
- volatile uint32_t updateEEPROMflagTime = 0;
- volatile int32_t sysFrequency = 10000;
- IntervalTimer timer10k;
- IntervalTimer timerStepper;
- volatile int32_t stepperPeriod = 7; //142857.1428
- volatile float masterTuning = 440;//442.9132;
- PWMServo servo0;
- PWMServo servo1;
- PWMServo servo2;
- PWMServo servo3;
- PWMServo servo4;
- PWMServo servo5;
- PWMServo servo6;
- uint32_t lastmillis = 0;
- uint32_t MILLIS = 0;
- bool noteIndicator[128];
- uint32_t NAnoteTime = 0;
- uint8_t StepperMIDICC = 0;
- int SteppOctaveShift = 0;
- void setup() {
- setupNotes();
- deviceSetup();
- readEEPROM();
- Serial.begin(115200);
- pinMode(13, OUTPUT); digitalWrite(13, 0);
- pinMode(ledR, OUTPUT); digitalWrite(ledR, 1);
- pinMode(ledG, OUTPUT); digitalWrite(ledG, 1);
- memset(noteIndicator,0,sizeof(noteIndicator));
- pl("hi");
- timer10k.begin(ISR10k,1000000/sysFrequency);
- timerStepper.begin(ISRStepper,stepperPeriod);
- //timerStepper0.begin(ISRStepper0,1000000/100);
- //timerStepper1.begin(ISRStepper1,1000000/100);
- //timerStepper2.begin(ISRStepper2,1000000/100);
- midiSetup();
- }
- void loop() {
- usbMIDI.read();
- //MIDI.read();
- if(updateEEPROMflag){
- if(updateEEPROMflagTime < millis()){
- updateEEPROMflag = 0;
- updateEEPROMflagTime = 4294967294;
- writeEEPROM();
- }
- }
- MILLIS = millis();
- if((MILLIS> lastmillis + 1000)){
- lastmillis = MILLIS;
- p("["); p(MILLIS/1000); pl("]");
- printNotes(0);
- digitalWrite(13, 1);
- }
- if((MILLIS> lastmillis)){
- digitalWrite(13, 0);
- }
- if(millis() > NAnoteTime +1000){
- digitalWrite(ledR, 1);
- }
- }
- void ISR10k(){
- TIMEmicros = micros();
- for(uint32_t i = 0; i < numberOfSols; i++){
- if(sol[i].gate){
- if(!sol[i].stayOnMode || !sol[i].forceStayOnMode){
- if(TIMEmicros > sol[i].releaseTime){
- //p("[");p(TIMEmicros);p("]");p("(");p(micros());pl(")");
- gateSol(i,0);
- }
- }
- }
- }
- }
- void ISRStepper(){
- digitalWrite(2,1);
- for(uint32_t i = 0; i < numberOfSteppers; i++){
- if(stepp[i].gate){
- digitalWrite(stepp[i].enPin,0);
- stepp[i].fCount++;
- if(stepp[i].fCount > stepp[i].fFlip){
- stepp[i].fCount = 0;
- stepp[i].stepPinState = !stepp[i].stepPinState;
- digitalWrite(stepp[i].stepPin,stepp[i].stepPinState);
- digitalWrite(stepp[i].directionPin,stepp[i].dir);
- stepp[i].stepCount++;
- if(stepp[i].stepCount>=stepp[i].stepsBeforeReverse){
- stepp[i].stepCount = 0;
- stepp[i].dir = !stepp[i].dir;
- }
- }
- }
- else{
- digitalWrite(stepp[i].enPin,1);
- }
- }
- /*
- TIMEmicros = micros();
- if(TIMEmicros > lastTIMEmicros + 10){
- lastTIMEmicros = TIMEmicros;
- for(uint32_t i = 0; i < numberOfSols; i++){
- if(sol[i].gate){
- if(!sol[i].stayOnMode || !sol[i].forceStayOnMode){
- if(TIMEmicros > sol[i].releaseTime){
- //p("[");p(TIMEmicros);p("]");p("(");p(micros());pl(")");
- gateSol(i,0);
- }
- }
- }
- }
- }*/
- digitalWrite(2,0);
- }
- void greenled(bool en){
- if(en){
- analogWrite(ledG,240);
- }else{
- analogWrite(ledG,256);
- //digitalWrite(ledG,1);
- }
- }
- /*
- inline uint16_t indOffset(int32_t change,int32_t Size){
- int32_t temp = Cindex + change;
- if(temp < 0){
- return Size + temp;
- }else{
- return temp;
- }
- }*/
- //-------------------------------------------------------------------------------------------------------------------------
- // CONTROL
- //-------------------------------------------------------------------------------------------------------------------------
- void setSolBaseOntimeFromMIDI(uint8_t ID, uint8_t midiVal){
- if(ID < 0){return;}
- if(ID >=numberOfSols){return;}
- if(midiVal == 0){
- setSolBaseOntime(ID, 20000000); //20seconds
- sol[ID].stayOnMode = 1;
- }else{
- setSolBaseOntime(ID, (uint32_t)( 300000 * pow( ((float)midiVal/127.0),4 ) ) );
- sol[ID].stayOnMode = 0;
- }
- updateEEPROMflag = 1;
- updateEEPROMflagTime = millis()+10000;
- }
- void setSolBaseOntime(uint8_t ID, uint32_t microSeconds){
- if(ID < 0){return;}
- if(ID >=numberOfSols){return;}
- sol[ID].baseOnTime = microSeconds;
- }
- void setStepperFequencyFromMIDI(uint8_t ID,uint8_t note){
- float freq = 0;
- if(note > 127){
- gateStepp(ID,0);
- }else{
- freq = pow(2,((float)((note+(SteppOctaveShift*12)) - 57))/12) * masterTuning ;
- //pl(freq);
- setStepperFequency(ID,freq);
- gateStepp(ID,1);
- }
- }
- //2^((149-49)/12) * 440 = 141917.50
- //2^((48 -49)/12) * 440 = 415.30469
- //1000000/7 = 142857.142
- //171.99(172) = 142857.142 / (415.30469 * 2)
- //415.282 = 142857.149 / (172 * 2)
- //415.282
- void setStepperFequency(uint8_t ID,float freq){
- if(freq < 0){return;}
- //if(freq > 4200){freq = 4200;}
- stepp[ID].fCount = 0;
- float fFlipFloat = (1000000.0 / (float)stepperPeriod) / (freq * 2.0);
- stepp[ID].fFlip = (uint32_t)round(fFlipFloat);
- stepp[ID].freqOut = freq;//(1000000.0 / (float)stepperPeriod) / (float)(stepp[ID].fFlip * 2);
- //p("stepper set: "); p(stepp[ID].freqOut); p(" ");p (fFlipFloat); p(" "); pl(stepp[ID].fFlip);
- }
- void setSolVelocity(uint8_t ID,uint8_t velocity){
- if(ID < 0){return;}
- if(ID >=numberOfSols){return;}
- if(velocity > 110){
- sol[ID].velocityMultiplyer = 2;
- sol[ID].onTimeSet = (uint32_t)(sol[ID].baseOnTime * sol[ID].velocityMultiplyer);
- sol[ID].forceStayOnMode = 0;
- }else if(velocity == 0){ //not used....
- sol[ID].velocityMultiplyer = 10000;
- sol[ID].onTimeSet = 20000000;
- sol[ID].forceStayOnMode = 1;
- }else{
- sol[ID].velocityMultiplyer = 1;
- sol[ID].onTimeSet = (uint32_t)(sol[ID].baseOnTime);
- sol[ID].forceStayOnMode = 0;
- }
- }
- void setServBasePositionFromMIDI(uint8_t ID, uint8_t Control, uint8_t val127){
- if(!serv[ID].en){return;}
- if(Control == 1){
- serv[ID].position1 = (uint8_t)((float)val127 * 1.4173);
- }else if(Control == 2){
- serv[ID].position2 = (uint8_t)((float)val127 * 1.4173);
- }else{
- return;
- }
- if(serv[ID].gate){
- setServo(ID, serv[ID].position2);
- }else{
- setServo(ID, serv[ID].position1);
- }
- updateEEPROMflag = 1;
- updateEEPROMflagTime = millis()+10000;
- }
- void setServoFromMIDI(uint8_t ID, uint8_t val127){
- setServo(ID, val127 * 1.4173);
- }
- void setServo(uint8_t ID, uint8_t angle){
- if(!serv[ID].en){return;}
- p("servo: ");p(ID);p(", angle: ");p(angle);
- switch(ID){
- case 0: servo0.write(angle); break;
- case 1: servo1.write(angle); break;
- case 2: servo2.write(angle); break;
- case 3: servo3.write(angle); break;
- case 4: servo4.write(angle); break;
- case 5: servo5.write(angle); break;
- case 6: servo6.write(angle); break;
- }
- }
- inline void gateSol(uint8_t ID,bool state){
- if(ID < 0){return;}
- if(ID >= numberOfSols){return;}
- if(!sol[ID].en){return;}
- if(state){
- sol[ID].trigTime = micros();
- sol[ID].releaseTime = sol[ID].trigTime + sol[ID].onTimeSet;
- digitalWrite(sol[ID].pin, sol[ID].polarity);
- //p("ID:"); p(ID); p(" pin:"); p(sol[ID].pin); p(" state:"); p(sol[ID].polarity);p(" trigtime:"); pl(sol[ID].trigTime);
- sol[ID].gate = 1;
- }else{
- //offtime = micros();
- digitalWrite(sol[ID].pin, !(sol[ID].polarity));//
- //p("ID:"); p(ID); p(" pin:"); p(sol[ID].pin); p(" state:"); p(!sol[ID].polarity);p(" time:"); pl(offtime);
- sol[ID].gate = 0;
- }
- }
- inline void gateStepp(uint8_t ID,bool state){
- if(ID < 0){return;}
- stepp[ID].gate = state;
- }
- inline void gateServ(uint8_t ID,bool state){
- if(ID < 0){return;}
- if(ID >=numberOfServos){return;}
- if(!serv[ID].en){return;}
- if(state){
- setServo(ID,serv[ID].position2);
- //p("ID:"); p(ID); p(" pin:"); p(sol[ID].pin); p(" state:"); p(sol[ID].polarity);p(" trigtime:"); pl(sol[ID].trigTime);
- serv[ID].gate = 1;
- }else{
- setServo(ID,serv[ID].position1);
- //p("ID:"); p(ID); p(" pin:"); p(sol[ID].pin); p(" state:"); p(!sol[ID].polarity);p(" time:"); pl(offtime);
- serv[ID].gate = 0;
- }
- }
- //-------------------------------------------------------------------------------------------------------------------------
- // DEVICES
- //-------------------------------------------------------------------------------------------------------------------------
- void deviceSetup(){
- //configureSolenoid(uint8_t ID, uint8_t drivePin, uint8_t note, uint8_t midiCC, bool polarity, bool bidirectional);
- //configureStepper(uint8_t ID, uint8_t stepPinIn, uint8_t directionPinIn,uint8_t enablePin, uint32_t stepsBeforeReverse);
- //configureServo (uint8_t ID, uint8_t pwmPin, uint8_t note, uint8_t midiCC1, uint8_t midiCC2);
- configureSolenoid(1, 4, 55, 20, 1, 0);
- configureSolenoid(2, 5, 56, 21, 1, 0);
- configureSolenoid(3, 6, 57, 22, 1, 0);
- configureSolenoid(4, 7, 58, 23, 1, 0);
- configureSolenoid(5, 8, 59, 24, 1, 0);
- configureSolenoid(6, 9, 60, 25, 1, 0);
- configureSolenoid(7, 10, 61, 26, 1, 0);
- configureSolenoid(8, 11, 62, 27, 1, 0);
- configureSolenoid(9, 14, 63, 28, 1, 0);
- configureSolenoid(10, 15, 64, 29, 1, 0);
- configureSolenoid(11, 16, 65, 30, 1, 0);
- configureSolenoid(12, 17, 66, 46, 1, 0);
- configureSolenoid(13, 18, 67, 47, 1, 0);
- configureSolenoid(14, 19, 68, 48, 1, 0);
- configureSolenoid(15, 20, 69, 49, 1, 0);
- configureSolenoid(16, 21, 70, 50, 1, 0);
- configureSolenoid(17, 22, 71, 51, 1, 0);
- configureSolenoid(18, 23, 72, 52, 1, 0);
- configureSolenoid(19, 12, 73, 53, 1, 0);
- configureSolenoid(20, 40, 74, 54, 1, 0);
- configureSolenoid(21, 41, 75, 55, 1, 0);
- configureSolenoid(22, 42, 76, 56, 1, 0);
- configureSolenoid(23, 51, 77, 57, 1, 0);
- configureSolenoid(24, 52, 78, 58, 1, 0);
- configureSolenoid(25, 53, 79, 59, 1, 0);
- configureServo(1, 29, 53, 102, 103);
- configureServo(2, 30, 52, 104, 105);
- configureServo(3, 35, 51, 106, 107);
- configureServo(4, 36, 50, 108, 109);
- configureServo(5, 37, 49, 110, 111);
- configureServo(6, 38, 48, 112, 113);
- numVoices = 4;
- StepperMIDICC = 114;
- configureStepper(0, 24, 25, 54, 1000000);
- configureStepper(1, 26, 27, 55, 1000000);
- configureStepper(2, 31, 32, 56, 1000000);
- configureStepper(3, 34, 33, 57, 1000000);
- //Floppy
- configureStepper(4, 49, 50, 48, 80);
- }
- void configureSolenoid(uint8_t ID, uint8_t drivePin, uint8_t note, uint8_t midiCC, bool polarity,bool bidirectional){
- sol[ID].pin = drivePin;
- sol[ID].polarity = polarity;
- pinMode(sol[ID].pin, OUTPUT);
- digitalWrite(sol[ID].pin, !(sol[ID].polarity));
- sol[ID].midiNote = note;
- sol[ID].midiCC = midiCC;
- sol[ID].bidirectional = bidirectional;
- sol[ID].en = 1;
- }
- void configureStepper(uint8_t ID, uint8_t stepPinIn, uint8_t directionPinIn,uint8_t enablePin, uint32_t stepsBeforeReverse){
- stepp[ID].stepPin = stepPinIn;
- stepp[ID].directionPin = directionPinIn;
- stepp[ID].enPin = enablePin;
- pinMode(stepp[ID].stepPin, OUTPUT);
- digitalWrite(stepp[ID].stepPin, 0);
- pinMode(stepp[ID].directionPin, OUTPUT);
- digitalWrite(stepp[ID].directionPin, 0);
- pinMode(stepp[ID].enPin, OUTPUT);
- digitalWrite(stepp[ID].enPin, 0);
- stepp[ID].stepsBeforeReverse = stepsBeforeReverse;
- stepp[ID].en = 1;
- }
- void configureServo(uint8_t ID, uint8_t pwmPin, uint8_t note, uint8_t midiCC1, uint8_t midiCC2){
- serv[ID].pwmPin = pwmPin;
- serv[ID].midiNote = note;
- serv[ID].midiCC1 = midiCC1;
- serv[ID].midiCC2 = midiCC2;
- serv[ID].en = 1;
- switch(ID){
- case 0: servo0.attach(pwmPin); break;
- case 1: servo1.attach(pwmPin); break;
- case 2: servo2.attach(pwmPin); break;
- case 3: servo3.attach(pwmPin); break;
- case 4: servo4.attach(pwmPin); break;
- case 5: servo5.attach(pwmPin); break;
- case 6: servo6.attach(pwmPin); break;
- }
- }
- //-------------------------------------------------------------------------------------------------------------------------
- // EEPROM
- //-------------------------------------------------------------------------------------------------------------------------
- void writeEEPROM(){
- uint16_t Offset = 0;
- uint32_t temp1 = 0;
- Offset = 0;
- for(uint32_t i = 0; i < numberOfSols; i++){
- if(sol[i].en){
- EEPROM.get((Offset+(4*i)),temp1);
- if(sol[i].baseOnTime != temp1){
- EEPROM.put((Offset+(4*i)),(uint32_t)sol[i].baseOnTime);
- }
- }
- }
- uint8_t temp2 = 0;
- Offset = 200;
- for(uint32_t i = 0; i < numberOfServos; i++){
- if(serv[i].en){
- EEPROM.get((Offset+(2*i)),temp2);
- if(serv[i].position1 != temp2){
- EEPROM.put((Offset+(2*i)),(uint8_t)serv[i].position1);
- }
- EEPROM.get((1+Offset+(2*i)),temp2);
- if(serv[i].position2 != temp2){
- EEPROM.put((1+Offset+(2*i)),(uint8_t)serv[i].position2);
- }
- }
- }
- pl("WRITING EEPROM");
- }
- void readEEPROM(){
- uint16_t Offset = 0;
- uint32_t temp1 = 0;
- Offset = 0;
- for(uint32_t i = 0; i < numberOfSols; i++){
- if(sol[i].en){
- EEPROM.get((Offset+(4*i)),temp1);
- //pl(temp1);
- if(temp1!=0xFFFFFFFF){
- sol[i].baseOnTime = temp1;
- }
- }
- }
- uint8_t temp2 = 0;
- Offset = 200;
- for(uint32_t i = 0; i < numberOfServos; i++){
- if(serv[i].en){
- EEPROM.get((Offset+(2*i)),temp2);
- //pl(temp2);
- if(temp2!=0xFF){
- serv[i].position1 = temp2;
- }
- EEPROM.get((1+Offset+(2*i)),temp2);
- //pl(temp2);
- if(temp2!=0xFF){
- serv[i].position2 = temp2;
- }
- }
- }
- }
- //-------------------------------------------------------------------------------------------------------------------------
- // MIDI
- //-------------------------------------------------------------------------------------------------------------------------
- void midiSetup(){
- midiReset();
- usbMIDI.setHandleNoteOn(midiNoteOn);
- usbMIDI.setHandleNoteOff(midiNoteOff);
- //usbMIDI.setHandlePitchChange(midiPitchChange);
- usbMIDI.setHandleControlChange(midiControlChange);
- MIDI.setHandleNoteOn(midiNoteOn);
- MIDI.setHandleNoteOff(midiNoteOff);
- //MIDI.setHandlePitchBend(midiPitchChange);
- MIDI.setHandleControlChange(midiControlChange);
- MIDI.begin(0);
- midiReset();
- }
- //-----------------------------------------------------------------------------------------------------------------------------
- void midiNoteOn(byte channel, byte note, byte velocity){//60 == 0 == 33.3333
- p("note on: "); p(channel);p(" ");p(note);p(" ");p(velocity);pl( );
- noteIndicator[note] = 1;
- greenled(1);//on
- bool NAnote = 1;
- switch(channel){
- case 10:
- for(uint32_t ID=0;ID<numberOfSols;ID++){
- if(sol[ID].midiNote == note){
- NAnote = 0;
- setSolVelocity(ID,velocity);
- gateSol(ID,1);
- p("ID:"); p(ID); p(" base:"); p(sol[ID].baseOnTime); p(" mulit:"); p(sol[ID].velocityMultiplyer);p(" output:"); pl(sol[ID].onTimeSet);
- break;
- }
- }
- for(uint32_t ID=0;ID<numberOfServos;ID++){
- if(serv[ID].midiNote == note){
- NAnote = 0;
- gateServ(ID,1);
- }
- }
- if(NAnote){digitalWrite(ledR, 0); NAnoteTime = millis();}
- break;
- case 1:
- addNote(0,note);
- distrubuteNotesToVoices(notes[0], voices, numVoices);
- for(uint32_t i = 0; i< numVoices; i++){
- setStepperFequencyFromMIDI(i,voices[i]);
- }
- break;
- case 2:
- addNote(1,note);
- distrubuteNotesToVoices(notes[1], floppyVoice, 1);
- setStepperFequencyFromMIDI(4,floppyVoice[0]);
- break;
- default:
- digitalWrite(ledR, 0);
- NAnoteTime = millis();
- break;
- }
- }
- //-----------------------------------------------------------------------------------------------------------------------------
- void midiNoteOff(byte channel, byte note, byte velocity){
- p("note off: "); p(channel);p(" ");p(note);p(" ");p(velocity);pl( );
- switch(channel){
- case 10:
- //if(velocity == 0){ //fix for note-Off-0-velocity being actually note-on.... Dosent work, cannot distiguish between Real and Fake note-Off-0-velocity
- // midiNoteOn(channel,note,velocity);
- //}else{
- for(uint32_t ID=0;ID<numberOfSols;ID++){
- if(sol[ID].midiNote == note){
- if(sol[ID].stayOnMode || sol[ID].forceStayOnMode){
- gateSol(ID,0);
- break;
- }
- }
- }
- for(uint32_t ID=0;ID<numberOfServos;ID++){
- if(serv[ID].midiNote == note){
- gateServ(ID,0);
- }
- }
- //}
- break;
- case 1:
- remNote(0,note);
- distrubuteNotesToVoices(notes[0], voices, numVoices);
- for(uint32_t i = 0; i< numVoices; i++){
- setStepperFequencyFromMIDI(i,voices[i]);
- }
- break;
- case 2:
- remNote(1,note);
- distrubuteNotesToVoices(notes[1], floppyVoice, 1);
- setStepperFequencyFromMIDI(4,floppyVoice[0]);
- break;
- default:
- break;
- }
- noteIndicator[note] = 0;
- bool res = 0;
- for(uint32_t note = 0; note < 128; note++){
- if(noteIndicator[note]){res = 1;}
- }
- greenled(res);
- }
- //-----------------------------------------------------------------------------------------------------------------------------
- void midiControlChange(byte channel, byte control, byte value){
- p("control: "); p(channel);p(" ");p(control);p(" ");p(value);pl( );
- switch(channel){
- case 10:
- for(uint32_t ID=0;ID<numberOfSols;ID++){
- if(sol[ID].midiCC == control){
- setSolBaseOntimeFromMIDI(ID, value);
- p("ID:"); p(ID); p(" base:"); p(sol[ID].baseOnTime); p(" mulit:"); p(sol[ID].velocityMultiplyer);p(" output:"); pl(sol[ID].onTimeSet);
- }
- }
- for(uint32_t ID=0;ID<numberOfServos;ID++){
- if(serv[ID].midiCC1 == control){
- setServBasePositionFromMIDI(ID, 1, value);
- }
- if(serv[ID].midiCC2 == control){
- setServBasePositionFromMIDI(ID, 2, value);
- }
- }
- break;
- case 1:
- if(control == StepperMIDICC){
- SteppOctaveShift = ((round((float)value / 12.7)) - 5);
- }
- break;
- case 2:
- if(control == StepperMIDICC){
- SteppOctaveShift = ((round((float)value / 12.7)) - 5);
- }
- break;
- default:
- digitalWrite(ledR, 0);
- NAnoteTime = millis();
- break;
- }
- }
- //-----------------------------------------------------------------------------------------------------------------------------
- void midiReset(){
- // notesOn = 0;
- //memset(noteBuffer,0,sizeof(noteBuffer));
- }
- //-----------------------------------------------------------------------------------------------------------------------------
- void setupNotes(){
- memset(voices,255,sizeof(voices));
- memset(notes,255,sizeof(notes));
- numNotes[0] = 0;
- numNotes[1] = 0;
- }
- uint8_t addNote(uint8_t chan, uint8_t note){
- p("Add:"); pl(note);
- if(chan > 4){return 254;}
- if(note > 127){return 254;}
- for(uint32_t i = 0; i < 128; i++){
- if(notes[chan][i] == note){
- return 254;//do nothing error
- }
- if(notes[chan][i] == 255){
- break;
- }
- }
- notes[chan][numNotes[chan]] = note;
- numNotes[chan]++;
- return note;
- }
- //{15,74,56,33, 255,255,255,255}
- //{15,74,33,33,255,255,255,255}
- //{15,74,33,255,255,255,255,255}
- //{15,66,255,255,255,255,255,255}
- //{66,66,255,255,255,255,255,255}
- //{66,255,255,255,255,255,255,255}
- uint8_t remNote(uint8_t chan, uint8_t note){
- p("Rem:"); pl(note);
- if(chan > 4){return 254;}
- if(note > 127){return 254;}
- uint8_t newNote = 253;
- for(uint32_t i = 0; i < 128; i++){
- if(notes[chan][i] == note){
- for(uint32_t k = i; k < 128; k++){
- notes[chan][k] = notes[chan][k+1];
- if(notes[chan][k] == 255){
- if(k==0){
- newNote = 255; //gate off
- }else{
- newNote = notes[chan][k-1];
- }
- goto SUCSESS;
- }
- }
- }
- if(notes[chan][i] == 255){
- return 254;//do nothing error
- }
- }
- SUCSESS:
- numNotes[chan]--;
- return newNote; //if newNote is 255, gate off
- }
- void distrubuteNotesToVoices(uint8_t *note, uint8_t *voice, uint8_t numberOfVoices){
- //[255][255][255]
- //{8,255,255,255,255,255,255,255}
- uint8_t ignoreV[numberOfVoices];
- uint8_t ignoreN[numberOfVoices];
- memset(ignoreV,0,sizeof(ignoreV));
- memset(ignoreN,0,sizeof(ignoreN));
- uint8_t s = 0;
- for(uint8_t n = 0; n<128; n++){
- if((n >= numberOfVoices)&&(note[n] == 255)){
- s = n - numberOfVoices;
- break;
- }
- }
- //p("shift:"); pl(s);
- //find allready-allocated note-voice combos, and mark them to be skipped
- for(uint8_t v = 0; v<numberOfVoices; v++){
- if(voice[v] != 255){
- for(uint8_t n = 0; n<numberOfVoices; n++){
- if(note[n+s] != 255){
- if(voice[v] == note[n+s]){
- ignoreV[v] = 1;
- ignoreN[n] = 1;
- break;
- }
- }
- }
- }
- }
- //p("V[");p(ignoreV[0]);p("][");p(ignoreV[1]);p("][");p(ignoreV[2]);pl("]");
- //p("N[");p(ignoreN[0]);p("][");p(ignoreN[1]);p("][");p(ignoreN[2]);pl("]");
- //allocate notes to voices unless that are marked to be ignored
- for(uint8_t v = 0; v<numberOfVoices; v++){
- if(!ignoreV[v]){
- for(uint8_t n = 0; n<numberOfVoices; n++){
- if(!ignoreN[n]){
- voice[v] = note[n+s];
- ignoreV[v] = 1;
- ignoreN[n] = 1;
- break;
- }
- }
- }
- }
- //find where oldest note is in voices
- //
- return;
- }
- void printNotes(uint8_t chan){
- p("chan");
- p(chan);
- p(" notes:");
- p(numNotes[chan]);
- p(" {");
- for(uint32_t i = 0; i < 10; i++){
- p(notes[chan][i]);
- p(",");
- }
- pl("}");
- p("[");p(voices[0]);p("][");p(voices[1]);p("][");p(voices[2]);p("][");p(voices[3]);p("]");
- pl();
- p("[");p(stepp[0].freqOut);p("][");p(stepp[1].freqOut);p("][");p(stepp[2].freqOut);p("][");p(stepp[3].freqOut);p("]");
- pl();
- p("[");p(stepp[0].gate);p("][");p(stepp[1].gate);p("][");p(stepp[2].gate);p("][");p(stepp[3].gate);p("]");
- pl();
- }
Add Comment
Please, Sign In to add comment