initial implementation of pitch bending
This commit is contained in:
parent
e30766e799
commit
e64e4c19e8
|
@ -52,4 +52,16 @@ for i in range(start_pitch, end_pitch):
|
||||||
period = int(period / 2)
|
period = int(period / 2)
|
||||||
print(" " + str(period) + "ul,\t// " + name)
|
print(" " + str(period) + "ul,\t// " + name)
|
||||||
|
|
||||||
|
print("};")
|
||||||
|
|
||||||
|
print("")
|
||||||
|
print("// scale factors for bend values from 0 to 255")
|
||||||
|
print("// We don't support the full 16385 levels of MIDI bend")
|
||||||
|
print("// MIDI bend values have to be converted first to the nearest supported one")
|
||||||
|
print("constexpr float midi_pitch_bend_scale[256] = {")
|
||||||
|
|
||||||
|
for i in range(0, 256):
|
||||||
|
factor = pow(2, (8192 - i * 64) / 49152)
|
||||||
|
print(" " + str(factor) + "f,\t// " + str(i))
|
||||||
|
|
||||||
print("};")
|
print("};")
|
6
main.cpp
6
main.cpp
|
@ -53,6 +53,11 @@ void midi_note_off(uint8_t channel, uint8_t note, uint8_t velocity) {
|
||||||
motors[channel - 1].TickOff();
|
motors[channel - 1].TickOff();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void midi_pitch_bend(uint8_t channel, int bend) {
|
||||||
|
ASSERT_CHANNEL();
|
||||||
|
motors[channel - 1].TickPitchBend(bend);
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
// Arduino library initialization
|
// Arduino library initialization
|
||||||
// Needed for some functions to work (like micros)
|
// Needed for some functions to work (like micros)
|
||||||
|
@ -76,6 +81,7 @@ int main() {
|
||||||
// Set up MIDI callbacks
|
// Set up MIDI callbacks
|
||||||
MIDI.setHandleNoteOn(midi_note_on);
|
MIDI.setHandleNoteOn(midi_note_on);
|
||||||
MIDI.setHandleNoteOff(midi_note_off);
|
MIDI.setHandleNoteOff(midi_note_off);
|
||||||
|
MIDI.setHandlePitchBend(midi_pitch_bend);
|
||||||
|
|
||||||
unsigned long cur_micros;
|
unsigned long cur_micros;
|
||||||
unsigned long cur_half_micros;
|
unsigned long cur_half_micros;
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
MotorControl::MotorControl(int pin_dir, int pin_step) :
|
MotorControl::MotorControl(int pin_dir, int pin_step) :
|
||||||
pin_dir(pin_dir), pin_step(pin_step),
|
pin_dir(pin_dir), pin_step(pin_step),
|
||||||
last_tick_half_micros(0), tick_period_half_micros(0)
|
last_tick_half_micros(0), tick_period_half_micros(0),
|
||||||
|
tick_period_orig_half_micros(0)
|
||||||
{
|
{
|
||||||
// No actual constructor logic -- initialization is in Init()
|
// No actual constructor logic -- initialization is in Init()
|
||||||
}
|
}
|
||||||
|
@ -19,6 +20,7 @@ void MotorControl::Init() {
|
||||||
|
|
||||||
void MotorControl::TickOn(unsigned long period_half_micros) {
|
void MotorControl::TickOn(unsigned long period_half_micros) {
|
||||||
tick_period_half_micros = period_half_micros;
|
tick_period_half_micros = period_half_micros;
|
||||||
|
tick_period_orig_half_micros = period_half_micros;
|
||||||
// Force the next tick to happen
|
// Force the next tick to happen
|
||||||
last_tick_half_micros = 0;
|
last_tick_half_micros = 0;
|
||||||
}
|
}
|
||||||
|
@ -32,8 +34,19 @@ void MotorControl::TickAtPitch(unsigned int midi_pitch) {
|
||||||
TickOn(midi_pitch_period[midi_pitch - midi_pitch_offset]);
|
TickOn(midi_pitch_period[midi_pitch - midi_pitch_offset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MotorControl::TickPitchBend(int bend) {
|
||||||
|
if (bend < 0 || bend >= 16384) return;
|
||||||
|
if (tick_period_orig_half_micros == 0) return;
|
||||||
|
|
||||||
|
// Scale the MIDI bend value down to 0 - 255
|
||||||
|
bend = bend / 64;
|
||||||
|
|
||||||
|
tick_period_half_micros = (unsigned long) (((float) tick_period_orig_half_micros) * midi_pitch_bend_scale[bend]);
|
||||||
|
}
|
||||||
|
|
||||||
void MotorControl::TickOff() {
|
void MotorControl::TickOff() {
|
||||||
tick_period_half_micros = 0;
|
tick_period_half_micros = 0;
|
||||||
|
tick_period_orig_half_micros = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MotorControl::Tick(unsigned long cur_half_micros) {
|
void MotorControl::Tick(unsigned long cur_half_micros) {
|
||||||
|
|
|
@ -8,6 +8,8 @@ class MotorControl {
|
||||||
unsigned long last_tick_half_micros;
|
unsigned long last_tick_half_micros;
|
||||||
// Interval of motor ticking; 0 to disable the motor
|
// Interval of motor ticking; 0 to disable the motor
|
||||||
unsigned long tick_period_half_micros;
|
unsigned long tick_period_half_micros;
|
||||||
|
// Original period of motor ticking (without applying bend)
|
||||||
|
unsigned long tick_period_orig_half_micros;
|
||||||
|
|
||||||
void DoTick();
|
void DoTick();
|
||||||
public:
|
public:
|
||||||
|
@ -19,6 +21,8 @@ class MotorControl {
|
||||||
void TickOn(unsigned long period_half_micros);
|
void TickOn(unsigned long period_half_micros);
|
||||||
// Set the motor to tick with a given MIDI pitch
|
// Set the motor to tick with a given MIDI pitch
|
||||||
void TickAtPitch(unsigned int midi_pitch);
|
void TickAtPitch(unsigned int midi_pitch);
|
||||||
|
// Set the pitch bend
|
||||||
|
void TickPitchBend(int bend);
|
||||||
// Turn off the motor
|
// Turn off the motor
|
||||||
void TickOff();
|
void TickOff();
|
||||||
// Perform a tick if necessary
|
// Perform a tick if necessary
|
||||||
|
|
Loading…
Reference in New Issue