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