Hendrik Langer
5 years ago
12 changed files with 216 additions and 59 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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:]) |
Binary file not shown.
@ -0,0 +1,142 @@ |
|||
#ifndef _STEPPER_H |
|||
#define _STEPPER_H |
|||
|
|||
#include <Arduino.h> |
|||
#include <Tone.h> |
|||
|
|||
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 */ |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue