Mercurial > SDL_sound_CoreAudio
annotate decoders/timidity/instrum.c @ 532:a8492d97dd5a stable-1.0
Newer versions of Speex moved to a new include directory.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Thu, 17 Apr 2008 17:54:55 +0000 |
parents | cbc2a4ffeeec |
children |
rev | line source |
---|---|
199 | 1 /* |
2 | |
3 TiMidity -- Experimental MIDI to WAVE converter | |
4 Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi> | |
5 | |
6 This program is free software; you can redistribute it and/or modify | |
7 it under the terms of the GNU General Public License as published by | |
8 the Free Software Foundation; either version 2 of the License, or | |
9 (at your option) any later version. | |
10 | |
11 This program 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 | |
14 GNU General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with this program; if not, write to the Free Software | |
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
19 | |
20 instrum.c | |
21 | |
22 Code to load and unload GUS-compatible instrument patches. | |
23 | |
24 */ | |
25 | |
26 #if HAVE_CONFIG_H | |
27 # include <config.h> | |
28 #endif | |
29 | |
30 #include <stdio.h> | |
31 #include <string.h> | |
32 #include <stdlib.h> | |
33 | |
34 #include "SDL_sound.h" | |
35 | |
36 #define __SDL_SOUND_INTERNAL__ | |
37 #include "SDL_sound_internal.h" | |
38 | |
39 #include "timidity.h" | |
40 #include "options.h" | |
41 #include "common.h" | |
42 #include "instrum.h" | |
455
cbc2a4ffeeec
* Added support for loading DLS format instruments:
hercules
parents:
447
diff
changeset
|
43 #include "instrum_dls.h" |
199 | 44 #include "resample.h" |
45 #include "tables.h" | |
46 | |
47 static void free_instrument(Instrument *ip) | |
48 { | |
49 Sample *sp; | |
50 int i; | |
51 if (!ip) return; | |
52 for (i=0; i<ip->samples; i++) | |
53 { | |
54 sp=&(ip->sample[i]); | |
55 free(sp->data); | |
56 } | |
57 free(ip->sample); | |
58 free(ip); | |
59 } | |
60 | |
61 static void free_bank(MidiSong *song, int dr, int b) | |
62 { | |
63 int i; | |
64 ToneBank *bank=((dr) ? song->drumset[b] : song->tonebank[b]); | |
65 for (i=0; i<128; i++) | |
66 if (bank->instrument[i]) | |
67 { | |
68 /* Not that this could ever happen, of course */ | |
69 if (bank->instrument[i] != MAGIC_LOAD_INSTRUMENT) | |
70 free_instrument(bank->instrument[i]); | |
71 bank->instrument[i]=0; | |
72 } | |
73 } | |
74 | |
75 static Sint32 convert_envelope_rate(MidiSong *song, Uint8 rate) | |
76 { | |
77 Sint32 r; | |
78 | |
79 r = 3 - ((rate >> 6) & 0x3); | |
80 r *= 3; | |
81 r = (Sint32) (rate & 0x3f) << r; /* 6.9 fixed point */ | |
82 | |
83 /* 15.15 fixed point. */ | |
84 r = ((r * 44100) / song->rate) * song->control_ratio; | |
85 | |
86 #ifdef FAST_DECAY | |
87 return r << 10; | |
88 #else | |
89 return r << 9; | |
90 #endif | |
91 } | |
92 | |
93 static Sint32 convert_envelope_offset(Uint8 offset) | |
94 { | |
95 /* This is not too good... Can anyone tell me what these values mean? | |
96 Are they GUS-style "exponential" volumes? And what does that mean? */ | |
97 | |
98 /* 15.15 fixed point */ | |
99 return offset << (7+15); | |
100 } | |
101 | |
102 static Sint32 convert_tremolo_sweep(MidiSong *song, Uint8 sweep) | |
103 { | |
104 if (!sweep) | |
105 return 0; | |
106 | |
107 return | |
108 ((song->control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) / | |
109 (song->rate * sweep); | |
110 } | |
111 | |
112 static Sint32 convert_vibrato_sweep(MidiSong *song, Uint8 sweep, | |
113 Sint32 vib_control_ratio) | |
114 { | |
115 if (!sweep) | |
116 return 0; | |
117 | |
118 return | |
119 (Sint32) (FSCALE((double) (vib_control_ratio) * SWEEP_TUNING, SWEEP_SHIFT) | |
120 / (double)(song->rate * sweep)); | |
121 | |
122 /* this was overflowing with seashore.pat | |
123 | |
124 ((vib_control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) / | |
125 (song->rate * sweep); */ | |
126 } | |
127 | |
128 static Sint32 convert_tremolo_rate(MidiSong *song, Uint8 rate) | |
129 { | |
130 return | |
131 ((SINE_CYCLE_LENGTH * song->control_ratio * rate) << RATE_SHIFT) / | |
132 (TREMOLO_RATE_TUNING * song->rate); | |
133 } | |
134 | |
135 static Sint32 convert_vibrato_rate(MidiSong *song, Uint8 rate) | |
136 { | |
137 /* Return a suitable vibrato_control_ratio value */ | |
138 return | |
139 (VIBRATO_RATE_TUNING * song->rate) / | |
140 (rate * 2 * VIBRATO_SAMPLE_INCREMENTS); | |
141 } | |
142 | |
143 static void reverse_data(Sint16 *sp, Sint32 ls, Sint32 le) | |
144 { | |
145 Sint16 s, *ep=sp+le; | |
146 sp+=ls; | |
147 le-=ls; | |
148 le/=2; | |
149 while (le--) | |
150 { | |
151 s=*sp; | |
152 *sp++=*ep; | |
153 *ep--=s; | |
154 } | |
155 } | |
156 | |
157 /* | |
158 If panning or note_to_use != -1, it will be used for all samples, | |
159 instead of the sample-specific values in the instrument file. | |
160 | |
161 For note_to_use, any value <0 or >127 will be forced to 0. | |
162 | |
163 For other parameters, 1 means yes, 0 means no, other values are | |
164 undefined. | |
165 | |
166 TODO: do reverse loops right */ | |
167 static Instrument *load_instrument(MidiSong *song, char *name, int percussion, | |
168 int panning, int amp, int note_to_use, | |
169 int strip_loop, int strip_envelope, | |
170 int strip_tail) | |
171 { | |
172 Instrument *ip; | |
173 Sample *sp; | |
174 SDL_RWops *rw; | |
175 char tmp[1024]; | |
176 int i,j,noluck=0; | |
177 static char *patch_ext[] = PATCH_EXT_LIST; | |
178 | |
179 if (!name) return 0; | |
180 | |
181 /* Open patch file */ | |
455
cbc2a4ffeeec
* Added support for loading DLS format instruments:
hercules
parents:
447
diff
changeset
|
182 if ((rw=open_file(name)) == NULL) |
199 | 183 { |
184 noluck=1; | |
185 /* Try with various extensions */ | |
186 for (i=0; patch_ext[i]; i++) | |
187 { | |
188 if (strlen(name)+strlen(patch_ext[i])<1024) | |
189 { | |
190 strcpy(tmp, name); | |
191 strcat(tmp, patch_ext[i]); | |
455
cbc2a4ffeeec
* Added support for loading DLS format instruments:
hercules
parents:
447
diff
changeset
|
192 if ((rw=open_file(tmp)) != NULL) |
199 | 193 { |
194 noluck=0; | |
195 break; | |
196 } | |
197 } | |
198 } | |
199 } | |
200 | |
201 if (noluck) | |
202 { | |
203 SNDDBG(("Instrument `%s' can't be found.\n", name)); | |
204 return 0; | |
205 } | |
206 | |
207 SNDDBG(("Loading instrument %s\n", tmp)); | |
208 | |
209 /* Read some headers and do cursory sanity checks. There are loads | |
210 of magic offsets. This could be rewritten... */ | |
211 | |
212 if ((239 != SDL_RWread(rw, tmp, 1, 239)) || | |
213 (memcmp(tmp, "GF1PATCH110\0ID#000002", 22) && | |
214 memcmp(tmp, "GF1PATCH100\0ID#000002", 22))) /* don't know what the | |
215 differences are */ | |
216 { | |
217 SNDDBG(("%s: not an instrument\n", name)); | |
218 return 0; | |
219 } | |
220 | |
221 if (tmp[82] != 1 && tmp[82] != 0) /* instruments. To some patch makers, | |
222 0 means 1 */ | |
223 { | |
224 SNDDBG(("Can't handle patches with %d instruments\n", tmp[82])); | |
225 return 0; | |
226 } | |
227 | |
228 if (tmp[151] != 1 && tmp[151] != 0) /* layers. What's a layer? */ | |
229 { | |
230 SNDDBG(("Can't handle instruments with %d layers\n", tmp[151])); | |
231 return 0; | |
232 } | |
233 | |
234 ip=safe_malloc(sizeof(Instrument)); | |
235 ip->samples = tmp[198]; | |
236 ip->sample = safe_malloc(sizeof(Sample) * ip->samples); | |
237 for (i=0; i<ip->samples; i++) | |
238 { | |
239 | |
240 Uint8 fractions; | |
241 Sint32 tmplong; | |
242 Uint16 tmpshort; | |
243 Uint8 tmpchar; | |
244 | |
245 #define READ_CHAR(thing) \ | |
246 if (1 != SDL_RWread(rw, &tmpchar, 1, 1)) goto fail; \ | |
247 thing = tmpchar; | |
248 #define READ_SHORT(thing) \ | |
249 if (1 != SDL_RWread(rw, &tmpshort, 2, 1)) goto fail; \ | |
250 thing = SDL_SwapLE16(tmpshort); | |
251 #define READ_LONG(thing) \ | |
252 if (1 != SDL_RWread(rw, &tmplong, 4, 1)) goto fail; \ | |
253 thing = SDL_SwapLE32(tmplong); | |
254 | |
255 SDL_RWseek(rw, 7, SEEK_CUR); /* Skip the wave name */ | |
256 | |
257 if (1 != SDL_RWread(rw, &fractions, 1, 1)) | |
258 { | |
259 fail: | |
260 SNDDBG(("Error reading sample %d\n", i)); | |
261 for (j=0; j<i; j++) | |
262 free(ip->sample[j].data); | |
263 free(ip->sample); | |
264 free(ip); | |
265 return 0; | |
266 } | |
267 | |
268 sp=&(ip->sample[i]); | |
269 | |
270 READ_LONG(sp->data_length); | |
271 READ_LONG(sp->loop_start); | |
272 READ_LONG(sp->loop_end); | |
273 READ_SHORT(sp->sample_rate); | |
274 READ_LONG(sp->low_freq); | |
275 READ_LONG(sp->high_freq); | |
276 READ_LONG(sp->root_freq); | |
455
cbc2a4ffeeec
* Added support for loading DLS format instruments:
hercules
parents:
447
diff
changeset
|
277 sp->low_vel = 0; |
cbc2a4ffeeec
* Added support for loading DLS format instruments:
hercules
parents:
447
diff
changeset
|
278 sp->high_vel = 127; |
199 | 279 SDL_RWseek(rw, 2, SEEK_CUR); /* Why have a "root frequency" and then |
280 * "tuning"?? */ | |
281 | |
282 READ_CHAR(tmp[0]); | |
283 | |
284 if (panning==-1) | |
285 sp->panning = (tmp[0] * 8 + 4) & 0x7f; | |
286 else | |
287 sp->panning=(Uint8)(panning & 0x7F); | |
288 | |
289 /* envelope, tremolo, and vibrato */ | |
290 if (18 != SDL_RWread(rw, tmp, 1, 18)) goto fail; | |
291 | |
292 if (!tmp[13] || !tmp[14]) | |
293 { | |
294 sp->tremolo_sweep_increment= | |
295 sp->tremolo_phase_increment=sp->tremolo_depth=0; | |
296 SNDDBG((" * no tremolo\n")); | |
297 } | |
298 else | |
299 { | |
300 sp->tremolo_sweep_increment=convert_tremolo_sweep(song, tmp[12]); | |
301 sp->tremolo_phase_increment=convert_tremolo_rate(song, tmp[13]); | |
302 sp->tremolo_depth=tmp[14]; | |
303 SNDDBG((" * tremolo: sweep %d, phase %d, depth %d\n", | |
304 sp->tremolo_sweep_increment, sp->tremolo_phase_increment, | |
305 sp->tremolo_depth)); | |
306 } | |
307 | |
308 if (!tmp[16] || !tmp[17]) | |
309 { | |
310 sp->vibrato_sweep_increment= | |
311 sp->vibrato_control_ratio=sp->vibrato_depth=0; | |
312 SNDDBG((" * no vibrato\n")); | |
313 } | |
314 else | |
315 { | |
316 sp->vibrato_control_ratio=convert_vibrato_rate(song, tmp[16]); | |
317 sp->vibrato_sweep_increment= | |
318 convert_vibrato_sweep(song, tmp[15], sp->vibrato_control_ratio); | |
319 sp->vibrato_depth=tmp[17]; | |
320 SNDDBG((" * vibrato: sweep %d, ctl %d, depth %d\n", | |
321 sp->vibrato_sweep_increment, sp->vibrato_control_ratio, | |
322 sp->vibrato_depth)); | |
323 | |
324 } | |
325 | |
326 READ_CHAR(sp->modes); | |
327 | |
328 SDL_RWseek(rw, 40, SEEK_CUR); /* skip the useless scale frequency, scale | |
329 factor (what's it mean?), and reserved | |
330 space */ | |
331 | |
332 /* Mark this as a fixed-pitch instrument if such a deed is desired. */ | |
333 if (note_to_use!=-1) | |
334 sp->note_to_use=(Uint8)(note_to_use); | |
335 else | |
336 sp->note_to_use=0; | |
337 | |
338 /* seashore.pat in the Midia patch set has no Sustain. I don't | |
339 understand why, and fixing it by adding the Sustain flag to | |
340 all looped patches probably breaks something else. We do it | |
341 anyway. */ | |
342 | |
343 if (sp->modes & MODES_LOOPING) | |
344 sp->modes |= MODES_SUSTAIN; | |
345 | |
346 /* Strip any loops and envelopes we're permitted to */ | |
347 if ((strip_loop==1) && | |
348 (sp->modes & (MODES_SUSTAIN | MODES_LOOPING | | |
349 MODES_PINGPONG | MODES_REVERSE))) | |
350 { | |
351 SNDDBG((" - Removing loop and/or sustain\n")); | |
352 sp->modes &=~(MODES_SUSTAIN | MODES_LOOPING | | |
353 MODES_PINGPONG | MODES_REVERSE); | |
354 } | |
355 | |
356 if (strip_envelope==1) | |
357 { | |
358 if (sp->modes & MODES_ENVELOPE) | |
359 SNDDBG((" - Removing envelope\n")); | |
360 sp->modes &= ~MODES_ENVELOPE; | |
361 } | |
362 else if (strip_envelope != 0) | |
363 { | |
364 /* Have to make a guess. */ | |
365 if (!(sp->modes & (MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE))) | |
366 { | |
367 /* No loop? Then what's there to sustain? No envelope needed | |
368 either... */ | |
369 sp->modes &= ~(MODES_SUSTAIN|MODES_ENVELOPE); | |
370 SNDDBG((" - No loop, removing sustain and envelope\n")); | |
371 } | |
372 else if (!memcmp(tmp, "??????", 6) || tmp[11] >= 100) | |
373 { | |
374 /* Envelope rates all maxed out? Envelope end at a high "offset"? | |
375 That's a weird envelope. Take it out. */ | |
376 sp->modes &= ~MODES_ENVELOPE; | |
377 SNDDBG((" - Weirdness, removing envelope\n")); | |
378 } | |
379 else if (!(sp->modes & MODES_SUSTAIN)) | |
380 { | |
381 /* No sustain? Then no envelope. I don't know if this is | |
382 justified, but patches without sustain usually don't need the | |
383 envelope either... at least the Gravis ones. They're mostly | |
384 drums. I think. */ | |
385 sp->modes &= ~MODES_ENVELOPE; | |
386 SNDDBG((" - No sustain, removing envelope\n")); | |
387 } | |
388 } | |
389 | |
390 for (j=0; j<6; j++) | |
391 { | |
392 sp->envelope_rate[j]= | |
393 convert_envelope_rate(song, tmp[j]); | |
394 sp->envelope_offset[j]= | |
395 convert_envelope_offset(tmp[6+j]); | |
396 } | |
397 | |
398 /* Then read the sample data */ | |
399 sp->data = safe_malloc(sp->data_length); | |
400 if (1 != SDL_RWread(rw, sp->data, sp->data_length, 1)) | |
401 goto fail; | |
402 | |
403 if (!(sp->modes & MODES_16BIT)) /* convert to 16-bit data */ | |
404 { | |
405 Sint32 i=sp->data_length; | |
406 Uint8 *cp=(Uint8 *)(sp->data); | |
407 Uint16 *tmp,*new; | |
408 tmp=new=safe_malloc(sp->data_length*2); | |
409 while (i--) | |
410 *tmp++ = (Uint16)(*cp++) << 8; | |
411 cp=(Uint8 *)(sp->data); | |
412 sp->data = (sample_t *)new; | |
413 free(cp); | |
414 sp->data_length *= 2; | |
415 sp->loop_start *= 2; | |
416 sp->loop_end *= 2; | |
417 } | |
418 #if SDL_BYTEORDER == SDL_BIG_ENDIAN | |
419 else | |
420 /* convert to machine byte order */ | |
421 { | |
422 Sint32 i=sp->data_length/2; | |
423 Sint16 *tmp=(Sint16 *)sp->data,s; | |
424 while (i--) | |
425 { | |
447
c98a34c00069
Fixed MIDI decoding on bigendian systems.
Ryan C. Gordon <icculus@icculus.org>
parents:
199
diff
changeset
|
426 s=SDL_SwapLE16(*tmp); |
199 | 427 *tmp++=s; |
428 } | |
429 } | |
430 #endif | |
431 | |
432 if (sp->modes & MODES_UNSIGNED) /* convert to signed data */ | |
433 { | |
434 Sint32 i=sp->data_length/2; | |
435 Sint16 *tmp=(Sint16 *)sp->data; | |
436 while (i--) | |
437 *tmp++ ^= 0x8000; | |
438 } | |
439 | |
440 /* Reverse reverse loops and pass them off as normal loops */ | |
441 if (sp->modes & MODES_REVERSE) | |
442 { | |
443 Sint32 t; | |
444 /* The GUS apparently plays reverse loops by reversing the | |
445 whole sample. We do the same because the GUS does not SUCK. */ | |
446 | |
447 SNDDBG(("Reverse loop in %s\n", name)); | |
448 reverse_data((Sint16 *)sp->data, 0, sp->data_length/2); | |
449 | |
450 t=sp->loop_start; | |
451 sp->loop_start=sp->data_length - sp->loop_end; | |
452 sp->loop_end=sp->data_length - t; | |
453 | |
454 sp->modes &= ~MODES_REVERSE; | |
455 sp->modes |= MODES_LOOPING; /* just in case */ | |
456 } | |
457 | |
458 #ifdef ADJUST_SAMPLE_VOLUMES | |
459 if (amp!=-1) | |
460 sp->volume=(float)((amp) / 100.0); | |
461 else | |
462 { | |
463 /* Try to determine a volume scaling factor for the sample. | |
464 This is a very crude adjustment, but things sound more | |
465 balanced with it. Still, this should be a runtime option. */ | |
466 Sint32 i=sp->data_length/2; | |
467 Sint16 maxamp=0,a; | |
468 Sint16 *tmp=(Sint16 *)sp->data; | |
469 while (i--) | |
470 { | |
471 a=*tmp++; | |
472 if (a<0) a=-a; | |
473 if (a>maxamp) | |
474 maxamp=a; | |
475 } | |
476 sp->volume=(float)(32768.0 / maxamp); | |
477 SNDDBG((" * volume comp: %f\n", sp->volume)); | |
478 } | |
479 #else | |
480 if (amp!=-1) | |
481 sp->volume=(double)(amp) / 100.0; | |
482 else | |
483 sp->volume=1.0; | |
484 #endif | |
485 | |
486 sp->data_length /= 2; /* These are in bytes. Convert into samples. */ | |
487 sp->loop_start /= 2; | |
488 sp->loop_end /= 2; | |
489 | |
490 /* Then fractional samples */ | |
491 sp->data_length <<= FRACTION_BITS; | |
492 sp->loop_start <<= FRACTION_BITS; | |
493 sp->loop_end <<= FRACTION_BITS; | |
494 | |
495 /* Adjust for fractional loop points. This is a guess. Does anyone | |
496 know what "fractions" really stands for? */ | |
497 sp->loop_start |= | |
498 (fractions & 0x0F) << (FRACTION_BITS-4); | |
499 sp->loop_end |= | |
500 ((fractions>>4) & 0x0F) << (FRACTION_BITS-4); | |
501 | |
502 /* If this instrument will always be played on the same note, | |
503 and it's not looped, we can resample it now. */ | |
504 if (sp->note_to_use && !(sp->modes & MODES_LOOPING)) | |
505 pre_resample(song, sp); | |
506 | |
507 if (strip_tail==1) | |
508 { | |
509 /* Let's not really, just say we did. */ | |
510 SNDDBG((" - Stripping tail\n")); | |
511 sp->data_length = sp->loop_end; | |
512 } | |
513 } | |
514 | |
515 SDL_RWclose(rw); | |
516 return ip; | |
517 } | |
518 | |
519 static int fill_bank(MidiSong *song, int dr, int b) | |
520 { | |
521 int i, errors=0; | |
522 ToneBank *bank=((dr) ? song->drumset[b] : song->tonebank[b]); | |
523 if (!bank) | |
524 { | |
525 SNDDBG(("Huh. Tried to load instruments in non-existent %s %d\n", | |
526 (dr) ? "drumset" : "tone bank", b)); | |
527 return 0; | |
528 } | |
529 for (i=0; i<128; i++) | |
530 { | |
531 if (bank->instrument[i]==MAGIC_LOAD_INSTRUMENT) | |
532 { | |
455
cbc2a4ffeeec
* Added support for loading DLS format instruments:
hercules
parents:
447
diff
changeset
|
533 bank->instrument[i]=load_instrument_dls(song, dr, b, i); |
cbc2a4ffeeec
* Added support for loading DLS format instruments:
hercules
parents:
447
diff
changeset
|
534 if (bank->instrument[i]) |
cbc2a4ffeeec
* Added support for loading DLS format instruments:
hercules
parents:
447
diff
changeset
|
535 { |
cbc2a4ffeeec
* Added support for loading DLS format instruments:
hercules
parents:
447
diff
changeset
|
536 continue; |
cbc2a4ffeeec
* Added support for loading DLS format instruments:
hercules
parents:
447
diff
changeset
|
537 } |
199 | 538 if (!(bank->tone[i].name)) |
539 { | |
540 SNDDBG(("No instrument mapped to %s %d, program %d%s\n", | |
541 (dr)? "drum set" : "tone bank", b, i, | |
542 (b!=0) ? "" : " - this instrument will not be heard")); | |
543 if (b!=0) | |
544 { | |
545 /* Mark the corresponding instrument in the default | |
546 bank / drumset for loading (if it isn't already) */ | |
547 if (!dr) | |
548 { | |
549 if (!(song->tonebank[0]->instrument[i])) | |
550 song->tonebank[0]->instrument[i] = | |
551 MAGIC_LOAD_INSTRUMENT; | |
552 } | |
553 else | |
554 { | |
555 if (!(song->drumset[0]->instrument[i])) | |
556 song->drumset[0]->instrument[i] = | |
557 MAGIC_LOAD_INSTRUMENT; | |
558 } | |
559 } | |
560 bank->instrument[i] = 0; | |
561 errors++; | |
562 } | |
563 else if (!(bank->instrument[i] = | |
564 load_instrument(song, | |
565 bank->tone[i].name, | |
566 (dr) ? 1 : 0, | |
567 bank->tone[i].pan, | |
568 bank->tone[i].amp, | |
569 (bank->tone[i].note!=-1) ? | |
570 bank->tone[i].note : | |
571 ((dr) ? i : -1), | |
572 (bank->tone[i].strip_loop!=-1) ? | |
573 bank->tone[i].strip_loop : | |
574 ((dr) ? 1 : -1), | |
575 (bank->tone[i].strip_envelope != -1) ? | |
576 bank->tone[i].strip_envelope : | |
577 ((dr) ? 1 : -1), | |
578 bank->tone[i].strip_tail ))) | |
579 { | |
580 SNDDBG(("Couldn't load instrument %s (%s %d, program %d)\n", | |
581 bank->tone[i].name, | |
582 (dr)? "drum set" : "tone bank", b, i)); | |
583 errors++; | |
584 } | |
585 } | |
586 } | |
587 return errors; | |
588 } | |
589 | |
590 int load_missing_instruments(MidiSong *song) | |
591 { | |
592 int i=128,errors=0; | |
593 while (i--) | |
594 { | |
595 if (song->tonebank[i]) | |
596 errors+=fill_bank(song,0,i); | |
597 if (song->drumset[i]) | |
598 errors+=fill_bank(song,1,i); | |
599 } | |
600 return errors; | |
601 } | |
602 | |
603 void free_instruments(MidiSong *song) | |
604 { | |
605 int i=128; | |
606 while(i--) | |
607 { | |
608 if (song->tonebank[i]) | |
609 free_bank(song, 0, i); | |
610 if (song->drumset[i]) | |
611 free_bank(song, 1, i); | |
612 } | |
613 } | |
614 | |
615 int set_default_instrument(MidiSong *song, char *name) | |
616 { | |
617 Instrument *ip; | |
618 if (!(ip=load_instrument(song, name, 0, -1, -1, -1, 0, 0, 0))) | |
619 return -1; | |
620 song->default_instrument = ip; | |
621 song->default_program = SPECIAL_PROGRAM; | |
622 return 0; | |
623 } |