1 /*
2 
3 	TiMidity -- Experimental MIDI to WAVE converter
4 	Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
5 
6 	This library is free software; you can redistribute it and/or
7 	modify it under the terms of the GNU Lesser General Public
8 	License as published by the Free Software Foundation; either
9 	version 2.1 of the License, or (at your option) any later version.
10 
11 	This library is distributed in the hope that it will be useful,
12 	but WITHOUT ANY WARRANTY; without even the implied warranty of
13 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 	Lesser General Public License for more details.
15 
16 	You should have received a copy of the GNU Lesser General Public
17 	License along with this library; if not, write to the Free Software
18 	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 
20 	instrum.c
21 
22 	Code to load and unload GUS-compatible instrument patches.
23 
24 */
25 
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <math.h>
30 
31 #include "timidity.h"
32 #include "m_swap.h"
33 #include "files.h"
34 #include "templates.h"
35 #include "gf1patch.h"
36 
37 namespace Timidity
38 {
39 
40 extern Instrument *load_instrument_dls(Renderer *song, int drum, int bank, int instrument);
41 
Instrument()42 Instrument::Instrument()
43 : samples(0), sample(NULL)
44 {
45 }
46 
~Instrument()47 Instrument::~Instrument()
48 {
49 	Sample *sp;
50 	int i;
51 
52 	for (i = samples, sp = &(sample[0]); i != 0; i--, sp++)
53 	{
54 		if (sp->type == INST_GUS && sp->data != NULL)
55 		{
56 			free(sp->data);
57 		}
58 	}
59 	free(sample);
60 }
61 
ToneBank()62 ToneBank::ToneBank()
63 {
64 	tone = new ToneBankElement[128];;
65 	for (int i = 0; i < MAXPROG; ++i)
66 	{
67 		instrument[i] = 0;
68 	}
69 }
70 
~ToneBank()71 ToneBank::~ToneBank()
72 {
73 	delete[] tone;
74 	for (int i = 0; i < MAXPROG; i++)
75 	{
76 		if (instrument[i] != NULL && instrument[i] != MAGIC_LOAD_INSTRUMENT)
77 		{
78 			delete instrument[i];
79 			instrument[i] = NULL;
80 		}
81 	}
82 }
83 
convert_tremolo_sweep(Renderer * song,BYTE sweep)84 int convert_tremolo_sweep(Renderer *song, BYTE sweep)
85 {
86 	if (sweep == 0)
87 		return 0;
88 
89 	return
90 		int(((song->control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) / (song->rate * sweep));
91 }
92 
convert_vibrato_sweep(Renderer * song,BYTE sweep,int vib_control_ratio)93 int convert_vibrato_sweep(Renderer *song, BYTE sweep, int vib_control_ratio)
94 {
95 	if (sweep == 0)
96 		return 0;
97 
98 	return
99 		(int) (FSCALE((double) (vib_control_ratio) * SWEEP_TUNING, SWEEP_SHIFT) / (song->rate * sweep));
100 
101 	/* this was overflowing with seashore.pat
102 
103 	((vib_control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) / (song->rate * sweep);
104 	*/
105 }
106 
convert_tremolo_rate(Renderer * song,BYTE rate)107 int convert_tremolo_rate(Renderer *song, BYTE rate)
108 {
109 	return
110 		int(((song->control_ratio * rate) << RATE_SHIFT) / (TREMOLO_RATE_TUNING * song->rate));
111 }
112 
convert_vibrato_rate(Renderer * song,BYTE rate)113 int convert_vibrato_rate(Renderer *song, BYTE rate)
114 {
115 	/* Return a suitable vibrato_control_ratio value */
116 	return
117 		int((VIBRATO_RATE_TUNING * song->rate) / (rate * 2 * VIBRATO_SAMPLE_INCREMENTS));
118 }
119 
reverse_data(sample_t * sp,int ls,int le)120 static void reverse_data(sample_t *sp, int ls, int le)
121 {
122 	sample_t s, *ep = sp + le;
123 	sp += ls;
124 	le -= ls;
125 	le /= 2;
126 	while (le--)
127 	{
128 		    s = *sp;
129 		*sp++ = *ep;
130 		*ep-- = s;
131 	}
132 }
133 
134 /*
135 	If panning or note_to_use != -1, it will be used for all samples,
136 	instead of the sample-specific values in the instrument file.
137 
138 	For note_to_use, any value <0 or >127 will be forced to 0.
139 
140 	For other parameters, 1 means yes, 0 means no, other values are
141 	undefined.
142 
143 	TODO: do reverse loops right */
load_instrument(Renderer * song,const char * name,int percussion,int panning,int note_to_use,int strip_loop,int strip_envelope,int strip_tail)144 static Instrument *load_instrument(Renderer *song, const char *name, int percussion,
145 					int panning, int note_to_use,
146 					int strip_loop, int strip_envelope,
147 					int strip_tail)
148 {
149 	Instrument *ip;
150 	Sample *sp;
151 	FileReader *fp;
152 	GF1PatchHeader header;
153 	GF1InstrumentData idata;
154 	GF1LayerData layer_data;
155 	GF1PatchData patch_data;
156 	int i, j;
157 	bool noluck = false;
158 
159 	if (!name) return 0;
160 
161 	/* Open patch file */
162 	if ((fp = pathExpander.openFileReader(name, NULL)) == NULL)
163 	{
164 		/* Try with various extensions */
165 		FString tmp = name;
166 		tmp += ".pat";
167 		if ((fp = pathExpander.openFileReader(tmp, NULL)) == NULL)
168 		{
169 #ifdef __unix__			// Windows isn't case-sensitive.
170 			tmp.ToUpper();
171 			if ((fp = pathExpander.openFileReader(tmp, NULL)) == NULL)
172 #endif
173 			{
174 				noluck = true;
175 			}
176 		}
177 	}
178 
179 	if (noluck)
180 	{
181 		cmsg(CMSG_ERROR, VERB_NORMAL, "Instrument `%s' can't be found.\n", name);
182 		return 0;
183 	}
184 
185 	cmsg(CMSG_INFO, VERB_NOISY, "Loading instrument %s\n", name);
186 
187 	/* Read some headers and do cursory sanity checks. */
188 
189 	if (sizeof(header) != fp->Read(&header, sizeof(header)))
190 	{
191 failread:
192 		cmsg(CMSG_ERROR, VERB_NORMAL, "%s: Error reading instrument.\n", name);
193 		delete fp;
194 		return 0;
195 	}
196 	if (strncmp(header.Header, GF1_HEADER_TEXT, HEADER_SIZE - 4) != 0)
197 	{
198 		cmsg(CMSG_ERROR, VERB_NORMAL, "%s: Not an instrument.\n", name);
199 		delete fp;
200 		return 0;
201 	}
202 	if (strcmp(header.Header + 8, "110") < 0)
203 	{
204 		cmsg(CMSG_ERROR, VERB_NORMAL, "%s: Is an old and unsupported patch version.\n", name);
205 		delete fp;
206 		return 0;
207 	}
208 	if (sizeof(idata) != fp->Read(&idata, sizeof(idata)))
209 	{
210 		goto failread;
211 	}
212 
213 	header.WaveForms = LittleShort(header.WaveForms);
214 	header.MasterVolume = LittleShort(header.MasterVolume);
215 	header.DataSize = LittleLong(header.DataSize);
216 	idata.Instrument = LittleShort(idata.Instrument);
217 
218 	if (header.Instruments != 1 && header.Instruments != 0) /* instruments. To some patch makers, 0 means 1 */
219 	{
220 		cmsg(CMSG_ERROR, VERB_NORMAL, "Can't handle patches with %d instruments.\n", header.Instruments);
221 		delete fp;
222 		return 0;
223 	}
224 
225 	if (idata.Layers != 1 && idata.Layers != 0) /* layers. What's a layer? */
226 	{
227 		cmsg(CMSG_ERROR, VERB_NORMAL, "Can't handle instruments with %d layers.\n", idata.Layers);
228 		delete fp;
229 		return 0;
230 	}
231 
232 	if (sizeof(layer_data) != fp->Read(&layer_data, sizeof(layer_data)))
233 	{
234 		goto failread;
235 	}
236 
237 	if (layer_data.Samples == 0)
238 	{
239 		cmsg(CMSG_ERROR, VERB_NORMAL, "Instrument has 0 samples.\n");
240 		delete fp;
241 		return 0;
242 	}
243 
244 	ip = new Instrument;
245 	ip->samples = layer_data.Samples;
246 	ip->sample = (Sample *)safe_malloc(sizeof(Sample) * layer_data.Samples);
247 	memset(ip->sample, 0, sizeof(Sample) * layer_data.Samples);
248 	for (i = 0; i < layer_data.Samples; ++i)
249 	{
250 		if (sizeof(patch_data) != fp->Read(&patch_data, sizeof(patch_data)))
251 		{
252 fail:
253 			cmsg(CMSG_ERROR, VERB_NORMAL, "Error reading sample %d.\n", i);
254 			delete ip;
255 			delete fp;
256 			return 0;
257 		}
258 
259 		sp = &(ip->sample[i]);
260 
261 		sp->data_length = LittleLong(patch_data.WaveSize);
262 		sp->loop_start = LittleLong(patch_data.StartLoop);
263 		sp->loop_end = LittleLong(patch_data.EndLoop);
264 		sp->sample_rate = LittleShort(patch_data.SampleRate);
265 		sp->low_freq = float(LittleLong(patch_data.LowFrequency));
266 		sp->high_freq = float(LittleLong(patch_data.HighFrequency)) + 0.9999f;
267 		sp->root_freq = float(LittleLong(patch_data.RootFrequency));
268 		sp->high_vel = 127;
269 		sp->velocity = -1;
270 		sp->type = INST_GUS;
271 
272 		// Expand to SF2 range.
273 		if (panning == -1)
274 		{
275 			sp->panning = (patch_data.Balance & 0x0F) * 1000 / 15 - 500;
276 		}
277 		else
278 		{
279 			sp->panning = (panning & 0x7f) * 1000 / 127 - 500;
280 		}
281 		song->compute_pan((sp->panning + 500) / 1000.0, INST_GUS, sp->left_offset, sp->right_offset);
282 
283 		/* tremolo */
284 		if (patch_data.TremoloRate == 0 || patch_data.TremoloDepth == 0)
285 		{
286 			sp->tremolo_sweep_increment = 0;
287 			sp->tremolo_phase_increment = 0;
288 			sp->tremolo_depth = 0;
289 			cmsg(CMSG_INFO, VERB_DEBUG, " * no tremolo\n");
290 		}
291 		else
292 		{
293 			sp->tremolo_sweep_increment = convert_tremolo_sweep(song, patch_data.TremoloSweep);
294 			sp->tremolo_phase_increment = convert_tremolo_rate(song, patch_data.TremoloRate);
295 			sp->tremolo_depth = patch_data.TremoloDepth;
296 			cmsg(CMSG_INFO, VERB_DEBUG, " * tremolo: sweep %d, phase %d, depth %d\n",
297 				sp->tremolo_sweep_increment, sp->tremolo_phase_increment, sp->tremolo_depth);
298 		}
299 
300 		/* vibrato */
301 		if (patch_data.VibratoRate == 0 || patch_data.VibratoDepth == 0)
302 		{
303 			sp->vibrato_sweep_increment = 0;
304 			sp->vibrato_control_ratio = 0;
305 			sp->vibrato_depth = 0;
306 			cmsg(CMSG_INFO, VERB_DEBUG, " * no vibrato\n");
307 		}
308 		else
309 		{
310 			sp->vibrato_control_ratio = convert_vibrato_rate(song, patch_data.VibratoRate);
311 			sp->vibrato_sweep_increment = convert_vibrato_sweep(song, patch_data.VibratoSweep, sp->vibrato_control_ratio);
312 			sp->vibrato_depth = patch_data.VibratoDepth;
313 			cmsg(CMSG_INFO, VERB_DEBUG, " * vibrato: sweep %d, ctl %d, depth %d\n",
314 				sp->vibrato_sweep_increment, sp->vibrato_control_ratio, sp->vibrato_depth);
315 		}
316 
317 		sp->modes = patch_data.Modes;
318 
319 		/* Mark this as a fixed-pitch instrument if such a deed is desired. */
320 		if (note_to_use != -1)
321 		{
322 			sp->scale_note = note_to_use;
323 			sp->scale_factor = 0;
324 		}
325 		else
326 		{
327 			sp->scale_note = LittleShort(patch_data.ScaleFrequency);
328 			sp->scale_factor = LittleShort(patch_data.ScaleFactor);
329 			if (sp->scale_factor <= 2)
330 			{
331 				sp->scale_factor *= 1024;
332 			}
333 			else if (sp->scale_factor > 2048)
334 			{
335 				sp->scale_factor = 1024;
336 			}
337 			if (sp->scale_factor != 1024)
338 			{
339 				cmsg(CMSG_INFO, VERB_DEBUG, " * Scale: note %d, factor %d\n",
340 					sp->scale_note, sp->scale_factor);
341 			}
342 		}
343 
344 #if 0
345 		/* seashore.pat in the Midia patch set has no Sustain. I don't
346 		   understand why, and fixing it by adding the Sustain flag to
347 		   all looped patches probably breaks something else. We do it
348 		   anyway. */
349 
350 		if (sp->modes & PATCH_LOOPEN)
351 		{
352 			sp->modes |= PATCH_SUSTAIN;
353 		}
354 #endif
355 		/* [RH] Alas, eawpats has percussion instruments with bad envelopes. :(
356 		 * (See cymchina.pat for one example of this sadness.)
357 		 * Do this logic for instruments without a description, only. Hopefully that
358 		 * catches all the patches that need it without including any extra.
359 		 */
360 		for (j = 0; j < DESC_SIZE; ++j)
361 		{
362 			if (header.Description[j] != 0)
363 				break;
364 		}
365 		/* Strip any loops and envelopes we're permitted to */
366 		/* [RH] (But PATCH_BACKWARD isn't a loop flag at all!) */
367 		if ((strip_loop == 1) &&
368 			(sp->modes & (PATCH_SUSTAIN | PATCH_LOOPEN | PATCH_BIDIR | PATCH_BACKWARD)))
369 		{
370 			cmsg(CMSG_INFO, VERB_DEBUG, " - Removing loop and/or sustain\n");
371 			if (j == DESC_SIZE)
372 			{
373 				sp->modes &= ~(PATCH_SUSTAIN | PATCH_LOOPEN | PATCH_BIDIR | PATCH_BACKWARD);
374 			}
375 		}
376 
377 		if (strip_envelope == 1)
378 		{
379 			cmsg(CMSG_INFO, VERB_DEBUG, " - Removing envelope\n");
380 			/* [RH] The envelope isn't really removed, but this is the way the standard
381 			 * Gravis patches get that effect: All rates at maximum, and all offsets at
382 			 * a constant level.
383 			 */
384 			if (j == DESC_SIZE)
385 			{
386 				int k;
387 				for (k = 1; k < ENVELOPES; ++k)
388 				{ /* Find highest offset. */
389 					if (patch_data.EnvelopeOffset[k] > patch_data.EnvelopeOffset[0])
390 					{
391 						patch_data.EnvelopeOffset[0] = patch_data.EnvelopeOffset[k];
392 					}
393 				}
394 				for (k = 0; k < ENVELOPES; ++k)
395 				{
396 					patch_data.EnvelopeRate[k] = 63;
397 					patch_data.EnvelopeOffset[k] = patch_data.EnvelopeOffset[0];
398 				}
399 			}
400 		}
401 
402 		for (j = 0; j < 6; j++)
403 		{
404 			sp->envelope.gf1.rate[j] = patch_data.EnvelopeRate[j];
405 			/* [RH] GF1NEW clamps the offsets to the range [5,251], so we do too. */
406 			sp->envelope.gf1.offset[j] = clamp<BYTE>(patch_data.EnvelopeOffset[j], 5, 251);
407 		}
408 
409 		/* Then read the sample data */
410 		if (((sp->modes & PATCH_16) && sp->data_length/2 > MAX_SAMPLE_SIZE) ||
411 			(!(sp->modes & PATCH_16) && sp->data_length > MAX_SAMPLE_SIZE))
412 		{
413 			goto fail;
414 		}
415 		sp->data = (sample_t *)safe_malloc(sp->data_length);
416 
417 		if (sp->data_length != fp->Read(sp->data, sp->data_length))
418 			goto fail;
419 
420 		convert_sample_data(sp, sp->data);
421 
422 		/* Reverse reverse loops and pass them off as normal loops */
423 		if (sp->modes & PATCH_BACKWARD)
424 		{
425 			int t;
426 			/* The GUS apparently plays reverse loops by reversing the
427 			   whole sample. We do the same because the GUS does not SUCK. */
428 
429 			cmsg(CMSG_WARNING, VERB_NORMAL, "Reverse loop in %s\n", name);
430 			reverse_data((sample_t *)sp->data, 0, sp->data_length);
431 			sp->data[sp->data_length] = sp->data[sp->data_length - 1];
432 
433 			t = sp->loop_start;
434 			sp->loop_start = sp->data_length - sp->loop_end;
435 			sp->loop_end = sp->data_length - t;
436 
437 			sp->modes &= ~PATCH_BACKWARD;
438 			sp->modes |= PATCH_LOOPEN; /* just in case */
439 		}
440 
441 		/* Then fractional samples */
442 		sp->data_length <<= FRACTION_BITS;
443 		sp->loop_start <<= FRACTION_BITS;
444 		sp->loop_end <<= FRACTION_BITS;
445 
446 		/* Adjust for fractional loop points. */
447 		sp->loop_start |= (patch_data.Fractions & 0x0F) << (FRACTION_BITS-4);
448 		sp->loop_end   |= (patch_data.Fractions & 0xF0) << (FRACTION_BITS-4-4);
449 
450 		/* If this instrument will always be played on the same note,
451 		   and it's not looped, we can resample it now. */
452 		if (sp->scale_factor == 0 && !(sp->modes & PATCH_LOOPEN))
453 		{
454 			pre_resample(song, sp);
455 		}
456 
457 		if (strip_tail == 1)
458 		{
459 			/* Let's not really, just say we did. */
460 			cmsg(CMSG_INFO, VERB_DEBUG, " - Stripping tail\n");
461 			sp->data_length = sp->loop_end;
462 		}
463 	}
464 	delete fp;
465 	return ip;
466 }
467 
convert_sample_data(Sample * sp,const void * data)468 void convert_sample_data(Sample *sp, const void *data)
469 {
470 	/* convert everything to 32-bit floating point data */
471 	sample_t *newdata = NULL;
472 
473 	switch (sp->modes & (PATCH_16 | PATCH_UNSIGNED))
474 	{
475 	case 0:
476 	  {					/* 8-bit, signed */
477 		SBYTE *cp = (SBYTE *)data;
478 		newdata = (sample_t *)safe_malloc((sp->data_length + 1) * sizeof(sample_t));
479 		for (int i = 0; i < sp->data_length; ++i)
480 		{
481 			if (cp[i] < 0)
482 			{
483 				newdata[i] = float(cp[i]) / 128.f;
484 			}
485 			else
486 			{
487 				newdata[i] = float(cp[i]) / 127.f;
488 			}
489 		}
490 		break;
491 	  }
492 
493 	case PATCH_UNSIGNED:
494 	  {					/* 8-bit, unsigned */
495 		BYTE *cp = (BYTE *)data;
496 		newdata = (sample_t *)safe_malloc((sp->data_length + 1) * sizeof(sample_t));
497 		for (int i = 0; i < sp->data_length; ++i)
498 		{
499 			int c = cp[i] - 128;
500 			if (c < 0)
501 			{
502 				newdata[i] = float(c) / 128.f;
503 			}
504 			else
505 			{
506 				newdata[i] = float(c) / 127.f;
507 			}
508 		}
509 		break;
510 	  }
511 
512 	case PATCH_16:
513 	  {					/* 16-bit, signed */
514 		SWORD *cp = (SWORD *)data;
515 		/* Convert these to samples */
516 		sp->data_length >>= 1;
517 		sp->loop_start >>= 1;
518 		sp->loop_end >>= 1;
519 		newdata = (sample_t *)safe_malloc((sp->data_length + 1) * sizeof(sample_t));
520 		for (int i = 0; i < sp->data_length; ++i)
521 		{
522 			int c = LittleShort(cp[i]);
523 			if (c < 0)
524 			{
525 				newdata[i] = float(c) / 32768.f;
526 			}
527 			else
528 			{
529 				newdata[i] = float(c) / 32767.f;
530 			}
531 		}
532 		break;
533 	  }
534 
535 	case PATCH_16 | PATCH_UNSIGNED:
536 	  {					/* 16-bit, unsigned */
537 		WORD *cp = (WORD *)data;
538 		/* Convert these to samples */
539 		sp->data_length >>= 1;
540 		sp->loop_start >>= 1;
541 		sp->loop_end >>= 1;
542 		newdata = (sample_t *)safe_malloc((sp->data_length + 1) * sizeof(sample_t));
543 		for (int i = 0; i < sp->data_length; ++i)
544 		{
545 			int c = LittleShort(cp[i]) - 32768;
546 			if (c < 0)
547 			{
548 				newdata[i] = float(c) / 32768.f;
549 			}
550 			else
551 			{
552 				newdata[i] = float(c) / 32767.f;
553 			}
554 		}
555 		break;
556 	  }
557 	}
558 	/* Duplicate the final sample for linear interpolation. */
559 	newdata[sp->data_length] = newdata[sp->data_length - 1];
560 	if (sp->data != NULL)
561 	{
562 		free(sp->data);
563 	}
564 	sp->data = newdata;
565 }
566 
fill_bank(Renderer * song,int dr,int b)567 static int fill_bank(Renderer *song, int dr, int b)
568 {
569 	int i, errors = 0;
570 	ToneBank *bank = ((dr) ? drumset[b] : tonebank[b]);
571 	if (bank == NULL)
572 	{
573 		cmsg(CMSG_ERROR, VERB_NORMAL,
574 			"Huh. Tried to load instruments in non-existent %s %d\n",
575 			(dr) ? "drumset" : "tone bank", b);
576 		return 0;
577 	}
578 	for (i = 0; i < MAXPROG; i++)
579 	{
580 		if (bank->instrument[i] == MAGIC_LOAD_INSTRUMENT)
581 		{
582 			bank->instrument[i] = NULL;
583 			bank->instrument[i] = load_instrument_dls(song, dr, b, i);
584 			if (bank->instrument[i] != NULL)
585 			{
586 				continue;
587 			}
588 			Instrument *ip;
589 			ip = load_instrument_font_order(song, 0, dr, b, i);
590 			if (ip == NULL)
591 			{
592 				if (bank->tone[i].fontbank >= 0)
593 				{
594 					ip = load_instrument_font(song, bank->tone[i].name, dr, b, i);
595 				}
596 				else
597 				{
598 					ip = load_instrument(song, bank->tone[i].name,
599 						(dr) ? 1 : 0,
600 						bank->tone[i].pan,
601 						(bank->tone[i].note != -1) ? bank->tone[i].note : ((dr) ? i : -1),
602 						(bank->tone[i].strip_loop != -1) ? bank->tone[i].strip_loop : ((dr) ? 1 : -1),
603 						(bank->tone[i].strip_envelope != -1) ? bank->tone[i].strip_envelope : ((dr) ? 1 : -1),
604 						bank->tone[i].strip_tail);
605 				}
606 				if (ip == NULL)
607 				{
608 					ip = load_instrument_font_order(song, 1, dr, b, i);
609 				}
610 			}
611 			bank->instrument[i] = ip;
612 			if (ip == NULL)
613 			{
614 				if (bank->tone[i].name.IsEmpty())
615 				{
616 					cmsg(CMSG_WARNING, (b != 0) ? VERB_VERBOSE : VERB_NORMAL,
617 						"No instrument mapped to %s %d, program %d%s\n",
618 						(dr) ? "drum set" : "tone bank", b, i,
619 						(b != 0) ? "" : " - this instrument will not be heard");
620 				}
621 				else
622 				{
623 					cmsg(CMSG_ERROR, VERB_NORMAL,
624 						"Couldn't load instrument %s (%s %d, program %d)\n",
625 						bank->tone[i].name.GetChars(),
626 						(dr) ? "drum set" : "tone bank", b, i);
627 				}
628 				if (b != 0)
629 				{
630 					/* Mark the corresponding instrument in the default
631 					   bank / drumset for loading (if it isn't already) */
632 					if (((dr) ? drumset[0] : tonebank[0])->instrument[i] != NULL)
633 					{
634 						((dr) ? drumset[0] : tonebank[0])->instrument[i] = MAGIC_LOAD_INSTRUMENT;
635 					}
636 				}
637 				errors++;
638 			}
639 		}
640 	}
641 	return errors;
642 }
643 
load_missing_instruments()644 int Renderer::load_missing_instruments()
645 {
646 	int i = MAXBANK, errors = 0;
647 	while (i--)
648 	{
649 		if (tonebank[i] != NULL)
650 			errors += fill_bank(this, 0,i);
651 		if (drumset[i] != NULL)
652 			errors += fill_bank(this, 1,i);
653 	}
654 	return errors;
655 }
656 
free_instruments()657 void free_instruments()
658 {
659 	int i = MAXBANK;
660 	while (i--)
661 	{
662 		if (tonebank[i] != NULL)
663 		{
664 			delete tonebank[i];
665 			tonebank[i] = NULL;
666 		}
667 		if (drumset[i] != NULL)
668 		{
669 			delete drumset[i];
670 			drumset[i] = NULL;
671 		}
672 	}
673 }
674 
set_default_instrument(const char * name)675 int Renderer::set_default_instrument(const char *name)
676 {
677 	Instrument *ip;
678 	if ((ip = load_instrument(this, name, 0, -1, -1, 0, 0, 0)) == NULL)
679 	{
680 		return -1;
681 	}
682 	if (default_instrument != NULL)
683 	{
684 		delete default_instrument;
685 	}
686 	default_instrument = ip;
687 	default_program = SPECIAL_PROGRAM;
688 	return 0;
689 }
690 
691 }
692