You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
30 lines
1.1 KiB
30 lines
1.1 KiB
import mido
|
|
|
|
|
|
def process(midi: mido.MidiFile, vel_min: int, vel_max: int, tracks: set[int] | None = None) -> mido.MidiFile:
|
|
# Collect current velocity range from note_on messages in selected tracks
|
|
cur_min = 127
|
|
cur_max = 0
|
|
for i, track in enumerate(midi.tracks):
|
|
if tracks is not None and i not in tracks:
|
|
continue
|
|
for msg in track:
|
|
if msg.type == 'note_on' and msg.velocity > 0:
|
|
if msg.velocity < cur_min:
|
|
cur_min = msg.velocity
|
|
if msg.velocity > cur_max:
|
|
cur_max = msg.velocity
|
|
|
|
cur_range = cur_max - cur_min if cur_max > cur_min else 1
|
|
|
|
# Remap velocities to new range
|
|
for i, track in enumerate(midi.tracks):
|
|
if tracks is not None and i not in tracks:
|
|
continue
|
|
for msg in track:
|
|
if msg.type == 'note_on' and msg.velocity > 0:
|
|
ratio = (msg.velocity - cur_min) / cur_range
|
|
msg.velocity = round(vel_min + ratio * (vel_max - vel_min))
|
|
msg.velocity = max(1, min(127, msg.velocity))
|
|
|
|
return midi
|