import struct # Constants for MIDI to Frequency conversion A4_MIDI = 69 A4_FREQ = 440.0 def midi_to_freq(note): return A4_FREQ * (2 ** ((note - A4_MIDI) / 12.0)) def read_variable_length(data, index): value = 0 while True: byte = data[index] index += 1 value = (value << 7) | (byte & 0x7F) if not (byte & 0x80): break return value, index def parse_midi(filename): with open(filename, 'rb') as f: data = f.read() # Check MIDI header if data[:4] != b'MThd': raise ValueError("Invalid MIDI file") # Read header values header_size = struct.unpack('>I', data[4:8])[0] format_type, num_tracks, division = struct.unpack('>HHH', data[8:14]) index = 14 + (header_size - 6) print("Header size:", header_size) print("Format type:", format_type) print("Number of tracks:", num_tracks) print("Division:", division) notes = [] active_notes = {} last_time = 0 while index < len(data): if data[index:index+4] == b'MTrk': index += 4 track_length = struct.unpack('>I', data[index:index+4])[0] index += 4 track_end = index + track_length while index < track_end: delta_time, index = read_variable_length(data, index) last_time += delta_time event = data[index] index += 1 if event == 0xFF: # Meta event meta_type = data[index] index += 1 length, index = read_variable_length(data, index) index += length # Skip meta event data elif event >= 0x80: # MIDI event status = event & 0xF0 channel = event & 0x0F if status in (0x90, 0x80): # Note On/Off note = data[index] velocity = data[index + 1] index += 2 if status == 0x90 and velocity > 0: # Note On active_notes[note] = last_time elif status == 0x80 or (status == 0x90 and velocity == 0): # Note Off if note in active_notes: start_time = active_notes.pop(note) duration = last_time - start_time pause_duration = 0 if not notes else start_time - (notes[-1][1] + notes[-1][2]) notes.append((midi_to_freq(note), int(duration), int(pause_duration))) else: index += 1 # Skip unknown event return notes def generate_c_array(notes): c_code = "const struct Note notes[] = {\n" for freq, duration, pause in notes: c_code += f" {{{freq:.2f}, {duration}, {pause}}},\n" c_code += "};\n" return c_code # Example usage midi_file = "track_1.mid" # Replace with your MIDI file notes = parse_midi(midi_file) c_array = generate_c_array(notes) print(c_array)