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