Skip to content

Commit 987d416

Browse files
committed
y bend experiment
1 parent e9dd993 commit 987d416

File tree

3 files changed

+53
-5
lines changed

3 files changed

+53
-5
lines changed

src/core.py

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -789,12 +789,11 @@ def cb_midi_in(self, data, timestamp, force_channel=None):
789789
# rewrite the output channel based on app's MPE settings
790790
self.midi_write(self.midi_out, data, timestamp)
791791
else:
792-
# pitch bend
793792
# rewrite the output channel based on app's MPE settings
794793
if force_channel:
795-
data[0] = (d0 & 0xF0) + (force_channel-1)
794+
data[0] = (d0 & 0xF0) | (force_channel-1)
796795
elif not self.is_mpe():
797-
data[0] = (d0 & 0xF0) + (self.options.one_channel-1)
796+
data[0] = (d0 & 0xF0) | (self.options.one_channel-1)
798797

799798
skip = False
800799
if msg == 14:
@@ -831,6 +830,46 @@ def cb_midi_in(self, data, timestamp, force_channel=None):
831830
# print('pitch', bend, semitones)
832831
# stabilized = True
833832

833+
# This block has to happen before the below block rewrites y axis to pitch bend
834+
if self.options.y_bend:
835+
pb_range = self.options.bend_range * 2
836+
bend_threshold = 1 # units
837+
if msg == 14:
838+
# if y-bending enabled, rewrite pitch bend based on y bend value
839+
note = self.notes[ch]
840+
# if note.y_bend > EPSILON:
841+
val = decompose_pitch_bend((data[1], data[2]))
842+
note.bend = val
843+
val += note.y_bend / pb_range
844+
data[1], data[2] = compose_pitch_bend(val)
845+
846+
if msg == 11 and data[1] == 74:
847+
# print(data[2])
848+
if data[2] > 127 - bend_threshold:
849+
bend = (data[2] - (127 - bend_threshold)) / bend_threshold
850+
elif data[2] <= bend_threshold:
851+
# bend down?
852+
# bend = -(bend_threshold - data[2]) / bend_threshold
853+
bend = None
854+
else:
855+
bend = None
856+
note = self.notes[ch]
857+
data = [0xe0 | ch,0,0]
858+
if force_channel:
859+
data[0] = 0xe0 | (force_channel-1)
860+
elif not self.is_mpe():
861+
data[0] = 0xe0 | (self.options.one_channel-1)
862+
if bend is not None:
863+
if bend > 0.9:
864+
bend = 1.0
865+
elif bend < -0.9:
866+
bend = -1.0
867+
note.y_bend = bend
868+
data[1], data[2] = compose_pitch_bend(note.bend + note.y_bend / pb_range)
869+
else:
870+
note.y_bend = 0.0
871+
data[1], data[2] = compose_pitch_bend(note.bend + note.y_bend / pb_range)
872+
834873
if skip:
835874
pass
836875
elif msg == 11 and data[1] == 64: # sustain pedal
@@ -1127,6 +1166,9 @@ def __init__(self):
11271166
self.options.one_channel = get_option(
11281167
opts, "one_channel", DEFAULT_OPTIONS.one_channel
11291168
)
1169+
self.options.bend_range = get_option(
1170+
opts, "bend_range", DEFAULT_OPTIONS.bend_range
1171+
)
11301172

11311173
if "--lite" in sys.argv:
11321174
self.options.lite = True
@@ -1679,8 +1721,8 @@ def mpe_rpn(self, on=True):
16791721

16801722
def bend_rpn(self, on=True):
16811723
if on:
1682-
self.rpn(19, 24)
1683-
self.rpn(119, 24)
1724+
self.rpn(19, self.options.bend_range)
1725+
self.rpn(119, self.options.bend_range)
16841726
else:
16851727
self.rpn(19, 48)
16861728
self.rpn(119, 48)

src/note.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ def __init__(self):
1111
self.split = 0
1212
self.note = None
1313

14+
# apply additional bend?
15+
self.bend = 0.0
16+
self.y_bend = 0.0
17+
1418
# def logic(self, dt):
1519
# if self.pressed: # pressed, fade to pressure value
1620
# if self.intensity != self.pressure:

src/options.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,7 @@ class Options:
8989
# Allow Y axis to bend chromatically (not yet impl)
9090
y_bend: bool = False
9191

92+
bend_range: int = 24
93+
9294
DEFAULT_OPTIONS = Options()
9395

0 commit comments

Comments
 (0)