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