Skip to content

Commit af1a519

Browse files
Add pitch bend scaling for MPE slides + fix compose_pitch_bend overflow
- Add bend_scale setting (default 1.0) for adjusting pitch bend intensity - Fix compose_pitch_bend() overflow bug: max bend (16384) wrapped to min - Add helpful comments: LinnStrument Pitch Quantize must be OFF for smooth slides
1 parent 5d7941d commit af1a519

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

src/core.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,15 @@ def cb_midi_in(self, data, timestamp, force_channel=None):
957957

958958
skip = False
959959
if msg == 14:
960+
# Scale pitch bend for mech layout (bend_scale in settings.ini)
961+
# Especially useful for whole-tone slides - smooth bends let you
962+
# reliably hit semitones in between the whole tones
963+
# NOTE: LinnStrument Pitch Quantize must be OFF for smooth slides
964+
# NOTE: Synth must have MPE enabled for per-note slides
965+
bend_val = decompose_pitch_bend((data[1], data[2]))
966+
bend_val *= self.options.bend_scale
967+
data[1], data[2] = compose_pitch_bend(bend_val)
968+
960969
if self.is_split():
961970
# experimental: ignore pitch bend for a certain split
962971
split_chan = self.notes[ch].split
@@ -1386,6 +1395,11 @@ def __init__(self):
13861395
self.options.y_bend = get_option(
13871396
opts, "y_bend", DEFAULT_OPTIONS.y_bend
13881397
)
1398+
1399+
# Pitch bend scaling for mech layout (adjust if slides are too slow/fast)
1400+
self.options.bend_scale = get_option(
1401+
opts, "bend_scale", DEFAULT_OPTIONS.bend_scale
1402+
)
13891403

13901404
# self.options.mpe = get_option(
13911405
# opts, "mpe", DEFAULT_OPTIONS.mpe

src/settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ class Settings:
9696

9797
bend_range: int = 24
9898

99+
# Pitch bend scaling for mech layout (1.0 = no scaling, 2.0 = double)
100+
bend_scale: float = 1.0
101+
99102
row_offset: int = 5
100103
column_offset: int = 2
101104
base_offset: int = 4

src/util.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,12 @@ def decompose_pitch_bend(pitch_bend_bytes):
108108
return pitch_bend_norm
109109

110110
def compose_pitch_bend(pitch_bend_norm):
111-
pitch_bend_value = int((pitch_bend_norm + 1.0) * 8192)
111+
# Clamp input to valid range
112+
pitch_bend_norm = max(-1.0, min(1.0, pitch_bend_norm))
113+
# Scale to 0-16383 (14-bit MIDI pitch bend range)
114+
# Using 8191.5 and round() to correctly map: -1.0->0, 0.0->8192, 1.0->16383
115+
pitch_bend_value = int(round((pitch_bend_norm + 1.0) * 8191.5))
116+
pitch_bend_value = max(0, min(16383, pitch_bend_value)) # Ensure valid range
112117
pitch_bend_bytes = [pitch_bend_value & 0x7F, (pitch_bend_value >> 7) & 0x7F]
113118
return pitch_bend_bytes
114119

0 commit comments

Comments
 (0)