| 287 | } |
| 288 | |
| 289 | static int gmext_write_midi (const struct gmstream *stream, |
| 290 | std::vector<unsigned char> &midi) |
| 291 | { |
| 292 | // write MIDI file header |
| 293 | static const unsigned char midi_file_signature[8] = |
| 294 | { 'M','T','h','d',0,0,0,6 }; |
| 295 | for (int i=0; i<8; ++i) |
| 296 | midi.push_back(midi_file_signature[i]); |
| 297 | gmext_write_int16(midi, 1); |
| 298 | gmext_write_int16(midi, stream->ntracks + 1); |
| 299 | gmext_write_int16(midi, 24); |
| 300 | |
| 301 | // write global tempo track |
| 302 | static const unsigned char midi_track_header[8] = |
| 303 | { 'M','T','r','k',0,0,0,11 }; |
| 304 | for (int i=0; i<8; ++i) |
| 305 | midi.push_back(midi_track_header[i]); |
| 306 | gmext_write_delta(midi, 0); |
| 307 | gmext_write_tempo_ev(midi, stream->tempo); |
| 308 | gmext_write_delta(midi, 0); |
| 309 | gmext_write_end_ev(midi); |
| 310 | |
| 311 | // write tracks |
| 312 | for (int j=0; j<stream->ntracks; ++j) { |
| 313 | |
| 314 | // header |
| 315 | for (int i=0; i<4; ++i) |
| 316 | midi.push_back(midi_track_header[i]); |
| 317 | |
| 318 | size_t loffset = midi.size(); |
| 319 | for (int i=0; i<4; ++i) |
| 320 | midi.push_back(0); |
| 321 | |
| 322 | // initial data |
| 323 | static const unsigned char midi_track_init[8] = |
| 324 | { /* 0, 0xB0, */ 0x78, 0, 0, 0x79, 0, 0, 0x7B, 0 }; |
| 325 | midi.push_back(0); |
| 326 | midi.push_back(0xB0 | stream->tracks[j].channel); |
| 327 | for (int i=0; i<8; ++i) |
| 328 | midi.push_back(midi_track_init[i]); |
| 329 | |
| 330 | // body |
| 331 | struct output_status status = { 0, 0, 0 }; |
| 332 | if (gmext_write_sequence(midi, stream, |
| 333 | stream->tracks[j].channel, |
| 334 | &stream->tracks[j].seq, &status) == -1) |
| 335 | return -1; |
| 336 | |
| 337 | // end of track |
| 338 | gmext_write_delta(midi, status.delta); |
| 339 | gmext_write_end_ev(midi); |
| 340 | |
| 341 | // rewrite track length |
| 342 | unsigned char *p = &midi[loffset]; |
| 343 | size_t length = midi.size() - loffset - 4; |
| 344 | p[0] = length >> 24; |
| 345 | p[1] = length >> 16; |
| 346 | p[2] = length >> 8; |
no test coverage detected