diff --git a/Bizet Carmen Prelude.mid b/Bizet Carmen Prelude.mid new file mode 100644 index 0000000..5e315e6 Binary files /dev/null and b/Bizet Carmen Prelude.mid differ diff --git a/MapleLeafRag.mid b/MapleLeafRag.mid new file mode 100644 index 0000000..5bdf172 Binary files /dev/null and b/MapleLeafRag.mid differ diff --git a/OMFG-Hello by Bagio.mid b/OMFG-Hello by Bagio.mid new file mode 100644 index 0000000..5fe5e3b Binary files /dev/null and b/OMFG-Hello by Bagio.mid differ diff --git a/lestoreadorscl.mid b/lestoreadorscl.mid new file mode 100755 index 0000000..e50fe48 Binary files /dev/null and b/lestoreadorscl.mid differ diff --git a/platformio.ini b/platformio.ini index b9a30fd..7c87531 100644 --- a/platformio.ini +++ b/platformio.ini @@ -20,6 +20,7 @@ lib_deps = [env] framework = arduino +build_flags = -O2 #build_flags = ${common.build_flags} lib_deps = ${common.lib_deps} monitor_speed = 115200 diff --git a/send2.py b/send2.py new file mode 100644 index 0000000..dfb57bf --- /dev/null +++ b/send2.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 + +import sys, argparse +import time +import threading + +import mido +import serial + +drum_channels = [9] + +def serialreceive(ser): + print("Serial running") + while ser: + try: + line = ser.readline().decode() + print(line) + except Exception: + pass + + +def main(argv): + inputfile = '' + outputport = '' + parser = argparse.ArgumentParser() + 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() + time.sleep(1) +# portmidi = mido.Backend('mido.backends.portmidi') + with mido.open_input() 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' or msg.type == 'pitchwheel': + 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)) + 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/shakira-medley.mid b/shakira-medley.mid new file mode 100644 index 0000000..7e2e8d9 Binary files /dev/null and b/shakira-medley.mid differ diff --git a/src/main.cpp b/src/main.cpp index fa2ce20..3896ad3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,8 +10,10 @@ #include #include -#include "midi/noteList.h" -#include "midi/pitches.h" +//#include "midi/noteList.h" +//#include "midi/pitches.h" + +#include "stepper.h" struct MySettings : public midi::DefaultSettings { @@ -22,7 +24,7 @@ MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, Serial, MIDI, MySettings); const int NUM_STEPPER = 5; -Tone freq[NUM_STEPPER]; +TimerStepper stepper[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) @@ -34,7 +36,6 @@ struct playing_t { }; volatile playing_t playing[NUM_STEPPER] = {0,255}; - int findSameNotes(byte noteNumber) { int candidate = -1; bool alreadyPlayingHarmonic = false; @@ -66,15 +67,10 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) //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); + stepper[i].playNote(inNumber); playing[i].noteNumber = inNumber; playing[i].channel = inChannel; previousMillis[i] = millis(); @@ -109,7 +104,7 @@ void handleNoteOff(byte inChannel, byte inNumber, byte inVelocity) digitalWrite(LED_PIN, LOW); for (int i=0; i> 7; for (int i=0; i= interval || previousMillis[i] == 0) { - digitalWrite(enable_pin[i], HIGH); + stepper[i].disable(); playing[i].noteNumber = 0; playing[i].channel = 255; } @@ -193,18 +161,7 @@ void loop() //Serial.println("test"); MIDI.read(); - //readMIDI(); - // turn the LED on (HIGH is the voltage level) - //digitalWrite(LED_PIN, HIGH); - //tone(X_STEP_PIN, 16*440U); - // wait for a second - //delay(100); - // turn the LED off by making the voltage LOW - //digitalWrite(LED_PIN, LOW); - //tone(X_STEP_PIN, 120U); - // wait for a second - //delay(100); - + for (int i=0; i +#include + +class FrequencyLUT { + public: + FrequencyLUT(); + uint16_t* frequencies; + uint16_t& operator[](int); +}; + +FrequencyLUT::FrequencyLUT() { + int pitch = 24; + frequencies = malloc(128*sizeof(uint16_t)); + for (int d=0; d<128; d++) { + frequencies[d] = pow(2.0, (d-69.0+pitch)/12.0) * 440.0; + } +} + +uint16_t& FrequencyLUT::operator[](int index) { + return frequencies[index]; +} + +FrequencyLUT frequencies; + +class Stepper { + public: + virtual void begin(int dir_pin, int step_pin, int enable_pin); + virtual void playTone(uint16_t freq) = 0; + virtual void playNote(int8_t midi_note); + virtual void bend(int value); + virtual void loop(); + virtual void stopTone() = 0; + void enable(); + void disable(); + protected: + int8_t currentNote; + int dir_pin; + int step_pin; + int enable_pin; + uint8_t multiplicator = 4; +}; + +class TimerStepper : public Stepper { + public: + void begin(int dir_pin, int step_pin, int enable_pin) override; + void playTone(uint16_t freq) override; + void stopTone() override; + void loop() {}; + private: + Tone tone; +}; + +class LoopStepper : public Stepper { + public: + void begin(int dir_pin, int step_pin, int enable_pin) override; + void playTone(uint16_t freq) override; + void stopTone() override; + void loop() override; + private: + unsigned long currentStepMicros; + unsigned long prevStepMicros; +}; + +void Stepper::begin(int dir_pin, int step_pin, int enable_pin) { + this->dir_pin = dir_pin; + this->step_pin = step_pin; + this->enable_pin = enable_pin; + + pinMode(dir_pin, OUTPUT); + pinMode(step_pin, OUTPUT); + pinMode(enable_pin, OUTPUT); + + digitalWrite(enable_pin, HIGH); +} + +void Stepper::enable() { + digitalWrite(enable_pin, LOW); +} + +void Stepper::disable() { + digitalWrite(enable_pin, HIGH); +} + +void Stepper::playNote(int8_t midi_note) { + currentNote = midi_note; + uint16_t f = frequencies[midi_note]; + f *= multiplicator; + while (f > 12000) f/=2; + playTone(f); +} + +void Stepper::bend(int value) { + uint16_t f = frequencies[currentNote]; + uint16_t f_b = f * pow(2, (double)value/(4096.0*12)); + playTone(f_b); +} + +void TimerStepper::begin(int dir_pin, int step_pin, int enable_pin) { + Stepper::begin(dir_pin, step_pin, enable_pin); + tone.begin(step_pin); +} + +void TimerStepper::playTone(uint16_t freq) { + enable(); + tone.play(freq); +} + +void TimerStepper::stopTone() { + currentNote = 0; + tone.stop(); +} + +void LoopStepper::begin(int dir_pin, int step_pin, int enable_pin) { + Stepper::begin(dir_pin, step_pin, enable_pin); + multiplicator = 1; +} + +void LoopStepper::playTone(uint16_t freq) { + enable(); + prevStepMicros = micros(); + currentStepMicros = 1000000UL / freq; +} + +void LoopStepper::stopTone() { + currentStepMicros = 0; +} + +void LoopStepper::loop() { + if (currentStepMicros == 0) return; + if (micros() - prevStepMicros >= currentStepMicros) { + prevStepMicros += currentStepMicros; + digitalWrite(step_pin, HIGH); + digitalWrite(step_pin, LOW); + } +} + + + +#endif /* _STEPPER_H */ diff --git a/starwarsmedley.mid b/starwarsmedley.mid new file mode 100755 index 0000000..74299dc Binary files /dev/null and b/starwarsmedley.mid differ diff --git a/wannabe05.mid b/wannabe05.mid new file mode 100755 index 0000000..57fc473 Binary files /dev/null and b/wannabe05.mid differ diff --git a/william_tell_overture.mid b/william_tell_overture.mid new file mode 100755 index 0000000..22a5ffa Binary files /dev/null and b/william_tell_overture.mid differ