| 87 | } |
| 88 | |
| 89 | void demonstrateMIDIFileIO() |
| 90 | { |
| 91 | std::cout << "\n=== MIDI File I/O Demo ===\n"; |
| 92 | |
| 93 | // Create a simple MIDI file in memory |
| 94 | std::vector<uint8_t> midiData = { |
| 95 | // MIDI file header |
| 96 | 'M', 'T', 'h', 'd', // Chunk type |
| 97 | 0x00, 0x00, 0x00, 0x06, // Chunk length |
| 98 | 0x00, 0x00, // Format type 0 |
| 99 | 0x00, 0x01, // Number of tracks |
| 100 | 0x00, 0x60, // Ticks per quarter note (96) |
| 101 | |
| 102 | // Track header |
| 103 | 'M', 'T', 'r', 'k', // Chunk type |
| 104 | 0x00, 0x00, 0x00, 0x0B, // Chunk length |
| 105 | |
| 106 | // Track events |
| 107 | 0x00, 0x90, 0x3C, 0x40, // Delta time 0, Note on C4, velocity 64 |
| 108 | 0x60, 0x80, 0x3C, 0x40, // Delta time 96, Note off C4, velocity 64 |
| 109 | 0x00, 0xFF, 0x2F, 0x00 // End of track |
| 110 | }; |
| 111 | |
| 112 | try |
| 113 | { |
| 114 | choc::midi::File midiFile; |
| 115 | midiFile.load (midiData.data(), midiData.size()); |
| 116 | |
| 117 | std::cout << "Successfully loaded MIDI file\n"; |
| 118 | std::cout << "Number of tracks: " << midiFile.tracks.size() << "\n"; |
| 119 | std::cout << "Time format: " << midiFile.timeFormat << " ticks per quarter note\n"; |
| 120 | |
| 121 | if (! midiFile.tracks.empty()) |
| 122 | { |
| 123 | std::cout << "Track 1 has " << midiFile.tracks[0].events.size() << " events:\n"; |
| 124 | |
| 125 | for (const auto& event : midiFile.tracks[0].events) |
| 126 | std::cout << " Tick " << event.tickPosition << ": " << event.message.getDescription() << "\n"; |
| 127 | } |
| 128 | |
| 129 | // Convert to sequence |
| 130 | auto sequence = midiFile.toSequence(); |
| 131 | std::cout << "\nConverted to sequence with " << sequence.events.size() << " events\n"; |
| 132 | |
| 133 | // Iterate through events with timing |
| 134 | std::cout << "\nEvents with timing (assuming 120 BPM):\n"; |
| 135 | |
| 136 | midiFile.iterateEvents ([](const choc::midi::LongMessage& msg, double timeInSeconds) |
| 137 | { |
| 138 | std::cout << " Time " << timeInSeconds << "s: " << msg.getDescription() << "\n"; |
| 139 | }); |
| 140 | } |
| 141 | catch (const std::runtime_error& e) |
| 142 | { |
| 143 | std::cout << "Error loading MIDI file: " << e.what() << "\n"; |
| 144 | } |
| 145 | } |
| 146 |
no test coverage detected