1 /*
2 SDLPoP, a port/conversion of the DOS game Prince of Persia.
3 Copyright (C) 2013-2021 Dávid Nagy
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
17
18 The authors of this program may be contacted at https://forum.princed.org
19
20 DESCRIPTION:
21 MIDI playback routines for SDLPoP.
22
23 CREDITS:
24 The OPL integration code is based in part on Chocolate Doom's MIDI interface, by Simon Howard (GPLv2-licensed).
25 Uses the Nuked OPL3 emulator by Alexey Khokholov (GPLv2-licensed).
26 MIDI playback code also published as standalone playback program 'popmidi' by Falcury (GPLv3)
27 */
28
29 #include "common.h"
30 #include "opl3.h"
31 #include "math.h"
32
33 #define MAX_MIDI_CHANNELS 16
34 #define MAX_OPL_VOICES 18
35
36 // OPL3 supports more channels (voices) than OPL2: you could increase the number of used voices (try it!)
37 // However, released notes can linger longer, so for some tracks it will sound too 'washed out'.
38 // For example, listen to these sounds with 18 voices enabled:
39 // * The potion music in Potion1.mff and Potion2.mff
40 // * The hourglass summoning sound in Jaffar.mff
41 #define NUM_OPL_VOICES 9
42
43 extern short midi_playing; // seg009.c
44 extern SDL_AudioSpec* digi_audiospec; // seg009.c
45 extern int digi_unavailable; // seg009.c
46
47 static opl3_chip opl_chip;
48 static void* instruments_data;
49 static instrument_type* instruments;
50 static int num_instruments;
51 static byte voice_note[MAX_OPL_VOICES];
52 static int voice_instrument[MAX_OPL_VOICES];
53 static int voice_channel[MAX_OPL_VOICES];
54 static int channel_instrument[MAX_MIDI_CHANNELS];
55 static int last_used_voice;
56 static int num_midi_tracks;
57 static parsed_midi_type parsed_midi;
58 static midi_track_type* midi_tracks;
59 static int64_t midi_current_pos; // in MIDI ticks
60 static float midi_current_pos_fract_part; // partial ticks after the decimal point
61 static int ticks_to_next_pause; // in MIDI ticks
62 static dword us_per_beat;
63 static dword ticks_per_beat;
64 static int mixing_freq;
65 static sbyte midi_semitones_higher;
66 static float current_midi_tempo_modifier;
67
68 // Tempo adjustments for specific songs:
69 // * PV scene, with 'Story 3 Jaffar enters':
70 // Speed must be exactly right, otherwise it will not line up with the flashing animation in the cutscene.
71 // The 'Jaffar enters' song has tempo 705882 (maybe this tempo was carefully fine-tuned)?
72 // * Intro music: playback speed must match the title appearances/transitions.
73 const float midi_tempo_modifiers[58] = {
74 [sound_53_story_3_Jaffar_comes] = -0.03f, // 3% speedup
75 [sound_54_intro_music] = 0.03f, // 3% slowdown
76 };
77
78 // The hardcoded instrument is used as a fallback, if instrument data is not available for some reason.
79 static instrument_type hardcoded_instrument = {
80 0x13, 0x09, 0x04, {{0x02, 0x8D, 0xD7, 0x37, 0x00}, {0x03, 0x03, 0xF5, 0x18, 0x00}}, 0x00, {0x00, 0x00},
81 };
82
83 // Read a variable length integer (max 4 bytes).
midi_read_variable_length(byte ** buffer_position)84 static dword midi_read_variable_length(byte** buffer_position) {
85 dword result = 0;
86 byte* pos = *buffer_position;
87 int i;
88 for (i = 0; i < 4; ++i) {
89 result = (result << 7) | (pos[i] & 0x7F);
90 if ((pos[i] & 0x80) == 0) break; // The most significant bit being 0 means that this is the last u8.
91 }
92 *buffer_position += i+1; // Advance the pointer, so we know where the next field starts.
93 return result;
94 }
95
free_parsed_midi(parsed_midi_type * parsed_midi)96 void free_parsed_midi(parsed_midi_type* parsed_midi) {
97 for (int i = 0; i < parsed_midi->num_tracks; ++i) {
98 free(parsed_midi->tracks[i].events);
99 }
100 free(parsed_midi->tracks);
101 memset(&parsed_midi, 0, sizeof(parsed_midi));
102 }
103
parse_midi(midi_raw_chunk_type * midi,parsed_midi_type * parsed_midi)104 bool parse_midi(midi_raw_chunk_type* midi, parsed_midi_type* parsed_midi) {
105 parsed_midi->ticks_per_beat = 24;
106 if (memcmp(midi->chunk_type, "MThd", 4) != 0) {
107 printf("Warning: Tried to play a midi sound without the 'MThd' chunk header.\n");
108 return 0;
109 }
110 if (SDL_SwapBE32(midi->chunk_length) != 6) {
111 printf("Warning: Midi file with an invalid header length (expected 6, is %d)\n",
112 SDL_SwapBE32(midi->chunk_length));
113 return 0;
114 }
115 word midi_format = SDL_SwapBE16(midi->header.format);
116 if (midi_format >= 2) {
117 printf("Warning: Unsupported midi format %d (only type 0 or 1 files are supported)\n", midi_format);
118 return 0;
119 }
120 word num_tracks = SDL_SwapBE16(midi->header.num_tracks);
121 if (num_tracks < 1) {
122 printf("Warning: Midi sound does not have any tracks.\n");
123 return 0;
124 }
125 int division = SDL_SwapBE16(midi->header.time_division);
126 if (division < 0) {
127 division = (-(division / 256)) * (division & 0xFF); // Translate time delta from the alternative SMTPE format.
128 }
129 parsed_midi->ticks_per_beat = division;
130
131 parsed_midi->tracks = calloc(1, num_tracks * sizeof(midi_track_type));
132 parsed_midi->num_tracks = num_tracks;
133 midi_raw_chunk_type* next_track_chunk = (midi_raw_chunk_type*) midi->header.tracks; // The first track chunk starts after the header chunk.
134 byte last_event_type = 0;
135 for (int track_index = 0; track_index < num_tracks; ++track_index) {
136 midi_raw_chunk_type* track_chunk = next_track_chunk;
137 if (memcmp(track_chunk->chunk_type, "MTrk", 4) != 0) {
138 printf("Warning: midi track without 'MTrk' chunk header.\n");
139 free(parsed_midi->tracks);
140 memset(&parsed_midi, 0, sizeof(parsed_midi));
141 return 0;
142 }
143 next_track_chunk = (midi_raw_chunk_type*) (track_chunk->data + (dword) SDL_SwapBE32(track_chunk->chunk_length));
144 midi_track_type* track = &parsed_midi->tracks[track_index];
145 byte* buffer_position = track_chunk->data;
146 for (;;) {
147 track->events = realloc(track->events, (++track->num_events) * sizeof(midi_event_type));
148 midi_event_type* event = &track->events[track->num_events - 1];
149 event->delta_time = midi_read_variable_length(&buffer_position);
150 event->event_type = *buffer_position;
151 if (event->event_type & 0x80) {
152 if (event->event_type < 0xF8) last_event_type = event->event_type;
153 ++buffer_position;
154 } else {
155 event->event_type = last_event_type; // Implicit use of the previous event type.
156 }
157 // Determine the event type and parse the event.
158 int num_channel_event_params = 1;
159 switch (event->event_type & 0xF0) {
160 case 0x80: // note off
161 case 0x90: // note on
162 case 0xA0: // aftertouch
163 case 0xB0: // controller
164 case 0xE0: // pitch bend
165 num_channel_event_params = 2; //fallthrough
166 case 0xC0: // program change
167 case 0xD0: { // channel aftertouch
168 // Read the channel event.
169 event->channel.channel = event->event_type & 0x0F;
170 event->event_type &= 0xF0;
171 event->channel.param1 = *buffer_position++;
172 if (num_channel_event_params == 2) {
173 event->channel.param2 = *buffer_position++;
174 }
175 }
176 break;
177 default:
178 // Not a channel event.
179 switch (event->event_type) {
180 case 0xF0: // SysEx
181 case 0xF7: // SysEx split
182 // Read SysEx event
183 event->sysex.length = midi_read_variable_length(&buffer_position);
184 event->sysex.data = buffer_position;
185 buffer_position += event->sysex.length;
186 break;
187 case 0xFF: // Meta event
188 event->meta.type = *buffer_position++;
189 event->meta.length = midi_read_variable_length(&buffer_position);
190 event->meta.data = buffer_position;
191 buffer_position += event->meta.length;
192 break;
193 default:
194 printf("Warning: unknown midi event type 0x%02x (track %d, event %d)\n",
195 event->event_type, track_index, track->num_events - 1);
196 free_parsed_midi(parsed_midi);
197 return 0;
198 }
199 }
200 if (event->event_type == 0xFF /* meta event */ && event->meta.type == 0x2F /* end of track */) {
201 break;
202 }
203 if (buffer_position >= (byte*) next_track_chunk) {
204 printf("Error parsing MIDI events (track %d)\n", track_index);
205 free_parsed_midi(parsed_midi);
206 return 0;
207 }
208
209 }
210
211 }
212
213 // printf("Midi file looks good...\n");
214 return 1;
215 }
216
217 #if 0
218 void print_midi_event(int track_index, int event_index, midi_event_type* event) {
219 printf("Track %d Event %3d (dt=%4d): ", track_index, event_index, event->delta_time);
220 switch (event->event_type) {
221 default:
222 printf("unknown type (%x)", event->event_type);
223 break;
224 case 0x80: // note off
225 printf("noteoff: ch %d, par %02x|%02x", event->channel.channel, event->channel.param1, event->channel.param2);
226 break;
227 case 0x90: // note on
228 printf("noteon: ch %d, par %02x|%02x", event->channel.channel, event->channel.param1, event->channel.param2);
229 {
230 float octaves_from_A4 = ((int)event->channel.param1 - 69) / 12.0f;
231 float frequency = powf(2.0f, octaves_from_A4) * 440.0f;
232 float f_number_float = frequency * (float)(1 << 20) / 49716.0f;
233 int b = (int)(log2f(f_number_float) - 9) & 7;
234 int f = ((int)f_number_float >> b) & 1023;
235 printf(", freq = %.1f Hz, F=%d, b=%d", frequency, f, b);
236 }
237 break;
238 case 0xA0: // aftertouch
239 printf("aftertouch: ch %d, par %x|%x", event->channel.channel, event->channel.param1, event->channel.param2);
240 break;
241 case 0xB0: // controller
242 printf("controller: ch %d, par %x|%x", event->channel.channel, event->channel.param1, event->channel.param2);
243 break;
244 case 0xE0: // pitch bend
245 printf("pitch bend: ch %d, par %x|%x", event->channel.channel, event->channel.param1, event->channel.param2);
246 break;
247 case 0xC0: // program change
248 printf("program change: ch %d, par %x", event->channel.channel, event->channel.param1);
249 break;
250 case 0xD0:
251 printf("channel aftertouch: ch %d, par %x", event->channel.channel, event->channel.param1);
252 break;
253 case 0xF0: // SysEx
254 printf("sysex event (length=%d): ", event->sysex.length);
255 for (int i = 0; i<event->sysex.length; ++i) {
256 printf("%02x ", event->sysex.data[i]);
257 }
258 break;
259 case 0xF7: // SysEx split
260 printf("sysex split event");
261 // Read SysEx event
262 break;
263 case 0xFF: // Meta event
264 printf("meta: %02x (length=%d): ", event->meta.type, event->meta.length);
265 switch(event->meta.type) {
266 default:
267 printf("unknown type");
268 break;
269 case 0:
270 printf("sequence number");
271 break;
272 case 1:
273 printf("text event");
274 break;
275 case 2:
276 printf("copyright notice");
277 break;
278 case 3:
279 printf("sequence/track name: ");
280 {
281 char* text = malloc(event->meta.length+1);
282 memcpy(text, event->meta.data, event->meta.length);
283 text[event->meta.length] = '\0';
284 printf("%s", text);
285 free(text);
286 }
287 break;
288 case 4:
289 printf("instrument name");
290 break;
291 case 0x51:
292 printf("set tempo: ");
293 {
294 byte* data = event->meta.data;
295 int new_tempo = (data[0]<<16) | (data[1]<<8) | (data[2]);
296 printf("set tempo: %d", new_tempo);
297 }
298 break;
299 case 0x54:
300 printf("SMTPE offset: ");
301 for (int i = 0; i<event->meta.length; ++i) {
302 printf("%02x ", event->meta.data[i]);
303 }
304 break;
305 case 0x58:
306 printf("time signature: ");
307 for (int i = 0; i<event->meta.length; ++i) {
308 printf("%02x ", event->meta.data[i]);
309 }
310 break;
311 case 0x2F:
312 printf("end of track");
313 break;
314 }
315 break;
316
317 }
318 putchar('\n');
319 }
320 #endif
321
322 static byte opl_cached_regs[512];
323
opl_reset(int freq)324 static void opl_reset(int freq) {
325 OPL3_Reset(&opl_chip, freq);
326 memset(opl_cached_regs, 0, sizeof(opl_cached_regs));
327 }
328
opl_write_reg(word reg,byte value)329 static void opl_write_reg(word reg, byte value) {
330 OPL3_WriteReg(&opl_chip, reg, value);
331 opl_cached_regs[reg] = value;
332 }
333
opl_write_reg_masked(word reg,byte value,byte mask)334 static void opl_write_reg_masked(word reg, byte value, byte mask) {
335 byte cached = opl_cached_regs[reg] & ~mask;
336 value = cached | (value & mask);
337 opl_write_reg(reg, value);
338 }
339
340
341 // Reference: https://www.fit.vutbr.cz/~arnost/opl/opl3.html#appendixA
342 //static u8 adlib_op[] = {0, 1, 2, 8, 9, 10, 16, 17, 18};
343 static byte sbpro_op[] = { 0, 1, 2, 6, 7, 8, 12, 13, 14, 18, 19, 20, 24, 25, 26, 30, 31, 32};
344
345 static word reg_pair_offsets[] = {0x000,0x001,0x002,0x003,0x004,0x005,
346 0x008,0x009,0x00A,0x00B,0x00C,0x00D,
347 0x010,0x011,0x012,0x013,0x014,0x015,
348 0x100,0x101,0x102,0x103,0x104,0x105,
349 0x108,0x109,0x10A,0x10B,0x10C,0x10D,
350 0x110,0x111,0x112,0x113,0x114,0x115};
351
352 static word reg_single_offsets[] = {0,1,2,3,4,5,6,7,8,0x100,0x101,0x102,0x103,0x104,0x105,0x106,0x107,0x108};
353
opl_reg_pair_offset(byte voice,byte op)354 static word opl_reg_pair_offset(byte voice, byte op) {
355 word reg_offset = reg_pair_offsets[sbpro_op[voice]];
356 if (op == 1) reg_offset += 3;
357 return reg_offset;
358 }
359
opl_write_instrument(instrument_type * instrument,byte voice)360 static void opl_write_instrument(instrument_type* instrument, byte voice) {
361 opl_write_reg(0xC0 + reg_single_offsets[voice], instrument->FB_conn | 0x30 /* OPL3: L+R speaker enable */);
362 for (byte operator_index = 0; operator_index < 2; ++operator_index) {
363 operator_type* operator = &instrument->operators[operator_index];
364 word op_reg = opl_reg_pair_offset(voice, operator_index);
365 opl_write_reg(0x20 + op_reg, operator->mul);
366 opl_write_reg(0x40 + op_reg, operator->ksl_tl);
367 opl_write_reg(0x60 + op_reg, operator->a_d);
368 opl_write_reg(0x80 + op_reg, operator->s_r);
369 opl_write_reg(0xE0 + op_reg, operator->waveform);
370 }
371 }
372
midi_note_off(midi_event_type * event)373 static void midi_note_off(midi_event_type* event) {
374 byte note = event->channel.param1;
375 byte channel = event->channel.channel;
376 for (int voice = 0; voice < NUM_OPL_VOICES; ++voice) {
377 if (voice_channel[voice] == channel && voice_note[voice] == note) {
378 opl_write_reg_masked(0xB0 + reg_single_offsets[voice], 0, 0x20); // release key
379 voice_note[voice] = 0; // This voice is now free to be re-used.
380 break;
381 }
382 }
383 }
384
get_instrument(int id)385 static instrument_type* get_instrument(int id) {
386 if (id >= 0 && id < num_instruments) {
387 return &instruments[id];
388 } else {
389 return &instruments[0];
390 }
391 }
392
midi_note_on(midi_event_type * event)393 static void midi_note_on(midi_event_type* event) {
394 byte note = event->channel.param1;
395 byte velocity = event->channel.param2;
396 byte channel = event->channel.channel;
397 int instrument_id = channel_instrument[channel];
398 instrument_type* instrument = get_instrument(instrument_id);
399
400 if (velocity == 0) {
401 midi_note_off(event);
402 } else {
403 // Find a free OPL voice.
404 int voice = -1;
405 int test_voice = last_used_voice;
406 for (int i = 0; i < NUM_OPL_VOICES; ++i) {
407 // Don't use the same voice immediately again: that note is probably still be in the release phase.
408 ++test_voice;
409 test_voice %= NUM_OPL_VOICES;
410 if (voice_note[test_voice] == 0) {
411 voice = test_voice;
412 break;
413 }
414 }
415 last_used_voice = voice;
416 if (voice >= 0) {
417 // printf("voice %d\n", voice);
418
419 // Set the correct instrument for this voice.
420 if (voice_instrument[voice] != instrument_id) {
421 opl_write_instrument(instrument, voice);
422 voice_instrument[voice] = instrument_id;
423 }
424 voice_note[voice] = note;
425 voice_channel[voice] = channel;
426
427 // Calculate frequency for a MIDI note: note number 69 = A4 = 440 Hz.
428 // However, Prince of Persia treats notes as one octave (12 semitones) lower than that, by default.
429 // A special MIDI SysEx event is used to change the frequency of all notes.
430 float octaves_from_A4 = ((int)event->channel.param1 - 69 - 12 + midi_semitones_higher) / 12.0f;
431 float frequency = powf(2.0f, octaves_from_A4) * 440.0f;
432 float f_number_float = frequency * (float)(1 << 20) / 49716.0f;
433 int block = (int)(log2f(f_number_float) - 9) & 7;
434 int f = ((int)f_number_float >> block) & 1023;
435 word reg_offset = reg_single_offsets[voice];
436 // opl_write_reg_masked(0xB0 + reg_offset, 0, 0x20); // Turn note off first (should not be necessary)
437 opl_write_reg(0xA0 + reg_offset, f & 0xFF);
438 opl_write_reg(0xB0 + reg_offset, 0x20 | (block << 2) | (f >> 8));
439
440 // The modulator always uses its own base volume level.
441 opl_write_reg_masked(0x40 + opl_reg_pair_offset(voice, 0), instrument->operators[0].ksl_tl, 0x3F);
442
443 // The carrier volume level is calculated as a combination of its base volume and the MIDI note velocity.
444 //PRINCE.EXE disassembly: seg009:6C3C
445 int instr_volume = instrument->operators[1].ksl_tl & 0x3F;
446 int carrier_volume = ((instr_volume + 64) * 225) / (velocity + 161);
447 if (carrier_volume < 64) carrier_volume = 64;
448 if (carrier_volume > 127) carrier_volume = 127;
449 carrier_volume -= 64;
450 opl_write_reg_masked(0x40 + opl_reg_pair_offset(voice, 1), carrier_volume, 0x3F);
451 } else {
452 printf("skipping note, not enough OPL voices\n");
453 }
454
455 }
456
457 }
458
process_midi_event(midi_event_type * event)459 static void process_midi_event(midi_event_type* event) {
460 switch (event->event_type) {
461 case 0x80: // note off
462 midi_note_off(event);
463 break;
464 case 0x90: // note on
465 midi_note_on(event);
466 break;
467 case 0xC0: // program change
468 channel_instrument[event->channel.channel] = event->channel.param1;
469 break;
470 case 0xF0: // SysEx event:
471 if (event->sysex.length == 7) {
472 byte* data = event->sysex.data;
473 if (data[2] == 0x34 && (data[3] == 0 || data[3] == 1) && data[4] == 0) {
474 midi_semitones_higher = data[5]; // Make all notes higher by this amount.
475 }
476 }
477 break;
478 case 0xFF: // Meta event
479 switch(event->meta.type) {
480 default: break;
481 case 0x51: // set tempo
482 {
483 byte* data = event->meta.data;
484 int new_tempo = (data[0]<<16) | (data[1]<<8) | (data[2]);
485 new_tempo *= (1.0f + current_midi_tempo_modifier); // tempo adjustment for specific songs
486 us_per_beat = new_tempo;
487 }
488 break;
489 case 0x54: // SMTPE offset
490 break;
491 case 0x58: // time signature
492 break;
493 case 0x2F: // end of track
494 break;
495 }
496 break;
497 default: break;
498
499 }
500
501 }
502
503 #define ONE_SECOND_IN_US 1000000LL
504
midi_callback(void * userdata,Uint8 * stream,int len)505 void midi_callback(void *userdata, Uint8 *stream, int len) {
506 if (!midi_playing || len <= 0) return;
507 int frames_needed = len / 4;
508 while (frames_needed > 0) {
509 if (ticks_to_next_pause > 0) {
510 // Fill the audio buffer (we have already processed the MIDI events up till this point)
511 int64_t us_to_next_pause = ticks_to_next_pause * us_per_beat / ticks_per_beat;
512 int64_t us_needed = frames_needed * ONE_SECOND_IN_US / mixing_freq;
513 int64_t advance_us = MIN(us_to_next_pause, us_needed);
514 int available_frames = ((advance_us * mixing_freq) + ONE_SECOND_IN_US - 1) / ONE_SECOND_IN_US; // round up.
515 int advance_frames = MIN(available_frames, frames_needed);
516 advance_us = advance_frames * ONE_SECOND_IN_US / mixing_freq; // recalculate, in case the rounding up increased this.
517 short* temp_buffer = malloc(advance_frames * 4);
518 OPL3_GenerateStream(&opl_chip, temp_buffer, advance_frames);
519 if (is_sound_on && enable_music) {
520 for (int sample = 0; sample < advance_frames * 2; ++sample) {
521 ((short*)stream)[sample] += temp_buffer[sample];
522 }
523 }
524 free(temp_buffer);
525
526 frames_needed -= advance_frames;
527 stream += advance_frames * 4;
528 // Advance the current MIDI tick position.
529 // Keep track of the partial ticks that have elapsed so that we do not fall behind.
530 float ticks_elapsed_float = (float)advance_us * ticks_per_beat / us_per_beat;
531 int64_t ticks_elapsed = (int64_t) ticks_elapsed_float;
532 midi_current_pos_fract_part += (ticks_elapsed_float - ticks_elapsed);
533 if (midi_current_pos_fract_part > 1.0f) {
534 midi_current_pos_fract_part -= 1.0f;
535 ticks_elapsed += 1;
536 }
537 midi_current_pos += ticks_elapsed;
538 ticks_to_next_pause -= ticks_elapsed;
539 } else {
540 // Need to process MIDI events on one or more tracks.
541 int num_finished_tracks = 0;
542 for (int track_index = 0; track_index < num_midi_tracks; ++track_index) {
543 midi_track_type* track = &midi_tracks[track_index];
544
545 while (midi_current_pos >= track->next_pause_tick) {
546 int events_left = track->num_events - track->event_index;
547 if (events_left > 0) {
548 midi_event_type* event = &track->events[track->event_index++];
549 // print_midi_event(track_index, track->event_index-1, event);
550 process_midi_event(event);
551
552 // Need to look ahead: must delay processing of the next event, if there is a pause.
553 if (events_left > 1) {
554 midi_event_type* next_event = &track->events[track->event_index];
555 if (next_event->delta_time != 0) {
556 track->next_pause_tick += next_event->delta_time;
557 }
558 }
559 } else {
560 // reached the last event in this track.
561 ++num_finished_tracks;
562 break;
563 }
564 }
565 }
566 if (num_finished_tracks >= num_midi_tracks) {
567 // All tracks have finished. Fill the remaining samples with silence and stop playback.
568 SDL_memset(stream, 0, frames_needed * 4);
569 // printf("midi_callback(): sound ended\n");
570 SDL_LockAudio();
571 midi_playing = 0;
572 free_parsed_midi(&parsed_midi);
573 SDL_UnlockAudio();
574 return;
575 } else {
576 // Need to delay (let the OPL chip do its work) until one of the tracks needs to process a MIDI event again.
577 int64_t first_next_pause_tick = INT64_MAX;
578 for (int i = 0; i < num_midi_tracks; ++i) {
579 midi_track_type* track = &midi_tracks[i];
580 if (track->event_index >= track->num_events || midi_current_pos >= track->next_pause_tick) continue;
581 first_next_pause_tick = MIN(first_next_pause_tick, track->next_pause_tick);
582 }
583 if (first_next_pause_tick == INT64_MAX) {
584 printf("MIDI: Couldn't figure out how long to delay (this is a bug)\n");
585 quit(1);
586 }
587 ticks_to_next_pause = first_next_pause_tick - midi_current_pos;
588 if (ticks_to_next_pause < 0) {
589 printf("Tried to delay a negative amount of time (this is a bug)\n"); // This should never happen?
590 quit(1);
591 }
592 // printf(" delaying %d ticks = %.3f s\n",
593 // ticks_to_next_pause, (((us_per_beat / ticks_per_beat) * (dword)ticks_to_next_pause) / 1e6f));
594 }
595 }
596 }
597 }
598
599
stop_midi()600 void stop_midi() {
601 if (!midi_playing) return;
602 // SDL_PauseAudio(1);
603 SDL_LockAudio();
604 midi_playing = 0;
605 free_parsed_midi(&parsed_midi);
606 SDL_UnlockAudio();
607 }
608
free_midi_resources()609 void free_midi_resources() {
610 free(instruments_data);
611 }
612
init_midi()613 void init_midi() {
614 static bool initialized = false;
615 if (initialized) return;
616 initialized = true;
617
618 instruments = &hardcoded_instrument; // unused if instruments can be loaded normally.
619 int size;
620 dat_type* dathandle = open_dat("PRINCE.DAT", 0);
621 instruments_data = load_from_opendats_alloc(1, "bin", NULL, &size);
622 if (!instruments_data) {
623 printf("Missing MIDI instruments data (resource 1)\n");
624 } else {
625 num_instruments = *(byte*)instruments_data;
626 if (size == 1 + num_instruments*(int)sizeof(instrument_type)) {
627 instruments = (instrument_type*) ((byte*)instruments_data+1);
628 } else {
629 printf("MIDI instruments data (resource 1) is not the expected size\n");
630 num_instruments = 1;
631 }
632 }
633 if (dathandle != NULL) close_dat(dathandle);
634 }
635
play_midi_sound(sound_buffer_type far * buffer)636 void play_midi_sound(sound_buffer_type far *buffer) {
637 stop_midi();
638 if (buffer == NULL) return;
639 init_digi();
640 if (digi_unavailable) return;
641 init_midi();
642
643 if (!parse_midi((midi_raw_chunk_type*) &buffer->midi, &parsed_midi)) {
644 printf("Error reading MIDI music\n");
645 return;
646 }
647
648 // Initialize the OPL chip.
649 opl_reset(digi_audiospec->freq);
650 opl_write_reg(0x105, 0x01); // OPL3 enable (note: the PoP1 Adlib sounds don't actually use OPL3 extensions)
651 for (int voice = 0; voice < NUM_OPL_VOICES; ++voice) {
652 opl_write_instrument(&instruments[0], voice);
653 voice_instrument[voice] = 0;
654 voice_note[voice] = 0;
655 }
656 for (int channel = 0; channel < MAX_MIDI_CHANNELS; channel++) {
657 channel_instrument[channel] = channel;
658 }
659
660 midi_current_pos = 0;
661 midi_current_pos_fract_part = 0;
662 ticks_to_next_pause = 0;
663 midi_tracks = parsed_midi.tracks;
664 num_midi_tracks = parsed_midi.num_tracks;
665 midi_semitones_higher = 0;
666 us_per_beat = 500000; // default tempo (500000 us/beat == 120 bpm)
667 current_midi_tempo_modifier = midi_tempo_modifiers[current_sound];
668 ticks_per_beat = parsed_midi.ticks_per_beat;
669 mixing_freq = digi_audiospec->freq;
670 midi_playing = 1;
671 SDL_PauseAudio(0);
672 }
673