initial implementation of pitch bending
This commit is contained in:
parent
e30766e799
commit
e64e4c19e8
|
@ -53,3 +53,15 @@ for i in range(start_pitch, end_pitch):
|
|||
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("};")
|
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();
|
||||
}
|
||||
|
||||
void midi_pitch_bend(uint8_t channel, int bend) {
|
||||
ASSERT_CHANNEL();
|
||||
motors[channel - 1].TickPitchBend(bend);
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Arduino library initialization
|
||||
// Needed for some functions to work (like micros)
|
||||
|
@ -76,6 +81,7 @@ int main() {
|
|||
// Set up MIDI callbacks
|
||||
MIDI.setHandleNoteOn(midi_note_on);
|
||||
MIDI.setHandleNoteOff(midi_note_off);
|
||||
MIDI.setHandlePitchBend(midi_pitch_bend);
|
||||
|
||||
unsigned long cur_micros;
|
||||
unsigned long cur_half_micros;
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
MotorControl::MotorControl(int pin_dir, int 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()
|
||||
}
|
||||
|
@ -19,6 +20,7 @@ void MotorControl::Init() {
|
|||
|
||||
void MotorControl::TickOn(unsigned long period_half_micros) {
|
||||
tick_period_half_micros = period_half_micros;
|
||||
tick_period_orig_half_micros = period_half_micros;
|
||||
// Force the next tick to happen
|
||||
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]);
|
||||
}
|
||||
|
||||
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() {
|
||||
tick_period_half_micros = 0;
|
||||
tick_period_orig_half_micros = 0;
|
||||
}
|
||||
|
||||
void MotorControl::Tick(unsigned long cur_half_micros) {
|
||||
|
|
|
@ -8,6 +8,8 @@ class MotorControl {
|
|||
unsigned long last_tick_half_micros;
|
||||
// Interval of motor ticking; 0 to disable the motor
|
||||
unsigned long tick_period_half_micros;
|
||||
// Original period of motor ticking (without applying bend)
|
||||
unsigned long tick_period_orig_half_micros;
|
||||
|
||||
void DoTick();
|
||||
public:
|
||||
|
@ -19,6 +21,8 @@ class MotorControl {
|
|||
void TickOn(unsigned long period_half_micros);
|
||||
// Set the motor to tick with a given MIDI pitch
|
||||
void TickAtPitch(unsigned int midi_pitch);
|
||||
// Set the pitch bend
|
||||
void TickPitchBend(int bend);
|
||||
// Turn off the motor
|
||||
void TickOff();
|
||||
// Perform a tick if necessary
|
||||
|
|
Loading…
Reference in New Issue