src/codecs/timidity/instrum.c
author Ozkan Sezer
Mon, 16 Dec 2019 10:33:55 +0300
changeset 1083 7a3b49dbf90f
parent 999 1a87fe70802d
child 1084 c7cedfb5f65f
permissions -rw-r--r--
timidity: minor warning fixes

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