Skip to content

Instantly share code, notes, and snippets.

@Dobby233Liu
Last active September 30, 2025 13:38
Show Gist options
  • Save Dobby233Liu/7179f9282fb3ee08007a8da5cba24a96 to your computer and use it in GitHub Desktop.
Save Dobby233Liu/7179f9282fb3ee08007a8da5cba24a96 to your computer and use it in GitHub Desktop.
import mido
import sys
import math
def clean_pitch_bend(input_path, output_path):
mid = mido.MidiFile(input_path)
# should make sure each track only manipulate one channel first
# (if BENDY is used please color all relevant notes to color 1)
# if a track manipulates multiple channels
# 1) its most certainly incorrect behavior (for us)
# 2) it will prevent domino from loading the file
for tr_n, track in enumerate(mid.tracks):
last_pb = {}
new_events = []
fucked_up_bends = "BENDY" in track.name
channel = None
delay_accum = 0
for msg in track:
if isinstance(msg, mido.Message) and msg.type != "sysex":
if channel is None: channel = msg.channel
elif channel != msg.channel:
raise Exception(f"track {tr_n} manipulates multiple channels")
if fucked_up_bends and msg.is_cc(10):
# BENDY (the plugin I use to generate pitch bends in FL)
# sabotages panning like this for some reason
# TODO: dont do this to the init at measure 0 tick 0
msg.value += 1
if msg.type == "pitchwheel":
# pitch is a signed int in mido
# i cant tell whether its just off by 1 or the math is completely incorrect
fixed_pitch = math.floor(msg.pitch / 8191.0 * 8192.0) if fucked_up_bends else msg.pitch
target_pb = last_pb.get(channel, None)
if target_pb is not None and target_pb.pitch == fixed_pitch:
delay_accum += msg.time
continue
msg.pitch = fixed_pitch
print(msg.pitch, str(target_pb))
last_pb[channel] = msg
if delay_accum > 0:
msg.time += delay_accum
delay_accum = 0
new_events.append(msg)
track[:] = new_events
mid.save(output_path)
clean_pitch_bend(sys.argv[1], sys.argv[2])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment