Spaces:
Running
Running
File size: 1,491 Bytes
7152eb3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | import io
def transpose_midi(midi_bytes: bytes | None) -> bytes | None:
"""
Transpose all MIDI notes by +2 semitones (clamped to 0-127).
Args:
midi_bytes: Raw MIDI file bytes from the frontend
Returns:
Transposed MIDI file bytes
"""
if midi_bytes is None:
return None
try:
import mido
# Parse the MIDI file from bytes
midi_file = mido.MidiFile(file=io.BytesIO(midi_bytes))
# Create a new MIDI file with transposed notes
new_midi = mido.MidiFile(ticks_per_beat=midi_file.ticks_per_beat)
for track in midi_file.tracks:
new_track = mido.MidiTrack()
for msg in track:
if msg.type in ('note_on', 'note_off'):
# Transpose by +2 semitones, clamped to valid MIDI range
new_note = min(127, max(0, msg.note + 2))
new_msg = msg.copy(note=new_note)
new_track.append(new_msg)
else:
# Copy non-note messages as-is
new_track.append(msg.copy())
new_midi.tracks.append(new_track)
# Write to bytes
output = io.BytesIO()
new_midi.save(file=output)
return output.getvalue()
except Exception as e:
print(f"Error processing MIDI: {e}")
return midi_bytes # Return original on error
|