diff --git a/A-Whole-New-World-(Theme-From-'Aladdin').mid b/A-Whole-New-World-(Theme-From-'Aladdin').mid new file mode 100644 index 0000000..85a62a8 Binary files /dev/null and b/A-Whole-New-World-(Theme-From-'Aladdin').mid differ diff --git a/Bohemian-Rhapsody-1.mid b/Bohemian-Rhapsody-1.mid new file mode 100644 index 0000000..5e1a8af Binary files /dev/null and b/Bohemian-Rhapsody-1.mid differ diff --git a/Star-Wars-Theme-(From-'Star-Wars').mid b/Star-Wars-Theme-(From-'Star-Wars').mid new file mode 100644 index 0000000..b0fe849 Binary files /dev/null and b/Star-Wars-Theme-(From-'Star-Wars').mid differ diff --git a/darude-sandstorm.mid b/darude-sandstorm.mid new file mode 100644 index 0000000..b112d62 Binary files /dev/null and b/darude-sandstorm.mid differ diff --git a/mario64-medley.mid b/mario64-medley.mid new file mode 100644 index 0000000..1067088 Binary files /dev/null and b/mario64-medley.mid differ diff --git a/platformio.ini b/platformio.ini index 9ecc526..b9a30fd 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,7 +13,7 @@ default_envs = megaatmega2560 [common] lib_deps = - Tone + ToneLibrary # AccelStepper # SpeedyStepper MIDI Library diff --git a/send.py b/send.py index 1756908..8d16d76 100644 --- a/send.py +++ b/send.py @@ -1,15 +1,17 @@ #!/usr/bin/env python3 -import sys, getopt +import sys, argparse import time import threading from mido import MidiFile import serial +drum_channels = [9] + def serialreceive(ser): print("Serial running") - while True: + while ser: try: line = ser.readline().decode() print(line) @@ -20,32 +22,36 @@ def serialreceive(ser): def main(argv): inputfile = '' outputport = '' - try: - opts, args = getopt.getopt(argv, "hi:o:",["ifile=","oport="]) - except getopt.GetoptError: - print('send.py -i -o ') - sys.exit(2) - for opt, arg in opts: - if opt == '-h': - print('send.py -i -o ') - sys.exit() - elif opt in ("-i", "--ifile"): - inputfile = arg - elif opt in ("-o", "--oport"): - outputport = arg - with serial.Serial(outputport, 115200, timeout=12) as ser: + parser = argparse.ArgumentParser() + parser.add_argument('midifilename', help="the midi file you want to send") + parser.add_argument('-P', '--serialport', help="serial port to open", default="/dev/ttyUSB0") + parser.add_argument('--with-drums', action="store_true", help="send percussion track 10") + args = parser.parse_args() + with serial.Serial(args.serialport, 115200, timeout=12) as ser: receivethread = threading.Thread(target=serialreceive, args=(ser,)) + receivethread.daemon = True receivethread.start() - with MidiFile(inputfile) as mid: + time.sleep(1) + with MidiFile(args.midifilename) as mid: for msg in mid: time.sleep(msg.time) if not msg.is_meta: if msg.type == 'note_on' or msg.type == 'note_off': - print(msg) - ser.write(msg.bin()) + if (not (msg.channel in drum_channels)) or args.with_drums: + print(msg) + ser.write(msg.bin()) + else: + print("skipped percussion: " + str(msg)) else: print("not sent: " + str(msg)) - #time.sleep(1000) + if msg.type == 'program_change' and msg.program in [50,]: + drum_channels.append(msg.channel) + + else: + print("meta message: " + str(msg)) + print("EOF") + print("done") + print("serial closed") if __name__ == "__main__": main(sys.argv[1:]) diff --git a/smario.mid b/smario.mid new file mode 100644 index 0000000..c273142 Binary files /dev/null and b/smario.mid differ diff --git a/src/main.cpp b/src/main.cpp index 5fa17de..bac279d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,14 +20,33 @@ MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, Serial, MIDI, MySettings); -Tone freq1; -Tone freq2; -Tone freq3; +const int NUM_STEPPER = 5; -int ledState = LOW; // ledState used to set the LED +Tone freq[NUM_STEPPER]; + +unsigned long previousMillis[NUM_STEPPER] = {0}; // will store last time LED was updated const long interval = 1000; // interval at which to blink (milliseconds) -unsigned long previousMillis = 0; // will store last time LED was updated -unsigned long lastMillis[3] = {0,0,0}; // will store last time LED was updated +volatile byte playing[NUM_STEPPER] = {0}; +int enable_pin[NUM_STEPPER] = {X_ENABLE_PIN, Y_ENABLE_PIN, Z_ENABLE_PIN, E0_ENABLE_PIN, E1_ENABLE_PIN}; + + +int findSameNotes(byte noteNumber) { + int candidate = -1; + bool alreadyPlayingHarmonic = false; + for (int i=0; i= 0 && !alreadyPlayingHarmonic) return candidate; + return -1; +} void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) @@ -38,20 +57,37 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) // Serial.println(inVelocity); // Serial.flush(); //noTone(); - long freq = sNotePitches[inNumber]; - freq *=4; - while (freq > 12000) freq/=2; - if (inChannel == 9) digitalWrite(LED_PIN, HIGH); - if (inChannel == 9) { - freq1.play(freq); - lastMillis[0] = millis(); - } else if (inChannel == 7) { - freq2.play(freq); - lastMillis[1] = millis(); - } else if (inChannel == 2) { - freq3.play(freq); - lastMillis[2] = millis(); + + //if (inChannel == 0 || inChannel >= 32) return; + //if (inChannel == 8) return; + + long f = sNotePitches[inNumber]; + f *= 4; + while (f > 12000) f/=2; + //digitalWrite(LED_PIN, HIGH); + bool sent = false; + for (int i=0; i= 0) { + digitalWrite(enable_pin[i], LOW); + freq[i].play(f); + playing[i] = inNumber; + previousMillis[i] = millis(); + } + } + } void handleNoteOff(byte inChannel, byte inNumber, byte inVelocity) { @@ -59,21 +95,30 @@ void handleNoteOff(byte inChannel, byte inNumber, byte inVelocity) // Serial.print(inNumber); // Serial.print("\tvelocity: "); // Serial.println(inVelocity); - if (inChannel == 9) digitalWrite(LED_PIN, LOW); - if (inChannel == 9) freq1.stop(); - if (inChannel == 7) freq2.stop(); - if (inChannel == 2) freq3.stop(); + + //if (inChannel == 0 || inChannel >= 32) return; + //if (inChannel == 8) return; + + digitalWrite(LED_PIN, LOW); + for (int i=0; i= interval) { - previousMillis = currentMillis; - Serial.println("arduino"); - // if the LED is off turn it on and vice-versa: - if (ledState == LOW) { - ledState = HIGH; - } else { - ledState = LOW; - } - // set the LED with the ledState of the variable: - //digitalWrite(LED_PIN, ledState); - } - - if (currentMillis - lastMillis[0] >= 2000 || lastMillis[0] == 0) { - digitalWrite(X_ENABLE_PIN, HIGH); - } else { - digitalWrite(X_ENABLE_PIN, LOW); - } - if (currentMillis - lastMillis[1] >= 2000 || lastMillis[1] == 0) { - digitalWrite(Y_ENABLE_PIN, HIGH); - } else { - digitalWrite(Y_ENABLE_PIN, LOW); - } - if (currentMillis - lastMillis[2] >= 2000 || lastMillis[2] == 0) { - digitalWrite(Z_ENABLE_PIN, HIGH); - } else { - digitalWrite(Z_ENABLE_PIN, LOW); + for (int i=0; i= interval || previousMillis[i] == 0) { + digitalWrite(enable_pin[i], HIGH); + playing[i] = 0; + } } //Serial.println("test"); @@ -159,4 +183,7 @@ void loop() //tone(X_STEP_PIN, 120U); // wait for a second //delay(100); + + + } diff --git a/src/midi/pitches.h b/src/midi/pitches.h index 284c14d..0cb1542 100644 --- a/src/midi/pitches.h +++ b/src/midi/pitches.h @@ -92,6 +92,14 @@ #define NOTE_CS8 4435 #define NOTE_D8 4699 #define NOTE_DS8 4978 +#define NOTE_E8 5274 +#define NOTE_F8 5588 +#define NOTE_FS8 5920 +#define NOTE_G8 6272 +#define NOTE_GS8 6645 +#define NOTE_A8 7040 +#define NOTE_AS8 7459 +#define NOTE_B8 7902 static const uint16_t sNotePitches[] = { NOTE_B0, NOTE_C1, NOTE_CS1, NOTE_D1, NOTE_DS1, NOTE_E1, NOTE_F1, NOTE_FS1, @@ -104,5 +112,7 @@ static const uint16_t sNotePitches[] = { NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5, NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6, NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, - NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7, NOTE_C8, NOTE_CS8, NOTE_D8, NOTE_DS8, + NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7, NOTE_C8, NOTE_CS8, NOTE_D8, + NOTE_DS8, NOTE_E8, NOTE_F8, NOTE_FS8, NOTE_G8, NOTE_GS8, NOTE_A8, NOTE_AS8, + NOTE_B8 }; diff --git a/toto-africa.mid b/toto-africa.mid new file mode 100644 index 0000000..d4ffd3b Binary files /dev/null and b/toto-africa.mid differ