Merged over timidity from SDL_sound
authorSam Lantinga <slouken@libsdl.org>
Tue, 17 Oct 2017 21:54:04 -0700
changeset 782e7d3a8f73e88
parent 781 90487b4b7ade
child 783 2b559c85819d
Merged over timidity from SDL_sound
This has changes to make it safe to load MIDI files as sound chunks and adds the ability to seek in MIDI files
Also cherry picked some patches from the original SDL_mixer timidity to fix buffer overruns and so forth.
mixer.c
music_timidity.c
timidity/CHANGES
timidity/FAQ
timidity/README
timidity/TODO
timidity/common.c
timidity/common.h
timidity/config.h
timidity/ctrlmode.c
timidity/ctrlmode.h
timidity/dls1.h
timidity/dls2.h
timidity/filter.c
timidity/filter.h
timidity/instrum.c
timidity/instrum.h
timidity/instrum_dls.c
timidity/instrum_dls.h
timidity/mix.c
timidity/mix.h
timidity/options.h
timidity/output.c
timidity/output.h
timidity/playmidi.c
timidity/playmidi.h
timidity/readmidi.c
timidity/readmidi.h
timidity/resample.c
timidity/resample.h
timidity/sdl_a.c
timidity/sdl_c.c
timidity/tables.c
timidity/tables.h
timidity/timidity.c
timidity/timidity.h
     1.1 --- a/mixer.c	Tue Oct 17 16:55:58 2017 -0700
     1.2 +++ b/mixer.c	Tue Oct 17 21:54:04 2017 -0700
     1.3 @@ -568,7 +568,6 @@
     1.4          /* These music interfaces are not safe to use while music is playing */
     1.5          if (interface->api == MIX_MUSIC_CMD ||
     1.6               interface->api == MIX_MUSIC_MIKMOD ||
     1.7 -             interface->api == MIX_MUSIC_TIMIDITY ||
     1.8               interface->api == MIX_MUSIC_NATIVEMIDI) {
     1.9              continue;
    1.10          }
     2.1 --- a/music_timidity.c	Tue Oct 17 16:55:58 2017 -0700
     2.2 +++ b/music_timidity.c	Tue Oct 17 21:54:04 2017 -0700
     2.3 @@ -28,35 +28,29 @@
     2.4  #include "timidity/timidity.h"
     2.5  
     2.6  
     2.7 -static int samplesize;
     2.8 -
     2.9  static int TIMIDITY_Open(const SDL_AudioSpec *spec)
    2.10  {
    2.11 -    samplesize = spec->size / spec->samples;
    2.12 -    if (Timidity_Init(spec->freq, spec->format, spec->channels, spec->samples) != 0) {
    2.13 -        Mix_SetError("%s", Timidity_Error());
    2.14 -        return -1;
    2.15 -    }
    2.16 -    return 0;
    2.17 +    return Timidity_Init();
    2.18  }
    2.19  
    2.20  static void TIMIDITY_Close(void)
    2.21  {
    2.22 -    Timidity_Close();
    2.23 +    Timidity_Exit();
    2.24  }
    2.25  
    2.26  void *TIMIDITY_CreateFromRW(SDL_RWops *src, int freesrc)
    2.27  {
    2.28 -    MidiSong *music = Timidity_LoadSong_RW(src, freesrc);
    2.29 -    if (!music) {
    2.30 -        Mix_SetError("%s", Timidity_Error());
    2.31 +    MidiSong *music = Timidity_LoadSong(src, &music_spec);
    2.32 +    if (music && freesrc) {
    2.33 +        SDL_RWclose(src);
    2.34      }
    2.35      return music;
    2.36  }
    2.37  
    2.38  static void TIMIDITY_SetVolume(void *context, int volume)
    2.39  {
    2.40 -    Timidity_SetVolume(volume);
    2.41 +    MidiSong *music = (MidiSong *)context;
    2.42 +    Timidity_SetVolume(music, volume);
    2.43  }
    2.44  
    2.45  static int TIMIDITY_Play(void *context)
    2.46 @@ -66,21 +60,21 @@
    2.47      return 0;
    2.48  }
    2.49  
    2.50 -static SDL_bool TIMIDITY_IsPlaying(void *context)
    2.51 -{
    2.52 -    return Timidity_Active() ? SDL_TRUE : SDL_FALSE;
    2.53 -}
    2.54 -
    2.55  static int TIMIDITY_GetAudio(void *context, void *data, int bytes)
    2.56  {
    2.57 -    int samples = (bytes / samplesize);
    2.58 -    Timidity_PlaySome(data, samples);
    2.59 +    MidiSong *music = (MidiSong *)context;
    2.60 +    if (!Timidity_PlaySome(music, data, bytes)) {
    2.61 +        /* Nothing consumed, everything left */
    2.62 +        return bytes;
    2.63 +    }
    2.64      return 0;
    2.65  }
    2.66  
    2.67 -static void TIMIDITY_Stop(void *context)
    2.68 +static int TIMIDITY_Seek(void *context, double position)
    2.69  {
    2.70 -    Timidity_Stop();
    2.71 +    MidiSong *music = (MidiSong *)context;
    2.72 +    Timidity_Seek(music, (Uint32)(position * 1000));
    2.73 +    return 0;
    2.74  }
    2.75  
    2.76  static void TIMIDITY_Delete(void *context)
    2.77 @@ -103,9 +97,9 @@
    2.78      NULL,   /* CreateFromFile */
    2.79      TIMIDITY_SetVolume,
    2.80      TIMIDITY_Play,
    2.81 -    TIMIDITY_IsPlaying,
    2.82 +    NULL,   /* IsPlaying */
    2.83      TIMIDITY_GetAudio,
    2.84 -    NULL,   /* Seek */
    2.85 +    TIMIDITY_Seek,
    2.86      NULL,   /* Pause */
    2.87      NULL,   /* Resume */
    2.88      NULL,   /* Stop */
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/timidity/CHANGES	Tue Oct 17 21:54:04 2017 -0700
     3.3 @@ -0,0 +1,77 @@
     3.4 +This version of TiMidity should contain all the fixes from the
     3.5 +September 25 2003 SDL_mixer CVS snapshot. In addition, I've made some
     3.6 +changes of my own, e.g.:
     3.7 +
     3.8 +* All file access is done through SDL_RWops. This means the MIDI
     3.9 +  stream no longer has to be a file. (The config file and instruments
    3.10 +  still have to be though.)
    3.11 +
    3.12 +* Replacing of TiMidity's endian-handling with SDL's.
    3.13 +
    3.14 +* Removal of much unused or unnecessary code, such as
    3.15 +
    3.16 +  + The "hooks" for putting a user interface onto TiMidity.
    3.17 +  + The antialias filter. It wasn't active, and even at 4 kHz I
    3.18 +    couldn't hear any difference when activating it.
    3.19 +  + Removed all traces of LOOKUP_HACK and LOOKUP_INTERPOLATION.
    3.20 +    According to the code comments they weren't very good anyway.
    3.21 +    ("degrades sound quality noticeably"). I also removed the
    3.22 +    disclaimer about the "8-bit uLaw to 16-bit PCM and the 13-bit-PCM
    3.23 +    to 8-bit uLaw tables" disclaimer, since I believe those were the
    3.24 +    tables I removed.
    3.25 +  + Removed LOOKUP_SINE since it was already commented out. I think we
    3.26 +    can count on our target audience having math co-processors
    3.27 +    nowadays.
    3.28 +  + Removed USE_LDEXP since it wasn't being used and "it doesn't make
    3.29 +    much of a difference either way".
    3.30 +  + Removed decompress hack from open_file() since it didn't look very
    3.31 +    portable.
    3.32 +  + Removed heaps of unnecessary constants.
    3.33 +  + Removed unused functions.
    3.34 +  + Assume that LINEAR_INTERPOLATION is always used, so remove all
    3.35 +    code dealing with it not being so. It's not that I think the
    3.36 +    difference in audio quality is that great, but since it wouldn't
    3.37 +    compile without code changes I assume no one's used it for quite
    3.38 +    some time...
    3.39 +  + Assume PRECALC_LOOPS is always defined. Judging by the comments it
    3.40 +    may not make much of a difference either way, so why maintain two
    3.41 +    versions of the same code?
    3.42 +
    3.43 +* Moving several static globals into the MidiSong struct. This
    3.44 +  includes sample rate, formate, etc. which are now all per-song.
    3.45 +
    3.46 +* Moved some typedefs (e.g. MidiSong) to timidity.h for easy inclusion
    3.47 +  into the MIDI decoder.
    3.48 +
    3.49 +* Added free_pathlist().
    3.50 +
    3.51 +* Replaced TiMidity's own 8, 16 and 32-bit types with SDL's.
    3.52 +
    3.53 +* Made TiMidity look for its configuration file in both /etc and
    3.54 +  /usr/local/lib/timidity. (Windows version remains unchanged.)
    3.55 +
    3.56 +* Timidity_PlaySome() now takes three arguments. A MidiSong, a decode
    3.57 +  buffer and decode buffer size in bytes. (MidiSong is a new argument,
    3.58 +  and buffer size used to be in samples.)
    3.59 +
    3.60 +  In addition, it will return the number of bytes decoded.
    3.61 +
    3.62 +* Added Timidity_Exit().
    3.63 +
    3.64 +* Removed Timidity_Stop() and Timidity_Active(). Stopping playback
    3.65 +  should be handled by SDL_sound, and Timidity_PlaySome() will return
    3.66 +  0 when the MIDI stream is finished.
    3.67 +
    3.68 +* Modified the ToneBank stuff to allow some data to be shared between
    3.69 +  MidiSongs.
    3.70 +
    3.71 +* The following files have been removed: controls.c, controls.h,
    3.72 +  filter.c, filter.h, sdl_a.c, sdl_c.c
    3.73 +
    3.74 +* config.h has been renamed as options.h to avoid confusion with the
    3.75 +  automatically generated config.h for SDL_sound.
    3.76 +
    3.77 +* Added support for loading DLS format instruments:
    3.78 +	Timidity_LoadDLS(), Timidity_FreeDLS(), Timidity_LoadDLSSong()
    3.79 +
    3.80 +* Added Timidity_Init_NoConfig()
     4.1 --- a/timidity/FAQ	Tue Oct 17 16:55:58 2017 -0700
     4.2 +++ b/timidity/FAQ	Tue Oct 17 21:54:04 2017 -0700
     4.3 @@ -92,19 +92,7 @@
     4.4  
     4.5     - Use a smaller number of simultaneous voices.
     4.6  
     4.7 -   - Make sure you compiled with FAST_DECAY and PRECALC_LOOPS enabled
     4.8 -     in config.h
     4.9 -
    4.10 -   - If you don't have hardware to compute sines, recompile with
    4.11 -     LOOKUP_SINE enabled in config.h
    4.12 -
    4.13 -   - Recompile with LOOKUP_HACK enabled in config.h.
    4.14 -
    4.15 -   - Recompile with LINEAR_INTERPOLATION disabled in config.h.
    4.16 -
    4.17 -   - Recompile with DANGEROUS_RENICE enabled in config.h, and make
    4.18 -     TiMidity setuid root. This will help only if you frequently play
    4.19 -     music while other processes are running.
    4.20 +   - Make sure you compiled with FAST_DECAY enabled in options.h
    4.21  
    4.22     - Recompile with an Intel-optimized gcc for a 5-15%
    4.23       performance increase.
     5.1 --- a/timidity/README	Tue Oct 17 16:55:58 2017 -0700
     5.2 +++ b/timidity/README	Tue Oct 17 21:54:04 2017 -0700
     5.3 @@ -1,4 +1,5 @@
     5.4 -[This version of timidity has been stripped for simplicity in porting to SDL]
     5.5 +[This version of timidity has been stripped for simplicity in porting to SDL,
     5.6 +and then even further for SDL_sound]
     5.7  ---------------------------------*-text-*---------------------------------
     5.8  
     5.9          From http://www.cgs.fi/~tt/discontinued.html :
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/timidity/TODO	Tue Oct 17 21:54:04 2017 -0700
     6.3 @@ -0,0 +1,37 @@
     6.4 +* I don't like the indentation style at all, but for the most part
     6.5 +  I've left it alone.
     6.6 +
     6.7 +* Much of the code looks ugly to me.
     6.8 +
     6.9 +* The return value from SDL_RWread() is checked inconsistenly.
    6.10 +
    6.11 +* Group the members of MidiSong into logical units, i.e. structs?
    6.12 +
    6.13 +* The debug messages are probably a bit too noisy. I've removed one
    6.14 +  particularly annoying one, but...
    6.15 +
    6.16 +  Some of them should be turned into error messages instead.
    6.17 +
    6.18 +* Can the instrument handling be made more efficient? At the moment
    6.19 +  different MidiSongs may separately load the same instrument.
    6.20 +
    6.21 +  Note that the MidiSong's audio format affects how the instrument is
    6.22 +  loaded, so it's not as easy as just letting all MidiSongs share tone
    6.23 +  and drum banks.
    6.24 +
    6.25 +  At the moment they do share the data that is simply read from the
    6.26 +  config file, but that's just a quick hack to avoid having to read
    6.27 +  the config file every time a MIDI song is loaded.
    6.28 +
    6.29 +* Check if any of MidiStruct's members can safely be made into static
    6.30 +  globals again.
    6.31 +
    6.32 +* TiMidity++ adds a number of undocumented (?) extensions to the
    6.33 +  configuration syntax. These are not implemented here. In particular,
    6.34 +  the "map" keyword used by the "eawpats".
    6.35 +
    6.36 +* The other decoders generally only read as much of the file as is
    6.37 +  necessary. Could we do that in this decoder as well? (Currently it
    6.38 +  seems to convert the entire file into MIDI events first.)
    6.39 +
    6.40 +* Can it be optimized?
     7.1 --- a/timidity/common.c	Tue Oct 17 16:55:58 2017 -0700
     7.2 +++ b/timidity/common.c	Tue Oct 17 21:54:04 2017 -0700
     7.3 @@ -1,243 +1,122 @@
     7.4  /*
     7.5 +
     7.6      TiMidity -- Experimental MIDI to WAVE converter
     7.7      Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
     7.8  
     7.9      This program is free software; you can redistribute it and/or modify
    7.10      it under the terms of the Perl Artistic License, available in COPYING.
    7.11 - */
    7.12 +
    7.13 +    common.c
    7.14 +*/
    7.15 +
    7.16 +#if HAVE_CONFIG_H
    7.17 +#  include <config.h>
    7.18 +#endif
    7.19  
    7.20  #include <stdio.h>
    7.21  #include <stdlib.h>
    7.22  #include <string.h>
    7.23  
    7.24 -#include <errno.h>
    7.25 -#include "config.h"
    7.26 +#include "SDL.h"
    7.27 +
    7.28 +#include "options.h"
    7.29  #include "common.h"
    7.30 -#include "output.h"
    7.31 -#include "ctrlmode.h"
    7.32  
    7.33 -/* I guess "rb" should be right for any libc */
    7.34 -#define OPEN_MODE "rb"
    7.35 +/* The paths in this list will be tried whenever we're reading a file */
    7.36 +static PathList *pathlist = NULL; /* This is a linked list */
    7.37  
    7.38 -char current_filename[PATH_MAX];
    7.39 -
    7.40 -static PathList *pathlist=NULL;
    7.41 -
    7.42 -/* Try to open a file for reading. If the filename ends in one of the 
    7.43 -   defined compressor extensions, pipe the file through the decompressor */
    7.44 -static FILE *try_to_open(const char *name, int decompress, int noise_mode)
    7.45 +/* This is meant to find and open files for reading */
    7.46 +SDL_RWops *open_file(const char *name)
    7.47  {
    7.48 -  FILE *fp;
    7.49 -
    7.50 -  fp=fopen(name, OPEN_MODE); /* First just check that the file exists */
    7.51 -
    7.52 -  if (!fp)
    7.53 -    return 0;
    7.54 -
    7.55 -#ifdef DECOMPRESSOR_LIST
    7.56 -  if (decompress)
    7.57 -    {
    7.58 -      int l,el;
    7.59 -      static char *decompressor_list[] = DECOMPRESSOR_LIST, **dec;
    7.60 -      const char *cp;
    7.61 -      char tmp[PATH_MAX], tmp2[PATH_MAX], *cp2;
    7.62 -      /* Check if it's a compressed file */ 
    7.63 -      l=strlen(name);
    7.64 -      for (dec=decompressor_list; *dec; dec+=2)
    7.65 -	{
    7.66 -	  el=strlen(*dec);
    7.67 -	  if ((el>=l) || (strcmp(name+l-el, *dec)))
    7.68 -	    continue;
    7.69 -
    7.70 -	  /* Yes. Close the file, open a pipe instead. */
    7.71 -	  fclose(fp);
    7.72 -
    7.73 -	  /* Quote some special characters in the file name */
    7.74 -	  cp=name;
    7.75 -	  cp2=tmp2;
    7.76 -	  while (*cp)
    7.77 -	    {
    7.78 -	      switch(*cp)
    7.79 -		{
    7.80 -		case '\'':
    7.81 -		case '\\':
    7.82 -		case ' ':
    7.83 -		case '`':
    7.84 -		case '!':
    7.85 -		case '"':
    7.86 -		case '&':
    7.87 -		case ';':
    7.88 -		  *cp2++='\\';
    7.89 -		}
    7.90 -	      *cp2++=*cp++;
    7.91 -	    }
    7.92 -	  *cp2=0;
    7.93 -
    7.94 -	  sprintf(tmp, *(dec+1), tmp2);
    7.95 -	  fp=popen(tmp, "r");
    7.96 -	  break;
    7.97 -	}
    7.98 -    }
    7.99 -#endif
   7.100 -  
   7.101 -  return fp;
   7.102 -}
   7.103 -
   7.104 -/* This is meant to find and open files for reading, possibly piping
   7.105 -   them through a decompressor. */
   7.106 -FILE *open_file(const char *name, int decompress, int noise_mode)
   7.107 -{
   7.108 -  FILE *fp;
   7.109 -  PathList *plp;
   7.110 -  int l;
   7.111 +  SDL_RWops *rw;
   7.112  
   7.113    if (!name || !(*name))
   7.114      {
   7.115 -      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Attempted to open nameless file.");
   7.116 +      SNDDBG(("Attempted to open nameless file.\n"));
   7.117        return 0;
   7.118      }
   7.119  
   7.120 -  if (pathlist==NULL) {
   7.121 -    /* Generate path list */
   7.122 -#ifdef DEFAULT_PATH
   7.123 -    add_to_pathlist(DEFAULT_PATH);
   7.124 -#endif
   7.125 -#ifdef DEFAULT_PATH1
   7.126 -    add_to_pathlist(DEFAULT_PATH1);
   7.127 -#endif
   7.128 -#ifdef DEFAULT_PATH2
   7.129 -    add_to_pathlist(DEFAULT_PATH2);
   7.130 -#endif
   7.131 -#ifdef DEFAULT_PATH3
   7.132 -    add_to_pathlist(DEFAULT_PATH3);
   7.133 -#endif
   7.134 -  }
   7.135 -
   7.136    /* First try the given name */
   7.137  
   7.138 -  strncpy(current_filename, name, PATH_MAX - 1);
   7.139 -  current_filename[PATH_MAX - 1]='\0';
   7.140 +  SNDDBG(("Trying to open %s\n", name));
   7.141 +  if ((rw = SDL_RWFromFile(name, "rb")))
   7.142 +    return rw;
   7.143  
   7.144 -  ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Trying to open %s", current_filename);
   7.145 -  if ((fp=try_to_open(current_filename, decompress, noise_mode)))
   7.146 -    return fp;
   7.147 +  if (name[0] != PATH_SEP)
   7.148 +  {
   7.149 +    char current_filename[1024];
   7.150 +    PathList *plp = pathlist;
   7.151 +    int l;
   7.152  
   7.153 -#ifdef ENOENT
   7.154 -  if (noise_mode && (errno != ENOENT))
   7.155 -    {
   7.156 -      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", 
   7.157 -	   current_filename, strerror(errno));
   7.158 -      return 0;
   7.159 -    }
   7.160 -#endif
   7.161 -
   7.162 -  plp=pathlist;
   7.163 -  if (name[0] != PATH_SEP)
   7.164      while (plp)  /* Try along the path then */
   7.165        {
   7.166 -	*current_filename=0;
   7.167 -	l=(int)strlen(plp->path);
   7.168 +	*current_filename = 0;
   7.169 +	l = strlen(plp->path);
   7.170  	if(l)
   7.171  	  {
   7.172  	    strcpy(current_filename, plp->path);
   7.173 -	    if(current_filename[l-1]!=PATH_SEP)
   7.174 -	      strcat(current_filename, PATH_STRING);
   7.175 +	    if(current_filename[l - 1] != PATH_SEP)
   7.176 +	    {
   7.177 +	      current_filename[l] = PATH_SEP;
   7.178 +	      current_filename[l + 1] = '\0';
   7.179 +	    }
   7.180  	  }
   7.181  	strcat(current_filename, name);
   7.182 -	ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Trying to open %s", current_filename);
   7.183 -	if ((fp=try_to_open(current_filename, decompress, noise_mode)))
   7.184 -	  return fp;
   7.185 -#ifdef ENOENT
   7.186 -	if (noise_mode && (errno != ENOENT))
   7.187 -	  {
   7.188 -	    ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", 
   7.189 -		 current_filename, strerror(errno));
   7.190 -	    return 0;
   7.191 -	  }
   7.192 -#endif
   7.193 -	plp=plp->next;
   7.194 +	SNDDBG(("Trying to open %s\n", current_filename));
   7.195 +	if ((rw = SDL_RWFromFile(current_filename, "rb")))
   7.196 +	  return rw;
   7.197 +	plp = plp->next;
   7.198        }
   7.199 +  }
   7.200    
   7.201    /* Nothing could be opened. */
   7.202 -
   7.203 -  *current_filename=0;
   7.204 -  
   7.205 -  if (noise_mode>=2)
   7.206 -    ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", name, strerror(errno));
   7.207 -  
   7.208 +  SNDDBG(("Could not open %s\n", name));
   7.209    return 0;
   7.210  }
   7.211  
   7.212 -/* This closes files opened with open_file */
   7.213 -void close_file(FILE *fp)
   7.214 -{
   7.215 -#ifdef DECOMPRESSOR_LIST
   7.216 -  if (pclose(fp)) /* Any better ideas? */
   7.217 -#endif
   7.218 -    fclose(fp);
   7.219 -
   7.220 -  strncpy(current_filename, "MIDI file", PATH_MAX - 1);
   7.221 -}
   7.222 -
   7.223 -/* This is meant for skipping a few bytes in a file or fifo. */
   7.224 -void skip(FILE *fp, size_t len)
   7.225 -{
   7.226 -  size_t c;
   7.227 -  char tmp[PATH_MAX];
   7.228 -  while (len>0)
   7.229 -    {
   7.230 -      c=len;
   7.231 -      if (c>PATH_MAX) c=PATH_MAX;
   7.232 -      len-=c;
   7.233 -      if (c!=fread(tmp, 1, c, fp))
   7.234 -	ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: skip: %s",
   7.235 -	     current_filename, strerror(errno));
   7.236 -    }
   7.237 -}
   7.238 -
   7.239  /* This'll allocate memory or die. */
   7.240  void *safe_malloc(size_t count)
   7.241  {
   7.242    void *p;
   7.243 -  if (count > (1<<21))
   7.244 -    {
   7.245 -      ctl->cmsg(CMSG_FATAL, VERB_NORMAL, 
   7.246 -	   "Strange, I feel like allocating %d bytes. This must be a bug.",
   7.247 -	   count);
   7.248 -    }
   7.249 -  else if ((p=malloc(count)))
   7.250 -    return p;
   7.251 -  else
   7.252 -    ctl->cmsg(CMSG_FATAL, VERB_NORMAL, "Sorry. Couldn't malloc %d bytes.", count);
   7.253  
   7.254 -  ctl->close();
   7.255 -  exit(10);
   7.256 -  return(NULL);
   7.257 +  p = malloc(count);
   7.258 +  if (p == NULL)
   7.259 +    SNDDBG(("Sorry. Couldn't malloc %d bytes.\n", count));
   7.260 +
   7.261 +  return p;
   7.262  }
   7.263  
   7.264  /* This adds a directory to the path list */
   7.265  void add_to_pathlist(const char *s)
   7.266  {
   7.267 -  PathList *plp=safe_malloc(sizeof(PathList));
   7.268 -  strcpy((plp->path=safe_malloc(strlen(s)+1)),s);
   7.269 -  plp->next=pathlist;
   7.270 -  pathlist=plp;
   7.271 +  PathList *plp = safe_malloc(sizeof(PathList));
   7.272 +
   7.273 +  if (plp == NULL)
   7.274 +      return;
   7.275 +
   7.276 +  plp->path = safe_malloc(strlen(s) + 1);
   7.277 +  if (plp->path == NULL)
   7.278 +  {
   7.279 +      free(plp);
   7.280 +      return;
   7.281 +  }
   7.282 +
   7.283 +  strcpy(plp->path, s);
   7.284 +  plp->next = pathlist;
   7.285 +  pathlist = plp;
   7.286  }
   7.287  
   7.288 -/* Free memory associated to path list */
   7.289  void free_pathlist(void)
   7.290  {
   7.291 -  PathList *plp, *next_plp;
   7.292 +    PathList *plp = pathlist;
   7.293 +    PathList *next;
   7.294  
   7.295 -  plp = pathlist;
   7.296 -  while (plp) {
   7.297 -    if (plp->path) {
   7.298 -      free(plp->path);
   7.299 -      plp->path=NULL;
   7.300 +    while (plp)
   7.301 +    {
   7.302 +	next = plp->next;
   7.303 +	free(plp->path);
   7.304 +	free(plp);
   7.305 +	plp = next;
   7.306      }
   7.307 -    next_plp = plp->next;
   7.308 -    free(plp);
   7.309 -    plp = next_plp;
   7.310 -  }
   7.311 -  pathlist = NULL;
   7.312 +    pathlist = NULL;
   7.313  }
     8.1 --- a/timidity/common.h	Tue Oct 17 16:55:58 2017 -0700
     8.2 +++ b/timidity/common.h	Tue Oct 17 21:54:04 2017 -0700
     8.3 @@ -1,39 +1,20 @@
     8.4  /*
     8.5 +
     8.6      TiMidity -- Experimental MIDI to WAVE converter
     8.7      Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
     8.8  
     8.9      This program is free software; you can redistribute it and/or modify
    8.10      it under the terms of the Perl Artistic License, available in COPYING.
    8.11 - */
    8.12  
    8.13 -#include <limits.h>
    8.14 -
    8.15 -#ifndef PATH_MAX   /* GNU Hurd doesn't limit path size, thus no PATH_MAX... */
    8.16 -#define PATH_MAX 1024   /* ...so we'll just impose an arbitrary limit. */
    8.17 -#endif
    8.18 -
    8.19 -extern char *program_name, current_filename[];
    8.20 -
    8.21 -extern FILE *msgfp;
    8.22 -
    8.23 -extern int num_ochannels;
    8.24 -
    8.25 -#define MULTICHANNEL_OUT
    8.26 -#define MAX_OUT_CHANNELS 6
    8.27 +   common.h
    8.28 +*/
    8.29  
    8.30  typedef struct {
    8.31    char *path;
    8.32    void *next;
    8.33  } PathList;
    8.34  
    8.35 -/* Noise modes for open_file */
    8.36 -#define OF_SILENT	0
    8.37 -#define OF_NORMAL	1
    8.38 -#define OF_VERBOSE	2
    8.39 -
    8.40 -extern FILE *open_file(const char *name, int decompress, int noise_mode);
    8.41 +extern SDL_RWops *open_file(const char *name);
    8.42  extern void add_to_pathlist(const char *s);
    8.43 +extern void *safe_malloc(size_t count);
    8.44  extern void free_pathlist(void);
    8.45 -extern void close_file(FILE *fp);
    8.46 -extern void skip(FILE *fp, size_t len);
    8.47 -extern void *safe_malloc(size_t count);
     9.1 --- a/timidity/config.h	Tue Oct 17 16:55:58 2017 -0700
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,226 +0,0 @@
     9.4 -/*
     9.5 -    TiMidity -- Experimental MIDI to WAVE converter
     9.6 -    Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
     9.7 -
     9.8 -    This program is free software; you can redistribute it and/or modify
     9.9 -    it under the terms of the Perl Artistic License, available in COPYING.
    9.10 - */
    9.11 -
    9.12 -/* This is for use with the SDL library */
    9.13 -#define SDL
    9.14 -#include "SDL_config.h"
    9.15 -#include "SDL_endian.h"
    9.16 -
    9.17 -#define TIMIDITY_ERROR_SIZE 1024
    9.18 -
    9.19 -/* When a patch file can't be opened, one of these extensions is
    9.20 -   appended to the filename and the open is tried again.
    9.21 - */
    9.22 -#define PATCH_EXT_LIST { ".pat", 0 }
    9.23 -
    9.24 -/* Acoustic Grand Piano seems to be the usual default instrument. */
    9.25 -#define DEFAULT_PROGRAM 0
    9.26 -
    9.27 -/* 9 here is MIDI channel 10, which is the standard percussion channel.
    9.28 -   Some files (notably C:\WINDOWS\CANYON.MID) think that 16 is one too. 
    9.29 -   On the other hand, some files know that 16 is not a drum channel and
    9.30 -   try to play music on it. This is now a runtime option, so this isn't
    9.31 -   a critical choice anymore. */
    9.32 -#define DEFAULT_DRUMCHANNELS (1<<9)
    9.33 -
    9.34 -/* A somewhat arbitrary frequency range. The low end of this will
    9.35 -   sound terrible as no lowpass filtering is performed on most
    9.36 -   instruments before resampling. */
    9.37 -#define MIN_OUTPUT_RATE 	4000
    9.38 -#define MAX_OUTPUT_RATE 	65000
    9.39 -
    9.40 -/* In percent. */
    9.41 -/* #define DEFAULT_AMPLIFICATION 	70 */
    9.42 -/* #define DEFAULT_AMPLIFICATION 	50 */
    9.43 -#define DEFAULT_AMPLIFICATION 	30
    9.44 -
    9.45 -/* Default sampling rate, default polyphony, and maximum polyphony.
    9.46 -   All but the last can be overridden from the command line. */
    9.47 -#define DEFAULT_RATE	32000
    9.48 -/* #define DEFAULT_VOICES	32 */
    9.49 -/* #define MAX_VOICES	48 */
    9.50 -#define DEFAULT_VOICES	256
    9.51 -#define MAX_VOICES	256
    9.52 -#define MAXCHAN		16
    9.53 -/* #define MAXCHAN		64 */
    9.54 -#define MAXNOTE		128
    9.55 -
    9.56 -/* 1000 here will give a control ratio of 22:1 with 22 kHz output.
    9.57 -   Higher CONTROLS_PER_SECOND values allow more accurate rendering
    9.58 -   of envelopes and tremolo. The cost is CPU time. */
    9.59 -#define CONTROLS_PER_SECOND 1000
    9.60 -
    9.61 -/* Strongly recommended. This option increases CPU usage by half, but
    9.62 -   without it sound quality is very poor. */
    9.63 -#define LINEAR_INTERPOLATION
    9.64 -
    9.65 -/* This is an experimental kludge that needs to be done right, but if
    9.66 -   you've got an 8-bit sound card, or cheap multimedia speakers hooked
    9.67 -   to your 16-bit output device, you should definitely give it a try.
    9.68 -
    9.69 -   Defining LOOKUP_HACK causes table lookups to be used in mixing
    9.70 -   instead of multiplication. We convert the sample data to 8 bits at
    9.71 -   load time and volumes to logarithmic 7-bit values before looking up
    9.72 -   the product, which degrades sound quality noticeably.
    9.73 -
    9.74 -   Defining LOOKUP_HACK should save ~20% of CPU on an Intel machine.
    9.75 -   LOOKUP_INTERPOLATION might give another ~5% */
    9.76 -/* #define LOOKUP_HACK
    9.77 -   #define LOOKUP_INTERPOLATION */
    9.78 -
    9.79 -/* Make envelopes twice as fast. Saves ~20% CPU time (notes decay
    9.80 -   faster) and sounds more like a GUS. There is now a command line
    9.81 -   option to toggle this as well. */
    9.82 -/* #define FAST_DECAY */
    9.83 -
    9.84 -/* How many bits to use for the fractional part of sample positions.
    9.85 -   This affects tonal accuracy. The entire position counter must fit
    9.86 -   in 32 bits, so with FRACTION_BITS equal to 12, the maximum size of
    9.87 -   a sample is 1048576 samples (2 megabytes in memory). The GUS gets
    9.88 -   by with just 9 bits and a little help from its friends...
    9.89 -   "The GUS does not SUCK!!!" -- a happy user :) */
    9.90 -#define FRACTION_BITS 12
    9.91 -
    9.92 -#define MAX_SAMPLE_SIZE (1 << (32-FRACTION_BITS))
    9.93 -
    9.94 -typedef double FLOAT_T;
    9.95 -
    9.96 -/* For some reason the sample volume is always set to maximum in all
    9.97 -   patch files. Define this for a crude adjustment that may help
    9.98 -   equalize instrument volumes. */
    9.99 -#define ADJUST_SAMPLE_VOLUMES
   9.100 -
   9.101 -/* The number of samples to use for ramping out a dying note. Affects
   9.102 -   click removal. */
   9.103 -#define MAX_DIE_TIME 20
   9.104 -
   9.105 -/* On some machines (especially PCs without math coprocessors),
   9.106 -   looking up sine values in a table will be significantly faster than
   9.107 -   computing them on the fly. Uncomment this to use lookups. */
   9.108 -/* #define LOOKUP_SINE */
   9.109 -
   9.110 -/* Shawn McHorse's resampling optimizations. These may not in fact be
   9.111 -   faster on your particular machine and compiler. You'll have to run
   9.112 -   a benchmark to find out. */
   9.113 -#define PRECALC_LOOPS
   9.114 -
   9.115 -/* If calling ldexp() is faster than a floating point multiplication
   9.116 -   on your machine/compiler/libm, uncomment this. It doesn't make much
   9.117 -   difference either way, but hey -- it was on the TODO list, so it
   9.118 -   got done. */
   9.119 -/* #define USE_LDEXP */
   9.120 -
   9.121 -/**************************************************************************/
   9.122 -/* Anything below this shouldn't need to be changed unless you're porting
   9.123 -   to a new machine with other than 32-bit, big-endian words. */
   9.124 -/**************************************************************************/
   9.125 -
   9.126 -/* change FRACTION_BITS above, not these */
   9.127 -#define INTEGER_BITS (32 - FRACTION_BITS)
   9.128 -#define INTEGER_MASK (0xFFFFFFFF << FRACTION_BITS)
   9.129 -#define FRACTION_MASK (~ INTEGER_MASK)
   9.130 -
   9.131 -/* This is enforced by some computations that must fit in an int */
   9.132 -#define MAX_CONTROL_RATIO 255
   9.133 -
   9.134 -typedef unsigned int uint32;
   9.135 -typedef int int32; 
   9.136 -typedef unsigned short uint16;
   9.137 -typedef short int16;
   9.138 -typedef unsigned char uint8;
   9.139 -typedef char int8;
   9.140 -
   9.141 -/* Instrument files are little-endian, MIDI files big-endian, so we
   9.142 -   need to do some conversions. */
   9.143 -
   9.144 -#define XCHG_SHORT(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
   9.145 -# define XCHG_LONG(x) ((((x)&0xFF)<<24) | \
   9.146 -		      (((x)&0xFF00)<<8) | \
   9.147 -		      (((x)&0xFF0000)>>8) | \
   9.148 -		      (((x)>>24)&0xFF))
   9.149 -
   9.150 -#if SDL_BYTEORDER == SDL_LIL_ENDIAN
   9.151 -#define LE_SHORT(x) x
   9.152 -#define LE_LONG(x) x
   9.153 -#define BE_SHORT(x) XCHG_SHORT(x)
   9.154 -#define BE_LONG(x) XCHG_LONG(x)
   9.155 -#else
   9.156 -#define BE_SHORT(x) x
   9.157 -#define BE_LONG(x) x
   9.158 -#define LE_SHORT(x) XCHG_SHORT(x)
   9.159 -#define LE_LONG(x) XCHG_LONG(x)
   9.160 -#endif
   9.161 -
   9.162 -#define MAX_AMPLIFICATION 800
   9.163 -
   9.164 -/* You could specify a complete path, e.g. "/etc/timidity.cfg", and
   9.165 -   then specify the library directory in the configuration file. */
   9.166 -#define CONFIG_FILE	"timidity.cfg"
   9.167 -#define CONFIG_FILE_ETC "/etc/timidity.cfg"
   9.168 -#define CONFIG_FILE_ETC_TIMIDITY_FREEPATS "/etc/timidity/freepats.cfg"
   9.169 -
   9.170 -#if defined(__WIN32__) || defined(__OS2__)
   9.171 -#define DEFAULT_PATH	"C:\\TIMIDITY"
   9.172 -#else
   9.173 -#define DEFAULT_PATH	"/etc/timidity"
   9.174 -#define DEFAULT_PATH1	"/usr/share/timidity"
   9.175 -#define DEFAULT_PATH2	"/usr/local/share/timidity"
   9.176 -#define DEFAULT_PATH3	"/usr/local/lib/timidity"
   9.177 -#endif
   9.178 -
   9.179 -/* These affect general volume */
   9.180 -#define GUARD_BITS 3
   9.181 -#define AMP_BITS (15-GUARD_BITS)
   9.182 -
   9.183 -#ifdef LOOKUP_HACK
   9.184 -   typedef int8 sample_t;
   9.185 -   typedef uint8 final_volume_t;
   9.186 -#  define FINAL_VOLUME(v) (~_l2u[v])
   9.187 -#  define MIXUP_SHIFT 5
   9.188 -#  define MAX_AMP_VALUE 4095
   9.189 -#else
   9.190 -   typedef int16 sample_t;
   9.191 -   typedef int32 final_volume_t;
   9.192 -#  define FINAL_VOLUME(v) (v)
   9.193 -#  define MAX_AMP_VALUE ((1<<(AMP_BITS+1))-1)
   9.194 -#endif
   9.195 -
   9.196 -typedef int16 resample_t;
   9.197 -
   9.198 -#ifdef USE_LDEXP
   9.199 -#  define FSCALE(a,b) ldexp((a),(b))
   9.200 -#  define FSCALENEG(a,b) ldexp((a),-(b))
   9.201 -#else
   9.202 -#  define FSCALE(a,b) (float)((a) * (double)(1<<(b)))
   9.203 -#  define FSCALENEG(a,b) (float)((a) * (1.0L / (double)(1<<(b))))
   9.204 -#endif
   9.205 -
   9.206 -/* Vibrato and tremolo Choices of the Day */
   9.207 -#define SWEEP_TUNING 38
   9.208 -#define VIBRATO_AMPLITUDE_TUNING 1.0L
   9.209 -#define VIBRATO_RATE_TUNING 38
   9.210 -#define TREMOLO_AMPLITUDE_TUNING 1.0L
   9.211 -#define TREMOLO_RATE_TUNING 38
   9.212 -
   9.213 -#define SWEEP_SHIFT 16
   9.214 -#define RATE_SHIFT 5
   9.215 -
   9.216 -#define VIBRATO_SAMPLE_INCREMENTS 32
   9.217 -
   9.218 -#ifndef PI
   9.219 -  #define PI 3.14159265358979323846
   9.220 -#endif
   9.221 -
   9.222 -/* The path separator (D.M.) */
   9.223 -#if defined(__WIN32__) || defined(__OS2__)
   9.224 -#  define PATH_SEP '\\'
   9.225 -#  define PATH_STRING "\\"
   9.226 -#else
   9.227 -#  define PATH_SEP '/'
   9.228 -#  define PATH_STRING "/"
   9.229 -#endif
    10.1 --- a/timidity/ctrlmode.c	Tue Oct 17 16:55:58 2017 -0700
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,26 +0,0 @@
    10.4 -/*
    10.5 -    TiMidity -- Experimental MIDI to WAVE converter
    10.6 -    Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
    10.7 -
    10.8 -    This program is free software; you can redistribute it and/or modify
    10.9 -    it under the terms of the Perl Artistic License, available in COPYING.
   10.10 - */
   10.11 -
   10.12 -#include "config.h"
   10.13 -#include "ctrlmode.h"
   10.14 -
   10.15 -#ifdef SDL
   10.16 -  extern ControlMode sdl_control_mode;
   10.17 -# ifndef DEFAULT_CONTROL_MODE
   10.18 -#  define DEFAULT_CONTROL_MODE &sdl_control_mode
   10.19 -# endif
   10.20 -#endif
   10.21 -
   10.22 -ControlMode *ctl_list[]={
   10.23 -#ifdef SDL
   10.24 -  &sdl_control_mode,
   10.25 -#endif
   10.26 -  0
   10.27 -};
   10.28 -
   10.29 -ControlMode *ctl=DEFAULT_CONTROL_MODE;
    11.1 --- a/timidity/ctrlmode.h	Tue Oct 17 16:55:58 2017 -0700
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,74 +0,0 @@
    11.4 -/*
    11.5 -    TiMidity -- Experimental MIDI to WAVE converter
    11.6 -    Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
    11.7 -
    11.8 -    This program is free software; you can redistribute it and/or modify
    11.9 -    it under the terms of the Perl Artistic License, available in COPYING.
   11.10 - */
   11.11 -
   11.12 -/* Return values for ControlMode.read */
   11.13 -
   11.14 -#define RC_ERROR -1
   11.15 -#define RC_NONE 0
   11.16 -#define RC_QUIT 1
   11.17 -#define RC_NEXT 2
   11.18 -#define RC_PREVIOUS 3 /* Restart this song at beginning, or the previous
   11.19 -			 song if we're less than a second into this one. */
   11.20 -#define RC_FORWARD 4
   11.21 -#define RC_BACK 5
   11.22 -#define RC_JUMP 6
   11.23 -#define RC_TOGGLE_PAUSE 7 /* Pause/continue */
   11.24 -#define RC_RESTART 8 /* Restart song at beginning */
   11.25 -
   11.26 -#define RC_PAUSE 9 /* Really pause playing */
   11.27 -#define RC_CONTINUE 10 /* Continue if paused */
   11.28 -#define RC_REALLY_PREVIOUS 11 /* Really go to the previous song */
   11.29 -#define RC_CHANGE_VOLUME 12
   11.30 -#define RC_LOAD_FILE 13		/* Load a new midifile */
   11.31 -#define RC_TUNE_END 14		/* The tune is over, play it again sam? */
   11.32 -
   11.33 -#define CMSG_INFO	0
   11.34 -#define CMSG_WARNING	1
   11.35 -#define CMSG_ERROR	2
   11.36 -#define CMSG_FATAL	3
   11.37 -#define CMSG_TRACE	4
   11.38 -#define CMSG_TIME	5
   11.39 -#define CMSG_TOTAL	6
   11.40 -#define CMSG_FILE	7
   11.41 -#define CMSG_TEXT	8
   11.42 -
   11.43 -#define VERB_NORMAL	0
   11.44 -#define VERB_VERBOSE	1
   11.45 -#define VERB_NOISY	2
   11.46 -#define VERB_DEBUG	3
   11.47 -#define VERB_DEBUG_SILLY	4
   11.48 -
   11.49 -typedef struct {
   11.50 -  char *id_name, id_character;
   11.51 -  int verbosity, trace_playing, opened;
   11.52 -
   11.53 -  int (*open)(int using_stdin, int using_stdout);
   11.54 -  void (*pass_playing_list)(int number_of_files, char *list_of_files[]);
   11.55 -  void (*close)(void);
   11.56 -  int (*read)(int32 *valp);
   11.57 -  int (*cmsg)(int type, int verbosity_level, char *fmt, ...);
   11.58 -
   11.59 -  void (*refresh)(void);
   11.60 -  void (*reset)(void);
   11.61 -  void (*file_name)(char *name);
   11.62 -  void (*total_time)(int tt);
   11.63 -  void (*current_time)(int ct);
   11.64 -
   11.65 -  void (*note)(int v);
   11.66 -  void (*master_volume)(int mv);
   11.67 -  void (*program)(int channel, int val); /* val<0 means drum set -val */
   11.68 -  void (*volume)(int channel, int val);
   11.69 -  void (*expression)(int channel, int val);
   11.70 -  void (*panning)(int channel, int val);
   11.71 -  void (*sustain)(int channel, int val);
   11.72 -  void (*pitch_bend)(int channel, int val);
   11.73 -  
   11.74 -} ControlMode;
   11.75 -
   11.76 -extern ControlMode *ctl_list[], *ctl; 
   11.77 -extern char timidity_error[];
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/timidity/dls1.h	Tue Oct 17 21:54:04 2017 -0700
    12.3 @@ -0,0 +1,266 @@
    12.4 +/*==========================================================================;
    12.5 +//
    12.6 +//  dls1.h
    12.7 +//
    12.8 +//
    12.9 +//  Description:
   12.10 +//
   12.11 +//  Interface defines and structures for the Instrument Collection Form
   12.12 +//  RIFF DLS.
   12.13 +//
   12.14 +//
   12.15 +//  Written by Sonic Foundry 1996.  Released for public use.
   12.16 +//
   12.17 +//=========================================================================*/
   12.18 +
   12.19 +#ifndef _INC_DLS1
   12.20 +#define _INC_DLS1
   12.21 +
   12.22 +/*//////////////////////////////////////////////////////////////////////////
   12.23 +//
   12.24 +//
   12.25 +// Layout of an instrument collection:
   12.26 +//
   12.27 +//
   12.28 +// RIFF [] 'DLS ' [dlid,colh,INSTLIST,WAVEPOOL,INFOLIST]
   12.29 +//
   12.30 +// INSTLIST
   12.31 +// LIST [] 'lins'
   12.32 +//               LIST [] 'ins ' [dlid,insh,RGNLIST,ARTLIST,INFOLIST]
   12.33 +//               LIST [] 'ins ' [dlid,insh,RGNLIST,ARTLIST,INFOLIST]
   12.34 +//               LIST [] 'ins ' [dlid,insh,RGNLIST,ARTLIST,INFOLIST]
   12.35 +//
   12.36 +// RGNLIST
   12.37 +// LIST [] 'lrgn' 
   12.38 +//               LIST [] 'rgn '  [rgnh,wsmp,wlnk,ARTLIST]
   12.39 +//               LIST [] 'rgn '  [rgnh,wsmp,wlnk,ARTLIST]
   12.40 +//               LIST [] 'rgn '  [rgnh,wsmp,wlnk,ARTLIST]
   12.41 +//
   12.42 +// ARTLIST
   12.43 +// LIST [] 'lart'
   12.44 +//         'art1' level 1 Articulation connection graph
   12.45 +//         'art2' level 2 Articulation connection graph
   12.46 +//         '3rd1' Possible 3rd party articulation structure 1
   12.47 +//         '3rd2' Possible 3rd party articulation structure 2 .... and so on
   12.48 +//
   12.49 +// WAVEPOOL 
   12.50 +// ptbl [] [pool table]
   12.51 +// LIST [] 'wvpl'
   12.52 +//               [path],
   12.53 +//               [path],
   12.54 +//               LIST [] 'wave' [dlid,RIFFWAVE]
   12.55 +//               LIST [] 'wave' [dlid,RIFFWAVE]
   12.56 +//               LIST [] 'wave' [dlid,RIFFWAVE]
   12.57 +//               LIST [] 'wave' [dlid,RIFFWAVE]
   12.58 +//               LIST [] 'wave' [dlid,RIFFWAVE]
   12.59 +//
   12.60 +// INFOLIST
   12.61 +// LIST [] 'INFO' 
   12.62 +//               'icmt' 'One of those crazy comments.'
   12.63 +//               'icop' 'Copyright (C) 1996 Sonic Foundry'
   12.64 +//
   12.65 +/////////////////////////////////////////////////////////////////////////*/
   12.66 +
   12.67 +
   12.68 +/*/////////////////////////////////////////////////////////////////////////
   12.69 +// FOURCC's used in the DLS file
   12.70 +/////////////////////////////////////////////////////////////////////////*/
   12.71 +
   12.72 +#define FOURCC_DLS   mmioFOURCC('D','L','S',' ')
   12.73 +#define FOURCC_DLID  mmioFOURCC('d','l','i','d')
   12.74 +#define FOURCC_COLH  mmioFOURCC('c','o','l','h')
   12.75 +#define FOURCC_WVPL  mmioFOURCC('w','v','p','l')
   12.76 +#define FOURCC_PTBL  mmioFOURCC('p','t','b','l')
   12.77 +#define FOURCC_PATH  mmioFOURCC('p','a','t','h')
   12.78 +#define FOURCC_wave  mmioFOURCC('w','a','v','e')
   12.79 +#define FOURCC_LINS  mmioFOURCC('l','i','n','s')
   12.80 +#define FOURCC_INS   mmioFOURCC('i','n','s',' ')
   12.81 +#define FOURCC_INSH  mmioFOURCC('i','n','s','h')
   12.82 +#define FOURCC_LRGN  mmioFOURCC('l','r','g','n')
   12.83 +#define FOURCC_RGN   mmioFOURCC('r','g','n',' ')
   12.84 +#define FOURCC_RGNH  mmioFOURCC('r','g','n','h')
   12.85 +#define FOURCC_LART  mmioFOURCC('l','a','r','t')
   12.86 +#define FOURCC_ART1  mmioFOURCC('a','r','t','1')
   12.87 +#define FOURCC_WLNK  mmioFOURCC('w','l','n','k')
   12.88 +#define FOURCC_WSMP  mmioFOURCC('w','s','m','p')
   12.89 +#define FOURCC_VERS  mmioFOURCC('v','e','r','s')
   12.90 +
   12.91 +/*/////////////////////////////////////////////////////////////////////////
   12.92 +// Articulation connection graph definitions 
   12.93 +/////////////////////////////////////////////////////////////////////////*/
   12.94 +
   12.95 +/* Generic Sources */
   12.96 +#define CONN_SRC_NONE              0x0000
   12.97 +#define CONN_SRC_LFO               0x0001
   12.98 +#define CONN_SRC_KEYONVELOCITY     0x0002
   12.99 +#define CONN_SRC_KEYNUMBER         0x0003
  12.100 +#define CONN_SRC_EG1               0x0004
  12.101 +#define CONN_SRC_EG2               0x0005
  12.102 +#define CONN_SRC_PITCHWHEEL        0x0006
  12.103 +
  12.104 +/* Midi Controllers 0-127 */
  12.105 +#define CONN_SRC_CC1               0x0081
  12.106 +#define CONN_SRC_CC7               0x0087
  12.107 +#define CONN_SRC_CC10              0x008a
  12.108 +#define CONN_SRC_CC11              0x008b
  12.109 +
  12.110 +/* Generic Destinations */
  12.111 +#define CONN_DST_NONE              0x0000
  12.112 +#define CONN_DST_ATTENUATION       0x0001
  12.113 +#define CONN_DST_PITCH             0x0003
  12.114 +#define CONN_DST_PAN               0x0004
  12.115 +
  12.116 +/* LFO Destinations */
  12.117 +#define CONN_DST_LFO_FREQUENCY     0x0104
  12.118 +#define CONN_DST_LFO_STARTDELAY    0x0105
  12.119 +
  12.120 +/* EG1 Destinations */
  12.121 +#define CONN_DST_EG1_ATTACKTIME    0x0206
  12.122 +#define CONN_DST_EG1_DECAYTIME     0x0207
  12.123 +#define CONN_DST_EG1_RELEASETIME   0x0209
  12.124 +#define CONN_DST_EG1_SUSTAINLEVEL  0x020a
  12.125 +
  12.126 +/* EG2 Destinations */
  12.127 +#define CONN_DST_EG2_ATTACKTIME    0x030a
  12.128 +#define CONN_DST_EG2_DECAYTIME     0x030b
  12.129 +#define CONN_DST_EG2_RELEASETIME   0x030d
  12.130 +#define CONN_DST_EG2_SUSTAINLEVEL  0x030e
  12.131 +
  12.132 +#define CONN_TRN_NONE              0x0000
  12.133 +#define CONN_TRN_CONCAVE           0x0001
  12.134 +
  12.135 +typedef struct _DLSID {
  12.136 +  ULONG    ulData1;
  12.137 +  USHORT   usData2;
  12.138 +  USHORT   usData3;
  12.139 +  BYTE     abData4[8];
  12.140 +} DLSID, FAR *LPDLSID;
  12.141 +
  12.142 +typedef struct _DLSVERSION {
  12.143 +  DWORD    dwVersionMS;
  12.144 +  DWORD    dwVersionLS;
  12.145 +} DLSVERSION, FAR *LPDLSVERSION;
  12.146 +                   
  12.147 +
  12.148 +typedef struct _CONNECTION {
  12.149 +  USHORT   usSource;
  12.150 +  USHORT   usControl;
  12.151 +  USHORT   usDestination;
  12.152 +  USHORT   usTransform;
  12.153 +  LONG     lScale;
  12.154 +} CONNECTION, FAR *LPCONNECTION;
  12.155 +
  12.156 +
  12.157 +/* Level 1 Articulation Data */
  12.158 +
  12.159 +typedef struct _CONNECTIONLIST {
  12.160 +  ULONG    cbSize;            /* size of the connection list structure */
  12.161 +  ULONG    cConnections;      /* count of connections in the list */
  12.162 +} CONNECTIONLIST, FAR *LPCONNECTIONLIST;
  12.163 +
  12.164 +
  12.165 +
  12.166 +/*/////////////////////////////////////////////////////////////////////////
  12.167 +// Generic type defines for regions and instruments
  12.168 +/////////////////////////////////////////////////////////////////////////*/
  12.169 +
  12.170 +typedef struct _RGNRANGE {
  12.171 +  USHORT usLow;
  12.172 +  USHORT usHigh;
  12.173 +} RGNRANGE, FAR * LPRGNRANGE;
  12.174 +
  12.175 +#define F_INSTRUMENT_DRUMS      0x80000000
  12.176 +
  12.177 +typedef struct _MIDILOCALE {
  12.178 +  ULONG ulBank;
  12.179 +  ULONG ulInstrument;
  12.180 +} MIDILOCALE, FAR *LPMIDILOCALE;
  12.181 +
  12.182 +/*/////////////////////////////////////////////////////////////////////////
  12.183 +// Header structures found in an DLS file for collection, instruments, and
  12.184 +// regions.
  12.185 +/////////////////////////////////////////////////////////////////////////*/
  12.186 +
  12.187 +#define F_RGN_OPTION_SELFNONEXCLUSIVE  0x0001
  12.188 +
  12.189 +typedef struct _RGNHEADER {
  12.190 +  RGNRANGE RangeKey;            /* Key range  */
  12.191 +  RGNRANGE RangeVelocity;       /* Velocity Range  */
  12.192 +  USHORT   fusOptions;          /* Synthesis options for this range */
  12.193 +  USHORT   usKeyGroup;          /* Key grouping for non simultaneous play */
  12.194 +                                /* 0 = no group, 1 up is group */
  12.195 +                                /* for Level 1 only groups 1-15 are allowed */
  12.196 +} RGNHEADER, FAR *LPRGNHEADER;
  12.197 +
  12.198 +typedef struct _INSTHEADER {
  12.199 +  ULONG      cRegions;          /* Count of regions in this instrument */
  12.200 +  MIDILOCALE Locale;            /* Intended MIDI locale of this instrument */
  12.201 +} INSTHEADER, FAR *LPINSTHEADER;
  12.202 +
  12.203 +typedef struct _DLSHEADER {
  12.204 +  ULONG      cInstruments;      /* Count of instruments in the collection */
  12.205 +} DLSHEADER, FAR *LPDLSHEADER;
  12.206 +
  12.207 +/*////////////////////////////////////////////////////////////////////////////
  12.208 +// definitions for the Wave link structure
  12.209 +////////////////////////////////////////////////////////////////////////////*/
  12.210 +
  12.211 +/* ****  For level 1 only WAVELINK_CHANNEL_MONO is valid  **** */
  12.212 +/* ulChannel allows for up to 32 channels of audio with each bit position */
  12.213 +/* specifiying a channel of playback */
  12.214 +
  12.215 +#define WAVELINK_CHANNEL_LEFT    0x0001l
  12.216 +#define WAVELINK_CHANNEL_RIGHT   0x0002l
  12.217 +
  12.218 +#define F_WAVELINK_PHASE_MASTER  0x0001
  12.219 +
  12.220 +typedef struct _WAVELINK { /* any paths or links are stored right after struct */
  12.221 +  USHORT   fusOptions;     /* options flags for this wave */
  12.222 +  USHORT   usPhaseGroup;   /* Phase grouping for locking channels */
  12.223 +  ULONG    ulChannel;      /* channel placement */
  12.224 +  ULONG    ulTableIndex;   /* index into the wave pool table, 0 based */
  12.225 +} WAVELINK, FAR *LPWAVELINK;
  12.226 +
  12.227 +#define POOL_CUE_NULL  0xffffffffl
  12.228 +
  12.229 +typedef struct _POOLCUE { 
  12.230 +  ULONG    ulOffset;       /* Offset to the entry in the list */
  12.231 +} POOLCUE, FAR *LPPOOLCUE;
  12.232 +
  12.233 +typedef struct _POOLTABLE {
  12.234 +  ULONG    cbSize;            /* size of the pool table structure */
  12.235 +  ULONG    cCues;             /* count of cues in the list */
  12.236 +} POOLTABLE, FAR *LPPOOLTABLE;
  12.237 +
  12.238 +/*////////////////////////////////////////////////////////////////////////////
  12.239 +// Structures for the "wsmp" chunk
  12.240 +////////////////////////////////////////////////////////////////////////////*/
  12.241 +
  12.242 +#define F_WSMP_NO_TRUNCATION     0x0001l
  12.243 +#define F_WSMP_NO_COMPRESSION    0x0002l
  12.244 +
  12.245 +
  12.246 +typedef struct _rwsmp {
  12.247 +  ULONG   cbSize;
  12.248 +  USHORT  usUnityNote;         /* MIDI Unity Playback Note */
  12.249 +  SHORT   sFineTune;           /* Fine Tune in log tuning */
  12.250 +  LONG    lAttenuation;        /* Overall Attenuation to be applied to data */
  12.251 +  ULONG   fulOptions;          /* Flag options  */
  12.252 +  ULONG   cSampleLoops;        /* Count of Sample loops, 0 loops is one shot */
  12.253 +} WSMPL, FAR *LPWSMPL;
  12.254 +
  12.255 +
  12.256 +/* This loop type is a normal forward playing loop which is continually */
  12.257 +/* played until the envelope reaches an off threshold in the release */
  12.258 +/* portion of the volume envelope */
  12.259 +
  12.260 +#define WLOOP_TYPE_FORWARD   0
  12.261 +
  12.262 +typedef struct _rloop {
  12.263 +  ULONG cbSize;
  12.264 +  ULONG ulType;              /* Loop Type */
  12.265 +  ULONG ulStart;             /* Start of loop in samples */
  12.266 +  ULONG ulLength;            /* Length of loop in samples */
  12.267 +} WLOOP, FAR *LPWLOOP;
  12.268 +
  12.269 +#endif /*_INC_DLS1 */
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/timidity/dls2.h	Tue Oct 17 21:54:04 2017 -0700
    13.3 @@ -0,0 +1,130 @@
    13.4 +/*
    13.5 + 
    13.6 + 	dls2.h
    13.7 + 	
    13.8 + 	Description:
    13.9 + 
   13.10 + 	Interface defines and structures for the DLS2 extensions of DLS.
   13.11 + 
   13.12 + 
   13.13 +     Written by Microsoft 1998.  Released for public use.
   13.14 + 
   13.15 +*/
   13.16 + 
   13.17 +#ifndef _INC_DLS2
   13.18 +#define _INC_DLS2
   13.19 + 
   13.20 +/*
   13.21 +     FOURCC's used in the DLS2 file, in addition to DLS1 chunks
   13.22 +*/
   13.23 + 
   13.24 +#define FOURCC_RGN2  mmioFOURCC('r','g','n','2')
   13.25 +#define FOURCC_LAR2  mmioFOURCC('l','a','r','2')
   13.26 +#define FOURCC_ART2  mmioFOURCC('a','r','t','2')
   13.27 +#define FOURCC_CDL   mmioFOURCC('c','d','l',' ')
   13.28 +#define FOURCC_DLID	 mmioFOURCC('d','l','i','d')
   13.29 + 
   13.30 +/*
   13.31 +     Articulation connection graph definitions. These are in addition to
   13.32 +     the definitions in the DLS1 header.
   13.33 +*/
   13.34 + 
   13.35 +/* Generic Sources (in addition to DLS1 sources. */
   13.36 +#define CONN_SRC_POLYPRESSURE		0x0007	/* Polyphonic Pressure */
   13.37 +#define CONN_SRC_CHANNELPRESSURE		0x0008	/* Channel Pressure */
   13.38 +#define CONN_SRC_VIBRATO			0x0009	/* Vibrato LFO */
   13.39 +#define CONN_SRC_MONOPRESSURE       	0x000a  /* MIDI Mono pressure */
   13.40 + 
   13.41 + 
   13.42 +/* Midi Controllers */
   13.43 +#define CONN_SRC_CC91			0x00db	/* Reverb Send */
   13.44 +#define CONN_SRC_CC93			0x00dd	/* Chorus Send */
   13.45 + 
   13.46 + 
   13.47 +/* Generic Destinations */
   13.48 +#define CONN_DST_GAIN			0x0001	/* Same as CONN_DST_ ATTENUATION, but more appropriate terminology. */
   13.49 +#define CONN_DST_KEYNUMBER 0x0005  /* Key Number Generator */
   13.50 + 
   13.51 +/* Audio Channel Output Destinations */
   13.52 +#define CONN_DST_LEFT			0x0010	/* Left Channel Send */
   13.53 +#define CONN_DST_RIGHT			0x0011	/* Right Channel Send */
   13.54 +#define CONN_DST_CENTER			0x0012	/* Center Channel Send */
   13.55 +#define CONN_DST_LEFTREAR			0x0013	/* Left Rear Channel Send */
   13.56 +#define CONN_DST_RIGHTREAR			0x0014	/* Right Rear Channel Send */
   13.57 +#define CONN_DST_LFE_CHANNEL		0x0015	/* LFE Channel Send */
   13.58 +#define CONN_DST_CHORUS			0x0080	/* Chorus Send */
   13.59 +#define CONN_DST_REVERB			0x0081	/* Reverb Send */
   13.60 + 
   13.61 +/* Vibrato LFO Destinations */
   13.62 +#define CONN_DST_VIB_FREQUENCY		0x0114	/* Vibrato Frequency */
   13.63 +#define CONN_DST_VIB_STARTDELAY		0x0115	/* Vibrato Start Delay */
   13.64 + 
   13.65 +/* EG1 Destinations */
   13.66 +#define CONN_DST_EG1_DELAYTIME		0x020B	/* EG1 Delay Time */
   13.67 +#define CONN_DST_EG1_HOLDTIME		0x020C	/* EG1 Hold Time */
   13.68 +#define CONN_DST_EG1_SHUTDOWNTIME		0x020D	/* EG1 Shutdown Time */
   13.69 + 
   13.70 + 
   13.71 +/*	EG2 Destinations */
   13.72 +#define CONN_DST_EG2_DELAYTIME		0x030F	/* EG2 Delay Time */
   13.73 +#define CONN_DST_EG2_HOLDTIME		0x0310	/* EG2 Hold Time */
   13.74 + 
   13.75 + 
   13.76 +/* Filter Destinations */
   13.77 +#define CONN_DST_FILTER_CUTOFF		0x0500	/* Filter Cutoff Frequency */
   13.78 +#define CONN_DST_FILTER_Q			0x0501	/* Filter Resonance */
   13.79 + 
   13.80 + 
   13.81 +/* Transforms */
   13.82 +#define CONN_TRN_CONVEX			0x0002	/* Convex Transform */
   13.83 +#define CONN_TRN_SWITCH			0x0003	/* Switch Transform */
   13.84 + 
   13.85 + 
   13.86 +/*	Conditional chunk operators */
   13.87 + #define DLS_CDL_AND			0x0001	/* X = X & Y */
   13.88 + #define DLS_CDL_OR			0x0002	/* X = X | Y */
   13.89 + #define DLS_CDL_XOR			0x0003	/* X = X ^ Y */
   13.90 + #define DLS_CDL_ADD			0x0004	/* X = X + Y */
   13.91 + #define DLS_CDL_SUBTRACT		0x0005	/* X = X - Y */
   13.92 + #define DLS_CDL_MULTIPLY		0x0006	/* X = X * Y */
   13.93 + #define DLS_CDL_DIVIDE		0x0007	/* X = X / Y */
   13.94 + #define DLS_CDL_LOGICAL_AND	0x0008	/* X = X && Y */
   13.95 + #define DLS_CDL_LOGICAL_OR		0x0009	/* X = X || Y */
   13.96 + #define DLS_CDL_LT			0x000A	/* X = (X < Y) */
   13.97 + #define DLS_CDL_LE			0x000B	/* X = (X <= Y) */
   13.98 + #define DLS_CDL_GT			0x000C	/* X = (X > Y) */
   13.99 + #define DLS_CDL_GE			0x000D	/* X = (X >= Y) */
  13.100 + #define DLS_CDL_EQ			0x000E	/* X = (X == Y) */
  13.101 + #define DLS_CDL_NOT			0x000F	/* X = !X */
  13.102 + #define DLS_CDL_CONST		0x0010	/* 32-bit constant */
  13.103 + #define DLS_CDL_QUERY		0x0011	/* 32-bit value returned from query */
  13.104 + #define DLS_CDL_QUERYSUPPORTED	0x0012	/* Test to see if query is supported by synth */
  13.105 + 
  13.106 +/*
  13.107 +  Loop and release
  13.108 +*/
  13.109 +
  13.110 +#define WLOOP_TYPE_RELEASE 1
  13.111 +
  13.112 +/*
  13.113 +  WaveLink chunk <wlnk-ck>
  13.114 +*/
  13.115 +
  13.116 +#define F_WAVELINK_MULTICHANNEL 0x0002
  13.117 +
  13.118 +
  13.119 +/*
  13.120 +  DLSID queries for <cdl-ck>
  13.121 +*/
  13.122 +
  13.123 +DEFINE_GUID(DLSID_GMInHardware, 0x178f2f24, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
  13.124 +DEFINE_GUID(DLSID_GSInHardware, 0x178f2f25, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
  13.125 +DEFINE_GUID(DLSID_XGInHardware, 0x178f2f26, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
  13.126 +DEFINE_GUID(DLSID_SupportsDLS1, 0x178f2f27, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
  13.127 +DEFINE_GUID(DLSID_SupportsDLS2, 0xf14599e5, 0x4689, 0x11d2, 0xaf, 0xa6, 0x0, 0xaa, 0x0, 0x24, 0xd8, 0xb6);
  13.128 +DEFINE_GUID(DLSID_SampleMemorySize, 0x178f2f28, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
  13.129 +DEFINE_GUID(DLSID_ManufacturersID, 0xb03e1181, 0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
  13.130 +DEFINE_GUID(DLSID_ProductID, 0xb03e1182, 0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
  13.131 +DEFINE_GUID(DLSID_SamplePlaybackRate, 0x2a91f713, 0xa4bf, 0x11d2, 0xbb, 0xdf, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
  13.132 +
  13.133 +#endif	/* _INC_DLS2 */
    14.1 --- a/timidity/filter.c	Tue Oct 17 16:55:58 2017 -0700
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,191 +0,0 @@
    14.4 -/*
    14.5 -    TiMidity -- Experimental MIDI to WAVE converter
    14.6 -    Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
    14.7 -
    14.8 -    This program is free software; you can redistribute it and/or modify
    14.9 -    it under the terms of the Perl Artistic License, available in COPYING.
   14.10 -
   14.11 -   filter.c: written by Vincent Pagel ( pagel@loria.fr ) 
   14.12 - 
   14.13 -   implements fir antialiasing filter : should help when setting sample
   14.14 -   rates as low as 8Khz.
   14.15 -
   14.16 -   April 95
   14.17 -      - first draft
   14.18 -
   14.19 -   22/5/95
   14.20 -      - modify "filter" so that it simulate leading and trailing 0 in the buffer
   14.21 -   */
   14.22 -
   14.23 -#include <stdio.h>
   14.24 -#include <string.h>
   14.25 -#include <math.h>
   14.26 -#include <stdlib.h>
   14.27 -#include "config.h"
   14.28 -#include "common.h"
   14.29 -#include "ctrlmode.h"
   14.30 -#include "instrum.h"
   14.31 -#include "filter.h"
   14.32 -
   14.33 -/*  bessel  function   */
   14.34 -static float ino(float x)
   14.35 -{
   14.36 -    float y, de, e, sde;
   14.37 -    int i;
   14.38 -    
   14.39 -    y = x / 2;
   14.40 -    e = 1.0;
   14.41 -    de = 1.0;
   14.42 -    i = 1;
   14.43 -    do {
   14.44 -	de = de * y / (float) i;
   14.45 -	sde = de * de;
   14.46 -	e += sde;
   14.47 -    } while (!( (e * 1.0e-08 - sde > 0) || (i++ > 25) ));
   14.48 -    return(e);
   14.49 -}	
   14.50 -
   14.51 -/* Kaiser Window (symetric) */
   14.52 -static void kaiser(float *w,int n,float beta)
   14.53 -{
   14.54 -    float xind, xi;
   14.55 -    int i;
   14.56 -    
   14.57 -    xind = (float)((2*n - 1) * (2*n - 1));
   14.58 -    for (i =0; i<n ; i++) 
   14.59 -	{
   14.60 -	    xi = (float)(i + 0.5);
   14.61 -	    w[i] = ino((float)(beta * sqrt((double)(1. - 4 * xi * xi / xind))))
   14.62 -		/ ino((float)beta);
   14.63 -	}
   14.64 -}
   14.65 -
   14.66 -/*
   14.67 - * fir coef in g, cuttoff frequency in fc
   14.68 - */
   14.69 -static void designfir(float *g , float fc)
   14.70 -{
   14.71 -    int i;
   14.72 -    float xi, omega, att, beta ;
   14.73 -    float w[ORDER2];
   14.74 -    
   14.75 -    for (i =0; i < ORDER2 ;i++) 
   14.76 -	{
   14.77 -	    xi = (float) (i + 0.5);
   14.78 -	    omega = (float)(PI * xi);
   14.79 -	    g[i] = (float)(sin( (double) omega * fc) / omega);
   14.80 -	}
   14.81 -    
   14.82 -    att = 40.; /* attenuation  in  db */
   14.83 -    beta = (float) (exp(log((double)0.58417 * (att - 20.96)) * 0.4) + 0.07886 
   14.84 -	* (att - 20.96));
   14.85 -    kaiser( w, ORDER2, beta);
   14.86 -    
   14.87 -    /* Matrix product */
   14.88 -    for (i =0; i < ORDER2 ; i++)
   14.89 -	g[i] = g[i] * w[i];
   14.90 -}
   14.91 -
   14.92 -/*
   14.93 - * FIR filtering -> apply the filter given by coef[] to the data buffer
   14.94 - * Note that we simulate leading and trailing 0 at the border of the 
   14.95 - * data buffer
   14.96 - */
   14.97 -static void filter(sample_t *result,sample_t *data, int32 length,float coef[])
   14.98 -{
   14.99 -    int32 sample,i,sample_window;
  14.100 -    int16 peak = 0;
  14.101 -    float sum;
  14.102 -
  14.103 -    /* Simulate leading 0 at the begining of the buffer */
  14.104 -     for (sample = 0; sample < ORDER2 ; sample++ )
  14.105 -	{
  14.106 -	    sum = 0.0;
  14.107 -	    sample_window= sample - ORDER2;
  14.108 -	   
  14.109 -	    for (i = 0; i < ORDER ;i++) 
  14.110 -		sum += (float)(coef[i] *
  14.111 -		    ((sample_window<0)? 0.0 : data[sample_window++])) ;
  14.112 -	    
  14.113 -	    /* Saturation ??? */
  14.114 -	    if (sum> 32767.) { sum=32767.; peak++; }
  14.115 -	    if (sum< -32768.) { sum=-32768; peak++; }
  14.116 -	    result[sample] = (sample_t) sum;
  14.117 -	}
  14.118 -
  14.119 -    /* The core of the buffer  */
  14.120 -    for (sample = ORDER2; sample < length - ORDER + ORDER2 ; sample++ )
  14.121 -	{
  14.122 -	    sum = 0.0;
  14.123 -	    sample_window= sample - ORDER2;
  14.124 -
  14.125 -	    for (i = 0; i < ORDER ;i++) 
  14.126 -		sum += data[sample_window++] * coef[i];
  14.127 -	    
  14.128 -	    /* Saturation ??? */
  14.129 -	    if (sum> 32767.) { sum=32767.; peak++; }
  14.130 -	    if (sum< -32768.) { sum=-32768; peak++; }
  14.131 -	    result[sample] = (sample_t) sum;
  14.132 -	}
  14.133 -    
  14.134 -    /* Simulate 0 at the end of the buffer */
  14.135 -    for (sample = length - ORDER + ORDER2; sample < length ; sample++ )
  14.136 -	{
  14.137 -	    sum = 0.0;
  14.138 -	    sample_window= sample - ORDER2;
  14.139 -	    
  14.140 -	    for (i = 0; i < ORDER ;i++) 
  14.141 -		sum += (float)(coef[i] *
  14.142 -		    ((sample_window>=length)? 0.0 : data[sample_window++])) ;
  14.143 -	    
  14.144 -	    /* Saturation ??? */
  14.145 -	    if (sum> 32767.) { sum=32767.; peak++; }
  14.146 -	    if (sum< -32768.) { sum=-32768; peak++; }
  14.147 -	    result[sample] = (sample_t) sum;
  14.148 -	}
  14.149 -
  14.150 -    if (peak)
  14.151 -	ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
  14.152 -		  "Saturation %2.3f %%.", 100.0*peak/ (float) length);
  14.153 -}
  14.154 -
  14.155 -/***********************************************************************/
  14.156 -/* Prevent aliasing by filtering any freq above the output_rate        */
  14.157 -/*                                                                     */
  14.158 -/* I don't worry about looping point -> they will remain soft if they  */
  14.159 -/* were already                                                        */
  14.160 -/***********************************************************************/
  14.161 -void antialiasing(Sample *sp, int32 output_rate )
  14.162 -{
  14.163 -    sample_t *temp;
  14.164 -    int i;
  14.165 -    float fir_symetric[ORDER];
  14.166 -    float fir_coef[ORDER2];
  14.167 -    float freq_cut;  /* cutoff frequency [0..1.0] FREQ_CUT/SAMP_FREQ*/
  14.168 - 
  14.169 -
  14.170 -    ctl->cmsg(CMSG_INFO, VERB_NOISY, "Antialiasing: Fsample=%iKHz",
  14.171 -	      sp->sample_rate);
  14.172 - 
  14.173 -    /* No oversampling  */
  14.174 -    if (output_rate>=sp->sample_rate)
  14.175 -	return;
  14.176 -    
  14.177 -    freq_cut= (float) output_rate / (float) sp->sample_rate;
  14.178 -    ctl->cmsg(CMSG_INFO, VERB_NOISY, "Antialiasing: cutoff=%f%%",
  14.179 -	      freq_cut*100.);
  14.180 -
  14.181 -    designfir(fir_coef,freq_cut);
  14.182 -    
  14.183 -    /* Make the filter symetric */
  14.184 -    for (i = 0 ; i<ORDER2 ;i++) 
  14.185 -	fir_symetric[ORDER-1 - i] = fir_symetric[i] = fir_coef[ORDER2-1 - i];
  14.186 -    
  14.187 -    /* We apply the filter we have designed on a copy of the patch */
  14.188 -    temp = safe_malloc(sp->data_length);
  14.189 -    memcpy(temp,sp->data,sp->data_length);
  14.190 -    
  14.191 -    filter(sp->data,temp,sp->data_length/sizeof(sample_t),fir_symetric);
  14.192 -    
  14.193 -    free(temp);
  14.194 -}
    15.1 --- a/timidity/filter.h	Tue Oct 17 16:55:58 2017 -0700
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,23 +0,0 @@
    15.4 -/*
    15.5 -    TiMidity -- Experimental MIDI to WAVE converter
    15.6 -    Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
    15.7 -
    15.8 -    This program is free software; you can redistribute it and/or modify
    15.9 -    it under the terms of the Perl Artistic License, available in COPYING.
   15.10 -
   15.11 -   filter.h : written by Vincent Pagel ( pagel@loria.fr )
   15.12 -
   15.13 -   implements fir antialiasing filter : should help when setting sample
   15.14 -   rates as low as 8Khz.
   15.15 -
   15.16 -   */
   15.17 -
   15.18 -/* Order of the FIR filter = 20 should be enough ! */
   15.19 -#define ORDER 20
   15.20 -#define ORDER2 ORDER/2
   15.21 -
   15.22 -#ifndef PI
   15.23 -#define PI   3.14159265
   15.24 -#endif
   15.25 -
   15.26 -extern void antialiasing(Sample *sp, int32 output_rate);
    16.1 --- a/timidity/instrum.c	Tue Oct 17 16:55:58 2017 -0700
    16.2 +++ b/timidity/instrum.c	Tue Oct 17 21:54:04 2017 -0700
    16.3 @@ -1,166 +1,82 @@
    16.4  /*
    16.5 +
    16.6      TiMidity -- Experimental MIDI to WAVE converter
    16.7      Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
    16.8  
    16.9      This program is free software; you can redistribute it and/or modify
   16.10      it under the terms of the Perl Artistic License, available in COPYING.
   16.11 - */
   16.12 +
   16.13 +   instrum.c 
   16.14 +   
   16.15 +   Code to load and unload GUS-compatible instrument patches.
   16.16 +
   16.17 +*/
   16.18 +
   16.19 +#if HAVE_CONFIG_H
   16.20 +#  include <config.h>
   16.21 +#endif
   16.22  
   16.23  #include <stdio.h>
   16.24  #include <string.h>
   16.25  #include <stdlib.h>
   16.26  
   16.27 -#include "config.h"
   16.28 +#include "SDL.h"
   16.29 +
   16.30 +#include "timidity.h"
   16.31 +#include "options.h"
   16.32  #include "common.h"
   16.33  #include "instrum.h"
   16.34 -#include "playmidi.h"
   16.35 -#include "output.h"
   16.36 -#include "ctrlmode.h"
   16.37 +#include "instrum_dls.h"
   16.38  #include "resample.h"
   16.39  #include "tables.h"
   16.40 -#include "filter.h"
   16.41 -
   16.42 -/* Some functions get aggravated if not even the standard banks are 
   16.43 -   available. */
   16.44 -static ToneBank standard_tonebank, standard_drumset;
   16.45 -ToneBank 
   16.46 -  *tonebank[MAXBANK]={&standard_tonebank},
   16.47 -  *drumset[MAXBANK]={&standard_drumset};
   16.48 -
   16.49 -/* This is a special instrument, used for all melodic programs */
   16.50 -InstrumentLayer *default_instrument=0;
   16.51 -
   16.52 -/* This is only used for tracks that don't specify a program */
   16.53 -int default_program=DEFAULT_PROGRAM;
   16.54 -
   16.55 -int antialiasing_allowed=0;
   16.56 -#ifdef FAST_DECAY
   16.57 -int fast_decay=1;
   16.58 -#else
   16.59 -int fast_decay=0;
   16.60 -#endif
   16.61 -
   16.62 -
   16.63 -int current_tune_number = 0;
   16.64 -int last_tune_purged = 0;
   16.65 -int current_patch_memory = 0;
   16.66 -int max_patch_memory = 60000000;
   16.67 -
   16.68 -static void purge_as_required(void);
   16.69  
   16.70  static void free_instrument(Instrument *ip)
   16.71  {
   16.72    Sample *sp;
   16.73    int i;
   16.74    if (!ip) return;
   16.75 -
   16.76 -  if (!ip->contents)
   16.77    for (i=0; i<ip->samples; i++)
   16.78      {
   16.79        sp=&(ip->sample[i]);
   16.80 -      if (sp->data) free(sp->data);
   16.81 +      free(sp->data);
   16.82      }
   16.83    free(ip->sample);
   16.84 -
   16.85 -  if (!ip->contents)
   16.86 -  for (i=0; i<ip->right_samples; i++)
   16.87 -    {
   16.88 -      sp=&(ip->right_sample[i]);
   16.89 -      if (sp->data) free(sp->data);
   16.90 -    }
   16.91 -  if (ip->right_sample)
   16.92 -    free(ip->right_sample);
   16.93    free(ip);
   16.94  }
   16.95  
   16.96 -
   16.97 -static void free_layer(InstrumentLayer *lp)
   16.98 -{
   16.99 -  InstrumentLayer *next;
  16.100 -
  16.101 -  current_patch_memory -= lp->size;
  16.102 -
  16.103 -  for (; lp; lp = next)
  16.104 -   {
  16.105 -     next = lp->next;
  16.106 -     free_instrument(lp->instrument);
  16.107 -     free(lp);
  16.108 -   }
  16.109 -}
  16.110 -
  16.111 -static void free_bank(int dr, int b)
  16.112 +static void free_bank(MidiSong *song, int dr, int b)
  16.113  {
  16.114    int i;
  16.115 -  ToneBank *bank=((dr) ? drumset[b] : tonebank[b]);
  16.116 -  for (i=0; i<MAXPROG; i++)
  16.117 -  {
  16.118 -    if (bank->tone[i].layer)
  16.119 -    {
  16.120 -	  /* Not that this could ever happen, of course */
  16.121 -	  if (bank->tone[i].layer != MAGIC_LOAD_INSTRUMENT)
  16.122 -	  {
  16.123 -	    free_layer(bank->tone[i].layer);
  16.124 -	    bank->tone[i].layer=NULL;
  16.125 -	    bank->tone[i].last_used=-1;
  16.126 -	  }
  16.127 -    }
  16.128 -    if (bank->tone[i].name)
  16.129 -    {
  16.130 -      free(bank->tone[i].name);
  16.131 -      bank->tone[i].name = NULL;
  16.132 -    }
  16.133 -  }
  16.134 -}
  16.135 -
  16.136 -
  16.137 -static void free_old_bank(int dr, int b, int how_old)
  16.138 -{
  16.139 -  int i;
  16.140 -  ToneBank *bank=((dr) ? drumset[b] : tonebank[b]);
  16.141 -  for (i=0; i<MAXPROG; i++)
  16.142 -    if (bank->tone[i].layer && bank->tone[i].last_used < how_old)
  16.143 +  ToneBank *bank=((dr) ? song->drumset[b] : song->tonebank[b]);
  16.144 +  for (i=0; i<MAXBANK; i++)
  16.145 +    if (bank->instrument[i])
  16.146        {
  16.147 -	if (bank->tone[i].layer != MAGIC_LOAD_INSTRUMENT)
  16.148 -	  {
  16.149 -	    ctl->cmsg(CMSG_INFO, VERB_DEBUG,
  16.150 -		"Unloading %s %s[%d,%d] - last used %d.",
  16.151 -		(dr)? "drum" : "inst", bank->tone[i].name,
  16.152 -		i, b, bank->tone[i].last_used);
  16.153 -	    free_layer(bank->tone[i].layer);
  16.154 -	    bank->tone[i].layer=NULL;
  16.155 -	    bank->tone[i].last_used=-1;
  16.156 -	  }
  16.157 +	/* Not that this could ever happen, of course */
  16.158 +	if (bank->instrument[i] != MAGIC_LOAD_INSTRUMENT)
  16.159 +	  free_instrument(bank->instrument[i]);
  16.160 +	bank->instrument[i]=0;
  16.161        }
  16.162  }
  16.163  
  16.164 -
  16.165 -int32 convert_envelope_rate_attack(uint8 rate, uint8 fastness)
  16.166 +static Sint32 convert_envelope_rate(MidiSong *song, Uint8 rate)
  16.167  {
  16.168 -  int32 r;
  16.169 -
  16.170 -  r=3-((rate>>6) & 0x3);
  16.171 -  r*=3;
  16.172 -  r = (int32)(rate & 0x3f) << r; /* 6.9 fixed point */
  16.173 +  Sint32 r;
  16.174 +  
  16.175 +  r = 3 - ((rate >> 6) & 0x3);
  16.176 +  r *= 3;
  16.177 +  r = (Sint32) (rate & 0x3f) << r; /* 6.9 fixed point */
  16.178  
  16.179    /* 15.15 fixed point. */
  16.180 -  return (((r * 44100) / play_mode->rate) * control_ratio) 
  16.181 -    << 10;
  16.182 +  r = ((r * 44100) / song->rate) * song->control_ratio;
  16.183 +
  16.184 +#ifdef FAST_DECAY
  16.185 +  return r << 10;
  16.186 +#else
  16.187 +  return r << 9;
  16.188 +#endif
  16.189  }
  16.190  
  16.191 -int32 convert_envelope_rate(uint8 rate)
  16.192 -{
  16.193 -  int32 r;
  16.194 -
  16.195 -  r=3-((rate>>6) & 0x3);
  16.196 -  r*=3;
  16.197 -  r = (int32)(rate & 0x3f) << r; /* 6.9 fixed point */
  16.198 -
  16.199 -  /* 15.15 fixed point. */
  16.200 -  return (((r * 44100) / play_mode->rate) * control_ratio) 
  16.201 -    << ((fast_decay) ? 10 : 9);
  16.202 -}
  16.203 -
  16.204 -int32 convert_envelope_offset(uint8 offset)
  16.205 +static Sint32 convert_envelope_offset(Uint8 offset)
  16.206  {
  16.207    /* This is not too good... Can anyone tell me what these values mean?
  16.208       Are they GUS-style "exponential" volumes? And what does that mean? */
  16.209 @@ -169,49 +85,50 @@
  16.210    return offset << (7+15);
  16.211  }
  16.212  
  16.213 -int32 convert_tremolo_sweep(uint8 sweep)
  16.214 +static Sint32 convert_tremolo_sweep(MidiSong *song, Uint8 sweep)
  16.215  {
  16.216    if (!sweep)
  16.217      return 0;
  16.218  
  16.219    return
  16.220 -    ((control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) /
  16.221 -      (play_mode->rate * sweep);
  16.222 +    ((song->control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) /
  16.223 +      (song->rate * sweep);
  16.224  }
  16.225  
  16.226 -int32 convert_vibrato_sweep(uint8 sweep, int32 vib_control_ratio)
  16.227 +static Sint32 convert_vibrato_sweep(MidiSong *song, Uint8 sweep,
  16.228 +				    Sint32 vib_control_ratio)
  16.229  {
  16.230    if (!sweep)
  16.231      return 0;
  16.232  
  16.233    return
  16.234 -    (int32) (FSCALE((double) (vib_control_ratio) * SWEEP_TUNING, SWEEP_SHIFT)
  16.235 -	     / (double)(play_mode->rate * sweep));
  16.236 +    (Sint32) (FSCALE((double) (vib_control_ratio) * SWEEP_TUNING, SWEEP_SHIFT)
  16.237 +	     / (double)(song->rate * sweep));
  16.238  
  16.239    /* this was overflowing with seashore.pat
  16.240  
  16.241        ((vib_control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) /
  16.242 -      (play_mode->rate * sweep); */
  16.243 +      (song->rate * sweep); */
  16.244  }
  16.245  
  16.246 -int32 convert_tremolo_rate(uint8 rate)
  16.247 +static Sint32 convert_tremolo_rate(MidiSong *song, Uint8 rate)
  16.248  {
  16.249    return
  16.250 -    ((SINE_CYCLE_LENGTH * control_ratio * rate) << RATE_SHIFT) /
  16.251 -      (TREMOLO_RATE_TUNING * play_mode->rate);
  16.252 +    ((SINE_CYCLE_LENGTH * song->control_ratio * rate) << RATE_SHIFT) /
  16.253 +      (TREMOLO_RATE_TUNING * song->rate);
  16.254  }
  16.255  
  16.256 -int32 convert_vibrato_rate(uint8 rate)
  16.257 +static Sint32 convert_vibrato_rate(MidiSong *song, Uint8 rate)
  16.258  {
  16.259    /* Return a suitable vibrato_control_ratio value */
  16.260    return
  16.261 -    (VIBRATO_RATE_TUNING * play_mode->rate) / 
  16.262 +    (VIBRATO_RATE_TUNING * song->rate) / 
  16.263        (rate * 2 * VIBRATO_SAMPLE_INCREMENTS);
  16.264  }
  16.265  
  16.266 -static void reverse_data(int16 *sp, int32 ls, int32 le)
  16.267 +static void reverse_data(Sint16 *sp, Sint32 ls, Sint32 le)
  16.268  {
  16.269 -  int16 s, *ep=sp+le;
  16.270 +  Sint16 s, *ep=sp+le;
  16.271    sp+=ls;
  16.272    le-=ls;
  16.273    le/=2;
  16.274 @@ -233,255 +150,109 @@
  16.275     undefined.
  16.276  
  16.277     TODO: do reverse loops right */
  16.278 -static InstrumentLayer *load_instrument(const char *name, int font_type, int percussion,
  16.279 -				   int panning, int amp, int cfg_tuning, int note_to_use,
  16.280 +static Instrument *load_instrument(MidiSong *song, char *name, int percussion,
  16.281 +				   int panning, int amp, int note_to_use,
  16.282  				   int strip_loop, int strip_envelope,
  16.283 -				   int strip_tail, int bank, int gm_num, int sf_ix)
  16.284 +				   int strip_tail)
  16.285  {
  16.286 -  InstrumentLayer *lp, *lastlp, *headlp = 0;
  16.287    Instrument *ip;
  16.288 -  FILE *fp;
  16.289 -  uint8 tmp[1024];
  16.290 +  Sample *sp;
  16.291 +  SDL_RWops *rw;
  16.292 +  char tmp[1024];
  16.293    int i,j,noluck=0;
  16.294 -#ifdef PATCH_EXT_LIST
  16.295    static char *patch_ext[] = PATCH_EXT_LIST;
  16.296 -#endif
  16.297 -  int sf2flag = 0;
  16.298 -  int right_samples = 0;
  16.299 -  int stereo_channels = 1, stereo_layer;
  16.300 -  int vlayer_list[19][4], vlayer, vlayer_count = 0;
  16.301  
  16.302    if (!name) return 0;
  16.303    
  16.304    /* Open patch file */
  16.305 -  if ((fp=open_file(name, 1, OF_NORMAL)) == NULL)
  16.306 +  if ((rw=open_file(name)) == NULL)
  16.307      {
  16.308        noluck=1;
  16.309 -#ifdef PATCH_EXT_LIST
  16.310        /* Try with various extensions */
  16.311        for (i=0; patch_ext[i]; i++)
  16.312  	{
  16.313 -	  if (strlen(name)+strlen(patch_ext[i])<PATH_MAX)
  16.314 +	  if (strlen(name)+strlen(patch_ext[i])<1024)
  16.315  	    {
  16.316 -              char path[PATH_MAX];
  16.317 -	      strcpy(path, name);
  16.318 -	      strcat(path, patch_ext[i]);
  16.319 -	      if ((fp=open_file(path, 1, OF_NORMAL)) != NULL)
  16.320 +	      strcpy(tmp, name);
  16.321 +	      strcat(tmp, patch_ext[i]);
  16.322 +	      if ((rw=open_file(tmp)) != NULL)
  16.323  		{
  16.324  		  noluck=0;
  16.325  		  break;
  16.326  		}
  16.327  	    }
  16.328  	}
  16.329 -#endif
  16.330      }
  16.331    
  16.332    if (noluck)
  16.333      {
  16.334 -      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
  16.335 -		"Instrument `%s' can't be found.", name);
  16.336 +      SNDDBG(("Instrument `%s' can't be found.\n", name));
  16.337        return 0;
  16.338      }
  16.339        
  16.340 -  /*ctl->cmsg(CMSG_INFO, VERB_NOISY, "Loading instrument %s", current_filename);*/
  16.341 +  SNDDBG(("Loading instrument %s\n", tmp));
  16.342    
  16.343    /* Read some headers and do cursory sanity checks. There are loads
  16.344       of magic offsets. This could be rewritten... */
  16.345  
  16.346 -  if ((239 != fread(tmp, 1, 239, fp)) ||
  16.347 +  if ((239 != SDL_RWread(rw, tmp, 1, 239)) ||
  16.348        (memcmp(tmp, "GF1PATCH110\0ID#000002", 22) &&
  16.349         memcmp(tmp, "GF1PATCH100\0ID#000002", 22))) /* don't know what the
  16.350  						      differences are */
  16.351      {
  16.352 -      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: not an instrument", name);
  16.353 +      SNDDBG(("%s: not an instrument\n", name));
  16.354        return 0;
  16.355      }
  16.356 -
  16.357 -/* patch layout:
  16.358 - * bytes:  info:		starts at offset:
  16.359 - * 22	id (see above)		0
  16.360 - * 60	copyright		22
  16.361 - *  1	instruments		82
  16.362 - *  1	voices			83
  16.363 - *  1	channels		84
  16.364 - *  2	number of waveforms	85
  16.365 - *  2	master volume		87
  16.366 - *  4	datasize		89
  16.367 - * 36   reserved, but now:	93
  16.368 - * 	7 "SF2EXT\0" id			93
  16.369 - * 	1 right samples		       100
  16.370 - *     28 reserved		       101
  16.371 - *  2	instrument number	129
  16.372 - * 16	instrument name		131
  16.373 - *  4	instrument size		147
  16.374 - *  1	number of layers	151
  16.375 - * 40	reserved		152
  16.376 - *  1	layer duplicate		192
  16.377 - *  1	layer number		193
  16.378 - *  4	layer size		194
  16.379 - *  1	number of samples	198
  16.380 - * 40	reserved		199
  16.381 - * 				239
  16.382 - * THEN, for each sample, see below
  16.383 - */
  16.384 -
  16.385 -  if (!memcmp(tmp + 93, "SF2EXT", 6))
  16.386 -    {
  16.387 -	    sf2flag = 1;
  16.388 -	    vlayer_count = tmp[152];
  16.389 -    }
  16.390 -
  16.391 +  
  16.392    if (tmp[82] != 1 && tmp[82] != 0) /* instruments. To some patch makers, 
  16.393  				       0 means 1 */
  16.394      {
  16.395 -      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
  16.396 -	   "Can't handle patches with %d instruments", tmp[82]);
  16.397 +      SNDDBG(("Can't handle patches with %d instruments\n", tmp[82]));
  16.398        return 0;
  16.399      }
  16.400  
  16.401    if (tmp[151] != 1 && tmp[151] != 0) /* layers. What's a layer? */
  16.402      {
  16.403 -      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
  16.404 -	   "Can't handle instruments with %d layers", tmp[151]);
  16.405 +      SNDDBG(("Can't handle instruments with %d layers\n", tmp[151]));
  16.406        return 0;
  16.407      }
  16.408    
  16.409 +  ip=safe_malloc(sizeof(Instrument));
  16.410 +  ip->samples = tmp[198];
  16.411 +  ip->sample = safe_malloc(sizeof(Sample) * ip->samples);
  16.412 +  for (i=0; i<ip->samples; i++)
  16.413 +    {
  16.414  
  16.415 -  if (sf2flag && vlayer_count > 0) {
  16.416 -	for (i = 0; i < 9; i++)
  16.417 -	  for (j = 0; j < 4; j++)
  16.418 -	    vlayer_list[i][j] = tmp[153+i*4+j];
  16.419 -	for (i = 9; i < 19; i++)
  16.420 -	  for (j = 0; j < 4; j++)
  16.421 -	    vlayer_list[i][j] = tmp[199+(i-9)*4+j];
  16.422 -  }
  16.423 -  else {
  16.424 -	for (i = 0; i < 19; i++)
  16.425 -	  for (j = 0; j < 4; j++)
  16.426 -	    vlayer_list[i][j] = 0;
  16.427 -	vlayer_list[0][0] = 0;
  16.428 -	vlayer_list[0][1] = 127;
  16.429 -	vlayer_list[0][2] = tmp[198];
  16.430 -	vlayer_list[0][3] = 0;
  16.431 -	vlayer_count = 1;
  16.432 -  }
  16.433 -
  16.434 -  lastlp = 0;
  16.435 -
  16.436 -  for (vlayer = 0; vlayer < vlayer_count; vlayer++) {
  16.437 -
  16.438 -  lp=(InstrumentLayer *)safe_malloc(sizeof(InstrumentLayer));
  16.439 -  lp->size = sizeof(InstrumentLayer);
  16.440 -  lp->lo = vlayer_list[vlayer][0];
  16.441 -  lp->hi = vlayer_list[vlayer][1];
  16.442 -  ip=(Instrument *)safe_malloc(sizeof(Instrument));
  16.443 -  lp->size += sizeof(Instrument);
  16.444 -  lp->instrument = ip;
  16.445 -  lp->next = 0;
  16.446 -
  16.447 -  if (lastlp) lastlp->next = lp;
  16.448 -  else headlp = lp;
  16.449 -
  16.450 -  lastlp = lp;
  16.451 -
  16.452 -  if (sf2flag) ip->type = INST_SF2;
  16.453 -  else ip->type = INST_GUS;
  16.454 -  ip->samples = vlayer_list[vlayer][2];
  16.455 -  ip->sample = (Sample *)safe_malloc(sizeof(Sample) * ip->samples);
  16.456 -  lp->size += sizeof(Sample) * ip->samples;
  16.457 -  ip->left_samples = ip->samples;
  16.458 -  ip->left_sample = ip->sample;
  16.459 -  right_samples = vlayer_list[vlayer][3];
  16.460 -  ip->right_samples = right_samples;
  16.461 -  if (right_samples)
  16.462 -    {
  16.463 -      ip->right_sample = (Sample *)safe_malloc(sizeof(Sample) * right_samples);
  16.464 -      lp->size += sizeof(Sample) * right_samples;
  16.465 -      stereo_channels = 2;
  16.466 -    }
  16.467 -  else ip->right_sample = 0;
  16.468 -  ip->contents = 0;
  16.469 -
  16.470 -  ctl->cmsg(CMSG_INFO, VERB_NOISY, "%s%s[%d,%d] %s(%d-%d layer %d of %d)",
  16.471 -	(percussion)? "   ":"", name,
  16.472 -	(percussion)? note_to_use : gm_num, bank,
  16.473 -	(right_samples)? "(2) " : "",
  16.474 -	lp->lo, lp->hi, vlayer+1, vlayer_count);
  16.475 -
  16.476 - for (stereo_layer = 0; stereo_layer < stereo_channels; stereo_layer++)
  16.477 - {
  16.478 -  int sample_count = 0;
  16.479 -
  16.480 -  if (stereo_layer == 0) sample_count = ip->left_samples;
  16.481 -  else if (stereo_layer == 1) sample_count = ip->right_samples;
  16.482 -
  16.483 -  for (i=0; i < sample_count; i++)
  16.484 -    {
  16.485 -      uint8 fractions;
  16.486 -      int32 tmplong;
  16.487 -      uint16 tmpshort;
  16.488 -      uint16 sample_volume = 0;
  16.489 -      uint8 tmpchar;
  16.490 -      Sample *sp = 0;
  16.491 -      uint8 sf2delay = 0;
  16.492 +      Uint8 fractions;
  16.493 +      Sint32 tmplong;
  16.494 +      Uint16 tmpshort;
  16.495 +      Uint8 tmpchar;
  16.496  
  16.497  #define READ_CHAR(thing) \
  16.498 -      if ((size_t)1 != fread(&tmpchar, 1, 1, fp)) goto fail; \
  16.499 +      if (1 != SDL_RWread(rw, &tmpchar, 1, 1)) goto fail; \
  16.500        thing = tmpchar;
  16.501  #define READ_SHORT(thing) \
  16.502 -      if ((size_t)1 != fread(&tmpshort, 2, 1, fp)) goto fail; \
  16.503 -      thing = LE_SHORT(tmpshort);
  16.504 +      if (1 != SDL_RWread(rw, &tmpshort, 2, 1)) goto fail; \
  16.505 +      thing = SDL_SwapLE16(tmpshort);
  16.506  #define READ_LONG(thing) \
  16.507 -      if ((size_t)1 != fread(&tmplong, 4, 1, fp)) goto fail; \
  16.508 -      thing = LE_LONG(tmplong);
  16.509 +      if (1 != SDL_RWread(rw, &tmplong, 4, 1)) goto fail; \
  16.510 +      thing = SDL_SwapLE32(tmplong);
  16.511  
  16.512 -/*
  16.513 - *  7	sample name
  16.514 - *  1	fractions
  16.515 - *  4	length
  16.516 - *  4	loop start
  16.517 - *  4	loop end
  16.518 - *  2	sample rate
  16.519 - *  4	low frequency
  16.520 - *  4	high frequency
  16.521 - *  2	finetune
  16.522 - *  1	panning
  16.523 - *  6	envelope rates			|
  16.524 - *  6	envelope offsets		|  18 bytes
  16.525 - *  3	tremolo sweep, rate, depth	|
  16.526 - *  3	vibrato sweep, rate, depth	|
  16.527 - *  1	sample mode
  16.528 - *  2	scale frequency
  16.529 - *  2	scale factor
  16.530 - *  2	sample volume (??)
  16.531 - * 34	reserved
  16.532 - * Now: 1	delay
  16.533 - * 	33	reserved
  16.534 - */
  16.535 -      skip(fp, 7); /* Skip the wave name */
  16.536 +      SDL_RWseek(rw, 7, RW_SEEK_CUR); /* Skip the wave name */
  16.537  
  16.538 -      if (1 != fread(&fractions, 1, 1, fp))
  16.539 +      if (1 != SDL_RWread(rw, &fractions, 1, 1))
  16.540  	{
  16.541  	fail:
  16.542 -	  ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Error reading sample %d", i);
  16.543 -	  if (stereo_layer == 1)
  16.544 -	     {
  16.545 -	       for (j=0; j<i; j++)
  16.546 -	         free(ip->right_sample[j].data);
  16.547 -	       free(ip->right_sample);
  16.548 -	       i = ip->left_samples;
  16.549 -	     }
  16.550 +	  SNDDBG(("Error reading sample %d\n", i));
  16.551  	  for (j=0; j<i; j++)
  16.552 -	    free(ip->left_sample[j].data);
  16.553 -	  free(ip->left_sample);
  16.554 +	    free(ip->sample[j].data);
  16.555 +	  free(ip->sample);
  16.556  	  free(ip);
  16.557 -	  free(lp);
  16.558  	  return 0;
  16.559  	}
  16.560  
  16.561 -      if (stereo_layer == 0) sp=&(ip->left_sample[i]);
  16.562 -      else if (stereo_layer == 1) sp=&(ip->right_sample[i]);
  16.563 -
  16.564 +      sp=&(ip->sample[i]);
  16.565 +      
  16.566        READ_LONG(sp->data_length);
  16.567        READ_LONG(sp->loop_start);
  16.568        READ_LONG(sp->loop_end);
  16.569 @@ -489,91 +260,64 @@
  16.570        READ_LONG(sp->low_freq);
  16.571        READ_LONG(sp->high_freq);
  16.572        READ_LONG(sp->root_freq);
  16.573 -      skip(fp, 2); /* Why have a "root frequency" and then "tuning"?? */
  16.574 +      sp->low_vel = 0;
  16.575 +      sp->high_vel = 127;
  16.576 +      SDL_RWseek(rw, 2, RW_SEEK_CUR); /* Why have a "root frequency" and then
  16.577 +				    * "tuning"?? */
  16.578        
  16.579        READ_CHAR(tmp[0]);
  16.580  
  16.581        if (panning==-1)
  16.582  	sp->panning = (tmp[0] * 8 + 4) & 0x7f;
  16.583        else
  16.584 -	sp->panning=(uint8)(panning & 0x7F);
  16.585 -
  16.586 -      sp->resonance=0;
  16.587 -      sp->cutoff_freq=0;
  16.588 -      sp->reverberation=0;
  16.589 -      sp->chorusdepth=0;
  16.590 -      sp->exclusiveClass=0;
  16.591 -      sp->keyToModEnvHold=0;
  16.592 -      sp->keyToModEnvDecay=0;
  16.593 -      sp->keyToVolEnvHold=0;
  16.594 -      sp->keyToVolEnvDecay=0;
  16.595 -
  16.596 -      if (cfg_tuning)
  16.597 -	{
  16.598 -	  double tune_factor = (double)(cfg_tuning)/1200.0;
  16.599 -	  tune_factor = pow(2.0, tune_factor);
  16.600 -	  sp->root_freq = (uint32)( tune_factor * (double)sp->root_freq );
  16.601 -	}
  16.602 +	sp->panning=(Uint8)(panning & 0x7F);
  16.603  
  16.604        /* envelope, tremolo, and vibrato */
  16.605 -      if (18 != fread(tmp, 1, 18, fp)) goto fail; 
  16.606 +      if (18 != SDL_RWread(rw, tmp, 1, 18)) goto fail; 
  16.607  
  16.608        if (!tmp[13] || !tmp[14])
  16.609  	{
  16.610  	  sp->tremolo_sweep_increment=
  16.611  	    sp->tremolo_phase_increment=sp->tremolo_depth=0;
  16.612 -	  ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * no tremolo");
  16.613 +	  SNDDBG((" * no tremolo\n"));
  16.614  	}
  16.615        else
  16.616  	{
  16.617 -	  sp->tremolo_sweep_increment=convert_tremolo_sweep(tmp[12]);
  16.618 -	  sp->tremolo_phase_increment=convert_tremolo_rate(tmp[13]);
  16.619 +	  sp->tremolo_sweep_increment=convert_tremolo_sweep(song, tmp[12]);
  16.620 +	  sp->tremolo_phase_increment=convert_tremolo_rate(song, tmp[13]);
  16.621  	  sp->tremolo_depth=tmp[14];
  16.622 -	  ctl->cmsg(CMSG_INFO, VERB_DEBUG,
  16.623 -	       " * tremolo: sweep %d, phase %d, depth %d",
  16.624 +	  SNDDBG((" * tremolo: sweep %d, phase %d, depth %d\n",
  16.625  	       sp->tremolo_sweep_increment, sp->tremolo_phase_increment,
  16.626 -	       sp->tremolo_depth);
  16.627 +	       sp->tremolo_depth));
  16.628  	}
  16.629  
  16.630        if (!tmp[16] || !tmp[17])
  16.631  	{
  16.632  	  sp->vibrato_sweep_increment=
  16.633  	    sp->vibrato_control_ratio=sp->vibrato_depth=0;
  16.634 -	  ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * no vibrato");
  16.635 +	  SNDDBG((" * no vibrato\n"));
  16.636  	}
  16.637        else
  16.638  	{
  16.639 -	  sp->vibrato_control_ratio=convert_vibrato_rate(tmp[16]);
  16.640 +	  sp->vibrato_control_ratio=convert_vibrato_rate(song, tmp[16]);
  16.641  	  sp->vibrato_sweep_increment=
  16.642 -	    convert_vibrato_sweep(tmp[15], sp->vibrato_control_ratio);
  16.643 +	    convert_vibrato_sweep(song, tmp[15], sp->vibrato_control_ratio);
  16.644  	  sp->vibrato_depth=tmp[17];
  16.645 -	  ctl->cmsg(CMSG_INFO, VERB_DEBUG,
  16.646 -	       " * vibrato: sweep %d, ctl %d, depth %d",
  16.647 +	  SNDDBG((" * vibrato: sweep %d, ctl %d, depth %d\n",
  16.648  	       sp->vibrato_sweep_increment, sp->vibrato_control_ratio,
  16.649 -	       sp->vibrato_depth);
  16.650 +	       sp->vibrato_depth));
  16.651  
  16.652  	}
  16.653  
  16.654        READ_CHAR(sp->modes);
  16.655 -      READ_SHORT(tmpshort);
  16.656 -	  sp->freq_center = (uint8)tmpshort;
  16.657 -      READ_SHORT(sp->freq_scale);
  16.658  
  16.659 -      if (sf2flag)
  16.660 -        {
  16.661 -          READ_SHORT(sample_volume);
  16.662 -	  READ_CHAR(sf2delay);
  16.663 -          READ_CHAR(sp->exclusiveClass);
  16.664 -          skip(fp, 32);
  16.665 -	}
  16.666 -      else
  16.667 -        {
  16.668 -          skip(fp, 36);
  16.669 -        }
  16.670 +      SDL_RWseek(rw, 40, RW_SEEK_CUR); /* skip the useless scale frequency, scale
  16.671 +				       factor (what's it mean?), and reserved
  16.672 +				       space */
  16.673  
  16.674        /* Mark this as a fixed-pitch instrument if such a deed is desired. */
  16.675        if (note_to_use!=-1)
  16.676 -	sp->note_to_use=(uint8)(note_to_use);
  16.677 +	sp->note_to_use=(Uint8)(note_to_use);
  16.678        else
  16.679  	sp->note_to_use=0;
  16.680        
  16.681 @@ -590,7 +334,7 @@
  16.682  	  (sp->modes & (MODES_SUSTAIN | MODES_LOOPING | 
  16.683  			MODES_PINGPONG | MODES_REVERSE)))
  16.684  	{
  16.685 -	  ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Removing loop and/or sustain");
  16.686 +	  SNDDBG((" - Removing loop and/or sustain\n"));
  16.687  	  sp->modes &=~(MODES_SUSTAIN | MODES_LOOPING | 
  16.688  			MODES_PINGPONG | MODES_REVERSE);
  16.689  	}
  16.690 @@ -598,7 +342,7 @@
  16.691        if (strip_envelope==1)
  16.692  	{
  16.693  	  if (sp->modes & MODES_ENVELOPE)
  16.694 -	    ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Removing envelope");
  16.695 +	    SNDDBG((" - Removing envelope\n"));
  16.696  	  sp->modes &= ~MODES_ENVELOPE;
  16.697  	}
  16.698        else if (strip_envelope != 0)
  16.699 @@ -609,16 +353,14 @@
  16.700  	      /* No loop? Then what's there to sustain? No envelope needed
  16.701  		 either... */
  16.702  	      sp->modes &= ~(MODES_SUSTAIN|MODES_ENVELOPE);
  16.703 -	      ctl->cmsg(CMSG_INFO, VERB_DEBUG, 
  16.704 -			" - No loop, removing sustain and envelope");
  16.705 +	      SNDDBG((" - No loop, removing sustain and envelope\n"));
  16.706  	    }
  16.707  	  else if (!memcmp(tmp, "??????", 6) || tmp[11] >= 100) 
  16.708  	    {
  16.709  	      /* Envelope rates all maxed out? Envelope end at a high "offset"?
  16.710  		 That's a weird envelope. Take it out. */
  16.711  	      sp->modes &= ~MODES_ENVELOPE;
  16.712 -	      ctl->cmsg(CMSG_INFO, VERB_DEBUG, 
  16.713 -			" - Weirdness, removing envelope");
  16.714 +	      SNDDBG((" - Weirdness, removing envelope\n"));
  16.715  	    }
  16.716  	  else if (!(sp->modes & MODES_SUSTAIN))
  16.717  	    {
  16.718 @@ -627,65 +369,33 @@
  16.719  		 envelope either... at least the Gravis ones. They're mostly
  16.720  		 drums.  I think. */
  16.721  	      sp->modes &= ~MODES_ENVELOPE;
  16.722 -	      ctl->cmsg(CMSG_INFO, VERB_DEBUG, 
  16.723 -			" - No sustain, removing envelope");
  16.724 +	      SNDDBG((" - No sustain, removing envelope\n"));
  16.725  	    }
  16.726  	}
  16.727  
  16.728 -      sp->attenuation = 0;
  16.729 -
  16.730 -      for (j=ATTACK; j<DELAY; j++)
  16.731 +      for (j=0; j<6; j++)
  16.732  	{
  16.733  	  sp->envelope_rate[j]=
  16.734 -	    (j<3)? convert_envelope_rate_attack(tmp[j], 11) : convert_envelope_rate(tmp[j]);
  16.735 +	    convert_envelope_rate(song, tmp[j]);
  16.736  	  sp->envelope_offset[j]= 
  16.737  	    convert_envelope_offset(tmp[6+j]);
  16.738  	}
  16.739 -      if (sf2flag)
  16.740 -	{
  16.741 -	  if (sf2delay > 5) sf2delay = 5;
  16.742 -	  sp->envelope_rate[DELAY] = (int32)( (sf2delay*play_mode->rate) / 1000 );
  16.743 -	}
  16.744 -      else
  16.745 -	{
  16.746 -          sp->envelope_rate[DELAY]=0;
  16.747 -	}
  16.748 -      sp->envelope_offset[DELAY]=0;
  16.749 -
  16.750 -      for (j=ATTACK; j<DELAY; j++)
  16.751 -	{
  16.752 -	  sp->modulation_rate[j]=sp->envelope_rate[j];
  16.753 -	  sp->modulation_offset[j]=sp->envelope_offset[j];
  16.754 -	}
  16.755 -      sp->modulation_rate[DELAY] = sp->modulation_offset[DELAY] = 0;
  16.756 -      sp->modEnvToFilterFc=0;
  16.757 -      sp->modEnvToPitch=0;
  16.758 -      sp->lfo_sweep_increment = 0;
  16.759 -      sp->lfo_phase_increment = 0;
  16.760 -      sp->modLfoToFilterFc = 0;
  16.761 -      sp->vibrato_delay = 0;
  16.762  
  16.763        /* Then read the sample data */
  16.764 -      if (sp->data_length/2 > MAX_SAMPLE_SIZE)
  16.765 -        {
  16.766 -	  goto fail;
  16.767 -	}
  16.768 -      sp->data = (sample_t *)safe_malloc(sp->data_length + 1);
  16.769 -      lp->size += sp->data_length + 1;
  16.770 -
  16.771 -      if (1 != fread(sp->data, sp->data_length, 1, fp))
  16.772 +      sp->data = safe_malloc(sp->data_length);
  16.773 +      if (1 != SDL_RWread(rw, sp->data, sp->data_length, 1))
  16.774  	goto fail;
  16.775        
  16.776        if (!(sp->modes & MODES_16BIT)) /* convert to 16-bit data */
  16.777  	{
  16.778 -	  int32 i=sp->data_length;
  16.779 -	  uint8 *cp=(uint8 *)(sp->data);
  16.780 -	  uint16 *tmp,*newdta;
  16.781 -	  tmp=newdta=(uint16 *)safe_malloc(sp->data_length*2 + 2);
  16.782 +	  Sint32 i=sp->data_length;
  16.783 +	  Uint8 *cp=(Uint8 *)(sp->data);
  16.784 +	  Uint16 *tmp,*new;
  16.785 +	  tmp=new=safe_malloc(sp->data_length*2);
  16.786  	  while (i--)
  16.787 -	    *tmp++ = (uint16)(*cp++) << 8;
  16.788 -	  cp=(uint8 *)(sp->data);
  16.789 -	  sp->data = (sample_t *)newdta;
  16.790 +	    *tmp++ = (Uint16)(*cp++) << 8;
  16.791 +	  cp=(Uint8 *)(sp->data);
  16.792 +	  sp->data = (sample_t *)new;
  16.793  	  free(cp);
  16.794  	  sp->data_length *= 2;
  16.795  	  sp->loop_start *= 2;
  16.796 @@ -695,11 +405,11 @@
  16.797        else
  16.798  	/* convert to machine byte order */
  16.799  	{
  16.800 -	  int32 i=sp->data_length/2;
  16.801 -	  int16 *tmp=(int16 *)sp->data,s;
  16.802 +	  Sint32 i=sp->data_length/2;
  16.803 +	  Sint16 *tmp=(Sint16 *)sp->data,s;
  16.804  	  while (i--)
  16.805  	    { 
  16.806 -	      s=LE_SHORT(*tmp);
  16.807 +	      s=SDL_SwapLE16(*tmp);
  16.808  	      *tmp++=s;
  16.809  	    }
  16.810  	}
  16.811 @@ -707,8 +417,8 @@
  16.812        
  16.813        if (sp->modes & MODES_UNSIGNED) /* convert to signed data */
  16.814  	{
  16.815 -	  int32 i=sp->data_length/2;
  16.816 -	  int16 *tmp=(int16 *)sp->data;
  16.817 +	  Sint32 i=sp->data_length/2;
  16.818 +	  Sint16 *tmp=(Sint16 *)sp->data;
  16.819  	  while (i--)
  16.820  	    *tmp++ ^= 0x8000;
  16.821  	}
  16.822 @@ -716,12 +426,12 @@
  16.823        /* Reverse reverse loops and pass them off as normal loops */
  16.824        if (sp->modes & MODES_REVERSE)
  16.825  	{
  16.826 -	  int32 t;
  16.827 +	  Sint32 t;
  16.828  	  /* The GUS apparently plays reverse loops by reversing the
  16.829  	     whole sample. We do the same because the GUS does not SUCK. */
  16.830  
  16.831 -	  ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "Reverse loop in %s", name);
  16.832 -	  reverse_data((int16 *)sp->data, 0, sp->data_length/2);
  16.833 +	  SNDDBG(("Reverse loop in %s\n", name));
  16.834 +	  reverse_data((Sint16 *)sp->data, 0, sp->data_length/2);
  16.835  
  16.836  	  t=sp->loop_start;
  16.837  	  sp->loop_start=sp->data_length - sp->loop_end;
  16.838 @@ -731,26 +441,17 @@
  16.839  	  sp->modes |= MODES_LOOPING; /* just in case */
  16.840  	}
  16.841  
  16.842 -      /* If necessary do some anti-aliasing filtering  */
  16.843 -
  16.844 -      if (antialiasing_allowed)
  16.845 -	  antialiasing(sp,play_mode->rate);
  16.846 -
  16.847  #ifdef ADJUST_SAMPLE_VOLUMES
  16.848        if (amp!=-1)
  16.849 -	sp->volume=(FLOAT_T)((amp) / 100.0);
  16.850 -      else if (sf2flag)
  16.851 -	sp->volume=(FLOAT_T)((sample_volume) / 255.0);
  16.852 +	sp->volume=(float)((amp) / 100.0);
  16.853        else
  16.854  	{
  16.855  	  /* Try to determine a volume scaling factor for the sample.
  16.856  	     This is a very crude adjustment, but things sound more
  16.857  	     balanced with it. Still, this should be a runtime option. */
  16.858 -	  uint32 i, numsamps=sp->data_length/2;
  16.859 -	  uint32 higher=0, highcount=0;
  16.860 -	  int16 maxamp=0,a;
  16.861 -	  int16 *tmp=(int16 *)sp->data;
  16.862 -	  i = numsamps;
  16.863 +	  Sint32 i=sp->data_length/2;
  16.864 +	  Sint16 maxamp=0,a;
  16.865 +	  Sint16 *tmp=(Sint16 *)sp->data;
  16.866  	  while (i--)
  16.867  	    {
  16.868  	      a=*tmp++;
  16.869 @@ -758,22 +459,8 @@
  16.870  	      if (a>maxamp)
  16.871  		maxamp=a;
  16.872  	    }
  16.873 -	  tmp=(int16 *)sp->data;
  16.874 -	  i = numsamps;
  16.875 -	  while (i--)
  16.876 -	    {
  16.877 -	      a=*tmp++;
  16.878 -	      if (a<0) a=-a;
  16.879 -	      if (a > 3*maxamp/4)
  16.880 -		{
  16.881 -		   higher += a;
  16.882 -		   highcount++;
  16.883 -		}
  16.884 -	    }
  16.885 -	  if (highcount) higher /= highcount;
  16.886 -	  else higher = 10000;
  16.887 -	  sp->volume = (32768.0 * 0.875) /  (double)higher ;
  16.888 -	  ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * volume comp: %f", sp->volume);
  16.889 +	  sp->volume=(float)(32768.0 / maxamp);
  16.890 +	  SNDDBG((" * volume comp: %f\n", sp->volume));
  16.891  	}
  16.892  #else
  16.893        if (amp!=-1)
  16.894 @@ -783,28 +470,14 @@
  16.895  #endif
  16.896  
  16.897        sp->data_length /= 2; /* These are in bytes. Convert into samples. */
  16.898 -
  16.899        sp->loop_start /= 2;
  16.900        sp->loop_end /= 2;
  16.901 -      sp->data[sp->data_length] = sp->data[sp->data_length-1];
  16.902  
  16.903        /* Then fractional samples */
  16.904        sp->data_length <<= FRACTION_BITS;
  16.905        sp->loop_start <<= FRACTION_BITS;
  16.906        sp->loop_end <<= FRACTION_BITS;
  16.907  
  16.908 -    /* trim off zero data at end */
  16.909 -    {
  16.910 -	int ls = sp->loop_start>>FRACTION_BITS;
  16.911 -	int le = sp->loop_end>>FRACTION_BITS;
  16.912 -	int se = sp->data_length>>FRACTION_BITS;
  16.913 -	while (se > 1 && !sp->data[se-1]) se--;
  16.914 -	if (le > se) le = se;
  16.915 -	if (ls >= le) sp->modes &= ~MODES_LOOPING;
  16.916 -	sp->loop_end = le<<FRACTION_BITS;
  16.917 -	sp->data_length = se<<FRACTION_BITS;
  16.918 -    }
  16.919 -
  16.920        /* Adjust for fractional loop points. This is a guess. Does anyone
  16.921  	 know what "fractions" really stands for? */
  16.922        sp->loop_start |=
  16.923 @@ -815,196 +488,122 @@
  16.924        /* If this instrument will always be played on the same note,
  16.925  	 and it's not looped, we can resample it now. */
  16.926        if (sp->note_to_use && !(sp->modes & MODES_LOOPING))
  16.927 -	pre_resample(sp);
  16.928 +	pre_resample(song, sp);
  16.929  
  16.930 -#ifdef LOOKUP_HACK
  16.931 -      /* Squash the 16-bit data into 8 bits. */
  16.932 -      {
  16.933 -	uint8 *gulp,*ulp;
  16.934 -	int16 *swp;
  16.935 -	int l=sp->data_length >> FRACTION_BITS;
  16.936 -	gulp=ulp=safe_malloc(l+1);
  16.937 -	swp=(int16 *)sp->data;
  16.938 -	while(l--)
  16.939 -	  *ulp++ = (*swp++ >> 8) & 0xFF;
  16.940 -	free(sp->data);
  16.941 -	sp->data=(sample_t *)gulp;
  16.942 -      }
  16.943 -#endif
  16.944 -      
  16.945        if (strip_tail==1)
  16.946  	{
  16.947  	  /* Let's not really, just say we did. */
  16.948 -	  ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Stripping tail");
  16.949 +	  SNDDBG((" - Stripping tail\n"));
  16.950  	  sp->data_length = sp->loop_end;
  16.951  	}
  16.952 -    } /* end of sample loop */
  16.953 - } /* end of stereo layer loop */
  16.954 - } /* end of vlayer loop */
  16.955 +    }
  16.956  
  16.957 -
  16.958 -  close_file(fp);
  16.959 -  return headlp;
  16.960 +  SDL_RWclose(rw);
  16.961 +  return ip;
  16.962  }
  16.963  
  16.964 -static int fill_bank(int dr, int b)
  16.965 +static int fill_bank(MidiSong *song, int dr, int b)
  16.966  {
  16.967    int i, errors=0;
  16.968 -  ToneBank *bank=((dr) ? drumset[b] : tonebank[b]);
  16.969 +  ToneBank *bank=((dr) ? song->drumset[b] : song->tonebank[b]);
  16.970    if (!bank)
  16.971      {
  16.972 -      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
  16.973 -	   "Huh. Tried to load instruments in non-existent %s %d",
  16.974 -	   (dr) ? "drumset" : "tone bank", b);
  16.975 +      SNDDBG(("Huh. Tried to load instruments in non-existent %s %d\n",
  16.976 +	   (dr) ? "drumset" : "tone bank", b));
  16.977        return 0;
  16.978      }
  16.979 -  for (i=0; i<MAXPROG; i++)
  16.980 +  for (i=0; i<MAXBANK; i++)
  16.981      {
  16.982 -      if (bank->tone[i].layer==MAGIC_LOAD_INSTRUMENT)
  16.983 +      if (bank->instrument[i]==MAGIC_LOAD_INSTRUMENT)
  16.984  	{
  16.985 +          bank->instrument[i]=load_instrument_dls(song, dr, b, i);
  16.986 +          if (bank->instrument[i])
  16.987 +            {
  16.988 +              continue;
  16.989 +            }
  16.990  	  if (!(bank->tone[i].name))
  16.991  	    {
  16.992 -	      ctl->cmsg(CMSG_WARNING, (b!=0) ? VERB_VERBOSE : VERB_NORMAL,
  16.993 -		   "No instrument mapped to %s %d, program %d%s",
  16.994 +	      SNDDBG(("No instrument mapped to %s %d, program %d%s\n",
  16.995  		   (dr)? "drum set" : "tone bank", b, i, 
  16.996 -		   (b!=0) ? "" : " - this instrument will not be heard");
  16.997 +		   (b!=0) ? "" : " - this instrument will not be heard"));
  16.998  	      if (b!=0)
  16.999  		{
 16.1000  		  /* Mark the corresponding instrument in the default
 16.1001  		     bank / drumset for loading (if it isn't already) */
 16.1002  		  if (!dr)
 16.1003  		    {
 16.1004 -		      if (!(standard_tonebank.tone[i].layer))
 16.1005 -			standard_tonebank.tone[i].layer=
 16.1006 +		      if (!(song->tonebank[0]->instrument[i]))
 16.1007 +			song->tonebank[0]->instrument[i] =
 16.1008  			  MAGIC_LOAD_INSTRUMENT;
 16.1009  		    }
 16.1010  		  else
 16.1011  		    {
 16.1012 -		      if (!(standard_drumset.tone[i].layer))
 16.1013 -			standard_drumset.tone[i].layer=
 16.1014 +		      if (!(song->drumset[0]->instrument[i]))
 16.1015 +			song->drumset[0]->instrument[i] =
 16.1016  			  MAGIC_LOAD_INSTRUMENT;
 16.1017  		    }
 16.1018  		}
 16.1019 -	      bank->tone[i].layer=0;
 16.1020 +	      bank->instrument[i] = 0;
 16.1021  	      errors++;
 16.1022  	    }
 16.1023 -	  else if (!(bank->tone[i].layer=
 16.1024 -		     load_instrument(bank->tone[i].name, 
 16.1025 -			     	     bank->tone[i].font_type,
 16.1026 +	  else if (!(bank->instrument[i] =
 16.1027 +		     load_instrument(song,
 16.1028 +				     bank->tone[i].name, 
 16.1029  				     (dr) ? 1 : 0,
 16.1030  				     bank->tone[i].pan,
 16.1031  				     bank->tone[i].amp,
 16.1032 -				     bank->tone[i].tuning,
 16.1033  				     (bank->tone[i].note!=-1) ? 
 16.1034 -				       bank->tone[i].note :
 16.1035 -				       ((dr) ? i : -1),
 16.1036 +				     bank->tone[i].note :
 16.1037 +				     ((dr) ? i : -1),
 16.1038  				     (bank->tone[i].strip_loop!=-1) ?
 16.1039  				     bank->tone[i].strip_loop :
 16.1040  				     ((dr) ? 1 : -1),
 16.1041  				     (bank->tone[i].strip_envelope != -1) ? 
 16.1042  				     bank->tone[i].strip_envelope :
 16.1043  				     ((dr) ? 1 : -1),
 16.1044 -				     bank->tone[i].strip_tail,
 16.1045 -				     b,
 16.1046 -				     ((dr) ? i + 128 : i),
 16.1047 -				     bank->tone[i].sf_ix
 16.1048 -			    			 )))
 16.1049 +				     bank->tone[i].strip_tail )))
 16.1050  	    {
 16.1051 -	      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
 16.1052 -		   "Couldn't load instrument %s (%s %d, program %d)",
 16.1053 +	      SNDDBG(("Couldn't load instrument %s (%s %d, program %d)\n",
 16.1054  		   bank->tone[i].name,
 16.1055 -		   (dr)? "drum set" : "tone bank", b, i);
 16.1056 +		   (dr)? "drum set" : "tone bank", b, i));
 16.1057  	      errors++;
 16.1058  	    }
 16.1059 -	  else
 16.1060 -	    { /* it's loaded now */
 16.1061 -		bank->tone[i].last_used = current_tune_number;
 16.1062 -		current_patch_memory += bank->tone[i].layer->size;
 16.1063 -		purge_as_required();
 16.1064 -		if (current_patch_memory > max_patch_memory) {
 16.1065 -	      		ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
 16.1066 -		   		"Not enough memory to load instrument %s (%s %d, program %d)",
 16.1067 -		   		bank->tone[i].name,
 16.1068 -		   		(dr)? "drum set" : "tone bank", b, i);
 16.1069 -	      		errors++;
 16.1070 -	    		free_layer(bank->tone[i].layer);
 16.1071 -	    		bank->tone[i].layer=0;
 16.1072 -	    		bank->tone[i].last_used=-1;
 16.1073 -		}
 16.1074 -#if 0
 16.1075 -  	        if (check_for_rc()) {
 16.1076 -	    		free_layer(bank->tone[i].layer);
 16.1077 -	    		bank->tone[i].layer=0;
 16.1078 -	    		bank->tone[i].last_used=-1;
 16.1079 -			return 0;
 16.1080 -		}
 16.1081 -#endif
 16.1082 -	    }
 16.1083  	}
 16.1084      }
 16.1085    return errors;
 16.1086  }
 16.1087  
 16.1088 -static void free_old_instruments(int how_old)
 16.1089 +int load_missing_instruments(MidiSong *song)
 16.1090 +{
 16.1091 +  int i=MAXBANK,errors=0;
 16.1092 +  while (i--)
 16.1093 +    {
 16.1094 +      if (song->tonebank[i])
 16.1095 +	errors+=fill_bank(song,0,i);
 16.1096 +      if (song->drumset[i])
 16.1097 +	errors+=fill_bank(song,1,i);
 16.1098 +    }
 16.1099 +  return errors;
 16.1100 +}
 16.1101 +
 16.1102 +void free_instruments(MidiSong *song)
 16.1103  {
 16.1104    int i=MAXBANK;
 16.1105    while(i--)
 16.1106      {
 16.1107 -      if (tonebank[i])
 16.1108 -	free_old_bank(0, i, how_old);
 16.1109 -      if (drumset[i])
 16.1110 -	free_old_bank(1, i, how_old);
 16.1111 +      if (song->tonebank[i])
 16.1112 +	free_bank(song, 0, i);
 16.1113 +      if (song->drumset[i])
 16.1114 +	free_bank(song, 1, i);
 16.1115      }
 16.1116  }
 16.1117  
 16.1118 -static void purge_as_required(void)
 16.1119 +int set_default_instrument(MidiSong *song, char *name)
 16.1120  {
 16.1121 -  if (!max_patch_memory) return;
 16.1122 -
 16.1123 -  while (last_tune_purged < current_tune_number
 16.1124 -	&& current_patch_memory > max_patch_memory)
 16.1125 -    {
 16.1126 -	last_tune_purged++;
 16.1127 -	free_old_instruments(last_tune_purged);
 16.1128 -    }
 16.1129 -}
 16.1130 -
 16.1131 -
 16.1132 -int load_missing_instruments(void)
 16.1133 -{
 16.1134 -  int i=MAXBANK,errors=0;
 16.1135 -  while (i--)
 16.1136 -    {
 16.1137 -      if (tonebank[i])
 16.1138 -	errors+=fill_bank(0,i);
 16.1139 -      if (drumset[i])
 16.1140 -	errors+=fill_bank(1,i);
 16.1141 -    }
 16.1142 -  current_tune_number++;
 16.1143 -  return errors;
 16.1144 -}
 16.1145 -
 16.1146 -void free_instruments(void)
 16.1147 -{
 16.1148 -  int i=128;
 16.1149 -  while(i--)
 16.1150 -    {
 16.1151 -      if (tonebank[i])
 16.1152 -	free_bank(0,i);
 16.1153 -      if (drumset[i])
 16.1154 -	free_bank(1,i);
 16.1155 -    }
 16.1156 -}
 16.1157 -
 16.1158 -int set_default_instrument(const char *name)
 16.1159 -{
 16.1160 -  InstrumentLayer *lp;
 16.1161 -/*  if (!(lp=load_instrument(name, 0, -1, -1, -1, 0, 0, 0))) */
 16.1162 -  if (!(lp=load_instrument(name, FONT_NORMAL, 0, -1, -1, 0, -1, -1, -1, -1, 0, -1, -1)))
 16.1163 +  Instrument *ip;
 16.1164 +  if (!(ip=load_instrument(song, name, 0, -1, -1, -1, 0, 0, 0)))
 16.1165      return -1;
 16.1166 -  if (default_instrument)
 16.1167 -    free_layer(default_instrument);
 16.1168 -  default_instrument=lp;
 16.1169 -  default_program=SPECIAL_PROGRAM;
 16.1170 +  song->default_instrument = ip;
 16.1171 +  song->default_program = SPECIAL_PROGRAM;
 16.1172    return 0;
 16.1173  }
    17.1 --- a/timidity/instrum.h	Tue Oct 17 16:55:58 2017 -0700
    17.2 +++ b/timidity/instrum.h	Tue Oct 17 21:54:04 2017 -0700
    17.3 @@ -1,44 +1,14 @@
    17.4  /*
    17.5 +
    17.6      TiMidity -- Experimental MIDI to WAVE converter
    17.7      Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
    17.8  
    17.9      This program is free software; you can redistribute it and/or modify
   17.10      it under the terms of the Perl Artistic License, available in COPYING.
   17.11 - */
   17.12  
   17.13 +   instrum.h
   17.14  
   17.15 -typedef struct {
   17.16 -  int32
   17.17 -    loop_start, loop_end, data_length,
   17.18 -    sample_rate, low_freq, high_freq, root_freq;
   17.19 -  uint8
   17.20 -    root_tune, fine_tune;
   17.21 -  int32
   17.22 -    envelope_rate[7], envelope_offset[7],
   17.23 -    modulation_rate[7], modulation_offset[7];
   17.24 -  FLOAT_T
   17.25 -    volume, resonance,
   17.26 -    modEnvToFilterFc, modEnvToPitch, modLfoToFilterFc;
   17.27 -  sample_t *data;
   17.28 -  int32 
   17.29 -    tremolo_sweep_increment, tremolo_phase_increment, 
   17.30 -    lfo_sweep_increment, lfo_phase_increment,
   17.31 -    vibrato_sweep_increment, vibrato_control_ratio,
   17.32 -    cutoff_freq;
   17.33 -  uint8
   17.34 -    reverberation, chorusdepth,
   17.35 -    tremolo_depth, vibrato_depth,
   17.36 -    modes;
   17.37 -  uint8
   17.38 -    attenuation, freq_center;
   17.39 -  int8
   17.40 -    panning, note_to_use, exclusiveClass;
   17.41 -  int16
   17.42 -    scale_tuning, keyToModEnvHold, keyToModEnvDecay,
   17.43 -    keyToVolEnvHold, keyToVolEnvDecay;
   17.44 -  int32
   17.45 -    freq_scale, vibrato_delay;
   17.46 -} Sample;
   17.47 +   */
   17.48  
   17.49  /* Bits in modes: */
   17.50  #define MODES_16BIT	(1<<0)
   17.51 @@ -48,121 +18,13 @@
   17.52  #define MODES_REVERSE	(1<<4)
   17.53  #define MODES_SUSTAIN	(1<<5)
   17.54  #define MODES_ENVELOPE	(1<<6)
   17.55 -#define MODES_FAST_RELEASE	(1<<7)
   17.56  
   17.57 -#if 0
   17.58 -typedef struct {
   17.59 -  int samples;
   17.60 -  Sample *sample;
   17.61 -} Instrument;
   17.62 -#endif
   17.63 -
   17.64 -#define INST_GUS	0
   17.65 -#define INST_SF2	1
   17.66 -
   17.67 -typedef struct {
   17.68 -  int type;
   17.69 -  int samples;
   17.70 -  Sample *sample;
   17.71 -  int left_samples;
   17.72 -  Sample *left_sample;
   17.73 -  int right_samples;
   17.74 -  Sample *right_sample;
   17.75 -  unsigned char *contents;
   17.76 -} Instrument;
   17.77 -
   17.78 -
   17.79 -typedef struct _InstrumentLayer {
   17.80 -  uint8 lo, hi;
   17.81 -  int size;
   17.82 -  Instrument *instrument;
   17.83 -  struct _InstrumentLayer *next;
   17.84 -} InstrumentLayer;
   17.85 -
   17.86 -struct cfg_type {
   17.87 -	int font_code;
   17.88 -	int num;
   17.89 -	const char *name;
   17.90 -};
   17.91 -
   17.92 -#define FONT_NORMAL 0
   17.93 -#define FONT_FFF    1
   17.94 -#define FONT_SBK    2
   17.95 -#define FONT_TONESET 3
   17.96 -#define FONT_DRUMSET 4
   17.97 -#define FONT_PRESET 5
   17.98 -
   17.99 -
  17.100 -typedef struct {
  17.101 -  char *name;
  17.102 -  InstrumentLayer *layer;
  17.103 -  int font_type, sf_ix, last_used, tuning;
  17.104 -  int note, amp, pan, strip_loop, strip_envelope, strip_tail;
  17.105 -} ToneBankElement;
  17.106 -
  17.107 -#if 0
  17.108 -typedef struct {
  17.109 -  char *name;
  17.110 -  Instrument *instrument;
  17.111 -  int note, amp, pan, strip_loop, strip_envelope, strip_tail;
  17.112 -} ToneBankElement;
  17.113 -#endif
  17.114  /* A hack to delay instrument loading until after reading the
  17.115     entire MIDI file. */
  17.116 -#define MAGIC_LOAD_INSTRUMENT ((InstrumentLayer *)(-1))
  17.117 -
  17.118 -#define MAXPROG 128
  17.119 -#define MAXBANK 130
  17.120 -#define SFXBANK (MAXBANK-1)
  17.121 -#define SFXDRUM1 (MAXBANK-2)
  17.122 -#define SFXDRUM2 (MAXBANK-1)
  17.123 -#define XGDRUM 1
  17.124 -
  17.125 -#if 0
  17.126 -typedef struct {
  17.127 -  ToneBankElement tone[128];
  17.128 -} ToneBank;
  17.129 -#endif
  17.130 -
  17.131 -typedef struct {
  17.132 -  char *name;
  17.133 -  ToneBankElement tone[MAXPROG];
  17.134 -} ToneBank;
  17.135 -
  17.136 -
  17.137 -extern char *sf_file;
  17.138 -
  17.139 -extern ToneBank *tonebank[], *drumset[];
  17.140 -
  17.141 -#if 0
  17.142 -extern Instrument *default_instrument;
  17.143 -#endif
  17.144 -extern InstrumentLayer *default_instrument;
  17.145 -extern int default_program;
  17.146 -extern int antialiasing_allowed;
  17.147 -extern int fast_decay;
  17.148 -extern int free_instruments_afterwards;
  17.149 +#define MAGIC_LOAD_INSTRUMENT ((Instrument *) (-1))
  17.150  
  17.151  #define SPECIAL_PROGRAM -1
  17.152  
  17.153 -extern int load_missing_instruments(void);
  17.154 -extern void free_instruments(void);
  17.155 -extern void end_soundfont(void);
  17.156 -extern int set_default_instrument(const char *name);
  17.157 -
  17.158 -
  17.159 -extern int32 convert_tremolo_sweep(uint8 sweep);
  17.160 -extern int32 convert_vibrato_sweep(uint8 sweep, int32 vib_control_ratio);
  17.161 -extern int32 convert_tremolo_rate(uint8 rate);
  17.162 -extern int32 convert_vibrato_rate(uint8 rate);
  17.163 -
  17.164 -extern int init_soundfont(char *fname, int oldbank, int newbank, int level);
  17.165 -extern InstrumentLayer *load_sbk_patch(const char *name, int gm_num, int bank, int percussion,
  17.166 - int panning, int amp, int note_to_use, int sf_ix);
  17.167 -extern int current_tune_number;
  17.168 -extern int max_patch_memory;
  17.169 -extern int current_patch_memory;
  17.170 -#define XMAPMAX 800
  17.171 -extern int xmap[XMAPMAX][5];
  17.172 -extern void pcmap(int *b, int *v, int *p, int *drums);
  17.173 -
  17.174 +extern int load_missing_instruments(MidiSong *song);
  17.175 +extern void free_instruments(MidiSong *song);
  17.176 +extern int set_default_instrument(MidiSong *song, char *name);
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/timidity/instrum_dls.c	Tue Oct 17 21:54:04 2017 -0700
    18.3 @@ -0,0 +1,1255 @@
    18.4 +/*
    18.5 +
    18.6 +    TiMidity -- Experimental MIDI to WAVE converter
    18.7 +    Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
    18.8 +
    18.9 +    This program is free software; you can redistribute it and/or modify
   18.10 +    it under the terms of the Perl Artistic License, available in COPYING.
   18.11 +
   18.12 +   instrum.h
   18.13 +
   18.14 +   */
   18.15 +
   18.16 +#include <stdlib.h>
   18.17 +#include <string.h>
   18.18 +
   18.19 +#include "SDL.h"
   18.20 +#include "SDL_endian.h"
   18.21 +#include "SDL_rwops.h"
   18.22 +
   18.23 +#include "SDL.h"
   18.24 +
   18.25 +#include "timidity.h"
   18.26 +#include "options.h"
   18.27 +#include "instrum.h"
   18.28 +#include "tables.h"
   18.29 +#include "common.h"
   18.30 +
   18.31 +/*-------------------------------------------------------------------------*/
   18.32 +/* * * * * * * * * * * * * * * * * load_riff.h * * * * * * * * * * * * * * */
   18.33 +/*-------------------------------------------------------------------------*/
   18.34 +typedef struct _RIFF_Chunk {
   18.35 +    Uint32 magic;
   18.36 +    Uint32 length;
   18.37 +    Uint32 subtype;
   18.38 +    Uint8  *data;
   18.39 +    struct _RIFF_Chunk *child;
   18.40 +    struct _RIFF_Chunk *next;
   18.41 +} RIFF_Chunk;
   18.42 +
   18.43 +extern RIFF_Chunk* LoadRIFF(SDL_RWops *src);
   18.44 +extern void FreeRIFF(RIFF_Chunk *chunk);
   18.45 +extern void PrintRIFF(RIFF_Chunk *chunk, int level);
   18.46 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
   18.47 +
   18.48 +/*-------------------------------------------------------------------------*/
   18.49 +/* * * * * * * * * * * * * * * * * load_riff.c * * * * * * * * * * * * * * */
   18.50 +/*-------------------------------------------------------------------------*/
   18.51 +#define RIFF        0x46464952        /* "RIFF" */
   18.52 +#define LIST        0x5453494c        /* "LIST" */
   18.53 +
   18.54 +static RIFF_Chunk *AllocRIFFChunk()
   18.55 +{
   18.56 +    RIFF_Chunk *chunk = (RIFF_Chunk *)malloc(sizeof(*chunk));
   18.57 +    if ( !chunk ) {
   18.58 +        SDL_Error(SDL_ENOMEM);
   18.59 +        return NULL;
   18.60 +    }
   18.61 +    memset(chunk, 0, sizeof(*chunk));
   18.62 +    return chunk;
   18.63 +}
   18.64 +
   18.65 +static void FreeRIFFChunk(RIFF_Chunk *chunk)
   18.66 +{
   18.67 +    if ( chunk->child ) {
   18.68 +        FreeRIFFChunk(chunk->child);
   18.69 +    }
   18.70 +    if ( chunk->next ) {
   18.71 +        FreeRIFFChunk(chunk->next);
   18.72 +    }
   18.73 +    free(chunk);
   18.74 +}
   18.75 +
   18.76 +static int ChunkHasSubType(Uint32 magic)
   18.77 +{
   18.78 +    static Uint32 chunk_list[] = {
   18.79 +        RIFF, LIST
   18.80 +    };
   18.81 +    int i;
   18.82 +    for ( i = 0; i < SDL_TABLESIZE(chunk_list); ++i ) {
   18.83 +        if ( magic == chunk_list[i] ) {
   18.84 +            return 1;
   18.85 +        }
   18.86 +    }
   18.87 +    return 0;
   18.88 +}
   18.89 +
   18.90 +static int ChunkHasSubChunks(Uint32 magic)
   18.91 +{
   18.92 +    static Uint32 chunk_list[] = {
   18.93 +        RIFF, LIST
   18.94 +    };
   18.95 +    int i;
   18.96 +    for ( i = 0; i < SDL_TABLESIZE(chunk_list); ++i ) {
   18.97 +        if ( magic == chunk_list[i] ) {
   18.98 +            return 1;
   18.99 +        }
  18.100 +    }
  18.101 +    return 0;
  18.102 +}
  18.103 +
  18.104 +static void LoadSubChunks(RIFF_Chunk *chunk, Uint8 *data, Uint32 left)
  18.105 +{
  18.106 +    Uint8 *subchunkData;
  18.107 +    Uint32 subchunkDataLen;
  18.108 +
  18.109 +    while ( left > 8 ) {
  18.110 +        RIFF_Chunk *child = AllocRIFFChunk();
  18.111 +        RIFF_Chunk *next, *prev = NULL;
  18.112 +        for ( next = chunk->child; next; next = next->next ) {
  18.113 +            prev = next;
  18.114 +        }
  18.115 +        if ( prev ) {
  18.116 +            prev->next = child;
  18.117 +        } else {
  18.118 +            chunk->child = child;
  18.119 +        }
  18.120 +            
  18.121 +        child->magic = (data[0] <<  0) |
  18.122 +                       (data[1] <<  8) |
  18.123 +                       (data[2] << 16) |
  18.124 +                       (data[3] << 24);
  18.125 +        data += 4;
  18.126 +        left -= 4;
  18.127 +        child->length = (data[0] <<  0) |
  18.128 +                        (data[1] <<  8) |
  18.129 +                        (data[2] << 16) |
  18.130 +                        (data[3] << 24);
  18.131 +        data += 4;
  18.132 +        left -= 4;
  18.133 +        child->data = data;
  18.134 +
  18.135 +        if ( child->length > left ) {
  18.136 +            child->length = left;
  18.137 +        }
  18.138 +
  18.139 +        subchunkData = child->data;
  18.140 +        subchunkDataLen = child->length;
  18.141 +        if ( ChunkHasSubType(child->magic) && subchunkDataLen >= 4 ) {
  18.142 +            child->subtype = (subchunkData[0] <<  0) |
  18.143 +                     (subchunkData[1] <<  8) |
  18.144 +                     (subchunkData[2] << 16) |
  18.145 +                     (subchunkData[3] << 24);
  18.146 +            subchunkData += 4;
  18.147 +            subchunkDataLen -= 4;
  18.148 +        }
  18.149 +        if ( ChunkHasSubChunks(child->magic) ) {
  18.150 +            LoadSubChunks(child, subchunkData, subchunkDataLen);
  18.151 +        }
  18.152 +
  18.153 +        data += child->length;
  18.154 +        left -= child->length;
  18.155 +    }
  18.156 +}
  18.157 +
  18.158 +RIFF_Chunk *LoadRIFF(SDL_RWops *src)
  18.159 +{
  18.160 +    RIFF_Chunk *chunk;
  18.161 +    Uint8 *subchunkData;
  18.162 +    Uint32 subchunkDataLen;
  18.163 +
  18.164 +    /* Allocate the chunk structure */
  18.165 +    chunk = AllocRIFFChunk();
  18.166 +
  18.167 +    /* Make sure the file is in RIFF format */
  18.168 +    chunk->magic    = SDL_ReadLE32(src);
  18.169 +    chunk->length    = SDL_ReadLE32(src);
  18.170 +    if ( chunk->magic != RIFF ) {
  18.171 +        SDL_SetError("Not a RIFF file");
  18.172 +        FreeRIFFChunk(chunk);
  18.173 +        return NULL;
  18.174 +    }
  18.175 +    chunk->data = (Uint8 *)malloc(chunk->length);
  18.176 +    if ( chunk->data == NULL ) {
  18.177 +        SDL_Error(SDL_ENOMEM);
  18.178 +        FreeRIFFChunk(chunk);
  18.179 +        return NULL;
  18.180 +    }
  18.181 +    if ( SDL_RWread(src, chunk->data, chunk->length, 1) != 1 ) {
  18.182 +        SDL_Error(SDL_EFREAD);
  18.183 +        FreeRIFF(chunk);
  18.184 +        return NULL;
  18.185 +    }
  18.186 +    subchunkData = chunk->data;
  18.187 +    subchunkDataLen = chunk->length;
  18.188 +    if ( ChunkHasSubType(chunk->magic) && subchunkDataLen >= 4 ) {
  18.189 +        chunk->subtype = (subchunkData[0] <<  0) |
  18.190 +                 (subchunkData[1] <<  8) |
  18.191 +                 (subchunkData[2] << 16) |
  18.192 +                 (subchunkData[3] << 24);
  18.193 +        subchunkData += 4;
  18.194 +        subchunkDataLen -= 4;
  18.195 +    }
  18.196 +    if ( ChunkHasSubChunks(chunk->magic) ) {
  18.197 +        LoadSubChunks(chunk, subchunkData, subchunkDataLen);
  18.198 +    }
  18.199 +    return chunk;
  18.200 +}
  18.201 +
  18.202 +void FreeRIFF(RIFF_Chunk *chunk)
  18.203 +{
  18.204 +    free(chunk->data);
  18.205 +    FreeRIFFChunk(chunk);
  18.206 +}
  18.207 +
  18.208 +void PrintRIFF(RIFF_Chunk *chunk, int level)
  18.209 +{
  18.210 +    static char prefix[128];
  18.211 +
  18.212 +    if ( level == sizeof(prefix)-1 ) {
  18.213 +        return;
  18.214 +    }
  18.215 +    if ( level > 0 ) {
  18.216 +        prefix[(level-1)*2] = ' ';
  18.217 +        prefix[(level-1)*2+1] = ' ';
  18.218 +    }
  18.219 +    prefix[level*2] = '\0';
  18.220 +    printf("%sChunk: %c%c%c%c (%d bytes)", prefix,
  18.221 +        ((chunk->magic >>  0) & 0xFF),
  18.222 +        ((chunk->magic >>  8) & 0xFF),
  18.223 +        ((chunk->magic >> 16) & 0xFF),
  18.224 +        ((chunk->magic >> 24) & 0xFF), chunk->length);
  18.225 +    if ( chunk->subtype ) {
  18.226 +        printf(" subtype: %c%c%c%c",
  18.227 +            ((chunk->subtype >>  0) & 0xFF),
  18.228 +            ((chunk->subtype >>  8) & 0xFF),
  18.229 +            ((chunk->subtype >> 16) & 0xFF),
  18.230 +            ((chunk->subtype >> 24) & 0xFF));
  18.231 +    }
  18.232 +    printf("\n");
  18.233 +    if ( chunk->child ) {
  18.234 +        printf("%s{\n", prefix);
  18.235 +        PrintRIFF(chunk->child, level + 1);
  18.236 +        printf("%s}\n", prefix);
  18.237 +    }
  18.238 +    if ( chunk->next ) {
  18.239 +        PrintRIFF(chunk->next, level);
  18.240 +    }
  18.241 +    if ( level > 0 ) {
  18.242 +        prefix[(level-1)*2] = '\0';
  18.243 +    }
  18.244 +}
  18.245 +
  18.246 +#ifdef TEST_MAIN_RIFF
  18.247 +
  18.248 +main(int argc, char *argv[])
  18.249 +{
  18.250 +    int i;
  18.251 +    for ( i = 1; i < argc; ++i ) {
  18.252 +        RIFF_Chunk *chunk;
  18.253 +        SDL_RWops *src = SDL_RWFromFile(argv[i], "rb");
  18.254 +        if ( !src ) {
  18.255 +            fprintf(stderr, "Couldn't open %s: %s", argv[i], SDL_GetError());
  18.256 +            continue;
  18.257 +        }
  18.258 +        chunk = LoadRIFF(src);
  18.259 +        if ( chunk ) {
  18.260 +            PrintRIFF(chunk, 0);
  18.261 +            FreeRIFF(chunk);
  18.262 +        } else {
  18.263 +            fprintf(stderr, "Couldn't load %s: %s\n", argv[i], SDL_GetError());
  18.264 +        }
  18.265 +        SDL_RWclose(src);
  18.266 +    }
  18.267 +}
  18.268 +
  18.269 +#endif // TEST_MAIN
  18.270 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  18.271 +
  18.272 +/*-------------------------------------------------------------------------*/
  18.273 +/* * * * * * * * * * * * * * * * * load_dls.h  * * * * * * * * * * * * * * */
  18.274 +/*-------------------------------------------------------------------------*/
  18.275 +/* This code is based on the DLS spec version 1.1, available at:
  18.276 +    http://www.midi.org/about-midi/dls/dlsspec.shtml
  18.277 +*/
  18.278 +
  18.279 +/* Some typedefs so the public dls headers don't need to be modified */
  18.280 +#define FAR
  18.281 +typedef Uint8   BYTE;
  18.282 +typedef Sint16  SHORT;
  18.283 +typedef Uint16  USHORT;
  18.284 +typedef Uint16  WORD;
  18.285 +typedef Sint32  LONG;
  18.286 +typedef Uint32  ULONG;
  18.287 +typedef Uint32  DWORD;
  18.288 +#define mmioFOURCC(A, B, C, D)    \
  18.289 +    (((A) <<  0) | ((B) <<  8) | ((C) << 16) | ((D) << 24))
  18.290 +#define DEFINE_GUID(A, B, C, E, F, G, H, I, J, K, L, M)
  18.291 +
  18.292 +#include "dls1.h"
  18.293 +#include "dls2.h"
  18.294 +
  18.295 +typedef struct _WaveFMT {
  18.296 +    WORD wFormatTag;
  18.297 +    WORD wChannels;
  18.298 +    DWORD dwSamplesPerSec;
  18.299 +    DWORD dwAvgBytesPerSec;
  18.300 +    WORD wBlockAlign;
  18.301 +    WORD wBitsPerSample;
  18.302 +} WaveFMT;
  18.303 +
  18.304 +typedef struct _DLS_Wave {
  18.305 +    WaveFMT *format;
  18.306 +    Uint8 *data;
  18.307 +    Uint32 length;
  18.308 +    WSMPL *wsmp;
  18.309 +    WLOOP *wsmp_loop;
  18.310 +} DLS_Wave;
  18.311 +
  18.312 +typedef struct _DLS_Region {
  18.313 +    RGNHEADER *header;
  18.314 +    WAVELINK *wlnk;
  18.315 +    WSMPL *wsmp;
  18.316 +    WLOOP *wsmp_loop;
  18.317 +    CONNECTIONLIST *art;
  18.318 +    CONNECTION *artList;
  18.319 +} DLS_Region;
  18.320 +
  18.321 +typedef struct _DLS_Instrument {
  18.322 +    const char *name;
  18.323 +    INSTHEADER *header;
  18.324 +    DLS_Region *regions;
  18.325 +    CONNECTIONLIST *art;
  18.326 +    CONNECTION *artList;
  18.327 +} DLS_Instrument;
  18.328 +
  18.329 +typedef struct _DLS_Data {
  18.330 +    struct _RIFF_Chunk *chunk;
  18.331 +
  18.332 +    Uint32 cInstruments;
  18.333 +    DLS_Instrument *instruments;
  18.334 +
  18.335 +    POOLTABLE *ptbl;
  18.336 +    POOLCUE *ptblList;
  18.337 +    DLS_Wave *waveList;
  18.338 +
  18.339 +    const char *name;
  18.340 +    const char *artist;
  18.341 +    const char *copyright;
  18.342 +    const char *comments;
  18.343 +} DLS_Data;
  18.344 +
  18.345 +extern DLS_Data* LoadDLS(SDL_RWops *src);
  18.346 +extern void FreeDLS(DLS_Data *chunk);
  18.347 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  18.348 +
  18.349 +/*-------------------------------------------------------------------------*/
  18.350 +/* * * * * * * * * * * * * * * * * load_dls.c  * * * * * * * * * * * * * * */
  18.351 +/*-------------------------------------------------------------------------*/
  18.352 +
  18.353 +#define FOURCC_LIST    0x5453494c   /* "LIST" */
  18.354 +#define FOURCC_FMT     0x20746D66   /* "fmt " */
  18.355 +#define FOURCC_DATA    0x61746164   /* "data" */
  18.356 +#define FOURCC_INFO    mmioFOURCC('I','N','F','O')
  18.357 +#define FOURCC_IARL    mmioFOURCC('I','A','R','L')
  18.358 +#define FOURCC_IART    mmioFOURCC('I','A','R','T')
  18.359 +#define FOURCC_ICMS    mmioFOURCC('I','C','M','S')
  18.360 +#define FOURCC_ICMT    mmioFOURCC('I','C','M','T')
  18.361 +#define FOURCC_ICOP    mmioFOURCC('I','C','O','P')
  18.362 +#define FOURCC_ICRD    mmioFOURCC('I','C','R','D')
  18.363 +#define FOURCC_IENG    mmioFOURCC('I','E','N','G')
  18.364 +#define FOURCC_IGNR    mmioFOURCC('I','G','N','R')
  18.365 +#define FOURCC_IKEY    mmioFOURCC('I','K','E','Y')
  18.366 +#define FOURCC_IMED    mmioFOURCC('I','M','E','D')
  18.367 +#define FOURCC_INAM    mmioFOURCC('I','N','A','M')
  18.368 +#define FOURCC_IPRD    mmioFOURCC('I','P','R','D')
  18.369 +#define FOURCC_ISBJ    mmioFOURCC('I','S','B','J')
  18.370 +#define FOURCC_ISFT    mmioFOURCC('I','S','F','T')
  18.371 +#define FOURCC_ISRC    mmioFOURCC('I','S','R','C')
  18.372 +#define FOURCC_ISRF    mmioFOURCC('I','S','R','F')
  18.373 +#define FOURCC_ITCH    mmioFOURCC('I','T','C','H')
  18.374 +
  18.375 +
  18.376 +static void FreeRegions(DLS_Instrument *instrument)
  18.377 +{
  18.378 +    if ( instrument->regions ) {
  18.379 +        free(instrument->regions);
  18.380 +    }
  18.381 +}
  18.382 +
  18.383 +static void AllocRegions(DLS_Instrument *instrument)
  18.384 +{
  18.385 +    int datalen = (instrument->header->cRegions * sizeof(DLS_Region));
  18.386 +    FreeRegions(instrument);
  18.387 +    instrument->regions = (DLS_Region *)malloc(datalen);
  18.388 +    if ( instrument->regions ) {
  18.389 +        memset(instrument->regions, 0, datalen);
  18.390 +    }
  18.391 +}
  18.392 +
  18.393 +static void FreeInstruments(DLS_Data *data)
  18.394 +{
  18.395 +    if ( data->instruments ) {
  18.396 +        Uint32 i;
  18.397 +        for ( i = 0; i < data->cInstruments; ++i ) {
  18.398 +            FreeRegions(&data->instruments[i]);
  18.399 +        }
  18.400 +        free(data->instruments);
  18.401 +    }
  18.402 +}
  18.403 +
  18.404 +static void AllocInstruments(DLS_Data *data)
  18.405 +{
  18.406 +    int datalen = (data->cInstruments * sizeof(DLS_Instrument));
  18.407 +    FreeInstruments(data);
  18.408 +    data->instruments = (DLS_Instrument *)malloc(datalen);
  18.409 +    if ( data->instruments ) {
  18.410 +        memset(data->instruments, 0, datalen);
  18.411 +    }
  18.412 +}
  18.413 +
  18.414 +static void FreeWaveList(DLS_Data *data)
  18.415 +{
  18.416 +    if ( data->waveList ) {
  18.417 +        free(data->waveList);
  18.418 +    }
  18.419 +}
  18.420 +
  18.421 +static void AllocWaveList(DLS_Data *data)
  18.422 +{
  18.423 +    int datalen = (data->ptbl->cCues * sizeof(DLS_Wave));
  18.424 +    FreeWaveList(data);
  18.425 +    data->waveList = (DLS_Wave *)malloc(datalen);
  18.426 +    if ( data->waveList ) {
  18.427 +        memset(data->waveList, 0, datalen);
  18.428 +    }
  18.429 +}
  18.430 +
  18.431 +static void Parse_colh(DLS_Data *data, RIFF_Chunk *chunk)
  18.432 +{
  18.433 +    data->cInstruments = SDL_SwapLE32(*(Uint32 *)chunk->data);
  18.434 +    AllocInstruments(data);
  18.435 +}
  18.436 +
  18.437 +static void Parse_insh(DLS_Data *data, RIFF_Chunk *chunk, DLS_Instrument *instrument)
  18.438 +{
  18.439 +    INSTHEADER *header = (INSTHEADER *)chunk->data;
  18.440 +    header->cRegions = SDL_SwapLE32(header->cRegions);
  18.441 +    header->Locale.ulBank = SDL_SwapLE32(header->Locale.ulBank);
  18.442 +    header->Locale.ulInstrument = SDL_SwapLE32(header->Locale.ulInstrument);
  18.443 +    instrument->header = header;
  18.444 +    AllocRegions(instrument);
  18.445 +}
  18.446 +
  18.447 +static void Parse_rgnh(DLS_Data *data, RIFF_Chunk *chunk, DLS_Region *region)
  18.448 +{
  18.449 +    RGNHEADER *header = (RGNHEADER *)chunk->data;
  18.450 +    header->RangeKey.usLow = SDL_SwapLE16(header->RangeKey.usLow);
  18.451 +    header->RangeKey.usHigh = SDL_SwapLE16(header->RangeKey.usHigh);
  18.452 +    header->RangeVelocity.usLow = SDL_SwapLE16(header->RangeVelocity.usLow);
  18.453 +    header->RangeVelocity.usHigh = SDL_SwapLE16(header->RangeVelocity.usHigh);
  18.454 +    header->fusOptions = SDL_SwapLE16(header->fusOptions);
  18.455 +    header->usKeyGroup = SDL_SwapLE16(header->usKeyGroup);
  18.456 +    region->header = header;
  18.457 +}
  18.458 +
  18.459 +static void Parse_wlnk(DLS_Data *data, RIFF_Chunk *chunk, DLS_Region *region)
  18.460 +{
  18.461 +    WAVELINK *wlnk = (WAVELINK *)chunk->data;
  18.462 +    wlnk->fusOptions = SDL_SwapLE16(wlnk->fusOptions);
  18.463 +    wlnk->usPhaseGroup = SDL_SwapLE16(wlnk->usPhaseGroup);
  18.464 +    wlnk->ulChannel = SDL_SwapLE16(wlnk->ulChannel);
  18.465 +    wlnk->ulTableIndex = SDL_SwapLE16(wlnk->ulTableIndex);
  18.466 +    region->wlnk = wlnk;
  18.467 +}
  18.468 +
  18.469 +static void Parse_wsmp(DLS_Data *data, RIFF_Chunk *chunk, WSMPL **wsmp_ptr, WLOOP **wsmp_loop_ptr)
  18.470 +{
  18.471 +    Uint32 i;
  18.472 +    WSMPL *wsmp = (WSMPL *)chunk->data;
  18.473 +    WLOOP *loop;
  18.474 +    wsmp->cbSize = SDL_SwapLE32(wsmp->cbSize);
  18.475 +    wsmp->usUnityNote = SDL_SwapLE16(wsmp->usUnityNote);
  18.476 +    wsmp->sFineTune = SDL_SwapLE16(wsmp->sFineTune);
  18.477 +    wsmp->lAttenuation = SDL_SwapLE32(wsmp->lAttenuation);
  18.478 +    wsmp->fulOptions = SDL_SwapLE32(wsmp->fulOptions);
  18.479 +    wsmp->cSampleLoops = SDL_SwapLE32(wsmp->cSampleLoops);
  18.480 +    loop = (WLOOP *)((Uint8 *)chunk->data + wsmp->cbSize);
  18.481 +    *wsmp_ptr = wsmp;
  18.482 +    *wsmp_loop_ptr = loop;
  18.483 +    for ( i = 0; i < wsmp->cSampleLoops; ++i ) {
  18.484 +        loop->cbSize = SDL_SwapLE32(loop->cbSize);
  18.485 +        loop->ulType = SDL_SwapLE32(loop->ulType);
  18.486 +        loop->ulStart = SDL_SwapLE32(loop->ulStart);
  18.487 +        loop->ulLength = SDL_SwapLE32(loop->ulLength);
  18.488 +        ++loop;
  18.489 +    }
  18.490 +}
  18.491 +
  18.492 +static void Parse_art(DLS_Data *data, RIFF_Chunk *chunk, CONNECTIONLIST **art_ptr, CONNECTION **artList_ptr)
  18.493 +{
  18.494 +    Uint32 i;
  18.495 +    CONNECTIONLIST *art = (CONNECTIONLIST *)chunk->data;
  18.496 +    CONNECTION *artList;
  18.497 +    art->cbSize = SDL_SwapLE32(art->cbSize);
  18.498 +    art->cConnections = SDL_SwapLE32(art->cConnections);
  18.499 +    artList = (CONNECTION *)((Uint8 *)chunk->data + art->cbSize);
  18.500 +    *art_ptr = art;
  18.501 +    *artList_ptr = artList;
  18.502 +    for ( i = 0; i < art->cConnections; ++i ) {
  18.503 +        artList->usSource = SDL_SwapLE16(artList->usSource);
  18.504 +        artList->usControl = SDL_SwapLE16(artList->usControl);
  18.505 +        artList->usDestination = SDL_SwapLE16(artList->usDestination);
  18.506 +        artList->usTransform = SDL_SwapLE16(artList->usTransform);
  18.507 +        artList->lScale = SDL_SwapLE32(artList->lScale);
  18.508 +        ++artList;
  18.509 +    }
  18.510 +}
  18.511 +
  18.512 +static void Parse_lart(DLS_Data *data, RIFF_Chunk *chunk, CONNECTIONLIST **conn_ptr, CONNECTION **connList_ptr)
  18.513 +{
  18.514 +    /* FIXME: This only supports one set of connections */
  18.515 +    for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
  18.516 +        Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
  18.517 +        switch(magic) {
  18.518 +            case FOURCC_ART1:
  18.519 +            case FOURCC_ART2:
  18.520 +                Parse_art(data, chunk, conn_ptr, connList_ptr);
  18.521 +                return;
  18.522 +        }
  18.523 +    }
  18.524 +}
  18.525 +
  18.526 +static void Parse_rgn(DLS_Data *data, RIFF_Chunk *chunk, DLS_Region *region)
  18.527 +{
  18.528 +    for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
  18.529 +        Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
  18.530 +        switch(magic) {
  18.531 +            case FOURCC_RGNH:
  18.532 +                Parse_rgnh(data, chunk, region);
  18.533 +                break;
  18.534 +            case FOURCC_WLNK:
  18.535 +                Parse_wlnk(data, chunk, region);
  18.536 +                break;
  18.537 +            case FOURCC_WSMP:
  18.538 +                Parse_wsmp(data, chunk, &region->wsmp, &region->wsmp_loop);
  18.539 +                break;
  18.540 +            case FOURCC_LART:
  18.541 +            case FOURCC_LAR2:
  18.542 +                Parse_lart(data, chunk, &region->art, &region->artList);
  18.543 +                break;
  18.544 +        }
  18.545 +    }
  18.546 +}
  18.547 +
  18.548 +static void Parse_lrgn(DLS_Data *data, RIFF_Chunk *chunk, DLS_Instrument *instrument)
  18.549 +{
  18.550 +    Uint32 region = 0;
  18.551 +    for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
  18.552 +        Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
  18.553 +        switch(magic) {
  18.554 +            case FOURCC_RGN:
  18.555 +            case FOURCC_RGN2:
  18.556 +                if ( region < instrument->header->cRegions ) {
  18.557 +                    Parse_rgn(data, chunk, &instrument->regions[region++]);
  18.558 +                }
  18.559 +                break;
  18.560 +        }
  18.561 +    }
  18.562 +}
  18.563 +
  18.564 +static void Parse_INFO_INS(DLS_Data *data, RIFF_Chunk *chunk, DLS_Instrument *instrument)
  18.565 +{
  18.566 +    for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
  18.567 +        Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
  18.568 +        switch(magic) {
  18.569 +            case FOURCC_INAM: /* Name */
  18.570 +                instrument->name = (char *)chunk->data;
  18.571 +                break;
  18.572 +        }
  18.573 +    }
  18.574 +}
  18.575 +
  18.576 +static void Parse_ins(DLS_Data *data, RIFF_Chunk *chunk, DLS_Instrument *instrument)
  18.577 +{
  18.578 +    for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
  18.579 +        Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
  18.580 +        switch(magic) {
  18.581 +            case FOURCC_INSH:
  18.582 +                Parse_insh(data, chunk, instrument);
  18.583 +                break;
  18.584 +            case FOURCC_LRGN:
  18.585 +                Parse_lrgn(data, chunk, instrument);
  18.586 +                break;
  18.587 +            case FOURCC_LART:
  18.588 +            case FOURCC_LAR2:
  18.589 +                Parse_lart(data, chunk, &instrument->art, &instrument->artList);
  18.590 +                break;
  18.591 +            case FOURCC_INFO:
  18.592 +                Parse_INFO_INS(data, chunk, instrument);
  18.593 +                break;
  18.594 +        }
  18.595 +    }
  18.596 +}
  18.597 +
  18.598 +static void Parse_lins(DLS_Data *data, RIFF_Chunk *chunk)
  18.599 +{
  18.600 +    Uint32 instrument = 0;
  18.601 +    for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
  18.602 +        Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
  18.603 +        switch(magic) {
  18.604 +            case FOURCC_INS:
  18.605 +                if ( instrument < data->cInstruments ) {
  18.606 +                    Parse_ins(data, chunk, &data->instruments[instrument++]);
  18.607 +                }
  18.608 +                break;
  18.609 +        }
  18.610 +    }
  18.611 +}
  18.612 +
  18.613 +static void Parse_ptbl(DLS_Data *data, RIFF_Chunk *chunk)
  18.614 +{
  18.615 +    Uint32 i;
  18.616 +    POOLTABLE *ptbl = (POOLTABLE *)chunk->data;
  18.617 +    ptbl->cbSize = SDL_SwapLE32(ptbl->cbSize);
  18.618 +    ptbl->cCues = SDL_SwapLE32(ptbl->cCues);
  18.619 +    data->ptbl = ptbl;
  18.620 +    data->ptblList = (POOLCUE *)((Uint8 *)chunk->data + ptbl->cbSize);
  18.621 +    for ( i = 0; i < ptbl->cCues; ++i ) {
  18.622 +        data->ptblList[i].ulOffset = SDL_SwapLE32(data->ptblList[i].ulOffset);
  18.623 +    }
  18.624 +    AllocWaveList(data);
  18.625 +}
  18.626 +
  18.627 +static void Parse_fmt(DLS_Data *data, RIFF_Chunk *chunk, DLS_Wave *wave)
  18.628 +{
  18.629 +    WaveFMT *fmt = (WaveFMT *)chunk->data;
  18.630 +    fmt->wFormatTag = SDL_SwapLE16(fmt->wFormatTag);
  18.631 +    fmt->wChannels = SDL_SwapLE16(fmt->wChannels);
  18.632 +    fmt->dwSamplesPerSec = SDL_SwapLE32(fmt->dwSamplesPerSec);
  18.633 +    fmt->dwAvgBytesPerSec = SDL_SwapLE32(fmt->dwAvgBytesPerSec);
  18.634 +    fmt->wBlockAlign = SDL_SwapLE16(fmt->wBlockAlign);
  18.635 +    fmt->wBitsPerSample = SDL_SwapLE16(fmt->wBitsPerSample);
  18.636 +    wave->format = fmt;
  18.637 +}
  18.638 +
  18.639 +static void Parse_data(DLS_Data *data, RIFF_Chunk *chunk, DLS_Wave *wave)
  18.640 +{
  18.641 +    wave->data = chunk->data;
  18.642 +    wave->length = chunk->length;
  18.643 +}
  18.644 +
  18.645 +static void Parse_wave(DLS_Data *data, RIFF_Chunk *chunk, DLS_Wave *wave)
  18.646 +{
  18.647 +    for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
  18.648 +        Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
  18.649 +        switch(magic) {
  18.650 +            case FOURCC_FMT:
  18.651 +                Parse_fmt(data, chunk, wave);
  18.652 +                break;
  18.653 +            case FOURCC_DATA:
  18.654 +                Parse_data(data, chunk, wave);
  18.655 +                break;
  18.656 +            case FOURCC_WSMP:
  18.657 +                Parse_wsmp(data, chunk, &wave->wsmp, &wave->wsmp_loop);
  18.658 +                break;
  18.659 +        }
  18.660 +    }
  18.661 +}
  18.662 +
  18.663 +static void Parse_wvpl(DLS_Data *data, RIFF_Chunk *chunk)
  18.664 +{
  18.665 +    Uint32 wave = 0;
  18.666 +    for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
  18.667 +        Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
  18.668 +        switch(magic) {
  18.669 +            case FOURCC_wave:
  18.670 +                if ( wave < data->ptbl->cCues ) {
  18.671 +                    Parse_wave(data, chunk, &data->waveList[wave++]);
  18.672 +                }
  18.673 +                break;
  18.674 +        }
  18.675 +    }
  18.676 +}
  18.677 +
  18.678 +static void Parse_INFO_DLS(DLS_Data *data, RIFF_Chunk *chunk)
  18.679 +{
  18.680 +    for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
  18.681 +        Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
  18.682 +        switch(magic) {
  18.683 +            case FOURCC_IARL: /* Archival Location */
  18.684 +                break;
  18.685 +            case FOURCC_IART: /* Artist */
  18.686 +                data->artist = (char *)chunk->data;
  18.687 +                break;
  18.688 +            case FOURCC_ICMS: /* Commisioned */
  18.689 +                break;
  18.690 +            case FOURCC_ICMT: /* Comments */
  18.691 +                data->comments = (char *)chunk->data;
  18.692 +                break;
  18.693 +            case FOURCC_ICOP: /* Copyright */
  18.694 +                data->copyright = (char *)chunk->data;
  18.695 +                break;
  18.696 +            case FOURCC_ICRD: /* Creation Date */
  18.697 +                break;
  18.698 +            case FOURCC_IENG: /* Engineer */
  18.699 +                break;
  18.700 +            case FOURCC_IGNR: /* Genre */
  18.701 +                break;
  18.702 +            case FOURCC_IKEY: /* Keywords */
  18.703 +                break;
  18.704 +            case FOURCC_IMED: /* Medium */
  18.705 +                break;
  18.706 +            case FOURCC_INAM: /* Name */
  18.707 +                data->name = (char *)chunk->data;
  18.708 +                break;
  18.709 +            case FOURCC_IPRD: /* Product */
  18.710 +                break;
  18.711 +            case FOURCC_ISBJ: /* Subject */
  18.712 +                break;
  18.713 +            case FOURCC_ISFT: /* Software */
  18.714 +                break;
  18.715 +            case FOURCC_ISRC: /* Source */
  18.716 +                break;
  18.717 +            case FOURCC_ISRF: /* Source Form */
  18.718 +                break;
  18.719 +            case FOURCC_ITCH: /* Technician */
  18.720 +                break;
  18.721 +        }
  18.722 +    }
  18.723 +}
  18.724 +
  18.725 +DLS_Data *LoadDLS(SDL_RWops *src)
  18.726 +{
  18.727 +    RIFF_Chunk *chunk;
  18.728 +    DLS_Data *data = (DLS_Data *)malloc(sizeof(*data));
  18.729 +    if ( !data ) {
  18.730 +        SDL_Error(SDL_ENOMEM);
  18.731 +        return NULL;
  18.732 +    }
  18.733 +    memset(data, 0, sizeof(*data));
  18.734 +
  18.735 +    data->chunk = LoadRIFF(src);
  18.736 +    if ( !data->chunk ) {
  18.737 +        FreeDLS(data);
  18.738 +        return NULL;
  18.739 +    }
  18.740 +
  18.741 +    for ( chunk = data->chunk->child; chunk; chunk = chunk->next ) {
  18.742 +        Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
  18.743 +        switch(magic) {
  18.744 +            case FOURCC_COLH:
  18.745 +                Parse_colh(data, chunk);
  18.746 +                break;
  18.747 +            case FOURCC_LINS:
  18.748 +                Parse_lins(data, chunk);
  18.749 +                break;
  18.750 +            case FOURCC_PTBL:
  18.751 +                Parse_ptbl(data, chunk);
  18.752 +                break;
  18.753 +            case FOURCC_WVPL:
  18.754 +                Parse_wvpl(data, chunk);
  18.755 +                break;
  18.756 +            case FOURCC_INFO:
  18.757 +                Parse_INFO_DLS(data, chunk);
  18.758 +                break;
  18.759 +        }
  18.760 +    }
  18.761 +    return data;
  18.762 +}
  18.763 +
  18.764 +void FreeDLS(DLS_Data *data)
  18.765 +{
  18.766 +    if ( data->chunk ) {
  18.767 +        FreeRIFF(data->chunk);
  18.768 +    }
  18.769 +    FreeInstruments(data);
  18.770 +    FreeWaveList(data);
  18.771 +    free(data);
  18.772 +}
  18.773 +
  18.774 +static const char *SourceToString(USHORT usSource)
  18.775 +{
  18.776 +    switch(usSource) {
  18.777 +        case CONN_SRC_NONE:
  18.778 +            return "NONE";
  18.779 +        case CONN_SRC_LFO:
  18.780 +            return "LFO";
  18.781 +        case CONN_SRC_KEYONVELOCITY:
  18.782 +            return "KEYONVELOCITY";
  18.783 +        case CONN_SRC_KEYNUMBER:
  18.784 +            return "KEYNUMBER";
  18.785 +        case CONN_SRC_EG1:
  18.786 +            return "EG1";
  18.787 +        case CONN_SRC_EG2:
  18.788 +            return "EG2";
  18.789 +        case CONN_SRC_PITCHWHEEL:
  18.790 +            return "PITCHWHEEL";
  18.791 +        case CONN_SRC_CC1:
  18.792 +            return "CC1";
  18.793 +        case CONN_SRC_CC7:
  18.794 +            return "CC7";
  18.795 +        case CONN_SRC_CC10:
  18.796 +            return "CC10";
  18.797 +        case CONN_SRC_CC11:
  18.798 +            return "CC11";
  18.799 +        case CONN_SRC_POLYPRESSURE:
  18.800 +            return "POLYPRESSURE";
  18.801 +        case CONN_SRC_CHANNELPRESSURE:
  18.802 +            return "CHANNELPRESSURE";
  18.803 +        case CONN_SRC_VIBRATO:
  18.804 +            return "VIBRATO";
  18.805 +        case CONN_SRC_MONOPRESSURE:
  18.806 +            return "MONOPRESSURE";
  18.807 +        case CONN_SRC_CC91:
  18.808 +            return "CC91";
  18.809 +        case CONN_SRC_CC93:
  18.810 +            return "CC93";
  18.811 +        default:
  18.812 +            return "UNKNOWN";
  18.813 +    }
  18.814 +}
  18.815 +
  18.816 +static const char *TransformToString(USHORT usTransform)
  18.817 +{
  18.818 +    switch (usTransform) {
  18.819 +        case CONN_TRN_NONE:
  18.820 +            return "NONE";
  18.821 +        case CONN_TRN_CONCAVE:
  18.822 +            return "CONCAVE";
  18.823 +        case CONN_TRN_CONVEX:
  18.824 +            return "CONVEX";
  18.825 +        case CONN_TRN_SWITCH:
  18.826 +            return "SWITCH";
  18.827 +        default:
  18.828 +            return "UNKNOWN";
  18.829 +    }
  18.830 +}
  18.831 +
  18.832 +static const char *DestinationToString(USHORT usDestination)
  18.833 +{
  18.834 +    switch (usDestination) {
  18.835 +        case CONN_DST_NONE:
  18.836 +            return "NONE";
  18.837 +        case CONN_DST_ATTENUATION:
  18.838 +            return "ATTENUATION";
  18.839 +        case CONN_DST_PITCH:
  18.840 +            return "PITCH";
  18.841 +        case CONN_DST_PAN:
  18.842 +            return "PAN";
  18.843 +        case CONN_DST_LFO_FREQUENCY:
  18.844 +            return "LFO_FREQUENCY";
  18.845 +        case CONN_DST_LFO_STARTDELAY:
  18.846 +            return "LFO_STARTDELAY";
  18.847 +        case CONN_DST_EG1_ATTACKTIME:
  18.848 +            return "EG1_ATTACKTIME";
  18.849 +        case CONN_DST_EG1_DECAYTIME:
  18.850 +            return "EG1_DECAYTIME";
  18.851 +        case CONN_DST_EG1_RELEASETIME:
  18.852 +            return "EG1_RELEASETIME";
  18.853 +        case CONN_DST_EG1_SUSTAINLEVEL:
  18.854 +            return "EG1_SUSTAINLEVEL";
  18.855 +        case CONN_DST_EG2_ATTACKTIME:
  18.856 +            return "EG2_ATTACKTIME";
  18.857 +        case CONN_DST_EG2_DECAYTIME:
  18.858 +            return "EG2_DECAYTIME";
  18.859 +        case CONN_DST_EG2_RELEASETIME:
  18.860 +            return "EG2_RELEASETIME";
  18.861 +        case CONN_DST_EG2_SUSTAINLEVEL:
  18.862 +            return "EG2_SUSTAINLEVEL";
  18.863 +        case CONN_DST_KEYNUMBER:
  18.864 +            return "KEYNUMBER";
  18.865 +        case CONN_DST_LEFT:
  18.866 +            return "LEFT";
  18.867 +        case CONN_DST_RIGHT:
  18.868 +            return "RIGHT";
  18.869 +        case CONN_DST_CENTER:
  18.870 +            return "CENTER";
  18.871 +        case CONN_DST_LEFTREAR:
  18.872 +            return "LEFTREAR";
  18.873 +        case CONN_DST_RIGHTREAR:
  18.874 +            return "RIGHTREAR";
  18.875 +        case CONN_DST_LFE_CHANNEL:
  18.876 +            return "LFE_CHANNEL";
  18.877 +        case CONN_DST_CHORUS:
  18.878 +            return "CHORUS";
  18.879 +        case CONN_DST_REVERB:
  18.880 +            return "REVERB";
  18.881 +        case CONN_DST_VIB_FREQUENCY:
  18.882 +            return "VIB_FREQUENCY";
  18.883 +        case CONN_DST_VIB_STARTDELAY:
  18.884 +            return "VIB_STARTDELAY";
  18.885 +        case CONN_DST_EG1_DELAYTIME:
  18.886 +            return "EG1_DELAYTIME";
  18.887 +        case CONN_DST_EG1_HOLDTIME:
  18.888 +            return "EG1_HOLDTIME";
  18.889 +        case CONN_DST_EG1_SHUTDOWNTIME:
  18.890 +            return "EG1_SHUTDOWNTIME";
  18.891 +        case CONN_DST_EG2_DELAYTIME:
  18.892 +            return "EG2_DELAYTIME";
  18.893 +        case CONN_DST_EG2_HOLDTIME:
  18.894 +            return "EG2_HOLDTIME";
  18.895 +        case CONN_DST_FILTER_CUTOFF:
  18.896 +            return "FILTER_CUTOFF";
  18.897 +        case CONN_DST_FILTER_Q:
  18.898 +            return "FILTER_Q";
  18.899 +        default:
  18.900 +            return "UNKOWN";
  18.901 +    }
  18.902 +}
  18.903 +
  18.904 +static void PrintArt(const char *type, CONNECTIONLIST *art, CONNECTION *artList)
  18.905 +{
  18.906 +    Uint32 i;
  18.907 +    printf("%s Connections:\n", type);
  18.908 +    for ( i = 0; i < art->cConnections; ++i ) {
  18.909 +        printf("  Source: %s, Control: %s, Destination: %s, Transform: %s, Scale: %d\n",
  18.910 +            SourceToString(artList[i].usSource),
  18.911 +            SourceToString(artList[i].usControl),
  18.912 +            DestinationToString(artList[i].usDestination),
  18.913 +            TransformToString(artList[i].usTransform),
  18.914 +            artList[i].lScale);
  18.915 +    }
  18.916 +}
  18.917 +
  18.918 +static void PrintWave(DLS_Wave *wave, Uint32 index)
  18.919 +{
  18.920 +    WaveFMT *format = wave->format;
  18.921 +    if ( format ) {
  18.922 +        printf("  Wave %u: Format: %hu, %hu channels, %u Hz, %hu bits (length = %u)\n", index, format->wFormatTag, format->wChannels, format->dwSamplesPerSec, format->wBitsPerSample, wave->length);
  18.923 +    }
  18.924 +    if ( wave->wsmp ) {
  18.925 +        Uint32 i;
  18.926 +        printf("    wsmp->usUnityNote = %hu\n", wave->wsmp->usUnityNote);
  18.927 +        printf("    wsmp->sFineTune = %hd\n", wave->wsmp->sFineTune);
  18.928 +        printf("    wsmp->lAttenuation = %d\n", wave->wsmp->lAttenuation);
  18.929 +        printf("    wsmp->fulOptions = 0x%8.8x\n", wave->wsmp->fulOptions);
  18.930 +        printf("    wsmp->cSampleLoops = %u\n", wave->wsmp->cSampleLoops);
  18.931 +        for ( i = 0; i < wave->wsmp->cSampleLoops; ++i ) {
  18.932 +            WLOOP *loop = &wave->wsmp_loop[i];
  18.933 +            printf("    Loop %u:\n", i);
  18.934 +            printf("      ulStart = %u\n", loop->ulStart);
  18.935 +            printf("      ulLength = %u\n", loop->ulLength);
  18.936 +        }
  18.937 +    }
  18.938 +}
  18.939 +
  18.940 +static void PrintRegion(DLS_Region *region, Uint32 index)
  18.941 +{
  18.942 +    printf("  Region %u:\n", index);
  18.943 +    if ( region->header ) {
  18.944 +        printf("    RangeKey = { %hu - %hu }\n", region->header->RangeKey.usLow, region->header->RangeKey.usHigh);
  18.945 +        printf("    RangeVelocity = { %hu - %hu }\n", region->header->RangeVelocity.usLow, region->header->RangeVelocity.usHigh);
  18.946 +        printf("    fusOptions = 0x%4.4hx\n", region->header->fusOptions);
  18.947 +        printf("    usKeyGroup = %hu\n", region->header->usKeyGroup);
  18.948 +    }
  18.949 +    if ( region->wlnk ) {
  18.950 +        printf("    wlnk->fusOptions = 0x%4.4hx\n", region->wlnk->fusOptions);
  18.951 +        printf("    wlnk->usPhaseGroup = %hu\n", region->wlnk->usPhaseGroup);
  18.952 +        printf("    wlnk->ulChannel = %u\n", region->wlnk->ulChannel);
  18.953 +        printf("    wlnk->ulTableIndex = %u\n", region->wlnk->ulTableIndex);
  18.954 +    }
  18.955 +    if ( region->wsmp ) {
  18.956 +        Uint32 i;
  18.957 +        printf("    wsmp->usUnityNote = %hu\n", region->wsmp->usUnityNote);
  18.958 +        printf("    wsmp->sFineTune = %hd\n", region->wsmp->sFineTune);
  18.959 +        printf("    wsmp->lAttenuation = %d\n", region->wsmp->lAttenuation);
  18.960 +        printf("    wsmp->fulOptions = 0x%8.8x\n", region->wsmp->fulOptions);
  18.961 +        printf("    wsmp->cSampleLoops = %u\n", region->wsmp->cSampleLoops);
  18.962 +        for ( i = 0; i < region->wsmp->cSampleLoops; ++i ) {
  18.963 +            WLOOP *loop = &region->wsmp_loop[i];
  18.964 +            printf("    Loop %u:\n", i);
  18.965 +            printf("      ulStart = %u\n", loop->ulStart);
  18.966 +            printf("      ulLength = %u\n", loop->ulLength);
  18.967 +        }
  18.968 +    }
  18.969 +    if ( region->art && region->art->cConnections > 0 ) {
  18.970 +        PrintArt("Region", region->art, region->artList);
  18.971 +    }
  18.972 +}
  18.973 +
  18.974 +static void PrintInstrument(DLS_Instrument *instrument, Uint32 index)
  18.975 +{
  18.976 +    printf("Instrument %u:\n", index);
  18.977 +    if ( instrument->name ) {
  18.978 +        printf("  Name: %s\n", instrument->name);
  18.979 +    }
  18.980 +    if ( instrument->header ) {
  18.981 +        Uint32 i;
  18.982 +        printf("  ulBank = 0x%8.8x\n", instrument->header->Locale.ulBank);
  18.983 +        printf("  ulInstrument = %u\n", instrument->header->Locale.ulInstrument);
  18.984 +        printf("  Regions: %u\n", instrument->header->cRegions);
  18.985 +        for ( i = 0; i < instrument->header->cRegions; ++i ) {
  18.986 +            PrintRegion(&instrument->regions[i], i);
  18.987 +        }
  18.988 +    }
  18.989 +    if ( instrument->art && instrument->art->cConnections > 0 ) {
  18.990 +        PrintArt("Instrument", instrument->art, instrument->artList);
  18.991 +    }
  18.992 +};
  18.993 +
  18.994 +void PrintDLS(DLS_Data *data)
  18.995 +{
  18.996 +    printf("DLS Data:\n");
  18.997 +    printf("cInstruments = %u\n", data->cInstruments); 
  18.998 +    if ( data->instruments ) {
  18.999 +        Uint32 i;
 18.1000 +        for ( i = 0; i < data->cInstruments; ++i ) {
 18.1001 +            PrintInstrument(&data->instruments[i], i);
 18.1002 +        }
 18.1003 +    }
 18.1004 +    if ( data->ptbl && data->ptbl->cCues > 0 ) {
 18.1005 +        Uint32 i;
 18.1006 +        printf("Cues: ");
 18.1007 +        for ( i = 0; i < data->ptbl->cCues; ++i ) {
 18.1008 +            if ( i > 0 ) {
 18.1009 +                printf(", ");
 18.1010 +            }
 18.1011 +            printf("%u", data->ptblList[i].ulOffset);
 18.1012 +        }
 18.1013 +        printf("\n");
 18.1014 +    }
 18.1015 +    if ( data->waveList ) {
 18.1016 +        Uint32 i;
 18.1017 +        printf("Waves:\n");
 18.1018 +        for ( i = 0; i < data->ptbl->cCues; ++i ) {
 18.1019 +            PrintWave(&data->waveList[i], i);
 18.1020 +        }
 18.1021 +    }
 18.1022 +    if ( data->name ) {
 18.1023 +        printf("Name: %s\n", data->name);
 18.1024 +    }
 18.1025 +    if ( data->artist ) {
 18.1026 +        printf("Artist: %s\n", data->artist);
 18.1027 +    }
 18.1028 +    if ( data->copyright ) {
 18.1029 +        printf("Copyright: %s\n", data->copyright);
 18.1030 +    }
 18.1031 +    if ( data->comments ) {
 18.1032 +        printf("Comments: %s\n", data->comments);
 18.1033 +    }
 18.1034 +}
 18.1035 +
 18.1036 +#ifdef TEST_MAIN_DLS
 18.1037 +
 18.1038 +main(int argc, char *argv[])
 18.1039 +{
 18.1040 +    int i;
 18.1041 +    for ( i = 1; i < argc; ++i ) {
 18.1042 +        DLS_Data *data;
 18.1043 +        SDL_RWops *src = SDL_RWFromFile(argv[i], "rb");
 18.1044 +        if ( !src ) {
 18.1045 +            fprintf(stderr, "Couldn't open %s: %s", argv[i], SDL_GetError());
 18.1046 +            continue;
 18.1047 +        }
 18.1048 +        data = LoadDLS(src);
 18.1049 +        if ( data ) {
 18.1050 +            PrintRIFF(data->chunk, 0);
 18.1051 +            PrintDLS(data);
 18.1052 +            FreeDLS(data);
 18.1053 +        } else {
 18.1054 +            fprintf(stderr, "Couldn't load %s: %s\n", argv[i], SDL_GetError());
 18.1055 +        }
 18.1056 +        SDL_RWclose(src);
 18.1057 +    }
 18.1058 +}
 18.1059 +
 18.1060 +#endif // TEST_MAIN
 18.1061 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 18.1062 +
 18.1063 +/*-------------------------------------------------------------------------*/
 18.1064 +/* * * * * * * * * * * * * * * * * instrum_dls.c * * * * * * * * * * * * * */
 18.1065 +/*-------------------------------------------------------------------------*/
 18.1066 +
 18.1067 +DLS_Data *Timidity_LoadDLS(SDL_RWops *src)
 18.1068 +{
 18.1069 +  DLS_Data *patches = LoadDLS(src);
 18.1070 +  if (!patches) {
 18.1071 +    SNDDBG(("%s", SDL_GetError()));
 18.1072 +  }
 18.1073 +  return patches;
 18.1074 +}
 18.1075 +
 18.1076 +void Timidity_FreeDLS(DLS_Data *patches)
 18.1077 +{
 18.1078 +  FreeDLS(patches);
 18.1079 +}
 18.1080 +
 18.1081 +/* convert timecents to sec */
 18.1082 +static double to_msec(int timecent)
 18.1083 +{
 18.1084 +  if (timecent == 0x80000000 || timecent == 0)
 18.1085 +    return 0.0;
 18.1086 +  return 1000.0 * pow(2.0, (double)(timecent / 65536) / 1200.0);
 18.1087 +}
 18.1088 +
 18.1089 +/* convert decipercent to {0..1} */
 18.1090 +static double to_normalized_percent(int decipercent)
 18.1091 +{
 18.1092 +  return ((double)(decipercent / 65536)) / 1000.0;
 18.1093 +}
 18.1094 +
 18.1095 +/* convert from 8bit value to fractional offset (15.15) */
 18.1096 +static Sint32 to_offset(int offset)
 18.1097 +{
 18.1098 +	return (Sint32)offset << (7+15);
 18.1099 +}
 18.1100 +
 18.1101 +/* calculate ramp rate in fractional unit;
 18.1102 + * diff = 8bit, time = msec
 18.1103 + */
 18.1104 +static Sint32 calc_rate(MidiSong *song, int diff, int sample_rate, double msec)
 18.1105 +{
 18.1106 +    double rate;
 18.1107 +
 18.1108 +    if(msec < 6)
 18.1109 +      msec = 6;
 18.1110 +    if(diff == 0)
 18.1111 +      diff = 255;
 18.1112 +    diff <<= (7+15);
 18.1113 +    rate = ((double)diff / song->rate) * song->control_ratio * 1000.0 / msec;
 18.1114 +    return (Sint32)rate;
 18.1115 +}
 18.1116 +
 18.1117 +static int load_connection(ULONG cConnections, CONNECTION *artList, USHORT destination)
 18.1118 +{
 18.1119 +  ULONG i;
 18.1120 +  int value = 0;
 18.1121 +  for (i = 0; i < cConnections; ++i) {
 18.1122 +    CONNECTION *conn = &artList[i];
 18.1123 +    if(conn->usDestination == destination) {
 18.1124 +      // The formula for the destination is:
 18.1125 +      // usDestination = usDestination + usTransform(usSource * (usControl * lScale))
 18.1126 +      // Since we are only handling source/control of NONE and identity
 18.1127 +      // transform, this simplifies to: usDestination = usDestination + lScale
 18.1128 +      if (conn->usSource == CONN_SRC_NONE &&
 18.1129 +          conn->usControl == CONN_SRC_NONE &&
 18.1130 +          conn->usTransform == CONN_TRN_NONE)
 18.1131 +        value += conn->lScale;
 18.1132 +    }
 18.1133 +  }
 18.1134 +  return value;
 18.1135 +}
 18.1136 +
 18.1137 +static void load_region_dls(MidiSong *song, Sample *sample, DLS_Instrument *ins, Uint32 index)
 18.1138 +{
 18.1139 +  DLS_Region *rgn = &ins->regions[index];
 18.1140 +  DLS_Wave *wave = &song->patches->waveList[rgn->wlnk->ulTableIndex];
 18.1141 +
 18.1142 +  sample->low_freq = freq_table[rgn->header->RangeKey.usLow];
 18.1143 +  sample->high_freq = freq_table[rgn->header->RangeKey.usHigh];
 18.1144 +  sample->root_freq = freq_table[rgn->wsmp->usUnityNote];
 18.1145 +  sample->low_vel = rgn->header->RangeVelocity.usLow;
 18.1146 +  sample->high_vel = rgn->header->RangeVelocity.usHigh;
 18.1147 +
 18.1148 +  sample->modes = MODES_16BIT;
 18.1149 +  sample->sample_rate = wave->format->dwSamplesPerSec;
 18.1150 +  sample->data_length = wave->length / 2;
 18.1151 +  sample->data = (sample_t *)safe_malloc(wave->length);
 18.1152 +  memcpy(sample->data, wave->data, wave->length);
 18.1153 +  if (rgn->wsmp->cSampleLoops) {
 18.1154 +    sample->modes |= (MODES_LOOPING|MODES_SUSTAIN);
 18.1155 +    sample->loop_start = rgn->wsmp_loop->ulStart / 2;
 18.1156 +    sample->loop_end = sample->loop_start + (rgn->wsmp_loop->ulLength / 2);
 18.1157 +  }
 18.1158 +  sample->volume = 1.0f;
 18.1159 +
 18.1160 +  if (sample->modes & MODES_SUSTAIN) {
 18.1161 +    int value;
 18.1162 +    double attack, hold, decay, release; int sustain;
 18.1163 +    CONNECTIONLIST *art = NULL;
 18.1164 +    CONNECTION *artList = NULL;
 18.1165 +
 18.1166 +    if (ins->art && ins->art->cConnections > 0 && ins->artList) {
 18.1167 +      art = ins->art;
 18.1168 +      artList = ins->artList;
 18.1169 +    } else {
 18.1170 +      art = rgn->art;
 18.1171 +      artList = rgn->artList;
 18.1172 +    }
 18.1173 +
 18.1174 +    value = load_connection(art->cConnections, artList, CONN_DST_EG1_ATTACKTIME);
 18.1175 +    attack = to_msec(value);
 18.1176 +    value = load_connection(art->cConnections, artList, CONN_DST_EG1_HOLDTIME);
 18.1177 +    hold = to_msec(value);
 18.1178 +    value = load_connection(art->cConnections, artList, CONN_DST_EG1_DECAYTIME);
 18.1179 +    decay = to_msec(value);
 18.1180 +    value = load_connection(art->cConnections, artList, CONN_DST_EG1_RELEASETIME);
 18.1181 +    release = to_msec(value);
 18.1182 +    value = load_connection(art->cConnections, artList, CONN_DST_EG1_SUSTAINLEVEL);
 18.1183 +    sustain = (int)((1.0 - to_normalized_percent(value)) * 250.0);
 18.1184 +    value = load_connection(art->cConnections, artList, CONN_DST_PAN);
 18.1185 +    sample->panning = (int)((0.5 + to_normalized_percent(value)) * 127.0);
 18.1186 +
 18.1187 +/*
 18.1188 +printf("%d, Rate=%d LV=%d HV=%d Low=%d Hi=%d Root=%d Pan=%d Attack=%f Hold=%f Sustain=%d Decay=%f Release=%f\n", index, sample->sample_rate, rgn->header->RangeVelocity.usLow, rgn->header->RangeVelocity.usHigh, sample->low_freq, sample->high_freq, sample->root_freq, sample->panning, attack, hold, sustain, decay, release);
 18.1189 +*/
 18.1190 +
 18.1191 +    sample->envelope_offset[0] = to_offset(255);
 18.1192 +    sample->envelope_rate[0] = calc_rate(song, 255, sample->sample_rate, attack);
 18.1193 +
 18.1194 +    sample->envelope_offset[1] = to_offset(250);
 18.1195 +    sample->envelope_rate[1] = calc_rate(song, 5, sample->sample_rate, hold);
 18.1196 +
 18.1197 +    sample->envelope_offset[2] = to_offset(sustain);
 18.1198 +    sample->envelope_rate[2] = calc_rate(song, 255 - sustain, sample->sample_rate, decay);
 18.1199 +
 18.1200 +    sample->envelope_offset[3] = to_offset(0);
 18.1201 +    sample->envelope_rate[3] = calc_rate(song, 5 + sustain, sample->sample_rate, release);
 18.1202 +
 18.1203 +    sample->envelope_offset[4] = to_offset(0);
 18.1204 +    sample->envelope_rate[4] = to_offset(1);
 18.1205 +
 18.1206 +    sample->envelope_offset[5] = to_offset(0);
 18.1207 +    sample->envelope_rate[5] = to_offset(1);
 18.1208 +
 18.1209 +    sample->modes |= MODES_ENVELOPE;
 18.1210 +  }
 18.1211 +
 18.1212 +  sample->data_length <<= FRACTION_BITS;
 18.1213 +  sample->loop_start <<= FRACTION_BITS;
 18.1214 +  sample->loop_end <<= FRACTION_BITS;
 18.1215 +}
 18.1216 +
 18.1217 +Instrument *load_instrument_dls(MidiSong *song, int drum, int bank, int instrument)
 18.1218 +{
 18.1219 +  Instrument *inst;
 18.1220 +  Uint32 i;
 18.1221 +  DLS_Instrument *dls_ins;
 18.1222 +
 18.1223 +  if (!song->patches)
 18.1224 +   return(NULL);
 18.1225 +
 18.1226 +  drum = drum ? 0x80000000 : 0;
 18.1227 +  for (i = 0; i < song->patches->cInstruments; ++i) {
 18.1228 +    dls_ins = &song->patches->instruments[i];
 18.1229 +    if ((dls_ins->header->Locale.ulBank & 0x80000000) == drum &&
 18.1230 +        ((dls_ins->header->Locale.ulBank >> 8) & 0xFF) == bank &&
 18.1231 +        dls_ins->header->Locale.ulInstrument == instrument)
 18.1232 +      break;
 18.1233 +  }
 18.1234 +  if (i == song->patches->cInstruments && !bank) {
 18.1235 +    for (i = 0; i < song->patches->cInstruments; ++i) {
 18.1236 +      dls_ins = &song->patches->instruments[i];
 18.1237 +      if ((dls_ins->header->Locale.ulBank & 0x80000000) == drum &&
 18.1238 +          dls_ins->header->Locale.ulInstrument == instrument)
 18.1239 +        break;
 18.1240 +    }
 18.1241 +  }
 18.1242 +  if (i == song->patches->cInstruments) {
 18.1243 +    SNDDBG(("Couldn't find %s instrument %d in bank %d\n", drum ? "drum" : "melodic", instrument, bank));
 18.1244 +    return(NULL);
 18.1245 +  }
 18.1246 +
 18.1247 +  inst = (Instrument *)safe_malloc(sizeof(*inst));
 18.1248 +  inst->samples = dls_ins->header->cRegions;
 18.1249 +  inst->sample = (Sample *)safe_malloc(inst->samples * sizeof(*inst->sample));
 18.1250 +  memset(inst->sample, 0, inst->samples * sizeof(*inst->sample));
 18.1251 +/*
 18.1252 +printf("Found %s instrument %d in bank %d named %s with %d regions\n", drum ? "drum" : "melodic", instrument, bank, dls_ins->name, inst->samples);
 18.1253 +*/
 18.1254 +  for (i = 0; i < dls_ins->header->cRegions; ++i) {
 18.1255 +    load_region_dls(song, &inst->sample[i], dls_ins, i);
 18.1256 +  }
 18.1257 +  return(inst);
 18.1258 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/timidity/instrum_dls.h	Tue Oct 17 21:54:04 2017 -0700
    19.3 @@ -0,0 +1,13 @@
    19.4 +/*
    19.5 +
    19.6 +    TiMidity -- Experimental MIDI to WAVE converter
    19.7 +    Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
    19.8 +
    19.9 +    This program is free software; you can redistribute it and/or modify
   19.10 +    it under the terms of the Perl Artistic License, available in COPYING.
   19.11 +
   19.12 +   instrum.h
   19.13 +
   19.14 +   */
   19.15 +
   19.16 +extern Instrument *load_instrument_dls(MidiSong *song, int drum, int bank, int instrument);
    20.1 --- a/timidity/mix.c	Tue Oct 17 16:55:58 2017 -0700
    20.2 +++ b/timidity/mix.c	Tue Oct 17 21:54:04 2017 -0700
    20.3 @@ -1,177 +1,157 @@
    20.4  /*
    20.5 +
    20.6      TiMidity -- Experimental MIDI to WAVE converter
    20.7      Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
    20.8  
    20.9      This program is free software; you can redistribute it and/or modify
   20.10      it under the terms of the Perl Artistic License, available in COPYING.
   20.11 - */
   20.12 +
   20.13 +    mix.c */
   20.14 +
   20.15 +#if HAVE_CONFIG_H
   20.16 +#  include <config.h>
   20.17 +#endif
   20.18  
   20.19  #include <math.h>
   20.20  #include <stdio.h>
   20.21  #include <stdlib.h>
   20.22  
   20.23 -#include "config.h"
   20.24 -#include "common.h"
   20.25 +#include "SDL.h"
   20.26 +
   20.27 +#include "timidity.h"
   20.28 +#include "options.h"
   20.29  #include "instrum.h"
   20.30  #include "playmidi.h"
   20.31  #include "output.h"
   20.32 -#include "ctrlmode.h"
   20.33  #include "tables.h"
   20.34  #include "resample.h"
   20.35  #include "mix.h"
   20.36  
   20.37  /* Returns 1 if envelope runs out */
   20.38 -int recompute_envelope(int v)
   20.39 +int recompute_envelope(MidiSong *song, int v)
   20.40  {
   20.41    int stage;
   20.42  
   20.43 -  stage = voice[v].envelope_stage;
   20.44 +  stage = song->voice[v].envelope_stage;
   20.45  
   20.46    if (stage>5)
   20.47      {
   20.48        /* Envelope ran out. */
   20.49 -      int tmp=(voice[v].status == VOICE_DIE); /* Already displayed as dead */
   20.50 -      voice[v].status = VOICE_FREE;
   20.51 -      if(!tmp)
   20.52 -	ctl->note(v);
   20.53 +      song->voice[v].status = VOICE_FREE;
   20.54        return 1;
   20.55      }
   20.56  
   20.57 -  if (voice[v].sample->modes & MODES_ENVELOPE)
   20.58 +  if (song->voice[v].sample->modes & MODES_ENVELOPE)
   20.59      {
   20.60 -      if (voice[v].status==VOICE_ON || voice[v].status==VOICE_SUSTAINED)
   20.61 +      if (song->voice[v].status==VOICE_ON || song->voice[v].status==VOICE_SUSTAINED)
   20.62  	{
   20.63  	  if (stage>2)
   20.64  	    {
   20.65  	      /* Freeze envelope until note turns off. Trumpets want this. */
   20.66 -	      voice[v].envelope_increment=0;
   20.67 +	      song->voice[v].envelope_increment=0;
   20.68  	      return 0;
   20.69  	    }
   20.70  	}
   20.71      }
   20.72 -  voice[v].envelope_stage=stage+1;
   20.73 +  song->voice[v].envelope_stage=stage+1;
   20.74  
   20.75 -  if (voice[v].envelope_volume==voice[v].sample->envelope_offset[stage])
   20.76 -    return recompute_envelope(v);
   20.77 -  voice[v].envelope_target=voice[v].sample->envelope_offset[stage];
   20.78 -  voice[v].envelope_increment = voice[v].sample->envelope_rate[stage];
   20.79 -  if (voice[v].envelope_target<voice[v].envelope_volume)
   20.80 -    voice[v].envelope_increment = -voice[v].envelope_increment;
   20.81 +  if (song->voice[v].envelope_volume==song->voice[v].sample->envelope_offset[stage])
   20.82 +    return recompute_envelope(song, v);
   20.83 +  song->voice[v].envelope_target = song->voice[v].sample->envelope_offset[stage];
   20.84 +  song->voice[v].envelope_increment = song->voice[v].sample->envelope_rate[stage];
   20.85 +  if (song->voice[v].envelope_target < song->voice[v].envelope_volume)
   20.86 +    song->voice[v].envelope_increment = -song->voice[v].envelope_increment;
   20.87    return 0;
   20.88  }
   20.89  
   20.90 -void apply_envelope_to_amp(int v)
   20.91 +void apply_envelope_to_amp(MidiSong *song, int v)
   20.92  {
   20.93 -  FLOAT_T lamp=voice[v].left_amp, ramp, lramp, rramp, ceamp, lfeamp;
   20.94 -  int32 la,ra, lra, rra, cea, lfea;
   20.95 -  if (voice[v].panned == PANNED_MYSTERY)
   20.96 +  float lamp = song->voice[v].left_amp, ramp;
   20.97 +  Sint32 la,ra;
   20.98 +  if (song->voice[v].panned == PANNED_MYSTERY)
   20.99      {
  20.100 -      lramp=voice[v].lr_amp;
  20.101 -      ramp=voice[v].right_amp;
  20.102 -      ceamp=voice[v].ce_amp;
  20.103 -      rramp=voice[v].rr_amp;
  20.104 -      lfeamp=voice[v].lfe_amp;
  20.105 -
  20.106 -      if (voice[v].tremolo_phase_increment)
  20.107 +      ramp = song->voice[v].right_amp;
  20.108 +      if (song->voice[v].tremolo_phase_increment)
  20.109  	{
  20.110 -	  FLOAT_T tv = voice[v].tremolo_volume;
  20.111 -	  lramp *= tv;
  20.112 -	  lamp *= tv;
  20.113 -	  ceamp *= tv;
  20.114 -	  ramp *= tv;
  20.115 -	  rramp *= tv;
  20.116 -	  lfeamp *= tv;
  20.117 +	  lamp *= song->voice[v].tremolo_volume;
  20.118 +	  ramp *= song->voice[v].tremolo_volume;
  20.119  	}
  20.120 -      if (voice[v].sample->modes & MODES_ENVELOPE)
  20.121 +      if (song->voice[v].sample->modes & MODES_ENVELOPE)
  20.122  	{
  20.123 -	  FLOAT_T ev = (FLOAT_T)vol_table[voice[v].envelope_volume>>23];
  20.124 -	  lramp *= ev;
  20.125 -	  lamp *= ev;
  20.126 -	  ceamp *= ev;
  20.127 -	  ramp *= ev;
  20.128 -	  rramp *= ev;
  20.129 -	  lfeamp *= ev;
  20.130 +	  lamp *= (float)vol_table[song->voice[v].envelope_volume>>23];
  20.131 +	  ramp *= (float)vol_table[song->voice[v].envelope_volume>>23];
  20.132  	}
  20.133  
  20.134 -      la = (int32)FSCALE(lamp,AMP_BITS);
  20.135 -      ra = (int32)FSCALE(ramp,AMP_BITS);
  20.136 -      lra = (int32)FSCALE(lramp,AMP_BITS);
  20.137 -      rra = (int32)FSCALE(rramp,AMP_BITS);
  20.138 -      cea = (int32)FSCALE(ceamp,AMP_BITS);
  20.139 -      lfea = (int32)FSCALE(lfeamp,AMP_BITS);
  20.140 +      la = (Sint32)FSCALE(lamp,AMP_BITS);
  20.141        
  20.142 -      if (la>MAX_AMP_VALUE) la=MAX_AMP_VALUE;
  20.143 -      if (ra>MAX_AMP_VALUE) ra=MAX_AMP_VALUE;
  20.144 -      if (lra>MAX_AMP_VALUE) lra=MAX_AMP_VALUE;
  20.145 -      if (rra>MAX_AMP_VALUE) rra=MAX_AMP_VALUE;
  20.146 -      if (cea>MAX_AMP_VALUE) cea=MAX_AMP_VALUE;
  20.147 -      if (lfea>MAX_AMP_VALUE) lfea=MAX_AMP_VALUE;
  20.148 +      if (la>MAX_AMP_VALUE)
  20.149 +	la=MAX_AMP_VALUE;
  20.150  
  20.151 -      voice[v].lr_mix=FINAL_VOLUME(lra);
  20.152 -      voice[v].left_mix=FINAL_VOLUME(la);
  20.153 -      voice[v].ce_mix=FINAL_VOLUME(cea);
  20.154 -      voice[v].right_mix=FINAL_VOLUME(ra);
  20.155 -      voice[v].rr_mix=FINAL_VOLUME(rra);
  20.156 -      voice[v].lfe_mix=FINAL_VOLUME(lfea);
  20.157 +      ra = (Sint32)FSCALE(ramp,AMP_BITS);
  20.158 +      if (ra>MAX_AMP_VALUE)
  20.159 +	ra=MAX_AMP_VALUE;
  20.160 +      
  20.161 +      song->voice[v].left_mix = la;
  20.162 +      song->voice[v].right_mix = ra;
  20.163      }
  20.164    else
  20.165      {
  20.166 -      if (voice[v].tremolo_phase_increment)
  20.167 -	lamp *= voice[v].tremolo_volume;
  20.168 -      if (voice[v].sample->modes & MODES_ENVELOPE)
  20.169 -	lamp *= (FLOAT_T)vol_table[voice[v].envelope_volume>>23];
  20.170 +      if (song->voice[v].tremolo_phase_increment)
  20.171 +	lamp *= song->voice[v].tremolo_volume;
  20.172 +      if (song->voice[v].sample->modes & MODES_ENVELOPE)
  20.173 +	lamp *= (float)vol_table[song->voice[v].envelope_volume>>23];
  20.174  
  20.175 -      la = (int32)FSCALE(lamp,AMP_BITS);
  20.176 +      la = (Sint32)FSCALE(lamp,AMP_BITS);
  20.177  
  20.178        if (la>MAX_AMP_VALUE)
  20.179  	la=MAX_AMP_VALUE;
  20.180  
  20.181 -      voice[v].left_mix=FINAL_VOLUME(la);
  20.182 +      song->voice[v].left_mix = la;
  20.183      }
  20.184  }
  20.185  
  20.186 -static int update_envelope(int v)
  20.187 +static int update_envelope(MidiSong *song, int v)
  20.188  {
  20.189 -  voice[v].envelope_volume += voice[v].envelope_increment;
  20.190 +  song->voice[v].envelope_volume += song->voice[v].envelope_increment;
  20.191    /* Why is there no ^^ operator?? */
  20.192 -  if (((voice[v].envelope_increment < 0) &&
  20.193 -       (voice[v].envelope_volume <= voice[v].envelope_target)) ||
  20.194 -      ((voice[v].envelope_increment > 0) &&
  20.195 -	   (voice[v].envelope_volume >= voice[v].envelope_target)))
  20.196 +  if (((song->voice[v].envelope_increment < 0) &&
  20.197 +       (song->voice[v].envelope_volume <= song->voice[v].envelope_target)) ||
  20.198 +      ((song->voice[v].envelope_increment > 0) &&
  20.199 +	   (song->voice[v].envelope_volume >= song->voice[v].envelope_target)))
  20.200      {
  20.201 -      voice[v].envelope_volume = voice[v].envelope_target;
  20.202 -      if (recompute_envelope(v))
  20.203 +      song->voice[v].envelope_volume = song->voice[v].envelope_target;
  20.204 +      if (recompute_envelope(song, v))
  20.205  	return 1;
  20.206      }
  20.207    return 0;
  20.208  }
  20.209  
  20.210 -static void update_tremolo(int v)
  20.211 +static void update_tremolo(MidiSong *song, int v)
  20.212  {
  20.213 -  int32 depth=voice[v].sample->tremolo_depth<<7;
  20.214 +  Sint32 depth = song->voice[v].sample->tremolo_depth << 7;
  20.215  
  20.216 -  if (voice[v].tremolo_sweep)
  20.217 +  if (song->voice[v].tremolo_sweep)
  20.218      {
  20.219        /* Update sweep position */
  20.220  
  20.221 -      voice[v].tremolo_sweep_position += voice[v].tremolo_sweep;
  20.222 -      if (voice[v].tremolo_sweep_position>=(1<<SWEEP_SHIFT))
  20.223 -	voice[v].tremolo_sweep=0; /* Swept to max amplitude */
  20.224 +      song->voice[v].tremolo_sweep_position += song->voice[v].tremolo_sweep;
  20.225 +      if (song->voice[v].tremolo_sweep_position >= (1 << SWEEP_SHIFT))
  20.226 +	song->voice[v].tremolo_sweep=0; /* Swept to max amplitude */
  20.227        else
  20.228  	{
  20.229  	  /* Need to adjust depth */
  20.230 -	  depth *= voice[v].tremolo_sweep_position;
  20.231 +	  depth *= song->voice[v].tremolo_sweep_position;
  20.232  	  depth >>= SWEEP_SHIFT;
  20.233  	}
  20.234      }
  20.235  
  20.236 -  voice[v].tremolo_phase += voice[v].tremolo_phase_increment;
  20.237 +  song->voice[v].tremolo_phase += song->voice[v].tremolo_phase_increment;
  20.238  
  20.239 -  /* if (voice[v].tremolo_phase >= (SINE_CYCLE_LENGTH<<RATE_SHIFT))
  20.240 -     voice[v].tremolo_phase -= SINE_CYCLE_LENGTH<<RATE_SHIFT;  */
  20.241 +  /* if (song->voice[v].tremolo_phase >= (SINE_CYCLE_LENGTH<<RATE_SHIFT))
  20.242 +     song->voice[v].tremolo_phase -= SINE_CYCLE_LENGTH<<RATE_SHIFT;  */
  20.243  
  20.244 -  voice[v].tremolo_volume = (FLOAT_T) 
  20.245 -    (1.0 - FSCALENEG((sine(voice[v].tremolo_phase >> RATE_SHIFT) + 1.0)
  20.246 +  song->voice[v].tremolo_volume = (float) 
  20.247 +    (1.0 - FSCALENEG((sine(song->voice[v].tremolo_phase >> RATE_SHIFT) + 1.0)
  20.248  		    * depth * TREMOLO_AMPLITUDE_TUNING,
  20.249  		    17));
  20.250  
  20.251 @@ -180,54 +160,37 @@
  20.252  }
  20.253  
  20.254  /* Returns 1 if the note died */
  20.255 -static int update_signal(int v)
  20.256 +static int update_signal(MidiSong *song, int v)
  20.257  {
  20.258 -  if (voice[v].envelope_increment && update_envelope(v))
  20.259 +  if (song->voice[v].envelope_increment && update_envelope(song, v))
  20.260      return 1;
  20.261  
  20.262 -  if (voice[v].tremolo_phase_increment)
  20.263 -    update_tremolo(v);
  20.264 +  if (song->voice[v].tremolo_phase_increment)
  20.265 +    update_tremolo(song, v);
  20.266  
  20.267 -  apply_envelope_to_amp(v);
  20.268 +  apply_envelope_to_amp(song, v);
  20.269    return 0;
  20.270  }
  20.271  
  20.272 -#ifdef LOOKUP_HACK
  20.273 -#  define MIXATION(a)	*lp++ += mixup[(a<<8) | (uint8)s];
  20.274 -#else
  20.275 -#  define MIXATION(a)	*lp++ += (a)*s;
  20.276 -#endif
  20.277 +#define MIXATION(a)	*lp++ += (a)*s;
  20.278  
  20.279 -#define MIXSKIP lp++
  20.280 -#define MIXMAX(a,b) *lp++ += ((a>b)?a:b) * s
  20.281 -#define MIXCENT(a,b) *lp++ += (a/2+b/2) * s
  20.282 -#define MIXHALF(a)	*lp++ += (a>>1)*s;
  20.283 -
  20.284 -static void mix_mystery_signal(resample_t *sp, int32 *lp, int v, int count)
  20.285 +static void mix_mystery_signal(MidiSong *song, sample_t *sp, Sint32 *lp, int v,
  20.286 +			       int count)
  20.287  {
  20.288 -  Voice *vp = voice + v;
  20.289 +  Voice *vp = song->voice + v;
  20.290    final_volume_t 
  20.291 -    left_rear=vp->lr_mix, 
  20.292      left=vp->left_mix, 
  20.293 -    center=vp->ce_mix, 
  20.294 -    right=vp->right_mix, 
  20.295 -    right_rear=vp->rr_mix, 
  20.296 -    lfe=vp->lfe_mix;
  20.297 +    right=vp->right_mix;
  20.298    int cc;
  20.299 -  resample_t s;
  20.300 +  sample_t s;
  20.301  
  20.302    if (!(cc = vp->control_counter))
  20.303      {
  20.304 -      cc = control_ratio;
  20.305 -      if (update_signal(v))
  20.306 +      cc = song->control_ratio;
  20.307 +      if (update_signal(song, v))
  20.308  	return;	/* Envelope ran out */
  20.309 -
  20.310 -	left_rear = vp->lr_mix;
  20.311 -	left = vp->left_mix;
  20.312 -	center = vp->ce_mix;
  20.313 -	right = vp->right_mix;
  20.314 -	right_rear = vp->rr_mix;
  20.315 -	lfe = vp->lfe_mix;
  20.316 +      left = vp->left_mix;
  20.317 +      right = vp->right_mix;
  20.318      }
  20.319    
  20.320    while (count)
  20.321 @@ -237,26 +200,14 @@
  20.322  	while (cc--)
  20.323  	  {
  20.324  	    s = *sp++;
  20.325 -	      	MIXATION(left);
  20.326 -	      	MIXATION(right);
  20.327 -		if (num_ochannels >= 4) {
  20.328 -			MIXATION(left_rear);
  20.329 -			MIXATION(right_rear);
  20.330 -		}
  20.331 -		if (num_ochannels == 6) {
  20.332 -			MIXATION(center);
  20.333 -			MIXATION(lfe);
  20.334 -		}
  20.335 +	    MIXATION(left);
  20.336 +	    MIXATION(right);
  20.337  	  }
  20.338 -	cc = control_ratio;
  20.339 -	if (update_signal(v))
  20.340 +	cc = song->control_ratio;
  20.341 +	if (update_signal(song, v))
  20.342  	  return;	/* Envelope ran out */
  20.343 -	left_rear = vp->lr_mix;
  20.344  	left = vp->left_mix;
  20.345 -	center = vp->ce_mix;
  20.346  	right = vp->right_mix;
  20.347 -	right_rear = vp->rr_mix;
  20.348 -	lfe = vp->lfe_mix;
  20.349        }
  20.350      else
  20.351        {
  20.352 @@ -264,33 +215,26 @@
  20.353  	while (count--)
  20.354  	  {
  20.355  	    s = *sp++;
  20.356 -	      	MIXATION(left);
  20.357 -	      	MIXATION(right);
  20.358 -		if (num_ochannels >= 4) {
  20.359 -			MIXATION(left_rear);
  20.360 -			MIXATION(right_rear);
  20.361 -		}
  20.362 -		if (num_ochannels == 6) {
  20.363 -			MIXATION(center);
  20.364 -			MIXATION(lfe);
  20.365 -		}
  20.366 +	    MIXATION(left);
  20.367 +	    MIXATION(right);
  20.368  	  }
  20.369  	return;
  20.370        }
  20.371  }
  20.372  
  20.373 -static void mix_center_signal(resample_t *sp, int32 *lp, int v, int count)
  20.374 +static void mix_center_signal(MidiSong *song, sample_t *sp, Sint32 *lp, int v,
  20.375 +			      int count)
  20.376  {
  20.377 -  Voice *vp = voice + v;
  20.378 +  Voice *vp = song->voice + v;
  20.379    final_volume_t 
  20.380      left=vp->left_mix;
  20.381    int cc;
  20.382 -  resample_t s;
  20.383 +  sample_t s;
  20.384  
  20.385    if (!(cc = vp->control_counter))
  20.386      {
  20.387 -      cc = control_ratio;
  20.388 -      if (update_signal(v))
  20.389 +      cc = song->control_ratio;
  20.390 +      if (update_signal(song, v))
  20.391  	return;	/* Envelope ran out */
  20.392        left = vp->left_mix;
  20.393      }
  20.394 @@ -302,27 +246,11 @@
  20.395  	while (cc--)
  20.396  	  {
  20.397  	    s = *sp++;
  20.398 -		if (num_ochannels == 2) {
  20.399 -	    		MIXATION(left);
  20.400 -	    		MIXATION(left);
  20.401 -		}
  20.402 -		else if (num_ochannels == 4) {
  20.403 -			MIXATION(left);
  20.404 -			MIXSKIP;
  20.405 -			MIXATION(left);
  20.406 -			MIXSKIP;
  20.407 -		}
  20.408 -		else if (num_ochannels == 6) {
  20.409 -			MIXSKIP;
  20.410 -			MIXSKIP;
  20.411 -			MIXSKIP;
  20.412 -			MIXSKIP;
  20.413 -			MIXATION(left);
  20.414 -			MIXATION(left);
  20.415 -		}
  20.416 +	    MIXATION(left);
  20.417 +	    MIXATION(left);
  20.418  	  }
  20.419 -	cc = control_ratio;
  20.420 -	if (update_signal(v))
  20.421 +	cc = song->control_ratio;
  20.422 +	if (update_signal(song, v))
  20.423  	  return;	/* Envelope ran out */
  20.424  	left = vp->left_mix;
  20.425        }
  20.426 @@ -332,41 +260,26 @@
  20.427  	while (count--)
  20.428  	  {
  20.429  	    s = *sp++;
  20.430 -		if (num_ochannels == 2) {
  20.431 -	    		MIXATION(left);
  20.432 -	    		MIXATION(left);
  20.433 -		}
  20.434 -		else if (num_ochannels == 4) {
  20.435 -			MIXATION(left);
  20.436 -			MIXSKIP;
  20.437 -			MIXATION(left);
  20.438 -			MIXSKIP;
  20.439 -		}
  20.440 -		else if (num_ochannels == 6) {
  20.441 -			MIXSKIP;
  20.442 -			MIXSKIP;
  20.443 -			MIXSKIP;
  20.444 -			MIXSKIP;
  20.445 -			MIXATION(left);
  20.446 -			MIXATION(left);
  20.447 -		}
  20.448 +	    MIXATION(left);
  20.449 +	    MIXATION(left);
  20.450  	  }
  20.451  	return;
  20.452        }
  20.453  }
  20.454  
  20.455 -static void mix_single_left_signal(resample_t *sp, int32 *lp, int v, int count)
  20.456 +static void mix_single_signal(MidiSong *song, sample_t *sp, Sint32 *lp, int v,
  20.457 +			      int count)
  20.458  {
  20.459 -  Voice *vp = voice + v;
  20.460 +  Voice *vp = song->voice + v;
  20.461    final_volume_t 
  20.462      left=vp->left_mix;
  20.463    int cc;
  20.464 -  resample_t s;
  20.465 +  sample_t s;
  20.466    
  20.467    if (!(cc = vp->control_counter))
  20.468      {
  20.469 -      cc = control_ratio;
  20.470 -      if (update_signal(v))
  20.471 +      cc = song->control_ratio;
  20.472 +      if (update_signal(song, v))
  20.473  	return;	/* Envelope ran out */
  20.474        left = vp->left_mix;
  20.475      }
  20.476 @@ -378,23 +291,11 @@
  20.477  	while (cc--)
  20.478  	  {
  20.479  	    s = *sp++;
  20.480 -		if (num_ochannels == 2) {
  20.481 -			MIXATION(left);
  20.482 -	    		MIXSKIP;
  20.483 -		}
  20.484 -		if (num_ochannels >= 4) {
  20.485 -			MIXHALF(left);
  20.486 -	    		MIXSKIP;
  20.487 -			MIXATION(left);
  20.488 -	    		MIXSKIP;
  20.489 -		}
  20.490 -		if (num_ochannels == 6) {
  20.491 -	    		MIXSKIP;
  20.492 -			MIXATION(left);
  20.493 -		}
  20.494 +	    MIXATION(left);
  20.495 +	    lp++;
  20.496  	  }
  20.497 -	cc = control_ratio;
  20.498 -	if (update_signal(v))
  20.499 +	cc = song->control_ratio;
  20.500 +	if (update_signal(song, v))
  20.501  	  return;	/* Envelope ran out */
  20.502  	left = vp->left_mix;
  20.503        }
  20.504 @@ -404,103 +305,26 @@
  20.505  	while (count--)
  20.506  	  {
  20.507  	    s = *sp++;
  20.508 -		if (num_ochannels == 2) {
  20.509 -			MIXATION(left);
  20.510 -	    		MIXSKIP;
  20.511 -		}
  20.512 -		if (num_ochannels >= 4) {
  20.513 -			MIXHALF(left);
  20.514 -	    		MIXSKIP;
  20.515 -			MIXATION(left);
  20.516 -	    		MIXSKIP;
  20.517 -		}
  20.518 -		if (num_ochannels == 6) {
  20.519 -	    		MIXSKIP;
  20.520 -			MIXATION(left);
  20.521 -		}
  20.522 +	    MIXATION(left);
  20.523 +	    lp++;
  20.524  	  }
  20.525  	return;
  20.526        }
  20.527  }
  20.528  
  20.529 -static void mix_single_right_signal(resample_t *sp, int32 *lp, int v, int count)
  20.530 +static void mix_mono_signal(MidiSong *song, sample_t *sp, Sint32 *lp, int v,
  20.531 +			    int count)
  20.532  {
  20.533 -  Voice *vp = voice + v;
  20.534 +  Voice *vp = song->voice + v;
  20.535    final_volume_t 
  20.536      left=vp->left_mix;
  20.537    int cc;
  20.538 -  resample_t s;
  20.539 +  sample_t s;
  20.540    
  20.541    if (!(cc = vp->control_counter))
  20.542      {
  20.543 -      cc = control_ratio;
  20.544 -      if (update_signal(v))
  20.545 -	return;	/* Envelope ran out */
  20.546 -      left = vp->left_mix;
  20.547 -    }
  20.548 -  
  20.549 -  while (count)
  20.550 -    if (cc < count)
  20.551 -      {
  20.552 -	count -= cc;
  20.553 -	while (cc--)
  20.554 -	  {
  20.555 -	    s = *sp++;
  20.556 -		if (num_ochannels == 2) {
  20.557 -	    		MIXSKIP;
  20.558 -			MIXATION(left);
  20.559 -		}
  20.560 -		if (num_ochannels >= 4) {
  20.561 -	    		MIXSKIP;
  20.562 -			MIXHALF(left);
  20.563 -	    		MIXSKIP;
  20.564 -			MIXATION(left);
  20.565 -		} if (num_ochannels == 6) {
  20.566 -	    		MIXSKIP;
  20.567 -			MIXATION(left);
  20.568 -		}
  20.569 -	  }
  20.570 -	cc = control_ratio;
  20.571 -	if (update_signal(v))
  20.572 -	  return;	/* Envelope ran out */
  20.573 -	left = vp->left_mix;
  20.574 -      }
  20.575 -    else
  20.576 -      {
  20.577 -	vp->control_counter = cc - count;
  20.578 -	while (count--)
  20.579 -	  {
  20.580 -	    s = *sp++;
  20.581 -		if (num_ochannels == 2) {
  20.582 -	    		MIXSKIP;
  20.583 -			MIXATION(left);
  20.584 -		}
  20.585 -		if (num_ochannels >= 4) {
  20.586 -	    		MIXSKIP;
  20.587 -			MIXHALF(left);
  20.588 -	    		MIXSKIP;
  20.589 -			MIXATION(left);
  20.590 -		} if (num_ochannels == 6) {
  20.591 -	    		MIXSKIP;
  20.592 -			MIXATION(left);
  20.593 -		}
  20.594 -	  }
  20.595 -	return;
  20.596 -      }
  20.597 -}
  20.598 -
  20.599 -static void mix_mono_signal(resample_t *sp, int32 *lp, int v, int count)
  20.600 -{
  20.601 -  Voice *vp = voice + v;
  20.602 -  final_volume_t 
  20.603 -    left=vp->left_mix;
  20.604 -  int cc;
  20.605 -  resample_t s;
  20.606 -  
  20.607 -  if (!(cc = vp->control_counter))
  20.608 -    {
  20.609 -      cc = control_ratio;
  20.610 -      if (update_signal(v))
  20.611 +      cc = song->control_ratio;
  20.612 +      if (update_signal(song, v))
  20.613  	return;	/* Envelope ran out */
  20.614        left = vp->left_mix;
  20.615      }
  20.616 @@ -514,8 +338,8 @@
  20.617  	    s = *sp++;
  20.618  	    MIXATION(left);
  20.619  	  }
  20.620 -	cc = control_ratio;
  20.621 -	if (update_signal(v))
  20.622 +	cc = song->control_ratio;
  20.623 +	if (update_signal(song, v))
  20.624  	  return;	/* Envelope ran out */
  20.625  	left = vp->left_mix;
  20.626        }
  20.627 @@ -531,119 +355,54 @@
  20.628        }
  20.629  }
  20.630  
  20.631 -static void mix_mystery(resample_t *sp, int32 *lp, int v, int count)
  20.632 +static void mix_mystery(MidiSong *song, sample_t *sp, Sint32 *lp, int v, int count)
  20.633  {
  20.634    final_volume_t 
  20.635 -    left_rear=voice[v].lr_mix, 
  20.636 -    left=voice[v].left_mix, 
  20.637 -    center=voice[v].ce_mix, 
  20.638 -    right=voice[v].right_mix, 
  20.639 -    right_rear=voice[v].rr_mix, 
  20.640 -    lfe=voice[v].lfe_mix;
  20.641 -  resample_t s;
  20.642 +    left = song->voice[v].left_mix, 
  20.643 +    right = song->voice[v].right_mix;
  20.644 +  sample_t s;
  20.645    
  20.646    while (count--)
  20.647      {
  20.648        s = *sp++;
  20.649 -	      	MIXATION(left);
  20.650 -	      	MIXATION(right);
  20.651 -		if (num_ochannels >= 4) {
  20.652 -			MIXATION(left_rear);
  20.653 -			MIXATION(right_rear);
  20.654 -		}
  20.655 -		if (num_ochannels == 6) {
  20.656 -			MIXATION(center);
  20.657 -			MIXATION(lfe);
  20.658 -		}
  20.659 +      MIXATION(left);
  20.660 +      MIXATION(right);
  20.661      }
  20.662  }
  20.663  
  20.664 -static void mix_center(resample_t *sp, int32 *lp, int v, int count)
  20.665 +static void mix_center(MidiSong *song, sample_t *sp, Sint32 *lp, int v, int count)
  20.666  {
  20.667    final_volume_t 
  20.668 -    left=voice[v].left_mix;
  20.669 -  resample_t s;
  20.670 +    left = song->voice[v].left_mix;
  20.671 +  sample_t s;
  20.672    
  20.673    while (count--)
  20.674      {
  20.675        s = *sp++;
  20.676 -		if (num_ochannels == 2) {
  20.677 -      			MIXATION(left);
  20.678 -      			MIXATION(left);
  20.679 -		}
  20.680 -		else if (num_ochannels == 4) {
  20.681 -      			MIXATION(left);
  20.682 -      			MIXATION(left);
  20.683 -			MIXSKIP;
  20.684 -			MIXSKIP;
  20.685 -		}
  20.686 -		else if (num_ochannels == 6) {
  20.687 -			MIXSKIP;
  20.688 -			MIXSKIP;
  20.689 -			MIXSKIP;
  20.690 -			MIXSKIP;
  20.691 -			MIXATION(left);
  20.692 -			MIXATION(left);
  20.693 -		}
  20.694 +      MIXATION(left);
  20.695 +      MIXATION(left);
  20.696      }
  20.697  }
  20.698  
  20.699 -static void mix_single_left(resample_t *sp, int32 *lp, int v, int count)
  20.700 +static void mix_single(MidiSong *song, sample_t *sp, Sint32 *lp, int v, int count)
  20.701  {
  20.702    final_volume_t 
  20.703 -    left=voice[v].left_mix;
  20.704 -  resample_t s;
  20.705 +    left = song->voice[v].left_mix;
  20.706 +  sample_t s;
  20.707    
  20.708    while (count--)
  20.709      {
  20.710        s = *sp++;
  20.711 -		if (num_ochannels == 2) {
  20.712 -			MIXATION(left);
  20.713 -      			MIXSKIP;
  20.714 -		}
  20.715 -		if (num_ochannels >= 4) {
  20.716 -			MIXHALF(left);
  20.717 -      			MIXSKIP;
  20.718 -			MIXATION(left);
  20.719 -      			MIXSKIP;
  20.720 -		}
  20.721 -	       	if (num_ochannels == 6) {
  20.722 -      			MIXSKIP;
  20.723 -			MIXATION(left);
  20.724 -		}
  20.725 -    }
  20.726 -}
  20.727 -static void mix_single_right(resample_t *sp, int32 *lp, int v, int count)
  20.728 -{
  20.729 -  final_volume_t 
  20.730 -    left=voice[v].left_mix;
  20.731 -  resample_t s;
  20.732 -  
  20.733 -  while (count--)
  20.734 -    {
  20.735 -      s = *sp++;
  20.736 -		if (num_ochannels == 2) {
  20.737 -      			MIXSKIP;
  20.738 -			MIXATION(left);
  20.739 -		}
  20.740 -		if (num_ochannels >= 4) {
  20.741 -      			MIXSKIP;
  20.742 -			MIXHALF(left);
  20.743 -      			MIXSKIP;
  20.744 -			MIXATION(left);
  20.745 -		}
  20.746 -	       	if (num_ochannels == 6) {
  20.747 -      			MIXSKIP;
  20.748 -			MIXATION(left);
  20.749 -		}
  20.750 +      MIXATION(left);
  20.751 +      lp++;
  20.752      }
  20.753  }
  20.754  
  20.755 -static void mix_mono(resample_t *sp, int32 *lp, int v, int count)
  20.756 +static void mix_mono(MidiSong *song, sample_t *sp, Sint32 *lp, int v, int count)
  20.757  {
  20.758    final_volume_t 
  20.759 -    left=voice[v].left_mix;
  20.760 -  resample_t s;
  20.761 +    left = song->voice[v].left_mix;
  20.762 +  sample_t s;
  20.763    
  20.764    while (count--)
  20.765      {
  20.766 @@ -653,56 +412,43 @@
  20.767  }
  20.768  
  20.769  /* Ramp a note out in c samples */
  20.770 -static void ramp_out(resample_t *sp, int32 *lp, int v, int32 c)
  20.771 +static void ramp_out(MidiSong *song, sample_t *sp, Sint32 *lp, int v, Sint32 c)
  20.772  {
  20.773  
  20.774 -  /* should be final_volume_t, but uint8 gives trouble. */
  20.775 -  int32 left_rear, left, center, right, right_rear, lfe, li, ri;
  20.776 +  /* should be final_volume_t, but Uint8 gives trouble. */
  20.777 +  Sint32 left, right, li, ri;
  20.778  
  20.779 -  resample_t s = 0; /* silly warning about uninitialized s */
  20.780 +  sample_t s=0; /* silly warning about uninitialized s */
  20.781  
  20.782    /* Fix by James Caldwell */
  20.783    if ( c == 0 ) c = 1;
  20.784 -
  20.785 -  left = voice[v].left_mix;
  20.786 -  li = -(left/c);
  20.787 -  if (!li) li = -1;
  20.788 +  
  20.789 +  left=song->voice[v].left_mix;
  20.790 +  li=-(left/c);
  20.791 +  if (!li) li=-1;
  20.792  
  20.793    /* printf("Ramping out: left=%d, c=%d, li=%d\n", left, c, li); */
  20.794  
  20.795 -  if (!(play_mode->encoding & PE_MONO))
  20.796 +  if (!(song->encoding & PE_MONO))
  20.797      {
  20.798 -      if (voice[v].panned==PANNED_MYSTERY)
  20.799 +      if (song->voice[v].panned==PANNED_MYSTERY)
  20.800  	{
  20.801 -	  left_rear = voice[v].lr_mix;
  20.802 -	  center=voice[v].ce_mix;
  20.803 -	  right=voice[v].right_mix;
  20.804 -	  right_rear = voice[v].rr_mix;
  20.805 -	  lfe = voice[v].lfe_mix;
  20.806 -
  20.807 +	  right=song->voice[v].right_mix;
  20.808  	  ri=-(right/c);
  20.809  	  while (c--)
  20.810  	    {
  20.811 -	      left_rear += li; if (left_rear<0) left_rear=0;
  20.812 -	      left += li; if (left<0) left=0;
  20.813 -	      center += li; if (center<0) center=0;
  20.814 -	      right += ri; if (right<0) right=0;
  20.815 -	      right_rear += ri; if (right_rear<0) right_rear=0;
  20.816 -	      lfe += li; if (lfe<0) lfe=0;
  20.817 +	      left += li;
  20.818 +	      if (left<0)
  20.819 +		left=0;
  20.820 +	      right += ri;
  20.821 +	      if (right<0)
  20.822 +		right=0;
  20.823  	      s=*sp++;
  20.824 -	      	MIXATION(left);
  20.825 -	      	MIXATION(right);
  20.826 -		if (num_ochannels >= 4) {
  20.827 -			MIXATION(left_rear);
  20.828 -			MIXATION(right_rear);
  20.829 -		}
  20.830 -		if (num_ochannels == 6) {
  20.831 -			MIXATION(center);
  20.832 -			MIXATION(lfe);
  20.833 -		}
  20.834 +	      MIXATION(left);
  20.835 +	      MIXATION(right);
  20.836  	    }
  20.837  	}
  20.838 -      else if (voice[v].panned==PANNED_CENTER)
  20.839 +      else if (song->voice[v].panned==PANNED_CENTER)
  20.840  	{
  20.841  	  while (c--)
  20.842  	    {
  20.843 @@ -710,27 +456,11 @@
  20.844  	      if (left<0)
  20.845  		return;
  20.846  	      s=*sp++;	
  20.847 -		if (num_ochannels == 2) {
  20.848 -	      		MIXATION(left);
  20.849 -	      		MIXATION(left);
  20.850 -		}
  20.851 -		else if (num_ochannels == 4) {
  20.852 -			MIXATION(left);
  20.853 -	      		MIXATION(left);
  20.854 -			MIXSKIP;
  20.855 -			MIXSKIP;
  20.856 -		}
  20.857 -		else if (num_ochannels == 6) {
  20.858 -			MIXSKIP;
  20.859 -			MIXSKIP;
  20.860 -			MIXSKIP;
  20.861 -			MIXSKIP;
  20.862 -	      		MIXATION(left);
  20.863 -	      		MIXATION(left);
  20.864 -		}
  20.865 +	      MIXATION(left);
  20.866 +	      MIXATION(left);
  20.867  	    }
  20.868  	}
  20.869 -      else if (voice[v].panned==PANNED_LEFT)
  20.870 +      else if (song->voice[v].panned==PANNED_LEFT)
  20.871  	{
  20.872  	  while (c--)
  20.873  	    {
  20.874 @@ -739,17 +469,10 @@
  20.875  		return;
  20.876  	      s=*sp++;
  20.877  	      MIXATION(left);
  20.878 -	      MIXSKIP;
  20.879 -		if (num_ochannels >= 4) {
  20.880 -			MIXATION(left);
  20.881 -	      		MIXSKIP;
  20.882 -		} if (num_ochannels == 6) {
  20.883 -			MIXATION(left);
  20.884 -			MIXATION(left);
  20.885 -		}
  20.886 +	      lp++;
  20.887  	    }
  20.888  	}
  20.889 -      else if (voice[v].panned==PANNED_RIGHT)
  20.890 +      else if (song->voice[v].panned==PANNED_RIGHT)
  20.891  	{
  20.892  	  while (c--)
  20.893  	    {
  20.894 @@ -757,15 +480,8 @@
  20.895  	      if (left<0)
  20.896  		return;
  20.897  	      s=*sp++;
  20.898 -	      MIXSKIP;
  20.899 +	      lp++;
  20.900  	      MIXATION(left);
  20.901 -		if (num_ochannels >= 4) {
  20.902 -	      		MIXSKIP;
  20.903 -			MIXATION(left);
  20.904 -		} if (num_ochannels == 6) {
  20.905 -			MIXATION(left);
  20.906 -			MIXATION(left);
  20.907 -		}
  20.908  	    }
  20.909  	}
  20.910      }
  20.911 @@ -786,65 +502,55 @@
  20.912  
  20.913  /**************** interface function ******************/
  20.914  
  20.915 -void mix_voice(int32 *buf, int v, int32 c)
  20.916 +void mix_voice(MidiSong *song, Sint32 *buf, int v, Sint32 c)
  20.917  {
  20.918 -  Voice *vp=voice+v;
  20.919 -  int32 count=c;
  20.920 -  resample_t *sp;
  20.921 -  if (c<0) return;
  20.922 +  Voice *vp = song->voice + v;
  20.923 +  sample_t *sp;
  20.924    if (vp->status==VOICE_DIE)
  20.925      {
  20.926 -      if (count>=MAX_DIE_TIME)
  20.927 -	count=MAX_DIE_TIME;
  20.928 -      sp=resample_voice(v, &count);
  20.929 -      ramp_out(sp, buf, v, count);
  20.930 +      if (c>=MAX_DIE_TIME)
  20.931 +	c=MAX_DIE_TIME;
  20.932 +      sp=resample_voice(song, v, &c);
  20.933 +      ramp_out(song, sp, buf, v, c);
  20.934        vp->status=VOICE_FREE;
  20.935      }
  20.936    else
  20.937      {
  20.938 -      sp=resample_voice(v, &count);
  20.939 -      if (count<0) return;
  20.940 -      if (play_mode->encoding & PE_MONO)
  20.941 +      sp=resample_voice(song, v, &c);
  20.942 +      if (song->encoding & PE_MONO)
  20.943  	{
  20.944  	  /* Mono output. */
  20.945  	  if (vp->envelope_increment || vp->tremolo_phase_increment)
  20.946 -	    mix_mono_signal(sp, buf, v, count);
  20.947 +	    mix_mono_signal(song, sp, buf, v, c);
  20.948  	  else
  20.949 -	    mix_mono(sp, buf, v, count);
  20.950 +	    mix_mono(song, sp, buf, v, c);
  20.951  	}
  20.952        else
  20.953  	{
  20.954  	  if (vp->panned == PANNED_MYSTERY)
  20.955  	    {
  20.956  	      if (vp->envelope_increment || vp->tremolo_phase_increment)
  20.957 -		mix_mystery_signal(sp, buf, v, count);
  20.958 +		mix_mystery_signal(song, sp, buf, v, c);
  20.959  	      else
  20.960 -		mix_mystery(sp, buf, v, count);
  20.961 +		mix_mystery(song, sp, buf, v, c);
  20.962  	    }
  20.963  	  else if (vp->panned == PANNED_CENTER)
  20.964  	    {
  20.965  	      if (vp->envelope_increment || vp->tremolo_phase_increment)
  20.966 -		mix_center_signal(sp, buf, v, count);
  20.967 +		mix_center_signal(song, sp, buf, v, c);
  20.968  	      else
  20.969 -		mix_center(sp, buf, v, count);
  20.970 +		mix_center(song, sp, buf, v, c);
  20.971  	    }
  20.972  	  else
  20.973  	    { 
  20.974  	      /* It's either full left or full right. In either case,
  20.975  		 every other sample is 0. Just get the offset right: */
  20.976 +	      if (vp->panned == PANNED_RIGHT) buf++;
  20.977  	      
  20.978  	      if (vp->envelope_increment || vp->tremolo_phase_increment)
  20.979 -	      {
  20.980 -	        if (vp->panned == PANNED_RIGHT)
  20.981 -			mix_single_right_signal(sp, buf, v, count);
  20.982 -		else mix_single_left_signal(sp, buf, v, count);
  20.983 -	      }
  20.984 +		mix_single_signal(song, sp, buf, v, c);
  20.985  	      else 
  20.986 -	      {
  20.987 -	        if (vp->panned == PANNED_RIGHT)
  20.988 -			mix_single_right(sp, buf, v, count);
  20.989 -		else mix_single_left(sp, buf, v, count);
  20.990 -	      }
  20.991 +		mix_single(song, sp, buf, v, c);
  20.992  	    }
  20.993  	}
  20.994      }
    21.1 --- a/timidity/mix.h	Tue Oct 17 16:55:58 2017 -0700
    21.2 +++ b/timidity/mix.h	Tue Oct 17 21:54:04 2017 -0700
    21.3 @@ -1,11 +1,15 @@
    21.4  /*
    21.5 +
    21.6      TiMidity -- Experimental MIDI to WAVE converter
    21.7      Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
    21.8  
    21.9      This program is free software; you can redistribute it and/or modify
   21.10      it under the terms of the Perl Artistic License, available in COPYING.
   21.11 - */
   21.12  
   21.13 -extern void mix_voice(int32 *buf, int v, int32 c);
   21.14 -extern int recompute_envelope(int v);
   21.15 -extern void apply_envelope_to_amp(int v);
   21.16 +    mix.h
   21.17 +
   21.18 +*/
   21.19 +
   21.20 +extern void mix_voice(MidiSong *song, Sint32 *buf, int v, Sint32 c);
   21.21 +extern int recompute_envelope(MidiSong *song, int v);
   21.22 +extern void apply_envelope_to_amp(MidiSong *song, int v);
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/timidity/options.h	Tue Oct 17 21:54:04 2017 -0700
    22.3 @@ -0,0 +1,117 @@
    22.4 +/*
    22.5 +    TiMidity -- Experimental MIDI to WAVE converter
    22.6 +    Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
    22.7 +
    22.8 +    This program is free software; you can redistribute it and/or modify
    22.9 +    it under the terms of the Perl Artistic License, available in COPYING.
   22.10 +*/
   22.11 +
   22.12 +/* When a patch file can't be opened, one of these extensions is
   22.13 +   appended to the filename and the open is tried again.
   22.14 + */
   22.15 +#define PATCH_EXT_LIST { ".pat", 0 }
   22.16 +
   22.17 +/* Acoustic Grand Piano seems to be the usual default instrument. */
   22.18 +#define DEFAULT_PROGRAM 0
   22.19 +
   22.20 +/* 9 here is MIDI channel 10, which is the standard percussion channel.
   22.21 +   Some files (notably C:\WINDOWS\CANYON.MID) think that 16 is one too. 
   22.22 +   On the other hand, some files know that 16 is not a drum channel and
   22.23 +   try to play music on it. This is now a runtime option, so this isn't
   22.24 +   a critical choice anymore. */
   22.25 +#define DEFAULT_DRUMCHANNELS (1<<9)
   22.26 +
   22.27 +/* In percent. */
   22.28 +#define DEFAULT_AMPLIFICATION 	70
   22.29 +
   22.30 +/* Default polyphony */
   22.31 +/* #define DEFAULT_VOICES	32 */
   22.32 +#define DEFAULT_VOICES	256
   22.33 +
   22.34 +/* 1000 here will give a control ratio of 22:1 with 22 kHz output.
   22.35 +   Higher CONTROLS_PER_SECOND values allow more accurate rendering
   22.36 +   of envelopes and tremolo. The cost is CPU time. */
   22.37 +#define CONTROLS_PER_SECOND 1000
   22.38 +
   22.39 +/* Make envelopes twice as fast. Saves ~20% CPU time (notes decay
   22.40 +   faster) and sounds more like a GUS. There is now a command line
   22.41 +   option to toggle this as well. */
   22.42 +#define FAST_DECAY
   22.43 +
   22.44 +/* How many bits to use for the fractional part of sample positions.
   22.45 +   This affects tonal accuracy. The entire position counter must fit
   22.46 +   in 32 bits, so with FRACTION_BITS equal to 12, the maximum size of
   22.47 +   a sample is 1048576 samples (2 megabytes in memory). The GUS gets
   22.48 +   by with just 9 bits and a little help from its friends...
   22.49 +   "The GUS does not SUCK!!!" -- a happy user :) */
   22.50 +#define FRACTION_BITS 12
   22.51 +
   22.52 +/* For some reason the sample volume is always set to maximum in all
   22.53 +   patch files. Define this for a crude adjustment that may help
   22.54 +   equalize instrument volumes. */
   22.55 +#define ADJUST_SAMPLE_VOLUMES
   22.56 +
   22.57 +/* The number of samples to use for ramping out a dying note. Affects
   22.58 +   click removal. */
   22.59 +#define MAX_DIE_TIME 20
   22.60 +
   22.61 +/**************************************************************************/
   22.62 +/* Anything below this shouldn't need to be changed unless you're porting
   22.63 +   to a new machine with other than 32-bit, big-endian words. */
   22.64 +/**************************************************************************/
   22.65 +
   22.66 +/* change FRACTION_BITS above, not these */
   22.67 +#define INTEGER_MASK (0xFFFFFFFF << FRACTION_BITS)
   22.68 +#define FRACTION_MASK (~ INTEGER_MASK)
   22.69 +
   22.70 +/* This is enforced by some computations that must fit in an int */
   22.71 +#define MAX_CONTROL_RATIO 255
   22.72 +
   22.73 +#define MAX_AMPLIFICATION 800
   22.74 +
   22.75 +/* You could specify a complete path, e.g. "/etc/timidity.cfg", and
   22.76 +   then specify the library directory in the configuration file. */
   22.77 +#define CONFIG_FILE	"timidity.cfg"
   22.78 +#define CONFIG_FILE_ETC "/etc/timidity.cfg"
   22.79 +#define CONFIG_FILE_ETC_TIMIDITY_FREEPATS "/etc/timidity/freepats.cfg"
   22.80 +
   22.81 +#if defined(__WIN32__) || defined(__OS2__)
   22.82 +#define DEFAULT_PATH	"C:\\TIMIDITY"
   22.83 +#else
   22.84 +#define DEFAULT_PATH	"/etc/timidity"
   22.85 +#define DEFAULT_PATH1	"/usr/share/timidity"
   22.86 +#define DEFAULT_PATH2	"/usr/local/share/timidity"
   22.87 +#define DEFAULT_PATH3	"/usr/local/lib/timidity"
   22.88 +#endif
   22.89 +
   22.90 +/* These affect general volume */
   22.91 +#define GUARD_BITS 3
   22.92 +#define AMP_BITS (15-GUARD_BITS)
   22.93 +
   22.94 +#define MAX_AMP_VALUE ((1<<(AMP_BITS+1))-1)
   22.95 +
   22.96 +#define FSCALE(a,b) (float)((a) * (double)(1<<(b)))
   22.97 +#define FSCALENEG(a,b) (float)((a) * (1.0L / (double)(1<<(b))))
   22.98 +
   22.99 +/* Vibrato and tremolo Choices of the Day */
  22.100 +#define SWEEP_TUNING 38
  22.101 +#define VIBRATO_AMPLITUDE_TUNING 1.0L
  22.102 +#define VIBRATO_RATE_TUNING 38
  22.103 +#define TREMOLO_AMPLITUDE_TUNING 1.0L
  22.104 +#define TREMOLO_RATE_TUNING 38
  22.105 +
  22.106 +#define SWEEP_SHIFT 16
  22.107 +#define RATE_SHIFT 5
  22.108 +
  22.109 +#ifndef PI
  22.110 +  #define PI 3.14159265358979323846
  22.111 +#endif
  22.112 +
  22.113 +/* The path separator (D.M.) */
  22.114 +#if defined(__WIN32__) || defined(__OS2__)
  22.115 +#  define PATH_SEP '\\'
  22.116 +#else
  22.117 +#  define PATH_SEP '/'
  22.118 +#endif
  22.119 +
  22.120 +#define SNDDBG(X)
    23.1 --- a/timidity/output.c	Tue Oct 17 16:55:58 2017 -0700
    23.2 +++ b/timidity/output.c	Tue Oct 17 21:54:04 2017 -0700
    23.3 @@ -1,122 +1,102 @@
    23.4 -/*
    23.5 +/* 
    23.6 +
    23.7      TiMidity -- Experimental MIDI to WAVE converter
    23.8      Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
    23.9  
   23.10      This program is free software; you can redistribute it and/or modify
   23.11      it under the terms of the Perl Artistic License, available in COPYING.
   23.12 - */
   23.13  
   23.14 -#include "config.h"
   23.15 -#include "output.h"
   23.16 -#include "tables.h"
   23.17 +    output.c
   23.18 +    
   23.19 +    Audio output (to file / device) functions.
   23.20 +*/
   23.21  
   23.22 -
   23.23 -#ifdef SDL
   23.24 -extern PlayMode sdl_play_mode;
   23.25 -#define DEFAULT_PLAY_MODE &sdl_play_mode
   23.26 +#if HAVE_CONFIG_H
   23.27 +#  include <config.h>
   23.28  #endif
   23.29  
   23.30 -PlayMode *play_mode_list[] = {
   23.31 -#ifdef DEFAULT_PLAY_MODE
   23.32 -  DEFAULT_PLAY_MODE,
   23.33 -#endif
   23.34 -  0
   23.35 -};
   23.36 +#include "SDL.h"
   23.37  
   23.38 -#ifdef DEFAULT_PLAY_MODE
   23.39 -  PlayMode *play_mode=DEFAULT_PLAY_MODE;
   23.40 -#endif
   23.41 +#include "options.h"
   23.42 +#include "output.h"
   23.43  
   23.44  /*****************************************************************/
   23.45  /* Some functions to convert signed 32-bit data to other formats */
   23.46  
   23.47 -void s32tos8(void *dp, int32 *lp, int32 c)
   23.48 +void s32tos8(void *dp, Sint32 *lp, Sint32 c)
   23.49  {
   23.50 -  int8 *cp=(int8 *)(dp);
   23.51 -  int32 l;
   23.52 +  Sint8 *cp=(Sint8 *)(dp);
   23.53 +  Sint32 l;
   23.54    while (c--)
   23.55      {
   23.56        l=(*lp++)>>(32-8-GUARD_BITS);
   23.57        if (l>127) l=127;
   23.58        else if (l<-128) l=-128;
   23.59 -      *cp++ = (int8) (l);
   23.60 +      *cp++ = (Sint8) (l);
   23.61      }
   23.62  }
   23.63  
   23.64 -void s32tou8(void *dp, int32 *lp, int32 c)
   23.65 +void s32tou8(void *dp, Sint32 *lp, Sint32 c)
   23.66  {
   23.67 -  uint8 *cp=(uint8 *)(dp);
   23.68 -  int32 l;
   23.69 +  Uint8 *cp=(Uint8 *)(dp);
   23.70 +  Sint32 l;
   23.71    while (c--)
   23.72      {
   23.73        l=(*lp++)>>(32-8-GUARD_BITS);
   23.74        if (l>127) l=127;
   23.75        else if (l<-128) l=-128;
   23.76 -      *cp++ = 0x80 ^ ((uint8) l);
   23.77 +      *cp++ = 0x80 ^ ((Uint8) l);
   23.78      }
   23.79  }
   23.80  
   23.81 -void s32tos16(void *dp, int32 *lp, int32 c)
   23.82 +void s32tos16(void *dp, Sint32 *lp, Sint32 c)
   23.83  {
   23.84 -  int16 *sp=(int16 *)(dp);
   23.85 -  int32 l;
   23.86 +  Sint16 *sp=(Sint16 *)(dp);
   23.87 +  Sint32 l;
   23.88    while (c--)
   23.89      {
   23.90        l=(*lp++)>>(32-16-GUARD_BITS);
   23.91        if (l > 32767) l=32767;
   23.92        else if (l<-32768) l=-32768;
   23.93 -      *sp++ = (int16)(l);
   23.94 +      *sp++ = (Sint16)(l);
   23.95      }
   23.96  }
   23.97  
   23.98 -void s32tou16(void *dp, int32 *lp, int32 c)
   23.99 +void s32tou16(void *dp, Sint32 *lp, Sint32 c)
  23.100  {
  23.101 -  uint16 *sp=(uint16 *)(dp);
  23.102 -  int32 l;
  23.103 +  Uint16 *sp=(Uint16 *)(dp);
  23.104 +  Sint32 l;
  23.105    while (c--)
  23.106      {
  23.107        l=(*lp++)>>(32-16-GUARD_BITS);
  23.108        if (l > 32767) l=32767;
  23.109        else if (l<-32768) l=-32768;
  23.110 -      *sp++ = 0x8000 ^ (uint16)(l);
  23.111 +      *sp++ = 0x8000 ^ (Uint16)(l);
  23.112      }
  23.113  }
  23.114  
  23.115 -void s32tos16x(void *dp, int32 *lp, int32 c)
  23.116 +void s32tos16x(void *dp, Sint32 *lp, Sint32 c)
  23.117  {
  23.118 -  int16 *sp=(int16 *)(dp);
  23.119 -  int32 l;
  23.120 +  Sint16 *sp=(Sint16 *)(dp);
  23.121 +  Sint32 l;
  23.122    while (c--)
  23.123      {
  23.124        l=(*lp++)>>(32-16-GUARD_BITS);
  23.125        if (l > 32767) l=32767;
  23.126        else if (l<-32768) l=-32768;
  23.127 -      *sp++ = XCHG_SHORT((int16)(l));
  23.128 +      *sp++ = SDL_Swap16((Sint16)(l));
  23.129      }
  23.130  }
  23.131  
  23.132 -void s32tou16x(void *dp, int32 *lp, int32 c)
  23.133 +void s32tou16x(void *dp, Sint32 *lp, Sint32 c)
  23.134  {
  23.135 -  uint16 *sp=(uint16 *)(dp);
  23.136 -  int32 l;
  23.137 +  Uint16 *sp=(Uint16 *)(dp);
  23.138 +  Sint32 l;
  23.139    while (c--)
  23.140      {
  23.141        l=(*lp++)>>(32-16-GUARD_BITS);
  23.142        if (l > 32767) l=32767;
  23.143        else if (l<-32768) l=-32768;
  23.144 -      *sp++ = XCHG_SHORT(0x8000 ^ (uint16)(l));
  23.145 +      *sp++ = SDL_Swap16(0x8000 ^ (Uint16)(l));
  23.146      }
  23.147  }
  23.148 -
  23.149 -void s32toulaw(void *dp, int32 *lp, int32 c)
  23.150 -{
  23.151 -  uint8 *up=(uint8 *)(dp);
  23.152 -  int32 l;
  23.153 -  while (c--)
  23.154 -    {
  23.155 -      l=(*lp++)>>(32-13-GUARD_BITS);
  23.156 -      if (l > 4095) l=4095;
  23.157 -      else if (l<-4096) l=-4096;
  23.158 -      *up++ = _l2u[l];
  23.159 -    }
  23.160 -}
    24.1 --- a/timidity/output.h	Tue Oct 17 16:55:58 2017 -0700
    24.2 +++ b/timidity/output.h	Tue Oct 17 21:54:04 2017 -0700
    24.3 @@ -1,50 +1,35 @@
    24.4 -/*
    24.5 +/* 
    24.6 +
    24.7      TiMidity -- Experimental MIDI to WAVE converter
    24.8      Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
    24.9  
   24.10      This program is free software; you can redistribute it and/or modify
   24.11      it under the terms of the Perl Artistic License, available in COPYING.
   24.12 - */
   24.13 +
   24.14 +    output.h
   24.15 +
   24.16 +*/
   24.17  
   24.18  /* Data format encoding bits */
   24.19  
   24.20  #define PE_MONO 	0x01  /* versus stereo */
   24.21  #define PE_SIGNED	0x02  /* versus unsigned */
   24.22  #define PE_16BIT 	0x04  /* versus 8-bit */
   24.23 -#define PE_ULAW 	0x08  /* versus linear */
   24.24 -#define PE_BYTESWAP	0x10  /* versus the other way */
   24.25  
   24.26 -typedef struct {
   24.27 -  int32 rate, encoding;
   24.28 -  char *id_name;
   24.29 -} PlayMode;
   24.30 -
   24.31 -extern PlayMode *play_mode_list[], *play_mode;
   24.32 -extern int init_buffers(int kbytes);
   24.33 -
   24.34 -/* Conversion functions -- These overwrite the int32 data in *lp with
   24.35 +/* Conversion functions -- These overwrite the Sint32 data in *lp with
   24.36     data in another format */
   24.37  
   24.38 -/* The size of the output buffers */
   24.39 -extern int AUDIO_BUFFER_SIZE;
   24.40 -
   24.41 -/* Actual copy function */
   24.42 -extern void (*s32tobuf)(void *dp, int32 *lp, int32 c);
   24.43 -
   24.44  /* 8-bit signed and unsigned*/
   24.45 -extern void s32tos8(void *dp, int32 *lp, int32 c);
   24.46 -extern void s32tou8(void *dp, int32 *lp, int32 c);
   24.47 +extern void s32tos8(void *dp, Sint32 *lp, Sint32 c);
   24.48 +extern void s32tou8(void *dp, Sint32 *lp, Sint32 c);
   24.49  
   24.50  /* 16-bit */
   24.51 -extern void s32tos16(void *dp, int32 *lp, int32 c);
   24.52 -extern void s32tou16(void *dp, int32 *lp, int32 c);
   24.53 +extern void s32tos16(void *dp, Sint32 *lp, Sint32 c);
   24.54 +extern void s32tou16(void *dp, Sint32 *lp, Sint32 c);
   24.55  
   24.56  /* byte-exchanged 16-bit */
   24.57 -extern void s32tos16x(void *dp, int32 *lp, int32 c);
   24.58 -extern void s32tou16x(void *dp, int32 *lp, int32 c);
   24.59 -
   24.60 -/* uLaw (8 bits) */
   24.61 -extern void s32toulaw(void *dp, int32 *lp, int32 c);
   24.62 +extern void s32tos16x(void *dp, Sint32 *lp, Sint32 c);
   24.63 +extern void s32tou16x(void *dp, Sint32 *lp, Sint32 c);
   24.64  
   24.65  /* little-endian and big-endian specific */
   24.66  #if SDL_BYTEORDER == SDL_LIL_ENDIAN
    25.1 --- a/timidity/playmidi.c	Tue Oct 17 16:55:58 2017 -0700
    25.2 +++ b/timidity/playmidi.c	Tue Oct 17 21:54:04 2017 -0700
    25.3 @@ -1,142 +1,73 @@
    25.4  /*
    25.5 +
    25.6      TiMidity -- Experimental MIDI to WAVE converter
    25.7      Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
    25.8  
    25.9      This program is free software; you can redistribute it and/or modify
   25.10      it under the terms of the Perl Artistic License, available in COPYING.
   25.11 - */
   25.12 +
   25.13 +    playmidi.c -- random stuff in need of rearrangement
   25.14 +
   25.15 +*/
   25.16 +
   25.17 +#if HAVE_CONFIG_H
   25.18 +#  include <config.h>
   25.19 +#endif
   25.20  
   25.21  #include <stdio.h>
   25.22  #include <stdlib.h>
   25.23  #include <string.h>
   25.24  
   25.25 -#include <SDL_rwops.h>
   25.26 +#include "SDL.h"
   25.27  
   25.28 -#include "config.h"
   25.29 -#include "common.h"
   25.30 +#include "timidity.h"
   25.31 +#include "options.h"
   25.32  #include "instrum.h"
   25.33  #include "playmidi.h"
   25.34 -#include "readmidi.h"
   25.35  #include "output.h"
   25.36  #include "mix.h"
   25.37 -#include "ctrlmode.h"
   25.38 -#include "timidity.h"
   25.39 -
   25.40  #include "tables.h"
   25.41  
   25.42 -
   25.43 -static int opt_expression_curve = 2;
   25.44 -static int opt_volume_curve = 2;
   25.45 -static int opt_stereo_surround = 0;
   25.46 -
   25.47 -
   25.48 -Channel channel[MAXCHAN];
   25.49 -Voice voice[MAX_VOICES];
   25.50 -signed char drumvolume[MAXCHAN][MAXNOTE];
   25.51 -signed char drumpanpot[MAXCHAN][MAXNOTE];
   25.52 -signed char drumreverberation[MAXCHAN][MAXNOTE];
   25.53 -signed char drumchorusdepth[MAXCHAN][MAXNOTE];
   25.54 -
   25.55 -int
   25.56 -    voices=DEFAULT_VOICES;
   25.57 -
   25.58 -int32
   25.59 -    control_ratio=0,
   25.60 -    amplification=DEFAULT_AMPLIFICATION;
   25.61 -
   25.62 -FLOAT_T
   25.63 -    master_volume;
   25.64 -
   25.65 -int32 drumchannels=DEFAULT_DRUMCHANNELS;
   25.66 -int adjust_panning_immediately=0;
   25.67 -
   25.68 -struct _MidiSong {
   25.69 -	int32 samples;
   25.70 -	MidiEvent *events;
   25.71 -};
   25.72 -static int midi_playing = 0;
   25.73 -static int32 lost_notes, cut_notes;
   25.74 -static int32 *buffer_pointer;
   25.75 -static int32 buffered_count;
   25.76 -extern int32 *common_buffer;
   25.77 -extern resample_t *resample_buffer; /* to free it on Timidity_Close */
   25.78 -
   25.79 -static MidiEvent *event_list, *current_event;
   25.80 -static int32 sample_count, current_sample;
   25.81 -
   25.82 -int GM_System_On=0;
   25.83 -int XG_System_On=0;
   25.84 -int GS_System_On=0;
   25.85 -int XG_System_reverb_type;
   25.86 -int XG_System_chorus_type;
   25.87 -int XG_System_variation_type;
   25.88 -
   25.89 -
   25.90 -static void adjust_amplification(void)
   25.91 +static void adjust_amplification(MidiSong *song)
   25.92  { 
   25.93 -  master_volume = (FLOAT_T)(amplification) / (FLOAT_T)100.0;
   25.94 -  master_volume /= 2;
   25.95 +  song->master_volume = (float)(song->amplification) / (float)100.0;
   25.96  }
   25.97  
   25.98 -
   25.99 -static void adjust_master_volume(int32 vol)
  25.100 -{ 
  25.101 -  master_volume = (double)(vol*amplification) / 1638400.0L;
  25.102 -  master_volume /= 2;
  25.103 -}
  25.104 -
  25.105 -
  25.106 -static void reset_voices(void)
  25.107 +static void reset_voices(MidiSong *song)
  25.108  {
  25.109    int i;
  25.110    for (i=0; i<MAX_VOICES; i++)
  25.111 -    voice[i].status=VOICE_FREE;
  25.112 +    song->voice[i].status=VOICE_FREE;
  25.113  }
  25.114  
  25.115  /* Process the Reset All Controllers event */
  25.116 -static void reset_controllers(int c)
  25.117 +static void reset_controllers(MidiSong *song, int c)
  25.118  {
  25.119 -  channel[c].volume=90; /* Some standard says, although the SCC docs say 0. */
  25.120 -  channel[c].expression=127; /* SCC-1 does this. */
  25.121 -  channel[c].sustain=0;
  25.122 -  channel[c].pitchbend=0x2000;
  25.123 -  channel[c].pitchfactor=0; /* to be computed */
  25.124 -
  25.125 -  channel[c].reverberation = 0;
  25.126 -  channel[c].chorusdepth = 0;
  25.127 +  song->channel[c].volume=90; /* Some standard says, although the SCC docs say 0. */
  25.128 +  song->channel[c].expression=127; /* SCC-1 does this. */
  25.129 +  song->channel[c].sustain=0;
  25.130 +  song->channel[c].pitchbend=0x2000;
  25.131 +  song->channel[c].pitchfactor=0; /* to be computed */
  25.132  }
  25.133  
  25.134 -static void redraw_controllers(int c)
  25.135 -{
  25.136 -  ctl->volume(c, channel[c].volume);
  25.137 -  ctl->expression(c, channel[c].expression);
  25.138 -  ctl->sustain(c, channel[c].sustain);
  25.139 -  ctl->pitch_bend(c, channel[c].pitchbend);
  25.140 -}
  25.141 -
  25.142 -static void reset_midi(void)
  25.143 +static void reset_midi(MidiSong *song)
  25.144  {
  25.145    int i;
  25.146    for (i=0; i<MAXCHAN; i++)
  25.147      {
  25.148 -      reset_controllers(i);
  25.149 +      reset_controllers(song, i);
  25.150        /* The rest of these are unaffected by the Reset All Controllers event */
  25.151 -      channel[i].program=default_program;
  25.152 -      channel[i].panning=NO_PANNING;
  25.153 -      channel[i].pitchsens=2;
  25.154 -      channel[i].bank=0; /* tone bank or drum set */
  25.155 -      channel[i].harmoniccontent=64,
  25.156 -      channel[i].releasetime=64,
  25.157 -      channel[i].attacktime=64,
  25.158 -      channel[i].brightness=64,
  25.159 -      channel[i].sfx=0;
  25.160 +      song->channel[i].program=song->default_program;
  25.161 +      song->channel[i].panning=NO_PANNING;
  25.162 +      song->channel[i].pitchsens=2;
  25.163 +      song->channel[i].bank=0; /* tone bank or drum set */
  25.164      }
  25.165 -  reset_voices();
  25.166 +  reset_voices(song);
  25.167  }
  25.168  
  25.169 -static void select_sample(int v, Instrument *ip)
  25.170 +static void select_sample(MidiSong *song, int v, Instrument *ip, int vel)
  25.171  {
  25.172 -  int32 f, cdiff, diff, midfreq;
  25.173 +  Sint32 f, cdiff, diff;
  25.174    int s,i;
  25.175    Sample *sp, *closest;
  25.176  
  25.177 @@ -145,11 +76,22 @@
  25.178  
  25.179    if (s==1)
  25.180      {
  25.181 -      voice[v].sample=sp;
  25.182 +      song->voice[v].sample=sp;
  25.183        return;
  25.184      }
  25.185  
  25.186 -  f=voice[v].orig_frequency;
  25.187 +  f=song->voice[v].orig_frequency;
  25.188 +  for (i=0; i<s; i++)
  25.189 +    {
  25.190 +      if (sp->low_vel <= vel && sp->high_vel >= vel &&
  25.191 +          sp->low_freq <= f && sp->high_freq >= f)
  25.192 +	{
  25.193 +	  song->voice[v].sample=sp;
  25.194 +	  return;
  25.195 +	}
  25.196 +      sp++;
  25.197 +    }
  25.198 +
  25.199    /* 
  25.200       No suitable sample found! We'll select the sample whose root
  25.201       frequency is closest to the one we want. (Actually we should
  25.202 @@ -158,14 +100,9 @@
  25.203  
  25.204    cdiff=0x7FFFFFFF;
  25.205    closest=sp=ip->sample;
  25.206 -  midfreq = (sp->low_freq + sp->high_freq) / 2;
  25.207    for(i=0; i<s; i++)
  25.208      {
  25.209        diff=sp->root_freq - f;
  25.210 -  /*  But the root freq. can perfectly well lie outside the keyrange
  25.211 -   *  frequencies, so let's try:
  25.212 -   */
  25.213 -      /* diff=midfreq - f; */
  25.214        if (diff<0) diff=-diff;
  25.215        if (diff<cdiff)
  25.216  	{
  25.217 @@ -174,854 +111,248 @@
  25.218  	}
  25.219        sp++;
  25.220      }
  25.221 -  voice[v].sample=closest;
  25.222 +  song->voice[v].sample=closest;
  25.223    return;
  25.224  }
  25.225  
  25.226 -
  25.227 -
  25.228 -static void select_stereo_samples(int v, InstrumentLayer *lp)
  25.229 -{
  25.230 -  Instrument *ip;
  25.231 -  InstrumentLayer *nlp, *bestvel;
  25.232 -  int diffvel, midvel, mindiff;
  25.233 -
  25.234 -/* select closest velocity */
  25.235 -  bestvel = lp;
  25.236 -  mindiff = 500;
  25.237 -  for (nlp = lp; nlp; nlp = nlp->next) {
  25.238 -	midvel = (nlp->hi + nlp->lo)/2;
  25.239 -	if (!midvel) diffvel = 127;
  25.240 -	else if (voice[v].velocity < nlp->lo || voice[v].velocity > nlp->hi)
  25.241 -		diffvel = 200;
  25.242 -	else diffvel = voice[v].velocity - midvel;
  25.243 -	if (diffvel < 0) diffvel = -diffvel;
  25.244 -	if (diffvel < mindiff) {
  25.245 -		mindiff = diffvel;
  25.246 -		bestvel = nlp;
  25.247 -	}
  25.248 -  }
  25.249 -  ip = bestvel->instrument;
  25.250 -
  25.251 -  if (ip->right_sample) {
  25.252 -    ip->sample = ip->right_sample;
  25.253 -    ip->samples = ip->right_samples;
  25.254 -    select_sample(v, ip);
  25.255 -    voice[v].right_sample = voice[v].sample;
  25.256 -  }
  25.257 -  else voice[v].right_sample = 0;
  25.258 -  ip->sample = ip->left_sample;
  25.259 -  ip->samples = ip->left_samples;
  25.260 -  select_sample(v, ip);
  25.261 -}
  25.262 -
  25.263 -
  25.264 -static void recompute_freq(int v)
  25.265 +static void recompute_freq(MidiSong *song, int v)
  25.266  {
  25.267    int 
  25.268 -    sign=(voice[v].sample_increment < 0), /* for bidirectional loops */
  25.269 -    pb=channel[voice[v].channel].pitchbend;
  25.270 +    sign=(song->voice[v].sample_increment < 0), /* for bidirectional loops */
  25.271 +    pb=song->channel[song->voice[v].channel].pitchbend;
  25.272    double a;
  25.273    
  25.274 -  if (!voice[v].sample->sample_rate)
  25.275 +  if (!song->voice[v].sample->sample_rate)
  25.276      return;
  25.277  
  25.278 -  if (voice[v].vibrato_control_ratio)
  25.279 +  if (song->voice[v].vibrato_control_ratio)
  25.280      {
  25.281        /* This instrument has vibrato. Invalidate any precomputed
  25.282           sample_increments. */
  25.283  
  25.284        int i=VIBRATO_SAMPLE_INCREMENTS;
  25.285        while (i--)
  25.286 -	voice[v].vibrato_sample_increment[i]=0;
  25.287 +	song->voice[v].vibrato_sample_increment[i]=0;
  25.288      }
  25.289  
  25.290    if (pb==0x2000 || pb<0 || pb>0x3FFF)
  25.291 -    voice[v].frequency=voice[v].orig_frequency;
  25.292 +    song->voice[v].frequency = song->voice[v].orig_frequency;
  25.293    else
  25.294      {
  25.295        pb-=0x2000;
  25.296 -      if (!(channel[voice[v].channel].pitchfactor))
  25.297 +      if (!(song->channel[song->voice[v].channel].pitchfactor))
  25.298  	{
  25.299  	  /* Damn. Somebody bent the pitch. */
  25.300 -	  int32 i=pb*channel[voice[v].channel].pitchsens;
  25.301 +	  Sint32 i=pb*song->channel[song->voice[v].channel].pitchsens;
  25.302  	  if (pb<0)
  25.303  	    i=-i;
  25.304 -	  channel[voice[v].channel].pitchfactor=
  25.305 -	    (FLOAT_T)(bend_fine[(i>>5) & 0xFF] * bend_coarse[i>>13]);
  25.306 +	  song->channel[song->voice[v].channel].pitchfactor=
  25.307 +	    (float)(bend_fine[(i>>5) & 0xFF] * bend_coarse[i>>13]);
  25.308  	}
  25.309        if (pb>0)
  25.310 -	voice[v].frequency=
  25.311 -	  (int32)(channel[voice[v].channel].pitchfactor *
  25.312 -		  (double)(voice[v].orig_frequency));
  25.313 +	song->voice[v].frequency=
  25.314 +	  (Sint32)(song->channel[song->voice[v].channel].pitchfactor *
  25.315 +		  (double)(song->voice[v].orig_frequency));
  25.316        else
  25.317 -	voice[v].frequency=
  25.318 -	  (int32)((double)(voice[v].orig_frequency) /
  25.319 -		  channel[voice[v].channel].pitchfactor);
  25.320 +	song->voice[v].frequency=
  25.321 +	  (Sint32)((double)(song->voice[v].orig_frequency) /
  25.322 +		  song->channel[song->voice[v].channel].pitchfactor);
  25.323      }
  25.324  
  25.325 -  a = FSCALE(((double)(voice[v].sample->sample_rate) *
  25.326 -	      (double)(voice[v].frequency)) /
  25.327 -	     ((double)(voice[v].sample->root_freq) *
  25.328 -	      (double)(play_mode->rate)),
  25.329 +  a = FSCALE(((double)(song->voice[v].sample->sample_rate) *
  25.330 +	      (double)(song->voice[v].frequency)) /
  25.331 +	     ((double)(song->voice[v].sample->root_freq) *
  25.332 +	      (double)(song->rate)),
  25.333  	     FRACTION_BITS);
  25.334  
  25.335    if (sign) 
  25.336      a = -a; /* need to preserve the loop direction */
  25.337  
  25.338 -  voice[v].sample_increment = (int32)(a);
  25.339 +  song->voice[v].sample_increment = (Sint32)(a);
  25.340  }
  25.341  
  25.342 -static int expr_curve[128] = {
  25.343 -	7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 11, 
  25.344 -	11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 
  25.345 -	15, 16, 16, 17, 17, 17, 18, 18, 19, 19, 19, 20, 20, 21, 21, 22, 
  25.346 -	22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 28, 28, 29, 30, 30, 31, 
  25.347 -	32, 32, 33, 34, 35, 35, 36, 37, 38, 39, 39, 40, 41, 42, 43, 44, 
  25.348 -	45, 46, 47, 48, 49, 50, 51, 53, 54, 55, 56, 57, 59, 60, 61, 63, 
  25.349 -	64, 65, 67, 68, 70, 71, 73, 75, 76, 78, 80, 82, 83, 85, 87, 89, 
  25.350 -	91, 93, 95, 97, 99, 102, 104, 106, 109, 111, 113, 116, 118, 121,
  25.351 -	124, 127 
  25.352 -};
  25.353 -
  25.354 -static int panf(int pan, int speaker, int separation)
  25.355 +static void recompute_amp(MidiSong *song, int v)
  25.356  {
  25.357 -	int val;
  25.358 -	val = abs(pan - speaker);
  25.359 -	val = (val * 127) / separation;
  25.360 -	val = 127 - val;
  25.361 -	if (val < 0) val = 0;
  25.362 -	if (val > 127) val = 127;
  25.363 -	return expr_curve[val];
  25.364 -}
  25.365 -
  25.366 -
  25.367 -static int vcurve[128] = {
  25.368 -0,0,18,29,36,42,47,51,55,58,
  25.369 -60,63,65,67,69,71,73,74,76,77,
  25.370 -79,80,81,82,83,84,85,86,87,88,
  25.371 -89,90,91,92,92,93,94,95,95,96,
  25.372 -97,97,98,99,99,100,100,101,101,102,
  25.373 -103,103,104,104,105,105,106,106,106,107,
  25.374 -107,108,108,109,109,109,110,110,111,111,
  25.375 -111,112,112,112,113,113,114,114,114,115,
  25.376 -115,115,116,116,116,116,117,117,117,118,
  25.377 -118,118,119,119,119,119,120,120,120,120,
  25.378 -121,121,121,122,122,122,122,123,123,123,
  25.379 -123,123,124,124,124,124,125,125,125,125,
  25.380 -126,126,126,126,126,127,127,127
  25.381 -};
  25.382 -
  25.383 -static void recompute_amp(int v)
  25.384 -{
  25.385 -  int32 tempamp;
  25.386 -  int chan = voice[v].channel;
  25.387 -  int panning = voice[v].panning;
  25.388 -  int vol = channel[chan].volume;
  25.389 -  int expr = channel[chan].expression;
  25.390 -  int vel = vcurve[voice[v].velocity];
  25.391 -  FLOAT_T curved_expression, curved_volume;
  25.392 -
  25.393 -  if (channel[chan].kit)
  25.394 -   {
  25.395 -    int note = voice[v].sample->note_to_use;
  25.396 -    if (note>0 && drumvolume[chan][note]>=0) vol = drumvolume[chan][note];
  25.397 -    if (note>0 && drumpanpot[chan][note]>=0) panning = drumpanpot[chan][note];
  25.398 -   }
  25.399 -
  25.400 -  if (opt_expression_curve == 2) curved_expression = 127.0 * vol_table[expr];
  25.401 -  else if (opt_expression_curve == 1) curved_expression = 127.0 * expr_table[expr];
  25.402 -  else curved_expression = (FLOAT_T)expr;
  25.403 -
  25.404 -  if (opt_volume_curve == 2) curved_volume = 127.0 * vol_table[vol];
  25.405 -  else if (opt_volume_curve == 1) curved_volume = 127.0 * expr_table[vol];
  25.406 -  else curved_volume = (FLOAT_T)vol;
  25.407 -
  25.408 -  tempamp= (int32)((FLOAT_T)vel * curved_volume * curved_expression); /* 21 bits */
  25.409 +  Sint32 tempamp;
  25.410  
  25.411    /* TODO: use fscale */
  25.412  
  25.413 -  if (num_ochannels > 1)
  25.414 +  tempamp= (song->voice[v].velocity *
  25.415 +	    song->channel[song->voice[v].channel].volume * 
  25.416 +	    song->channel[song->voice[v].channel].expression); /* 21 bits */
  25.417 +
  25.418 +  if (!(song->encoding & PE_MONO))
  25.419      {
  25.420 -      if (panning > 60 && panning < 68)
  25.421 +      if (song->voice[v].panning > 60 && song->voice[v].panning < 68)
  25.422  	{
  25.423 -	  voice[v].panned=PANNED_CENTER;
  25.424 +	  song->voice[v].panned=PANNED_CENTER;
  25.425  
  25.426 -	  if (num_ochannels == 6) voice[v].left_amp =
  25.427 -		FSCALENEG((double) (tempamp) * voice[v].sample->volume *
  25.428 -			    master_volume, 20);
  25.429 -	  else voice[v].left_amp=
  25.430 -	        FSCALENEG((double)(tempamp) * voice[v].sample->volume *
  25.431 -			    master_volume, 21);
  25.432 +	  song->voice[v].left_amp=
  25.433 +	    FSCALENEG((double)(tempamp) * song->voice[v].sample->volume * song->master_volume,
  25.434 +		      21);
  25.435  	}
  25.436 -      else if (panning<5)
  25.437 +      else if (song->voice[v].panning<5)
  25.438  	{
  25.439 -	  voice[v].panned = PANNED_LEFT;
  25.440 +	  song->voice[v].panned = PANNED_LEFT;
  25.441  
  25.442 -	  voice[v].left_amp=
  25.443 -	    FSCALENEG((double)(tempamp) * voice[v].sample->volume * master_volume,
  25.444 +	  song->voice[v].left_amp=
  25.445 +	    FSCALENEG((double)(tempamp) * song->voice[v].sample->volume * song->master_volume,
  25.446  		      20);
  25.447  	}
  25.448 -      else if (panning>123)
  25.449 +      else if (song->voice[v].panning>123)
  25.450  	{
  25.451 -	  voice[v].panned = PANNED_RIGHT;
  25.452 +	  song->voice[v].panned = PANNED_RIGHT;
  25.453  
  25.454 -	  voice[v].left_amp= /* left_amp will be used */
  25.455 -	    FSCALENEG((double)(tempamp) * voice[v].sample->volume * master_volume,
  25.456 +	  song->voice[v].left_amp= /* left_amp will be used */
  25.457 +	    FSCALENEG((double)(tempamp) * song->voice[v].sample->volume * song->master_volume,
  25.458  		      20);
  25.459  	}
  25.460        else
  25.461  	{
  25.462 -	  FLOAT_T refv = (double)(tempamp) * voice[v].sample->volume * master_volume;
  25.463 -	  int wide_panning = 64;
  25.464 +	  song->voice[v].panned = PANNED_MYSTERY;
  25.465  
  25.466 -	  if (num_ochannels == 4) wide_panning = 95;
  25.467 -
  25.468 -	  voice[v].panned = PANNED_MYSTERY;
  25.469 -	  voice[v].lfe_amp = FSCALENEG(refv * 64, 27);
  25.470 -
  25.471 -		switch (num_ochannels)
  25.472 -		{
  25.473 -		    case 2:
  25.474 -		      voice[v].lr_amp = 0;
  25.475 -		      voice[v].left_amp = FSCALENEG(refv * (128-panning), 27);
  25.476 -		      voice[v].ce_amp = 0;
  25.477 -		      voice[v].right_amp = FSCALENEG(refv * panning, 27);
  25.478 -		      voice[v].rr_amp = 0;
  25.479 -		      break;
  25.480 -		    case 4:
  25.481 -		      voice[v].lr_amp = FSCALENEG(refv * panf(panning, 0, wide_panning), 27);
  25.482 -		      voice[v].left_amp = FSCALENEG(refv * panf(panning, 32, wide_panning), 27);
  25.483 -		      voice[v].ce_amp = 0;
  25.484 -		      voice[v].right_amp = FSCALENEG(refv * panf(panning, 95, wide_panning), 27);
  25.485 -		      voice[v].rr_amp = FSCALENEG(refv * panf(panning, 128, wide_panning), 27);
  25.486 -		      break;
  25.487 -		    case 6:
  25.488 -		      voice[v].lr_amp = FSCALENEG(refv * panf(panning, 0, wide_panning), 27);
  25.489 -		      voice[v].left_amp = FSCALENEG(refv * panf(panning, 32, wide_panning), 27);
  25.490 -		      voice[v].ce_amp = FSCALENEG(refv * panf(panning, 64, wide_panning), 27);
  25.491 -		      voice[v].right_amp = FSCALENEG(refv * panf(panning, 95, wide_panning), 27);
  25.492 -		      voice[v].rr_amp = FSCALENEG(refv * panf(panning, 128, wide_panning), 27);
  25.493 -		      break;
  25.494 -		}
  25.495 -
  25.496 +	  song->voice[v].left_amp=
  25.497 +	    FSCALENEG((double)(tempamp) * song->voice[v].sample->volume * song->master_volume,
  25.498 +		      27);
  25.499 +	  song->voice[v].right_amp = song->voice[v].left_amp * (song->voice[v].panning);
  25.500 +	  song->voice[v].left_amp *= (float)(127 - song->voice[v].panning);
  25.501  	}
  25.502      }
  25.503    else
  25.504      {
  25.505 -      voice[v].panned=PANNED_CENTER;
  25.506 +      song->voice[v].panned = PANNED_CENTER;
  25.507  
  25.508 -      voice[v].left_amp=
  25.509 -	FSCALENEG((double)(tempamp) * voice[v].sample->volume * master_volume,
  25.510 +      song->voice[v].left_amp=
  25.511 +	FSCALENEG((double)(tempamp) * song->voice[v].sample->volume * song->master_volume,
  25.512  		  21);
  25.513      }
  25.514  }
  25.515  
  25.516 +static void start_note(MidiSong *song, MidiEvent *e, int i)
  25.517 +{
  25.518 +  Instrument *ip;
  25.519 +  int j;
  25.520  
  25.521 -#define NOT_CLONE 0
  25.522 -#define STEREO_CLONE 1
  25.523 -#define REVERB_CLONE 2
  25.524 -#define CHORUS_CLONE 3
  25.525 +  if (ISDRUMCHANNEL(song, e->channel))
  25.526 +    {
  25.527 +      if (!(ip=song->drumset[song->channel[e->channel].bank]->instrument[e->a]))
  25.528 +	{
  25.529 +	  if (!(ip=song->drumset[0]->instrument[e->a]))
  25.530 +	    return; /* No instrument? Then we can't play. */
  25.531 +	}
  25.532 +      if (ip->samples != 1)
  25.533 +	{
  25.534 +	  SNDDBG(("Strange: percussion instrument with %d samples!",
  25.535 +		  ip->samples));
  25.536 +	}
  25.537  
  25.538 +      if (ip->sample->note_to_use) /* Do we have a fixed pitch? */
  25.539 +	song->voice[i].orig_frequency = freq_table[(int)(ip->sample->note_to_use)];
  25.540 +      else
  25.541 +	song->voice[i].orig_frequency = freq_table[e->a & 0x7F];
  25.542 +      
  25.543 +      /* drums are supposed to have only one sample */
  25.544 +      song->voice[i].sample = ip->sample;
  25.545 +    }
  25.546 +  else
  25.547 +    {
  25.548 +      if (song->channel[e->channel].program == SPECIAL_PROGRAM)
  25.549 +	ip=song->default_instrument;
  25.550 +      else if (!(ip=song->tonebank[song->channel[e->channel].bank]->
  25.551 +		 instrument[song->channel[e->channel].program]))
  25.552 +	{
  25.553 +	  if (!(ip=song->tonebank[0]->instrument[song->channel[e->channel].program]))
  25.554 +	    return; /* No instrument? Then we can't play. */
  25.555 +	}
  25.556  
  25.557 -/* just a variant of note_on() */
  25.558 -static int vc_alloc(int j)
  25.559 +      if (ip->sample->note_to_use) /* Fixed-pitch instrument? */
  25.560 +	song->voice[i].orig_frequency = freq_table[(int)(ip->sample->note_to_use)];
  25.561 +      else
  25.562 +	song->voice[i].orig_frequency = freq_table[e->a & 0x7F];
  25.563 +      select_sample(song, i, ip, e->b);
  25.564 +    }
  25.565 +
  25.566 +  song->voice[i].status = VOICE_ON;
  25.567 +  song->voice[i].channel = e->channel;
  25.568 +  song->voice[i].note = e->a;
  25.569 +  song->voice[i].velocity = e->b;
  25.570 +  song->voice[i].sample_offset = 0;
  25.571 +  song->voice[i].sample_increment = 0; /* make sure it isn't negative */
  25.572 +
  25.573 +  song->voice[i].tremolo_phase = 0;
  25.574 +  song->voice[i].tremolo_phase_increment = song->voice[i].sample->tremolo_phase_increment;
  25.575 +  song->voice[i].tremolo_sweep = song->voice[i].sample->tremolo_sweep_increment;
  25.576 +  song->voice[i].tremolo_sweep_position = 0;
  25.577 +
  25.578 +  song->voice[i].vibrato_sweep = song->voice[i].sample->vibrato_sweep_increment;
  25.579 +  song->voice[i].vibrato_sweep_position = 0;
  25.580 +  song->voice[i].vibrato_control_ratio = song->voice[i].sample->vibrato_control_ratio;
  25.581 +  song->voice[i].vibrato_control_counter = song->voice[i].vibrato_phase = 0;
  25.582 +  for (j=0; j<VIBRATO_SAMPLE_INCREMENTS; j++)
  25.583 +    song->voice[i].vibrato_sample_increment[j] = 0;
  25.584 +
  25.585 +  if (song->channel[e->channel].panning != NO_PANNING)
  25.586 +    song->voice[i].panning = song->channel[e->channel].panning;
  25.587 +  else
  25.588 +    song->voice[i].panning = song->voice[i].sample->panning;
  25.589 +
  25.590 +  recompute_freq(song, i);
  25.591 +  recompute_amp(song, i);
  25.592 +  if (song->voice[i].sample->modes & MODES_ENVELOPE)
  25.593 +    {
  25.594 +      /* Ramp up from 0 */
  25.595 +      song->voice[i].envelope_stage = 0;
  25.596 +      song->voice[i].envelope_volume = 0;
  25.597 +      song->voice[i].control_counter = 0;
  25.598 +      recompute_envelope(song, i);
  25.599 +      apply_envelope_to_amp(song, i);
  25.600 +    }
  25.601 +  else
  25.602 +    {
  25.603 +      song->voice[i].envelope_increment = 0;
  25.604 +      apply_envelope_to_amp(song, i);
  25.605 +    }
  25.606 +}
  25.607 +
  25.608 +static void kill_note(MidiSong *song, int i)
  25.609  {
  25.610 -  int i=voices; 
  25.611 +  song->voice[i].status = VOICE_DIE;
  25.612 +}
  25.613 +
  25.614 +/* Only one instance of a note can be playing on a single channel. */
  25.615 +static void note_on(MidiSong *song)
  25.616 +{
  25.617 +  int i = song->voices, lowest=-1; 
  25.618 +  Sint32 lv=0x7FFFFFFF, v;
  25.619 +  MidiEvent *e = song->current_event;
  25.620  
  25.621    while (i--)
  25.622      {
  25.623 -      if (i == j) continue;
  25.624 -      if (voice[i].status & VOICE_FREE) {
  25.625 -	return i;
  25.626 -      }
  25.627 -    }
  25.628 -  return -1;
  25.629 -}
  25.630 -
  25.631 -static void kill_note(int i);
  25.632 -
  25.633 -static void kill_others(int i)
  25.634 -{
  25.635 -  int j=voices; 
  25.636 -
  25.637 -  if (!voice[i].sample->exclusiveClass) return;
  25.638 -
  25.639 -  while (j--)
  25.640 -    {
  25.641 -      if (voice[j].status & (VOICE_FREE|VOICE_OFF|VOICE_DIE)) continue;
  25.642 -      if (i == j) continue;
  25.643 -      if (voice[i].channel != voice[j].channel) continue;
  25.644 -      if (voice[j].sample->note_to_use)
  25.645 -      {
  25.646 -    	if (voice[j].sample->exclusiveClass != voice[i].sample->exclusiveClass) continue;
  25.647 -        kill_note(j);
  25.648 -      }
  25.649 -    }
  25.650 -}
  25.651 -
  25.652 -
  25.653 -static void clone_voice(Instrument *ip, int v, MidiEvent *e, int clone_type, int variationbank)
  25.654 -{
  25.655 -  int w, played_note, chorus=0, reverb=0, milli;
  25.656 -  int chan = voice[v].channel;
  25.657 -
  25.658 -  if (clone_type == STEREO_CLONE) {
  25.659 -	if (!voice[v].right_sample && variationbank != 3) return;
  25.660 -	if (variationbank == 6) return;
  25.661 -  }
  25.662 -
  25.663 -  if (channel[chan].kit) {
  25.664 -	reverb = drumreverberation[chan][voice[v].note];
  25.665 -	chorus = drumchorusdepth[chan][voice[v].note];
  25.666 -  }
  25.667 -  else {
  25.668 -	reverb = channel[chan].reverberation;
  25.669 -	chorus = channel[chan].chorusdepth;
  25.670 -  }
  25.671 -
  25.672 -  if (clone_type == REVERB_CLONE) chorus = 0;
  25.673 -  else if (clone_type == CHORUS_CLONE) reverb = 0;
  25.674 -  else if (clone_type == STEREO_CLONE) reverb = chorus = 0;
  25.675 -
  25.676 -  if (reverb > 127) reverb = 127;
  25.677 -  if (chorus > 127) chorus = 127;
  25.678 -
  25.679 -  if (clone_type == CHORUS_CLONE) {
  25.680 -	 if (variationbank == 32) chorus = 30;
  25.681 -	 else if (variationbank == 33) chorus = 60;
  25.682 -	 else if (variationbank == 34) chorus = 90;
  25.683 -  }
  25.684 -
  25.685 -  chorus /= 2;  /* This is an ad hoc adjustment. */
  25.686 -
  25.687 -  if (!reverb && !chorus && clone_type != STEREO_CLONE) return;
  25.688 -
  25.689 -  if ( (w = vc_alloc(v)) < 0 ) return;
  25.690 -
  25.691 -  voice[w] = voice[v];
  25.692 -  if (clone_type==STEREO_CLONE) voice[v].clone_voice = w;
  25.693 -  voice[w].clone_voice = v;
  25.694 -  voice[w].clone_type = clone_type;
  25.695 -
  25.696 -  voice[w].sample = voice[v].right_sample;
  25.697 -  voice[w].velocity= e->b;
  25.698 -
  25.699 -  milli = play_mode->rate/1000;
  25.700 -
  25.701 -  if (clone_type == STEREO_CLONE) {
  25.702 -    int left, right, leftpan, rightpan;
  25.703 -    int panrequest = voice[v].panning;
  25.704 -    if (variationbank == 3) {
  25.705 -	voice[v].panning = 0;
  25.706 -	voice[w].panning = 127;
  25.707 -    }
  25.708 -    else {
  25.709 -	if (voice[v].sample->panning > voice[w].sample->panning) {
  25.710 -	  left = w;
  25.711 -	  right = v;
  25.712 -	}
  25.713 -	else {
  25.714 -	  left = v;
  25.715 -	  right = w;
  25.716 -	}
  25.717 -#define INSTRUMENT_SEPARATION 12
  25.718 -	leftpan = panrequest - INSTRUMENT_SEPARATION / 2;
  25.719 -	rightpan = leftpan + INSTRUMENT_SEPARATION;
  25.720 -	if (leftpan < 0) {
  25.721 -		leftpan = 0;
  25.722 -		rightpan = leftpan + INSTRUMENT_SEPARATION;
  25.723 -	}
  25.724 -	if (rightpan > 127) {
  25.725 -		rightpan = 127;
  25.726 -		leftpan = rightpan - INSTRUMENT_SEPARATION;
  25.727 -	}
  25.728 -	voice[left].panning = leftpan;
  25.729 -	voice[right].panning = rightpan;
  25.730 -	voice[right].echo_delay = 20 * milli;
  25.731 -    }
  25.732 -  }
  25.733 -
  25.734 -  voice[w].volume = voice[w].sample->volume;
  25.735 -
  25.736 -  if (reverb) {
  25.737 -	if (opt_stereo_surround) {
  25.738 -		if (voice[w].panning > 64) voice[w].panning = 127;
  25.739 -		else voice[w].panning = 0;
  25.740 -	}
  25.741 -	else {
  25.742 -		if (voice[v].panning < 64) voice[w].panning = 64 + reverb/2;
  25.743 -		else voice[w].panning = 64 - reverb/2;
  25.744 -	}
  25.745 -
  25.746 -/* try 98->99 for melodic instruments ? (bit much for percussion) */
  25.747 -	voice[w].volume *= vol_table[(127-reverb)/8 + 98];
  25.748 -
  25.749 -	voice[w].echo_delay += reverb * milli;
  25.750 -	voice[w].envelope_rate[DECAY] *= 2;
  25.751 -	voice[w].envelope_rate[RELEASE] /= 2;
  25.752 -
  25.753 -	if (XG_System_reverb_type >= 0) {
  25.754 -	    int subtype = XG_System_reverb_type & 0x07;
  25.755 -	    int rtype = XG_System_reverb_type >>3;
  25.756 -	    switch (rtype) {
  25.757 -		case 0: /* no effect */
  25.758 -		  break;
  25.759 -		case 1: /* hall */
  25.760 -		  if (subtype) voice[w].echo_delay += 100 * milli;
  25.761 -		  break;
  25.762 -		case 2: /* room */
  25.763 -		  voice[w].echo_delay /= 2;
  25.764 -		  break;
  25.765 -		case 3: /* stage */
  25.766 -		  voice[w].velocity = voice[v].velocity;
  25.767 -		  break;
  25.768 -		case 4: /* plate */
  25.769 -		  voice[w].panning = voice[v].panning;
  25.770 -		  break;
  25.771 -		case 16: /* white room */
  25.772 -		  voice[w].echo_delay = 0;
  25.773 -		  break;
  25.774 -		case 17: /* tunnel */
  25.775 -		  voice[w].echo_delay *= 2;
  25.776 -		  voice[w].velocity /= 2;
  25.777 -		  break;
  25.778 -		case 18: /* canyon */
  25.779 -		  voice[w].echo_delay *= 2;
  25.780 -		  break;
  25.781 -		case 19: /* basement */
  25.782 -		  voice[w].velocity /= 2;
  25.783 -		  break;
  25.784 -	        default: break;
  25.785 -	    }
  25.786 -	}
  25.787 -  }
  25.788 -  played_note = voice[w].sample->note_to_use;
  25.789 -  if (!played_note) {
  25.790 -	played_note = e->a & 0x7f;
  25.791 -	if (variationbank == 35) played_note += 12;
  25.792 -	else if (variationbank == 36) played_note -= 12;
  25.793 -	else if (variationbank == 37) played_note += 7;
  25.794 -	else if (variationbank == 36) played_note -= 7;
  25.795 -  }
  25.796 -#if 0
  25.797 -  played_note = ( (played_note - voice[w].sample->freq_center) * voice[w].sample->freq_scale ) / 1024 +
  25.798 -		voice[w].sample->freq_center;
  25.799 -#endif
  25.800 -  voice[w].note = played_note;
  25.801 -  voice[w].orig_frequency = freq_table[played_note];
  25.802 -
  25.803 -  if (chorus) {
  25.804 -	if (opt_stereo_surround) {
  25.805 -	  if (voice[v].panning < 64) voice[w].panning = voice[v].panning + 32;
  25.806 -	  else voice[w].panning = voice[v].panning - 32;
  25.807 -	}
  25.808 -
  25.809 -	if (!voice[w].vibrato_control_ratio) {
  25.810 -		voice[w].vibrato_control_ratio = 100;
  25.811 -		voice[w].vibrato_depth = 6;
  25.812 -		voice[w].vibrato_sweep = 74;
  25.813 -	}
  25.814 -	voice[w].volume *= 0.40;
  25.815 -	voice[v].volume = voice[w].volume;
  25.816 -	recompute_amp(v);
  25.817 -        apply_envelope_to_amp(v);
  25.818 -	voice[w].vibrato_sweep = chorus/2;
  25.819 -	voice[w].vibrato_depth /= 2;
  25.820 -	if (!voice[w].vibrato_depth) voice[w].vibrato_depth = 2;
  25.821 -	voice[w].vibrato_control_ratio /= 2;
  25.822 -	voice[w].echo_delay += 30 * milli;
  25.823 -
  25.824 -	if (XG_System_chorus_type >= 0) {
  25.825 -	    int subtype = XG_System_chorus_type & 0x07;
  25.826 -	    int chtype = 0x0f & (XG_System_chorus_type >> 3);
  25.827 -	    switch (chtype) {
  25.828 -		case 0: /* no effect */
  25.829 -		  break;
  25.830 -		case 1: /* chorus */
  25.831 -		  chorus /= 3;
  25.832 -		  if(channel[ voice[w].channel ].pitchbend + chorus < 0x2000)
  25.833 -            		voice[w].orig_frequency =
  25.834 -				(uint32)( (FLOAT_T)voice[w].orig_frequency * bend_fine[chorus] );
  25.835 -        	  else voice[w].orig_frequency =
  25.836 -			(uint32)( (FLOAT_T)voice[w].orig_frequency / bend_fine[chorus] );
  25.837 -		  if (subtype) voice[w].vibrato_depth *= 2;
  25.838 -		  break;
  25.839 -		case 2: /* celeste */
  25.840 -		  voice[w].orig_frequency += (voice[w].orig_frequency/128) * chorus;
  25.841 -		  break;
  25.842 -		case 3: /* flanger */
  25.843 -		  voice[w].vibrato_control_ratio = 10;
  25.844 -		  voice[w].vibrato_depth = 100;
  25.845 -		  voice[w].vibrato_sweep = 8;
  25.846 -		  voice[w].echo_delay += 200 * milli;
  25.847 -		  break;
  25.848 -		case 4: /* symphonic : cf Children of the Night /128 bad, /1024 ok */
  25.849 -		  voice[w].orig_frequency += (voice[w].orig_frequency/512) * chorus;
  25.850 -		  voice[v].orig_frequency -= (voice[v].orig_frequency/512) * chorus;
  25.851 -		  recompute_freq(v);
  25.852 -		  break;
  25.853 -		case 8: /* phaser */
  25.854 -		  break;
  25.855 -	      default:
  25.856 -		  break;
  25.857 -	    }
  25.858 -	}
  25.859 -	else {
  25.860 -	    chorus /= 3;
  25.861 -	    if(channel[ voice[w].channel ].pitchbend + chorus < 0x2000)
  25.862 -          	voice[w].orig_frequency =
  25.863 -			(uint32)( (FLOAT_T)voice[w].orig_frequency * bend_fine[chorus] );
  25.864 -            else voice[w].orig_frequency =
  25.865 -		(uint32)( (FLOAT_T)voice[w].orig_frequency / bend_fine[chorus] );
  25.866 -	}
  25.867 -  }
  25.868 -#if 0
  25.869 -  voice[w].loop_start = voice[w].sample->loop_start;
  25.870 -  voice[w].loop_end = voice[w].sample->loop_end;
  25.871 -#endif
  25.872 -  voice[w].echo_delay_count = voice[w].echo_delay;
  25.873 -  if (reverb) voice[w].echo_delay *= 2;
  25.874 -
  25.875 -  recompute_freq(w);
  25.876 -  recompute_amp(w);
  25.877 -  if (voice[w].sample->modes & MODES_ENVELOPE)
  25.878 -    {
  25.879 -      /* Ramp up from 0 */
  25.880 -      voice[w].envelope_stage=ATTACK;
  25.881 -      voice[w].modulation_stage=ATTACK;
  25.882 -      voice[w].envelope_volume=0;
  25.883 -      voice[w].modulation_volume=0;
  25.884 -      voice[w].control_counter=0;
  25.885 -      voice[w].modulation_counter=0;
  25.886 -      recompute_envelope(w);
  25.887 -      /*recompute_modulation(w);*/
  25.888 -    }
  25.889 -  else
  25.890 -    {
  25.891 -      voice[w].envelope_increment=0;
  25.892 -      voice[w].modulation_increment=0;
  25.893 -    }
  25.894 -  apply_envelope_to_amp(w);
  25.895 -}
  25.896 -
  25.897 -
  25.898 -static void xremap(int *banknumpt, int *this_notept, int this_kit) {
  25.899 -	int i, newmap;
  25.900 -	int banknum = *banknumpt;
  25.901 -	int this_note = *this_notept;
  25.902 -	int newbank, newnote;
  25.903 -
  25.904 -	if (!this_kit) {
  25.905 -		if (banknum == SFXBANK && tonebank[SFXBANK]) return;
  25.906 -		if (banknum == SFXBANK && tonebank[120]) *banknumpt = 120;
  25.907 -		return;
  25.908 -	}
  25.909 -
  25.910 -	if (this_kit != 127 && this_kit != 126) return;
  25.911 -
  25.912 -	for (i = 0; i < XMAPMAX; i++) {
  25.913 -		newmap = xmap[i][0];
  25.914 -		if (!newmap) return;
  25.915 -		if (this_kit == 127 && newmap != XGDRUM) continue;
  25.916 -		if (this_kit == 126 && newmap != SFXDRUM1) continue;
  25.917 -		if (xmap[i][1] != banknum) continue;
  25.918 -		if (xmap[i][3] != this_note) continue;
  25.919 -		newbank = xmap[i][2];
  25.920 -		newnote = xmap[i][4];
  25.921 -		if (newbank == banknum && newnote == this_note) return;
  25.922 -		if (!drumset[newbank]) return;
  25.923 -		if (!drumset[newbank]->tone[newnote].layer) return;
  25.924 -		if (drumset[newbank]->tone[newnote].layer == MAGIC_LOAD_INSTRUMENT) return;
  25.925 -		*banknumpt = newbank;
  25.926 -		*this_notept = newnote;
  25.927 -		return;
  25.928 -	}
  25.929 -}
  25.930 -
  25.931 -
  25.932 -static void start_note(MidiEvent *e, int i)
  25.933 -{
  25.934 -  InstrumentLayer *lp;
  25.935 -  Instrument *ip;
  25.936 -  int j, banknum, ch=e->channel;
  25.937 -  int played_note, drumpan=NO_PANNING;
  25.938 -  int32 rt;
  25.939 -  int attacktime, releasetime, decaytime, variationbank;
  25.940 -  int brightness = channel[ch].brightness;
  25.941 -  int harmoniccontent = channel[ch].harmoniccontent;
  25.942 -  int this_note = e->a;
  25.943 -  int this_velocity = e->b;
  25.944 -  int drumsflag = channel[ch].kit;
  25.945 -  int this_prog = channel[ch].program;
  25.946 -
  25.947 -  if (channel[ch].sfx) banknum=channel[ch].sfx;
  25.948 -  else banknum=channel[ch].bank;
  25.949 -
  25.950 -  voice[i].velocity=this_velocity;
  25.951 -
  25.952 -  if (XG_System_On) xremap(&banknum, &this_note, drumsflag);
  25.953 -  /*   if (current_config_pc42b) pcmap(&banknum, &this_note, &this_prog, &drumsflag); */
  25.954 -
  25.955 -  if (drumsflag)
  25.956 -    {
  25.957 -      if (!(lp=drumset[banknum]->tone[this_note].layer))
  25.958 -	{
  25.959 -	  if (!(lp=drumset[0]->tone[this_note].layer))
  25.960 -	    return; /* No instrument? Then we can't play. */
  25.961 -	}
  25.962 -      ip = lp->instrument;
  25.963 -      if (ip->type == INST_GUS && ip->samples != 1)
  25.964 -	{
  25.965 -	  ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, 
  25.966 -	       "Strange: percussion instrument with %d samples!", ip->samples);
  25.967 -	}
  25.968 -
  25.969 -      if (ip->sample->note_to_use) /* Do we have a fixed pitch? */
  25.970 -	{
  25.971 -	  voice[i].orig_frequency=freq_table[(int)(ip->sample->note_to_use)];
  25.972 -	  drumpan=drumpanpot[ch][(int)ip->sample->note_to_use];
  25.973 -	}
  25.974 -      else
  25.975 -	voice[i].orig_frequency=freq_table[this_note & 0x7F];
  25.976 -
  25.977 -    }
  25.978 -  else
  25.979 -    {
  25.980 -      if (channel[ch].program==SPECIAL_PROGRAM)
  25.981 -	lp=default_instrument;
  25.982 -      else if (!(lp=tonebank[channel[ch].bank]->
  25.983 -		 tone[channel[ch].program].layer))
  25.984 -	{
  25.985 -	  if (!(lp=tonebank[0]->tone[this_prog].layer))
  25.986 -	    return; /* No instrument? Then we can't play. */
  25.987 -	}
  25.988 -      ip = lp->instrument;
  25.989 -      if (ip->sample->note_to_use) /* Fixed-pitch instrument? */
  25.990 -	voice[i].orig_frequency=freq_table[(int)(ip->sample->note_to_use)];
  25.991 -      else
  25.992 -	voice[i].orig_frequency=freq_table[this_note & 0x7F];
  25.993 -    }
  25.994 -
  25.995 -    select_stereo_samples(i, lp);
  25.996 -
  25.997 -  voice[i].starttime = e->time;
  25.998 -  played_note = voice[i].sample->note_to_use;
  25.999 -
 25.1000 -  if (!played_note || !drumsflag) played_note = this_note & 0x7f;
 25.1001 -#if 0
 25.1002 -  played_note = ( (played_note - voice[i].sample->freq_center) * voice[i].sample->freq_scale ) / 1024 +
 25.1003 -		voice[i].sample->freq_center;
 25.1004 -#endif
 25.1005 -  voice[i].status=VOICE_ON;
 25.1006 -  voice[i].channel=ch;
 25.1007 -  voice[i].note=played_note;
 25.1008 -  voice[i].velocity=this_velocity;
 25.1009 -  voice[i].sample_offset=0;
 25.1010 -  voice[i].sample_increment=0; /* make sure it isn't negative */
 25.1011 -
 25.1012 -  voice[i].tremolo_phase=0;
 25.1013 -  voice[i].tremolo_phase_increment=voice[i].sample->tremolo_phase_increment;
 25.1014 -  voice[i].tremolo_sweep=voice[i].sample->tremolo_sweep_increment;
 25.1015 -  voice[i].tremolo_sweep_position=0;
 25.1016 -
 25.1017 -  voice[i].vibrato_sweep=voice[i].sample->vibrato_sweep_increment;
 25.1018 -  voice[i].vibrato_sweep_position=0;
 25.1019 -  voice[i].vibrato_depth=voice[i].sample->vibrato_depth;
 25.1020 -  voice[i].vibrato_control_ratio=voice[i].sample->vibrato_control_ratio;
 25.1021 -  voice[i].vibrato_control_counter=voice[i].vibrato_phase=0;
 25.1022 -  voice[i].vibrato_delay = voice[i].sample->vibrato_delay;
 25.1023 -
 25.1024 -  kill_others(i);
 25.1025 -
 25.1026 -  for (j=0; j<VIBRATO_SAMPLE_INCREMENTS; j++)
 25.1027 -    voice[i].vibrato_sample_increment[j]=0;
 25.1028 -
 25.1029 -
 25.1030 -  attacktime = channel[ch].attacktime;
 25.1031 -  releasetime = channel[ch].releasetime;
 25.1032 -  decaytime = 64;
 25.1033 -  variationbank = channel[ch].variationbank;
 25.1034 -
 25.1035 -  switch (variationbank) {
 25.1036 -	case  8:
 25.1037 -		attacktime = 64+32;
 25.1038 -		break;
 25.1039 -	case 12:
 25.1040 -		decaytime = 64-32;
 25.1041 -		break;
 25.1042 -	case 16:
 25.1043 -		brightness = 64+16;
 25.1044 -		break;
 25.1045 -	case 17:
 25.1046 -		brightness = 64+32;
 25.1047 -		break;
 25.1048 -	case 18:
 25.1049 -		brightness = 64-16;
 25.1050 -		break;
 25.1051 -	case 19:
 25.1052 -		brightness = 64-32;
 25.1053 -		break;
 25.1054 -	case 20:
 25.1055 -		harmoniccontent = 64+16;
 25.1056 -		break;
 25.1057 -#if 0
 25.1058 -	case 24:
 25.1059 -		voice[i].modEnvToFilterFc=2.0;
 25.1060 -      		voice[i].sample->cutoff_freq = 800;
 25.1061 -		break;
 25.1062 -	case 25:
 25.1063 -		voice[i].modEnvToFilterFc=-2.0;
 25.1064 -      		voice[i].sample->cutoff_freq = 800;
 25.1065 -		break;
 25.1066 -	case 27:
 25.1067 -		voice[i].modLfoToFilterFc=2.0;
 25.1068 -		voice[i].lfo_phase_increment=109;
 25.1069 -		voice[i].lfo_sweep=122;
 25.1070 -      		voice[i].sample->cutoff_freq = 800;
 25.1071 -		break;
 25.1072 -	case 28:
 25.1073 -		voice[i].modLfoToFilterFc=-2.0;
 25.1074 -		voice[i].lfo_phase_increment=109;
 25.1075 -		voice[i].lfo_sweep=122;
 25.1076 -      		voice[i].sample->cutoff_freq = 800;
 25.1077 -		break;
 25.1078 -#endif
 25.1079 -	default:
 25.1080 -		break;
 25.1081 -  }
 25.1082 -
 25.1083 -
 25.1084 -  for (j=ATTACK; j<MAXPOINT; j++)
 25.1085 -    {
 25.1086 -	voice[i].envelope_rate[j]=voice[i].sample->envelope_rate[j];
 25.1087 -	voice[i].envelope_offset[j]=voice[i].sample->envelope_offset[j];
 25.1088 -    }
 25.1089 -
 25.1090 -  voice[i].echo_delay=voice[i].envelope_rate[DELAY];
 25.1091 -  voice[i].echo_delay_count = voice[i].echo_delay;
 25.1092 -
 25.1093 -  if (attacktime!=64)
 25.1094 -    {
 25.1095 -	rt = voice[i].envelope_rate[ATTACK];
 25.1096 -	rt = rt + ( (64-attacktime)*rt ) / 100;
 25.1097 -	if (rt > 1000) voice[i].envelope_rate[ATTACK] = rt;
 25.1098 -    }
 25.1099 -  if (releasetime!=64)
 25.1100 -    {
 25.1101 -	rt = voice[i].envelope_rate[RELEASE];
 25.1102 -	rt = rt + ( (64-releasetime)*rt ) / 100;
 25.1103 -	if (rt > 1000) voice[i].envelope_rate[RELEASE] = rt;
 25.1104 -    }
 25.1105 -  if (decaytime!=64)
 25.1106 -    {
 25.1107 -	rt = voice[i].envelope_rate[DECAY];
 25.1108 -	rt = rt + ( (64-decaytime)*rt ) / 100;
 25.1109 -	if (rt > 1000) voice[i].envelope_rate[DECAY] = rt;
 25.1110 -    }
 25.1111 -
 25.1112 -  if (channel[ch].panning != NO_PANNING)
 25.1113 -    voice[i].panning=channel[ch].panning;
 25.1114 -  else
 25.1115 -    voice[i].panning=voice[i].sample->panning;
 25.1116 -  if (drumpan != NO_PANNING)
 25.1117 -    voice[i].panning=drumpan;
 25.1118 -
 25.1119 -  if (variationbank == 1) {
 25.1120 -    int pan = voice[i].panning;
 25.1121 -    int disturb = 0;
 25.1122 -    /* If they're close up (no reverb) and you are behind the pianist,
 25.1123 -     * high notes come from the right, so we'll spread piano etc. notes
 25.1124 -     * out horizontally according to their pitches.
 25.1125 -     */
 25.1126 -    if (this_prog < 21) {
 25.1127 -	    int n = voice[i].velocity - 32;
 25.1128 -	    if (n < 0) n = 0;
 25.1129 -	    if (n > 64) n = 64;
 25.1130 -	    pan = pan/2 + n;
 25.1131 -	}
 25.1132 -    /* For other types of instruments, the music sounds more alive if
 25.1133 -     * notes come from slightly different directions.  However, instruments
 25.1134 -     * do drift around in a sometimes disconcerting way, so the following
 25.1135 -     * might not be such a good idea.
 25.1136 -     */
 25.1137 -    else disturb = (voice[i].velocity/32 % 8) +
 25.1138 -	(voice[i].note % 8); /* /16? */
 25.1139 -
 25.1140 -    if (pan < 64) pan += disturb;
 25.1141 -    else pan -= disturb;
 25.1142 -    if (pan < 0) pan = 0;
 25.1143 -    else if (pan > 127) pan = 127;
 25.1144 -    voice[i].panning = pan;
 25.1145 -  }
 25.1146 -
 25.1147 -  recompute_freq(i);
 25.1148 -  recompute_amp(i);
 25.1149 -  if (voice[i].sample->modes & MODES_ENVELOPE)
 25.1150 -    {
 25.1151 -      /* Ramp up from 0 */
 25.1152 -      voice[i].envelope_stage=ATTACK;
 25.1153 -      voice[i].envelope_volume=0;
 25.1154 -      voice[i].control_counter=0;
 25.1155 -      recompute_envelope(i);
 25.1156 -    }
 25.1157 -  else
 25.1158 -    {
 25.1159 -      voice[i].envelope_increment=0;
 25.1160 -    }
 25.1161 -  apply_envelope_to_amp(i);
 25.1162 -
 25.1163 -  voice[i].clone_voice = -1;
 25.1164 -  voice[i].clone_type = NOT_CLONE;
 25.1165 -
 25.1166 -  clone_voice(ip, i, e, STEREO_CLONE, variationbank);
 25.1167 -  clone_voice(ip, i, e, CHORUS_CLONE, variationbank);
 25.1168 -  clone_voice(ip, i, e, REVERB_CLONE, variationbank);
 25.1169 -
 25.1170 -  ctl->note(i);
 25.1171 -}
 25.1172 -
 25.1173 -static void kill_note(int i)
 25.1174 -{
 25.1175 -  voice[i].status=VOICE_DIE;
 25.1176 -  if (voice[i].clone_voice >= 0)
 25.1177 -	voice[ voice[i].clone_voice ].status=VOICE_DIE;
 25.1178 -  ctl->note(i);
 25.1179 -}
 25.1180 -
 25.1181 -
 25.1182 -/* Only one instance of a note can be playing on a single channel. */
 25.1183 -static void note_on(MidiEvent *e)
 25.1184 -{
 25.1185 -  int i=voices, lowest=-1; 
 25.1186 -  int32 lv=0x7FFFFFFF, v;
 25.1187 -
 25.1188 -  while (i--)
 25.1189 -    {
 25.1190 -      if (voice[i].status == VOICE_FREE)
 25.1191 +      if (song->voice[i].status == VOICE_FREE)
 25.1192  	lowest=i; /* Can't get a lower volume than silence */
 25.1193 -      else if (voice[i].channel==e->channel && 
 25.1194 -	       (voice[i].note==e->a || channel[voice[i].channel].mono))
 25.1195 -	kill_note(i);
 25.1196 +      else if (song->voice[i].channel==e->channel && 
 25.1197 +	       (song->voice[i].note==e->a || song->channel[song->voice[i].channel].mono))
 25.1198 +	kill_note(song, i);
 25.1199      }
 25.1200  
 25.1201    if (lowest != -1)
 25.1202      {
 25.1203        /* Found a free voice. */
 25.1204 -      start_note(e,lowest);
 25.1205 +      start_note(song,e,lowest);
 25.1206        return;
 25.1207      }
 25.1208    
 25.1209 -#if 0
 25.1210    /* Look for the decaying note with the lowest volume */
 25.1211 -  i=voices;
 25.1212 +  i = song->voices;
 25.1213    while (i--)
 25.1214      {
 25.1215 -      if (voice[i].status & ~(VOICE_ON | VOICE_DIE | VOICE_FREE))
 25.1216 +      if ((song->voice[i].status != VOICE_ON) &&
 25.1217 +	  (song->voice[i].status != VOICE_DIE))
 25.1218  	{
 25.1219 -	  v=voice[i].left_mix;
 25.1220 -	  if ((voice[i].panned==PANNED_MYSTERY) && (voice[i].right_mix>v))
 25.1221 -	    v=voice[i].right_mix;
 25.1222 +	  v = song->voice[i].left_mix;
 25.1223 +	  if ((song->voice[i].panned == PANNED_MYSTERY)
 25.1224 +	      && (song->voice[i].right_mix > v))
 25.1225 +	    v = song->voice[i].right_mix;
 25.1226  	  if (v<lv)
 25.1227  	    {
 25.1228  	      lv=v;
 25.1229 @@ -1029,718 +360,442 @@
 25.1230  	    }
 25.1231  	}
 25.1232      }
 25.1233 -#endif
 25.1234 -
 25.1235 -  /* Look for the decaying note with the lowest volume */
 25.1236 -  if (lowest==-1)
 25.1237 -   {
 25.1238 -   i=voices;
 25.1239 -   while (i--)
 25.1240 -    {
 25.1241 -      if ( (voice[i].status & ~(VOICE_ON | VOICE_DIE | VOICE_FREE)) &&
 25.1242 -	  (!voice[i].clone_type))
 25.1243 -	{
 25.1244 -	  v=voice[i].left_mix;
 25.1245 -	  if ((voice[i].panned==PANNED_MYSTERY) && (voice[i].right_mix>v))
 25.1246 -	    v=voice[i].right_mix;
 25.1247 -	  if (v<lv)
 25.1248 -	    {
 25.1249 -	      lv=v;
 25.1250 -	      lowest=i;
 25.1251 -	    }
 25.1252 -	}
 25.1253 -    }
 25.1254 -   }
 25.1255  
 25.1256    if (lowest != -1)
 25.1257      {
 25.1258 -      int cl = voice[lowest].clone_voice;
 25.1259 -
 25.1260        /* This can still cause a click, but if we had a free voice to
 25.1261  	 spare for ramping down this note, we wouldn't need to kill it
 25.1262  	 in the first place... Still, this needs to be fixed. Perhaps
 25.1263  	 we could use a reserve of voices to play dying notes only. */
 25.1264 -
 25.1265 -      if (cl >= 0) {
 25.1266 -	if (voice[cl].clone_type==STEREO_CLONE ||
 25.1267 -		       	(!voice[cl].clone_type && voice[lowest].clone_type==STEREO_CLONE))
 25.1268 -	   voice[cl].status=VOICE_FREE;
 25.1269 -	else if (voice[cl].clone_voice==lowest) voice[cl].clone_voice=-1;
 25.1270 -      }
 25.1271 -
 25.1272 -      cut_notes++;
 25.1273 -      voice[lowest].status=VOICE_FREE;
 25.1274 -      ctl->note(lowest);
 25.1275 -      start_note(e,lowest);
 25.1276 +      
 25.1277 +      song->cut_notes++;
 25.1278 +      song->voice[lowest].status=VOICE_FREE;
 25.1279 +      start_note(song,e,lowest);
 25.1280      }
 25.1281    else
 25.1282 -    lost_notes++;
 25.1283 +    song->lost_notes++;
 25.1284  }
 25.1285  
 25.1286 -static void finish_note(int i)
 25.1287 +static void finish_note(MidiSong *song, int i)
 25.1288  {
 25.1289 -  if (voice[i].sample->modes & MODES_ENVELOPE)
 25.1290 +  if (song->voice[i].sample->modes & MODES_ENVELOPE)
 25.1291      {
 25.1292        /* We need to get the envelope out of Sustain stage */
 25.1293 -      voice[i].envelope_stage=3;
 25.1294 -      voice[i].status=VOICE_OFF;
 25.1295 -      recompute_envelope(i);
 25.1296 -      apply_envelope_to_amp(i);
 25.1297 -      ctl->note(i);
 25.1298 +      song->voice[i].envelope_stage = 3;
 25.1299 +      song->voice[i].status = VOICE_OFF;
 25.1300 +      recompute_envelope(song, i);
 25.1301 +      apply_envelope_to_amp(song, i);
 25.1302      }
 25.1303    else
 25.1304      {
 25.1305        /* Set status to OFF so resample_voice() will let this voice out
 25.1306           of its loop, if any. In any case, this voice dies when it
 25.1307           hits the end of its data (ofs>=data_length). */
 25.1308 -      voice[i].status=VOICE_OFF;
 25.1309 +      song->voice[i].status = VOICE_OFF;
 25.1310      }
 25.1311 -
 25.1312 -  { int v;
 25.1313 -    if ( (v=voice[i].clone_voice) >= 0)
 25.1314 -      {
 25.1315 -	voice[i].clone_voice = -1;
 25.1316 -        finish_note(v);
 25.1317 -      }
 25.1318 -  }
 25.1319  }
 25.1320  
 25.1321 -static void note_off(MidiEvent *e)
 25.1322 +static void note_off(MidiSong *song)
 25.1323  {
 25.1324 -  int i=voices, v;
 25.1325 +  int i = song->voices;
 25.1326 +  MidiEvent *e = song->current_event;
 25.1327 +
 25.1328    while (i--)
 25.1329 -    if (voice[i].status==VOICE_ON &&
 25.1330 -	voice[i].channel==e->channel &&
 25.1331 -	voice[i].note==e->a)
 25.1332 +    if (song->voice[i].status == VOICE_ON &&
 25.1333 +	song->voice[i].channel == e->channel &&
 25.1334 +	song->voice[i].note == e->a)
 25.1335        {
 25.1336 -	if (channel[e->channel].sustain)
 25.1337 +	if (song->channel[e->channel].sustain)
 25.1338  	  {
 25.1339 -	    voice[i].status=VOICE_SUSTAINED;
 25.1340 -
 25.1341 -    	    if ( (v=voice[i].clone_voice) >= 0)
 25.1342 -	      {
 25.1343 -		if (voice[v].status == VOICE_ON)
 25.1344 -		  voice[v].status=VOICE_SUSTAINED;
 25.1345 -	      }
 25.1346 -
 25.1347 -	    ctl->note(i);
 25.1348 +	    song->voice[i].status = VOICE_SUSTAINED;
 25.1349  	  }
 25.1350  	else
 25.1351 -	  finish_note(i);
 25.1352 +	  finish_note(song, i);
 25.1353  	return;
 25.1354        }
 25.1355  }
 25.1356  
 25.1357  /* Process the All Notes Off event */
 25.1358 -static void all_notes_off(int c)
 25.1359 +static void all_notes_off(MidiSong *song)
 25.1360  {
 25.1361 -  int i=voices;
 25.1362 -  ctl->cmsg(CMSG_INFO, VERB_DEBUG, "All notes off on channel %d", c);
 25.1363 +  int i = song->voices;
 25.1364 +  int c = song->current_event->channel;
 25.1365 +
 25.1366 +  SNDDBG(("All notes off on channel %d", c));
 25.1367    while (i--)
 25.1368 -    if (voice[i].status==VOICE_ON &&
 25.1369 -	voice[i].channel==c)
 25.1370 +    if (song->voice[i].status == VOICE_ON &&
 25.1371 +	song->voice[i].channel == c)
 25.1372        {
 25.1373 -	if (channel[c].sustain) 
 25.1374 -	  {
 25.1375 -	    voice[i].status=VOICE_SUSTAINED;
 25.1376 -	    ctl->note(i);
 25.1377 -	  }
 25.1378 +	if (song->channel[c].sustain) 
 25.1379 +	  song->voice[i].status = VOICE_SUSTAINED;
 25.1380  	else
 25.1381 -	  finish_note(i);
 25.1382 +	  finish_note(song, i);
 25.1383        }
 25.1384  }
 25.1385  
 25.1386  /* Process the All Sounds Off event */
 25.1387 -static void all_sounds_off(int c)
 25.1388 +static void all_sounds_off(MidiSong *song)
 25.1389  {
 25.1390 -  int i=voices;
 25.1391 +  int i = song->voices;
 25.1392 +  int c = song->current_event->channel;
 25.1393 +
 25.1394    while (i--)
 25.1395 -    if (voice[i].channel==c && 
 25.1396 -	voice[i].status != VOICE_FREE &&
 25.1397 -	voice[i].status != VOICE_DIE)
 25.1398 +    if (song->voice[i].channel == c && 
 25.1399 +	song->voice[i].status != VOICE_FREE &&
 25.1400 +	song->voice[i].status != VOICE_DIE)
 25.1401        {
 25.1402 -	kill_note(i);
 25.1403 +	kill_note(song, i);
 25.1404        }
 25.1405  }
 25.1406  
 25.1407 -static void adjust_pressure(MidiEvent *e)
 25.1408 +static void adjust_pressure(MidiSong *song)
 25.1409  {
 25.1410 -  int i=voices;
 25.1411 +  MidiEvent *e = song->current_event;
 25.1412 +  int i = song->voices;
 25.1413 +  
 25.1414    while (i--)
 25.1415 -    if (voice[i].status==VOICE_ON &&
 25.1416 -	voice[i].channel==e->channel &&
 25.1417 -	voice[i].note==e->a)
 25.1418 +    if (song->voice[i].status == VOICE_ON &&
 25.1419 +	song->voice[i].channel == e->channel &&
 25.1420 +	song->voice[i].note == e->a)
 25.1421        {
 25.1422 -	voice[i].velocity=e->b;
 25.1423 -	recompute_amp(i);
 25.1424 -	apply_envelope_to_amp(i);
 25.1425 +	song->voice[i].velocity = e->b;
 25.1426 +	recompute_amp(song, i);
 25.1427 +	apply_envelope_to_amp(song, i);
 25.1428  	return;
 25.1429        }
 25.1430  }
 25.1431  
 25.1432 -static void adjust_panning(int c)
 25.1433 +static void drop_sustain(MidiSong *song)
 25.1434  {
 25.1435 -  int i=voices;
 25.1436 +  int i = song->voices;
 25.1437 +  int c = song->current_event->channel;
 25.1438 +
 25.1439    while (i--)
 25.1440 -    if ((voice[i].channel==c) &&
 25.1441 -	(voice[i].status==VOICE_ON || voice[i].status==VOICE_SUSTAINED))
 25.1442 +    if (song->voice[i].status == VOICE_SUSTAINED && song->voice[i].channel == c)
 25.1443 +      finish_note(song, i);
 25.1444 +}
 25.1445 +
 25.1446 +static void adjust_pitchbend(MidiSong *song)
 25.1447 +{
 25.1448 +  int c = song->current_event->channel;
 25.1449 +  int i = song->voices;
 25.1450 +  
 25.1451 +  while (i--)
 25.1452 +    if (song->voice[i].status != VOICE_FREE && song->voice[i].channel == c)
 25.1453        {
 25.1454 -	if (voice[i].clone_type != NOT_CLONE) continue;
 25.1455 -	voice[i].panning=channel[c].panning;
 25.1456 -	recompute_amp(i);
 25.1457 -	apply_envelope_to_amp(i);
 25.1458 +	recompute_freq(song, i);
 25.1459        }
 25.1460  }
 25.1461  
 25.1462 -static void drop_sustain(int c)
 25.1463 +static void adjust_volume(MidiSong *song)
 25.1464  {
 25.1465 -  int i=voices;
 25.1466 +  int c = song->current_event->channel;
 25.1467 +  int i = song->voices;
 25.1468 +
 25.1469    while (i--)
 25.1470 -    if (voice[i].status==VOICE_SUSTAINED && voice[i].channel==c)
 25.1471 -      finish_note(i);
 25.1472 -}
 25.1473 -
 25.1474 -static void adjust_pitchbend(int c)
 25.1475 -{
 25.1476 -  int i=voices;
 25.1477 -  while (i--)
 25.1478 -    if (voice[i].status!=VOICE_FREE && voice[i].channel==c)
 25.1479 +    if (song->voice[i].channel == c &&
 25.1480 +	(song->voice[i].status==VOICE_ON || song->voice[i].status==VOICE_SUSTAINED))
 25.1481        {
 25.1482 -	recompute_freq(i);
 25.1483 +	recompute_amp(song, i);
 25.1484 +	apply_envelope_to_amp(song, i);
 25.1485        }
 25.1486  }
 25.1487  
 25.1488 -static void adjust_volume(int c)
 25.1489 +static void seek_forward(MidiSong *song, Sint32 until_time)
 25.1490  {
 25.1491 -  int i=voices;
 25.1492 -  while (i--)
 25.1493 -    if (voice[i].channel==c &&
 25.1494 -	(voice[i].status==VOICE_ON || voice[i].status==VOICE_SUSTAINED))
 25.1495 -      {
 25.1496 -	recompute_amp(i);
 25.1497 -	apply_envelope_to_amp(i);
 25.1498 -      }
 25.1499 -}
 25.1500 -
 25.1501 -static void seek_forward(int32 until_time)
 25.1502 -{
 25.1503 -  reset_voices();
 25.1504 -  while (current_event->time < until_time)
 25.1505 +  reset_voices(song);
 25.1506 +  while (song->current_event->time < until_time)
 25.1507      {
 25.1508 -      switch(current_event->type)
 25.1509 +      switch(song->current_event->type)
 25.1510  	{
 25.1511  	  /* All notes stay off. Just handle the parameter changes. */
 25.1512  
 25.1513  	case ME_PITCH_SENS:
 25.1514 -	  channel[current_event->channel].pitchsens=
 25.1515 -	    current_event->a;
 25.1516 -	  channel[current_event->channel].pitchfactor=0;
 25.1517 +	  song->channel[song->current_event->channel].pitchsens =
 25.1518 +	    song->current_event->a;
 25.1519 +	  song->channel[song->current_event->channel].pitchfactor = 0;
 25.1520  	  break;
 25.1521  	  
 25.1522  	case ME_PITCHWHEEL:
 25.1523 -	  channel[current_event->channel].pitchbend=
 25.1524 -	    current_event->a + current_event->b * 128;
 25.1525 -	  channel[current_event->channel].pitchfactor=0;
 25.1526 +	  song->channel[song->current_event->channel].pitchbend =
 25.1527 +	    song->current_event->a + song->current_event->b * 128;
 25.1528 +	  song->channel[song->current_event->channel].pitchfactor = 0;
 25.1529  	  break;
 25.1530  	  
 25.1531  	case ME_MAINVOLUME:
 25.1532 -	  channel[current_event->channel].volume=current_event->a;
 25.1533 -	  break;
 25.1534 -	  
 25.1535 -	case ME_MASTERVOLUME:
 25.1536 -	  adjust_master_volume(current_event->a + (current_event->b <<7));
 25.1537 +	  song->channel[song->current_event->channel].volume =
 25.1538 +	    song->current_event->a;
 25.1539  	  break;
 25.1540  	  
 25.1541  	case ME_PAN:
 25.1542 -	  channel[current_event->channel].panning=current_event->a;
 25.1543 +	  song->channel[song->current_event->channel].panning =
 25.1544 +	    song->current_event->a;
 25.1545  	  break;
 25.1546  	      
 25.1547  	case ME_EXPRESSION:
 25.1548 -	  channel[current_event->channel].expression=current_event->a;
 25.1549 +	  song->channel[song->current_event->channel].expression =
 25.1550 +	    song->current_event->a;
 25.1551  	  break;
 25.1552  	  
 25.1553  	case ME_PROGRAM:
 25.1554 -	  /* if (ISDRUMCHANNEL(current_event->channel)) */
 25.1555 -	  if (channel[current_event->channel].kit)
 25.1556 +	  if (ISDRUMCHANNEL(song, song->current_event->channel))
 25.1557  	    /* Change drum set */
 25.1558 -	    channel[current_event->channel].bank=current_event->a;
 25.1559 +	    song->channel[song->current_event->channel].bank =
 25.1560 +	      song->current_event->a;
 25.1561  	  else
 25.1562 -	    channel[current_event->channel].program=current_event->a;
 25.1563 +	    song->channel[song->current_event->channel].program =
 25.1564 +	      song->current_event->a;
 25.1565  	  break;
 25.1566  
 25.1567  	case ME_SUSTAIN:
 25.1568 -	  channel[current_event->channel].sustain=current_event->a;
 25.1569 +	  song->channel[song->current_event->channel].sustain =
 25.1570 +	    song->current_event->a;
 25.1571  	  break;
 25.1572  
 25.1573 -
 25.1574 -	case ME_REVERBERATION:
 25.1575 -	  channel[current_event->channel].reverberation=current_event->a;
 25.1576 -	  break;
 25.1577 -
 25.1578 -	case ME_CHORUSDEPTH:
 25.1579 -	  channel[current_event->channel].chorusdepth=current_event->a;
 25.1580 -	  break;
 25.1581 -
 25.1582 -	case ME_HARMONICCONTENT:
 25.1583 -	  channel[current_event->channel].harmoniccontent=current_event->a;
 25.1584 -	  break;
 25.1585 -
 25.1586 -	case ME_RELEASETIME:
 25.1587 -	  channel[current_event->channel].releasetime=current_event->a;
 25.1588 -	  break;
 25.1589 -
 25.1590 -	case ME_ATTACKTIME:
 25.1591 -	  channel[current_event->channel].attacktime=current_event->a;
 25.1592 -	  break;
 25.1593 -
 25.1594 -	case ME_BRIGHTNESS:
 25.1595 -	  channel[current_event->channel].brightness=current_event->a;
 25.1596 -	  break;
 25.1597 -
 25.1598 -	case ME_TONE_KIT:
 25.1599 -	  if (current_event->a==SFX_BANKTYPE)
 25.1600 -		{
 25.1601 -		    channel[current_event->channel].sfx=SFXBANK;
 25.1602 -		    channel[current_event->channel].kit=0;
 25.1603 -		}
 25.1604 -	  else
 25.1605 -		{
 25.1606 -		    channel[current_event->channel].sfx=0;
 25.1607 -		    channel[current_event->channel].kit=current_event->a;
 25.1608 -		}
 25.1609 -	  break;
 25.1610 -
 25.1611 -
 25.1612  	case ME_RESET_CONTROLLERS:
 25.1613 -	  reset_controllers(current_event->channel);
 25.1614 +	  reset_controllers(song, song->current_event->channel);
 25.1615  	  break;
 25.1616  	      
 25.1617  	case ME_TONE_BANK:
 25.1618 -	  channel[current_event->channel].bank=current_event->a;
 25.1619 +	  song->channel[song->current_event->channel].bank =
 25.1620 +	    song->current_event->a;
 25.1621  	  break;
 25.1622  	  
 25.1623  	case ME_EOT:
 25.1624 -	  current_sample=current_event->time;
 25.1625 +	  song->current_sample = song->current_event->time;
 25.1626  	  return;
 25.1627  	}
 25.1628 -      current_event++;
 25.1629 +      song->current_event++;
 25.1630      }
 25.1631 -  /*current_sample=current_event->time;*/
 25.1632 -  if (current_event != event_list)
 25.1633 -    current_event--;
 25.1634 -  current_sample=until_time;
 25.1635 +  /*song->current_sample=song->current_event->time;*/
 25.1636 +  if (song->current_event != song->events)
 25.1637 +    song->current_event--;
 25.1638 +  song->current_sample=until_time;
 25.1639  }
 25.1640  
 25.1641 -static void skip_to(int32 until_time)
 25.1642 +static void skip_to(MidiSong *song, Sint32 until_time)
 25.1643  {
 25.1644 -  if (current_sample > until_time)
 25.1645 -    current_sample=0;
 25.1646 +  if (song->current_sample > until_time)
 25.1647 +    song->current_sample = 0;
 25.1648  
 25.1649 -  reset_midi();
 25.1650 -  buffered_count=0;
 25.1651 -  buffer_pointer=common_buffer;
 25.1652 -  current_event=event_list;
 25.1653 +  reset_midi(song);
 25.1654 +  song->buffered_count = 0;
 25.1655 +  song->buffer_pointer = song->common_buffer;
 25.1656 +  song->current_event = song->events;
 25.1657    
 25.1658    if (until_time)
 25.1659 -    seek_forward(until_time);
 25.1660 -  ctl->reset();
 25.1661 +    seek_forward(song, until_time);
 25.1662  }
 25.1663  
 25.1664 -static int apply_controls(void)
 25.1665 -{
 25.1666 -  int rc, i, did_skip=0;
 25.1667 -  int32 val;
 25.1668 -  /* ASCII renditions of CD player pictograms indicate approximate effect */
 25.1669 -  do
 25.1670 -    switch(rc=ctl->read(&val))
 25.1671 -      {
 25.1672 -      case RC_QUIT: /* [] */
 25.1673 -      case RC_LOAD_FILE:	  
 25.1674 -      case RC_NEXT: /* >>| */
 25.1675 -      case RC_REALLY_PREVIOUS: /* |<< */
 25.1676 -	return rc;
 25.1677 -	
 25.1678 -      case RC_CHANGE_VOLUME:
 25.1679 -	if (val>0 || amplification > -val)
 25.1680 -	  amplification += val;
 25.1681 -	else 
 25.1682 -	  amplification=0;
 25.1683 -	if (amplification > MAX_AMPLIFICATION)
 25.1684 -	  amplification=MAX_AMPLIFICATION;
 25.1685 -	adjust_amplification();
 25.1686 -	for (i=0; i<voices; i++)
 25.1687 -	  if (voice[i].status != VOICE_FREE)
 25.1688 -	    {
 25.1689 -	      recompute_amp(i);
 25.1690 -	      apply_envelope_to_amp(i);
 25.1691 -	    }
 25.1692 -	ctl->master_volume(amplification);
 25.1693 -	break;
 25.1694 -
 25.1695 -      case RC_PREVIOUS: /* |<< */
 25.1696 -	if (current_sample < 2*play_mode->rate)
 25.1697 -	  return RC_REALLY_PREVIOUS;
 25.1698 -	return RC_RESTART;
 25.1699 -
 25.1700 -      case RC_RESTART: /* |<< */
 25.1701 -	skip_to(0);
 25.1702 -	did_skip=1;
 25.1703 -	break;
 25.1704 -	
 25.1705 -      case RC_JUMP:
 25.1706 -	if (val >= sample_count)
 25.1707 -	  return RC_NEXT;
 25.1708 -	skip_to(val);
 25.1709 -	return rc;
 25.1710 -	
 25.1711 -      case RC_FORWARD: /* >> */
 25.1712 -	if (val+current_sample >= sample_count)
 25.1713 -	  return RC_NEXT;
 25.1714 -	skip_to(val+current_sample);
 25.1715 -	did_skip=1;
 25.1716 -	break;
 25.1717 -	
 25.1718 -      case RC_BACK: /* << */
 25.1719 -	if (current_sample > val)
 25.1720 -	  skip_to(current_sample-val);
 25.1721 -	else
 25.1722 -	  skip_to(0); /* We can't seek to end of previous song. */
 25.1723 -	did_skip=1;
 25.1724 -	break;
 25.1725 -      }
 25.1726 -  while (rc!= RC_NONE);
 25.1727 - 
 25.1728 -  /* Advertise the skip so that we stop computing the audio buffer */
 25.1729 -  if (did_skip)
 25.1730 -    return RC_JUMP; 
 25.1731 -  else
 25.1732 -    return rc;
 25.1733 -}
 25.1734 -
 25.1735 -static void do_compute_data(uint32 count)
 25.1736 +static void do_compute_data(MidiSong *song, Sint32 count)
 25.1737  {
 25.1738    int i;
 25.1739 -  if (!count) return; /* (gl) */
 25.1740 -  memset(buffer_pointer, 0, count * num_ochannels * 4);
 25.1741 -  for (i=0; i<voices; i++)
 25.1742 +  memset(song->buffer_pointer, 0, 
 25.1743 +	 (song->encoding & PE_MONO) ? (count * 4) : (count * 8));
 25.1744 +  for (i = 0; i < song->voices; i++)
 25.1745      {
 25.1746 -      if(voice[i].status != VOICE_FREE)
 25.1747 -	{
 25.1748 -	  if (!voice[i].sample_offset && voice[i].echo_delay_count)
 25.1749 -	    {
 25.1750 -		if ((uint32)voice[i].echo_delay_count >= count) voice[i].echo_delay_count -= count;
 25.1751 -		else
 25.1752 -		  {
 25.1753 -	            mix_voice(buffer_pointer+voice[i].echo_delay_count, i, count-voice[i].echo_delay_count);
 25.1754 -		    voice[i].echo_delay_count = 0;
 25.1755 -		  }
 25.1756 -	    }
 25.1757 -	  else mix_voice(buffer_pointer, i, count);
 25.1758 -	}
 25.1759 +      if(song->voice[i].status != VOICE_FREE)
 25.1760 +	mix_voice(song, song->buffer_pointer, i, count);
 25.1761      }
 25.1762 -  current_sample += count;
 25.1763 +  song->current_sample += count;
 25.1764  }
 25.1765  
 25.1766 -
 25.1767  /* count=0 means flush remaining buffered data to output device, then
 25.1768     flush the device itself */
 25.1769 -static int compute_data(void *stream, int32 count)
 25.1770 +static void compute_data(MidiSong *song, void *stream, Sint32 count)
 25.1771  {
 25.1772 -  int rc, channels;
 25.1773 +  int channels;
 25.1774  
 25.1775 -  if ( play_mode->encoding & PE_MONO )
 25.1776 +  if ( song->encoding & PE_MONO )
 25.1777      channels = 1;
 25.1778    else
 25.1779 -    channels = num_ochannels;
 25.1780 +    channels = 2;
 25.1781  
 25.1782    if (!count)
 25.1783      {
 25.1784 -      if (buffered_count)
 25.1785 -          s32tobuf(stream, common_buffer, channels*buffered_count);
 25.1786 -      buffer_pointer=common_buffer;
 25.1787 -      buffered_count=0;
 25.1788 -      return RC_NONE;
 25.1789 +      if (song->buffered_count)
 25.1790 +          song->write(stream, song->common_buffer, channels * song->buffered_count);
 25.1791 +      song->buffer_pointer = song->common_buffer;
 25.1792 +      song->buffered_count = 0;
 25.1793 +      return;
 25.1794      }
 25.1795  
 25.1796 -  while ((count+buffered_count) >= AUDIO_BUFFER_SIZE)
 25.1797 +  while ((count + song->buffered_count) >= song->buffer_size)
 25.1798      {
 25.1799 -      do_compute_data(AUDIO_BUFFER_SIZE-buffered_count);
 25.1800 -      count -= AUDIO_BUFFER_SIZE-buffered_count;
 25.1801 -      s32tobuf(stream, common_buffer, channels*AUDIO_BUFFER_SIZE);
 25.1802 -      buffer_pointer=common_buffer;
 25.1803 -      buffered_count=0;
 25.1804 -      
 25.1805 -      ctl->current_time(current_sample);
 25.1806 -      if ((rc=apply_controls())!=RC_NONE)
 25.1807 -	return rc;
 25.1808 +      do_compute_data(song, song->buffer_size - song->buffered_count);
 25.1809 +      count -= song->buffer_size - song->buffered_count;
 25.1810 +      song->write(stream, song->common_buffer, channels * song->buffer_size);
 25.1811 +      song->buffer_pointer = song->common_buffer;
 25.1812 +      song->buffered_count = 0;
 25.1813      }
 25.1814    if (count>0)
 25.1815      {
 25.1816 -      do_compute_data(count);
 25.1817 -      buffered_count += count;
 25.1818 -      buffer_pointer += count * channels;
 25.1819 +      do_compute_data(song, count);
 25.1820 +      song->buffered_count += count;
 25.1821 +      song->buffer_pointer += (song->encoding & PE_MONO) ? count : count*2;
 25.1822      }
 25.1823 -  return RC_NONE;
 25.1824  }
 25.1825  
 25.1826 -int Timidity_PlaySome(void *stream, int samples)
 25.1827 +void Timidity_Start(MidiSong *song)
 25.1828  {
 25.1829 -  int rc = RC_NONE;
 25.1830 -  int32 end_sample;
 25.1831 +  song->playing = 1;
 25.1832 +  adjust_amplification(song);
 25.1833 +  skip_to(song, 0);
 25.1834 +}
 25.1835 +
 25.1836 +void Timidity_Seek(MidiSong *song, Uint32 ms)
 25.1837 +{
 25.1838 +    skip_to(song, (ms * song->rate) / 1000);
 25.1839 +}
 25.1840 +
 25.1841 +Uint32 Timidity_GetSongLength(MidiSong *song)
 25.1842 +{
 25.1843 +  MidiEvent *last_event = &song->events[song->groomed_event_count - 1];
 25.1844 +  /* We want last_event->time * 1000 / song->rate */
 25.1845 +  Uint32 retvalue = (last_event->time / song->rate) * 1000;
 25.1846 +  retvalue       += (last_event->time % song->rate) * 1000 / song->rate;
 25.1847 +  return retvalue;
 25.1848 +}
 25.1849 +
 25.1850 +int Timidity_PlaySome(MidiSong *song, void *stream, Sint32 len)
 25.1851 +{
 25.1852 +  Sint32 start_sample, end_sample, samples;
 25.1853 +  int bytes_per_sample;
 25.1854 +
 25.1855 +  if (!song->playing)
 25.1856 +    return 0;
 25.1857    
 25.1858 -  if ( ! midi_playing ) {
 25.1859 -    return RC_NONE;
 25.1860 -  }
 25.1861 -  end_sample = current_sample+samples;
 25.1862 -  while ( current_sample < end_sample ) {
 25.1863 +  bytes_per_sample =
 25.1864 +        ((song->encoding & PE_MONO) ? 1 : 2)
 25.1865 +      * ((song->encoding & PE_16BIT) ? 2 : 1);
 25.1866 +  samples = len / bytes_per_sample;
 25.1867 +  
 25.1868 +  start_sample = song->current_sample;
 25.1869 +  end_sample = song->current_sample+samples;
 25.1870 +  while ( song->current_sample < end_sample ) {
 25.1871      /* Handle all events that should happen at this time */
 25.1872 -    while (current_event->time <= current_sample) {
 25.1873 -      switch(current_event->type) {
 25.1874 +    while (song->current_event->time <= song->current_sample) {
 25.1875 +      switch(song->current_event->type) {
 25.1876  
 25.1877          /* Effects affecting a single note */
 25.1878  
 25.1879          case ME_NOTEON:
 25.1880 -	  current_event->a += channel[current_event->channel].transpose;
 25.1881 -          if (!(current_event->b)) /* Velocity 0? */
 25.1882 -            note_off(current_event);
 25.1883 +          if (!(song->current_event->b)) /* Velocity 0? */
 25.1884 +            note_off(song);
 25.1885            else
 25.1886 -            note_on(current_event);
 25.1887 +            note_on(song);
 25.1888            break;
 25.1889    
 25.1890          case ME_NOTEOFF:
 25.1891 -	  current_event->a += channel[current_event->channel].transpose;
 25.1892 -          note_off(current_event);
 25.1893 +          note_off(song);
 25.1894            break;
 25.1895    
 25.1896          case ME_KEYPRESSURE:
 25.1897 -          adjust_pressure(current_event);
 25.1898 +          adjust_pressure(song);
 25.1899            break;
 25.1900    
 25.1901            /* Effects affecting a single channel */
 25.1902    
 25.1903          case ME_PITCH_SENS:
 25.1904 -          channel[current_event->channel].pitchsens=current_event->a;
 25.1905 -          channel[current_event->channel].pitchfactor=0;
 25.1906 +          song->channel[song->current_event->channel].pitchsens =
 25.1907 +	    song->current_event->a;
 25.1908 +          song->channel[song->current_event->channel].pitchfactor = 0;
 25.1909            break;
 25.1910            
 25.1911          case ME_PITCHWHEEL:
 25.1912 -          channel[current_event->channel].pitchbend=
 25.1913 -            current_event->a + current_event->b * 128;
 25.1914 -          channel[current_event->channel].pitchfactor=0;
 25.1915 +          song->channel[song->current_event->channel].pitchbend =
 25.1916 +            song->current_event->a + song->current_event->b * 128;
 25.1917 +          song->channel[song->current_event->channel].pitchfactor = 0;
 25.1918            /* Adjust pitch for notes already playing */
 25.1919 -          adjust_pitchbend(current_event->channel);
 25.1920 -          ctl->pitch_bend(current_event->channel, 
 25.1921 -              channel[current_event->channel].pitchbend);
 25.1922 +          adjust_pitchbend(song);
 25.1923            break;
 25.1924            
 25.1925          case ME_MAINVOLUME:
 25.1926 -          channel[current_event->channel].volume=current_event->a;
 25.1927 -          adjust_volume(current_event->channel);
 25.1928 -          ctl->volume(current_event->channel, current_event->a);
 25.1929 +          song->channel[song->current_event->channel].volume =
 25.1930 +	    song->current_event->a;
 25.1931 +          adjust_volume(song);
 25.1932            break;
 25.1933 -
 25.1934 -	case ME_MASTERVOLUME:
 25.1935 -	  adjust_master_volume(current_event->a + (current_event->b <<7));
 25.1936 -	  break;
 25.1937 -	      
 25.1938 -	case ME_REVERBERATION:
 25.1939 -	  channel[current_event->channel].reverberation=current_event->a;
 25.1940 -	  break;
 25.1941 -
 25.1942 -	case ME_CHORUSDEPTH:
 25.1943 -	  channel[current_event->channel].chorusdepth=current_event->a;
 25.1944 -	  break;
 25.1945 -
 25.1946 +          
 25.1947          case ME_PAN:
 25.1948 -          channel[current_event->channel].panning=current_event->a;
 25.1949 -          if (adjust_panning_immediately)
 25.1950 -            adjust_panning(current_event->channel);
 25.1951 -          ctl->panning(current_event->channel, current_event->a);
 25.1952 +          song->channel[song->current_event->channel].panning =
 25.1953 +	    song->current_event->a;
 25.1954            break;
 25.1955            
 25.1956          case ME_EXPRESSION:
 25.1957 -          channel[current_event->channel].expression=current_event->a;
 25.1958 -          adjust_volume(current_event->channel);
 25.1959 -          ctl->expression(current_event->channel, current_event->a);
 25.1960 +          song->channel[song->current_event->channel].expression =
 25.1961 +	    song->current_event->a;
 25.1962 +          adjust_volume(song);
 25.1963            break;
 25.1964    
 25.1965          case ME_PROGRAM:
 25.1966 -          /* if (ISDRUMCHANNEL(current_event->channel)) { */
 25.1967 -	  if (channel[current_event->channel].kit) {
 25.1968 +          if (ISDRUMCHANNEL(song, song->current_event->channel)) {
 25.1969              /* Change drum set */
 25.1970 -            channel[current_event->channel].bank=current_event->a;
 25.1971 +            song->channel[song->current_event->channel].bank =
 25.1972 +	      song->current_event->a;
 25.1973            }
 25.1974            else
 25.1975 -          {
 25.1976 -            channel[current_event->channel].program=current_event->a;
 25.1977 -          }
 25.1978 -          ctl->program(current_event->channel, current_event->a);
 25.1979 +            song->channel[song->current_event->channel].program =
 25.1980 +	      song->current_event->a;
 25.1981            break;
 25.1982    
 25.1983          case ME_SUSTAIN:
 25.1984 -          channel[current_event->channel].sustain=current_event->a;
 25.1985 -          if (!current_event->a)
 25.1986 -            drop_sustain(current_event->channel);
 25.1987 -          ctl->sustain(current_event->channel, current_event->a);
 25.1988 +          song->channel[song->current_event->channel].sustain =
 25.1989 +	    song->current_event->a;
 25.1990 +          if (!song->current_event->a)
 25.1991 +            drop_sustain(song);
 25.1992            break;
 25.1993            
 25.1994          case ME_RESET_CONTROLLERS:
 25.1995 -          reset_controllers(current_event->channel);
 25.1996 -          redraw_controllers(current_event->channel);
 25.1997 +          reset_controllers(song, song->current_event->channel);
 25.1998            break;
 25.1999    
 25.2000          case ME_ALL_NOTES_OFF:
 25.2001 -          all_notes_off(current_event->channel);
 25.2002 +          all_notes_off(song);
 25.2003            break;
 25.2004            
 25.2005          case ME_ALL_SOUNDS_OFF:
 25.2006 -          all_sounds_off(current_event->channel);
 25.2007 +          all_sounds_off(song);
 25.2008            break;
 25.2009 -
 25.2010 -	case ME_HARMONICCONTENT:
 25.2011 -	  channel[current_event->channel].harmoniccontent=current_event->a;
 25.2012 -	  break;
 25.2013 -
 25.2014 -	case ME_RELEASETIME:
 25.2015 -	  channel[current_event->channel].releasetime=current_event->a;
 25.2016 -	  break;
 25.2017 -
 25.2018 -	case ME_ATTACKTIME:
 25.2019 -	  channel[current_event->channel].attacktime=current_event->a;
 25.2020 -	  break;
 25.2021 -
 25.2022 -	case ME_BRIGHTNESS:
 25.2023 -	  channel[current_event->channel].brightness=current_event->a;
 25.2024 -	  break;
 25.2025 -
 25.2026 +          
 25.2027          case ME_TONE_BANK:
 25.2028 -          channel[current_event->channel].bank=current_event->a;
 25.2029 +          song->channel[song->current_event->channel].bank =
 25.2030 +	    song->current_event->a;
 25.2031            break;
 25.2032 -
 25.2033 -
 25.2034 -	case ME_TONE_KIT:
 25.2035 -	  if (current_event->a==SFX_BANKTYPE)
 25.2036 -	  {
 25.2037 -	    channel[current_event->channel].sfx=SFXBANK;
 25.2038 -	    channel[current_event->channel].kit=0;
 25.2039 -	  }
 25.2040 -	  else
 25.2041 -	  {
 25.2042 -	    channel[current_event->channel].sfx=0;
 25.2043 -	    channel[current_event->channel].kit=current_event->a;
 25.2044 -	  }
 25.2045 -	  break;
 25.2046 -
 25.2047 +  
 25.2048          case ME_EOT:
 25.2049            /* Give the last notes a couple of seconds to decay  */
 25.2050 -          ctl->cmsg(CMSG_INFO, VERB_VERBOSE,
 25.2051 -            "Playing time: ~%d seconds", current_sample/play_mode->rate+2);
 25.2052 -          ctl->cmsg(CMSG_INFO, VERB_VERBOSE,
 25.2053 -            "Notes cut: %d", cut_notes);
 25.2054 -          ctl->cmsg(CMSG_INFO, VERB_VERBOSE,
 25.2055 -          "Notes lost totally: %d", lost_notes);
 25.2056 -          midi_playing = 0;
 25.2057 -          return RC_TUNE_END;
 25.2058 +          SNDDBG(("Playing time: ~%d seconds\n",
 25.2059 +		  song->current_sample/song->rate+2));
 25.2060 +          SNDDBG(("Notes cut: %d\n", song->cut_notes));
 25.2061 +          SNDDBG(("Notes lost totally: %d\n", song->lost_notes));
 25.2062 +	  song->playing = 0;
 25.2063 +          return (song->current_sample - start_sample) * bytes_per_sample;
 25.2064          }
 25.2065 -      current_event++;
 25.2066 +      song->current_event++;
 25.2067      }
 25.2068 -    if (current_event->time > end_sample)
 25.2069 -      rc=compute_data(stream, end_sample-current_sample);
 25.2070 +    if (song->current_event->time > end_sample)
 25.2071 +      compute_data(song, stream, end_sample-song->current_sample);
 25.2072      else
 25.2073 -      rc=compute_data(stream, current_event->time-current_sample);
 25.2074 -    ctl->refresh();
 25.2075 -    if ( (rc!=RC_NONE) && (rc!=RC_JUMP))
 25.2076 -      break;
 25.2077 +      compute_data(song, stream, song->current_event->time-song->current_sample);
 25.2078    }
 25.2079 -  return rc;
 25.2080 +  return samples * bytes_per_sample;
 25.2081  }
 25.2082  
 25.2083 -
 25.2084 -void Timidity_SetVolume(int volume)
 25.2085 +void Timidity_SetVolume(MidiSong *song, int volume)
 25.2086  {
 25.2087    int i;
 25.2088    if (volume > MAX_AMPLIFICATION)
 25.2089 -    amplification=MAX_AMPLIFICATION;
 25.2090 +    song->amplification = MAX_AMPLIFICATION;
 25.2091    else
 25.2092    if (volume < 0)
 25.2093 -    amplification=0;
 25.2094 +    song->amplification = 0;
 25.2095    else
 25.2096 -    amplification=volume;
 25.2097 -  adjust_amplification();
 25.2098 -  for (i=0; i<voices; i++)
 25.2099 -    if (voice[i].status != VOICE_FREE)
 25.2100 +    song->amplification = volume;
 25.2101 +  adjust_amplification(song);
 25.2102 +  for (i = 0; i < song->voices; i++)
 25.2103 +    if (song->voice[i].status != VOICE_FREE)
 25.2104        {
 25.2105 -        recompute_amp(i);
 25.2106 -        apply_envelope_to_amp(i);
 25.2107 +        recompute_amp(song, i);
 25.2108 +        apply_envelope_to_amp(song, i);
 25.2109        }
 25.2110 -  ctl->master_volume(amplification);
 25.2111  }
 25.2112 -
 25.2113 -MidiSong *Timidity_LoadSong_RW(SDL_RWops *src, int freesrc)
 25.2114 -{
 25.2115 -  MidiSong *song;
 25.2116 -  int32 events;
 25.2117 -
 25.2118 -  /* Allocate memory for the song */
 25.2119 -  song = (MidiSong *)safe_malloc(sizeof(*song));
 25.2120 -  memset(song, 0, sizeof(*song));
 25.2121 -
 25.2122 -  strcpy(midi_name, "SDLrwops source");
 25.2123 -
 25.2124 -  song->events = read_midi_file(src, &events, &song->samples);
 25.2125 -  if (song->events) {
 25.2126 -    if (freesrc) {
 25.2127 -      SDL_RWclose(src);
 25.2128 -    }
 25.2129 -  } else {
 25.2130 -    free(song);
 25.2131 -    song = NULL;
 25.2132 -  }
 25.2133 -  return(song);
 25.2134 -}
 25.2135 -
 25.2136 -void Timidity_Start(MidiSong *song)
 25.2137 -{
 25.2138 -  load_missing_instruments();
 25.2139 -  adjust_amplification();
 25.2140 -  sample_count = song->samples;
 25.2141 -  event_list = song->events;
 25.2142 -  lost_notes=cut_notes=0;
 25.2143 -
 25.2144 -  skip_to(0);
 25.2145 -  midi_playing = 1;
 25.2146 -}
 25.2147 -
 25.2148 -int Timidity_Active(void)
 25.2149 -{
 25.2150 -	return(midi_playing);
 25.2151 -}
 25.2152 -
 25.2153 -void Timidity_Stop(void)
 25.2154 -{
 25.2155 -  midi_playing = 0;
 25.2156 -}
 25.2157 -
 25.2158 -void Timidity_FreeSong(MidiSong *song)
 25.2159 -{
 25.2160 -  if (free_instruments_afterwards)
 25.2161 -    free_instruments();
 25.2162 -  
 25.2163 -  free(song->events);
 25.2164 -  free(song);
 25.2165 -}
 25.2166 -
 25.2167 -void Timidity_Close(void)
 25.2168 -{
 25.2169 -  if (resample_buffer) {
 25.2170 -    free(resample_buffer);
 25.2171 -    resample_buffer=NULL;
 25.2172 -  }
 25.2173 -  if (common_buffer) {
 25.2174 -    free(common_buffer);
 25.2175 -    common_buffer=NULL;
 25.2176 -  }
 25.2177 -  free_instruments();
 25.2178 -  free_pathlist();
 25.2179 -}
 25.2180 -
    26.1 --- a/timidity/playmidi.h	Tue Oct 17 16:55:58 2017 -0700
    26.2 +++ b/timidity/playmidi.h	Tue Oct 17 21:54:04 2017 -0700
    26.3 @@ -1,15 +1,14 @@
    26.4  /*
    26.5 +
    26.6      TiMidity -- Experimental MIDI to WAVE converter
    26.7      Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
    26.8  
    26.9      This program is free software; you can redistribute it and/or modify
   26.10      it under the terms of the Perl Artistic License, available in COPYING.
   26.11 - */
   26.12  
   26.13 -typedef struct {
   26.14 -  int32 time;
   26.15 -  uint8 channel, type, a, b;
   26.16 -} MidiEvent;
   26.17 +   playmidi.h
   26.18 +
   26.19 +   */
   26.20  
   26.21  /* Midi events */
   26.22  #define ME_NONE 	0
   26.23 @@ -31,84 +30,11 @@
   26.24  #define ME_TONE_BANK	15
   26.25  
   26.26  #define ME_LYRIC	16
   26.27 -#define ME_TONE_KIT	17
   26.28 -#define ME_MASTERVOLUME	18
   26.29 -#define ME_CHANNEL_PRESSURE 19
   26.30 -
   26.31 -#define ME_HARMONICCONTENT	71
   26.32 -#define ME_RELEASETIME		72
   26.33 -#define ME_ATTACKTIME		73
   26.34 -#define ME_BRIGHTNESS		74
   26.35 -
   26.36 -#define ME_REVERBERATION	91
   26.37 -#define ME_CHORUSDEPTH		93
   26.38  
   26.39  #define ME_EOT		99
   26.40  
   26.41 -
   26.42 -#define SFX_BANKTYPE	64
   26.43 -
   26.44 -typedef struct {
   26.45 -  int
   26.46 -    bank, program, volume, sustain, panning, pitchbend, expression, 
   26.47 -    mono, /* one note only on this channel -- not implemented yet */
   26.48 -    /* new stuff */
   26.49 -    variationbank, reverberation, chorusdepth, harmoniccontent,
   26.50 -    releasetime, attacktime, brightness, kit, sfx,
   26.51 -    /* end new */
   26.52 -    pitchsens;
   26.53 -  FLOAT_T
   26.54 -    pitchfactor; /* precomputed pitch bend factor to save some fdiv's */
   26.55 -  char transpose;
   26.56 -  char *name;
   26.57 -} Channel;
   26.58 -
   26.59  /* Causes the instrument's default panning to be used. */
   26.60  #define NO_PANNING -1
   26.61 -/* envelope points */
   26.62 -#define MAXPOINT 7
   26.63 -
   26.64 -typedef struct {
   26.65 -  uint8
   26.66 -    status, channel, note, velocity, clone_type;
   26.67 -  Sample *sample;
   26.68 -  Sample *left_sample;
   26.69 -  Sample *right_sample;
   26.70 -  int32 clone_voice;
   26.71 -  int32
   26.72 -    orig_frequency, frequency,
   26.73 -    sample_offset, loop_start, loop_end;
   26.74 -  int32
   26.75 -    envelope_volume, modulation_volume;
   26.76 -  int32
   26.77 -    envelope_target, modulation_target;
   26.78 -  int32
   26.79 -    tremolo_sweep, tremolo_sweep_position, tremolo_phase,
   26.80 -    lfo_sweep, lfo_sweep_position, lfo_phase,
   26.81 -    vibrato_sweep, vibrato_sweep_position, vibrato_depth, vibrato_delay,
   26.82 -    starttime, echo_delay_count;
   26.83 -  int32
   26.84 -    echo_delay,
   26.85 -    sample_increment,
   26.86 -    envelope_increment,
   26.87 -    modulation_increment,
   26.88 -    tremolo_phase_increment,
   26.89 -    lfo_phase_increment;
   26.90 -  
   26.91 -  final_volume_t left_mix, right_mix, lr_mix, rr_mix, ce_mix, lfe_mix;
   26.92 -
   26.93 -  FLOAT_T
   26.94 -    left_amp, right_amp, lr_amp, rr_amp, ce_amp, lfe_amp,
   26.95 -    volume, tremolo_volume, lfo_volume;
   26.96 -  int32
   26.97 -    vibrato_sample_increment[VIBRATO_SAMPLE_INCREMENTS];
   26.98 -  int32
   26.99 -    envelope_rate[MAXPOINT], envelope_offset[MAXPOINT];
  26.100 -  int32
  26.101 -    vibrato_phase, vibrato_control_ratio, vibrato_control_counter,
  26.102 -    envelope_stage, modulation_stage, control_counter,
  26.103 -    modulation_delay, modulation_counter, panning, panned;
  26.104 -} Voice;
  26.105  
  26.106  /* Voice status options: */
  26.107  #define VOICE_FREE 0
  26.108 @@ -124,37 +50,4 @@
  26.109  #define PANNED_CENTER 3
  26.110  /* Anything but PANNED_MYSTERY only uses the left volume */
  26.111  
  26.112 -/* Envelope stages: */
  26.113 -#define ATTACK 0
  26.114 -#define HOLD 1
  26.115 -#define DECAY 2
  26.116 -#define RELEASE 3
  26.117 -#define RELEASEB 4
  26.118 -#define RELEASEC 5
  26.119 -#define DELAY 6
  26.120 -
  26.121 -extern Channel channel[16];
  26.122 -extern Voice voice[MAX_VOICES];
  26.123 -extern signed char drumvolume[MAXCHAN][MAXNOTE];
  26.124 -extern signed char drumpanpot[MAXCHAN][MAXNOTE];
  26.125 -extern signed char drumreverberation[MAXCHAN][MAXNOTE];
  26.126 -extern signed char drumchorusdepth[MAXCHAN][MAXNOTE];
  26.127 -
  26.128 -extern int32 control_ratio, amp_with_poly, amplification;
  26.129 -extern int32 drumchannels;
  26.130 -extern int adjust_panning_immediately;
  26.131 -extern int voices;
  26.132 -
  26.133 -#define ISDRUMCHANNEL(c) ((drumchannels & (1<<(c))))
  26.134 -
  26.135 -extern int GM_System_On;
  26.136 -extern int XG_System_On;
  26.137 -extern int GS_System_On;
  26.138 -
  26.139 -extern int XG_System_reverb_type;
  26.140 -extern int XG_System_chorus_type;
  26.141 -extern int XG_System_variation_type;
  26.142 -
  26.143 -extern int play_midi(MidiEvent *el, int32 events, int32 samples);
  26.144 -extern int play_midi_file(const char *fn);
  26.145 -extern void dumb_pass_playing_list(int number_of_files, char *list_of_files[]);
  26.146 +#define ISDRUMCHANNEL(s, c) (((s)->drumchannels & (1<<(c))))
    27.1 --- a/timidity/readmidi.c	Tue Oct 17 16:55:58 2017 -0700
    27.2 +++ b/timidity/readmidi.c	Tue Oct 17 21:54:04 2017 -0700
    27.3 @@ -1,254 +1,63 @@
    27.4  /*
    27.5 +
    27.6      TiMidity -- Experimental MIDI to WAVE converter
    27.7      Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
    27.8  
    27.9      This program is free software; you can redistribute it and/or modify
   27.10      it under the terms of the Perl Artistic License, available in COPYING.
   27.11 - */
   27.12 +*/
   27.13 +
   27.14 +#if HAVE_CONFIG_H
   27.15 +#  include <config.h>
   27.16 +#endif
   27.17  
   27.18  #include <stdio.h>
   27.19  #include <stdlib.h>
   27.20 -#include <errno.h>
   27.21  #include <string.h>
   27.22  
   27.23 -#include <SDL_rwops.h>
   27.24 +#include "SDL.h"
   27.25  
   27.26 -#include "config.h"
   27.27 +#include "options.h"
   27.28 +#include "timidity.h"
   27.29  #include "common.h"
   27.30  #include "instrum.h"
   27.31  #include "playmidi.h"
   27.32 -#include "readmidi.h"
   27.33 -#include "output.h"
   27.34 -#include "ctrlmode.h"
   27.35 -
   27.36 -int32 quietchannels=0;
   27.37 -
   27.38 -static int midi_port_number;
   27.39 -char midi_name[FILENAME_MAX+1];
   27.40 -
   27.41 -static int track_info, curr_track, curr_title_track;
   27.42 -static char title[128];
   27.43 -
   27.44 -#if MAXCHAN <= 16
   27.45 -#define MERGE_CHANNEL_PORT(ch) ((int)(ch))
   27.46 -#else
   27.47 -#define MERGE_CHANNEL_PORT(ch) ((int)(ch) | (midi_port_number << 4))
   27.48 -#endif
   27.49 -
   27.50 -/* to avoid some unnecessary parameter passing */
   27.51 -static MidiEventList *evlist;
   27.52 -static int32 event_count;
   27.53 -static SDL_RWops *rw;
   27.54 -static int32 at;
   27.55 -
   27.56 -/* These would both fit into 32 bits, but they are often added in
   27.57 -   large multiples, so it's simpler to have two roomy ints */
   27.58 -static int32 sample_increment, sample_correction; /*samples per MIDI delta-t*/
   27.59  
   27.60  /* Computes how many (fractional) samples one MIDI delta-time unit contains */
   27.61 -static void compute_sample_increment(int32 tempo, int32 divisions)
   27.62 +static void compute_sample_increment(MidiSong *song, Sint32 tempo,
   27.63 +				     Sint32 divisions)
   27.64  {
   27.65    double a;
   27.66 -  a = (double) (tempo) * (double) (play_mode->rate) * (65536.0/1000000.0) /
   27.67 +  a = (double) (tempo) * (double) (song->rate) * (65536.0/1000000.0) /
   27.68      (double)(divisions);
   27.69  
   27.70 -  sample_correction = (int32)(a) & 0xFFFF;
   27.71 -  sample_increment = (int32)(a) >> 16;
   27.72 +  song->sample_correction = (Sint32)(a) & 0xFFFF;
   27.73 +  song->sample_increment = (Sint32)(a) >> 16;
   27.74  
   27.75 -  ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Samples per delta-t: %d (correction %d)",
   27.76 -       sample_increment, sample_correction);
   27.77 +  SNDDBG(("Samples per delta-t: %d (correction %d)",
   27.78 +	  song->sample_increment, song->sample_correction));
   27.79  }
   27.80  
   27.81  /* Read variable-length number (7 bits per byte, MSB first) */
   27.82 -static int32 getvl(void)
   27.83 +static Sint32 getvl(SDL_RWops *rw)
   27.84  {
   27.85 -  int32 l=0;
   27.86 -  uint8 c;
   27.87 +  Sint32 l=0;
   27.88 +  Uint8 c;
   27.89    for (;;)
   27.90      {
   27.91 -      SDL_RWread(rw,&c,1,1);
   27.92 +      SDL_RWread(rw, &c, 1, 1);
   27.93        l += (c & 0x7f);
   27.94        if (!(c & 0x80)) return l;
   27.95        l<<=7;
   27.96      }
   27.97  }
   27.98  
   27.99 -
  27.100 -static int sysex(uint32 len, uint8 *syschan, uint8 *sysa, uint8 *sysb, SDL_RWops *rw)
  27.101 -{
  27.102 -  unsigned char *s=(unsigned char *)safe_malloc(len);
  27.103 -  int id, model, ch, port, adhi, adlo, cd, dta, dtb, dtc;
  27.104 -  if (len != (uint32)SDL_RWread(rw, s, 1, len))
  27.105 -    {
  27.106 -      free(s);
  27.107 -      return 0;
  27.108 -    }
  27.109 -  if (len<5) { free(s); return 0; }
  27.110 -  if (curr_track == curr_title_track && track_info > 1) title[0] = '\0';
  27.111 -  id=s[0]; port=s[1]; model=s[2]; adhi=s[3]; adlo=s[4];
  27.112 -  if (id==0x7e && port==0x7f && model==0x09 && adhi==0x01)
  27.113 -    {
  27.114 -      ctl->cmsg(CMSG_TEXT, VERB_VERBOSE, "GM System On", len);
  27.115 -      GM_System_On=1;
  27.116 -      free(s);
  27.117 -      return 0;
  27.118 -    }
  27.119 -  ch = adlo & 0x0f;
  27.120 -  *syschan=(uint8)ch;
  27.121 -  if (id==0x7f && len==7 && port==0x7f && model==0x04 && adhi==0x01)
  27.122 -    {
  27.123 -      ctl->cmsg(CMSG_TEXT, VERB_DEBUG, "Master Volume %d", s[4]+(s[5]<<7));
  27.124 -      *sysa = s[4];
  27.125 -      *sysb = s[5];
  27.126 -      free(s);
  27.127 -      return ME_MASTERVOLUME;
  27.128 -      /** return s[4]+(s[5]<<7); **/
  27.129 -    }
  27.130 -  if (len<8) { free(s); return 0; }
  27.131 -  port &=0x0f;
  27.132 -  ch = (adlo & 0x0f) | ((port & 0x03) << 4);
  27.133 -  *syschan=(uint8)ch;
  27.134 -  cd=s[5]; dta=s[6];
  27.135 -  if (len >= 8) dtb=s[7];
  27.136 -  else dtb=-1;
  27.137 -  if (len >= 9) dtc=s[8];
  27.138 -  else dtc=-1;
  27.139 -  free(s);
  27.140 -  if (id==0x43 && model==0x4c)
  27.141 -    {
  27.142 -	if (!adhi && !adlo && cd==0x7e && !dta)
  27.143 -	  {
  27.144 -      	    ctl->cmsg(CMSG_TEXT, VERB_VERBOSE, "XG System On", len);
  27.145 -	    XG_System_On=1;
  27.146 -	    #ifdef tplus
  27.147 -	    vol_table = xg_vol_table;
  27.148 -	    #endif
  27.149 -	  }
  27.150 -	else if (adhi == 2 && adlo == 1)
  27.151 -	 {
  27.152 -	    if (dtb==8) dtb=3;
  27.153 -	    switch (cd)
  27.154 -	      {
  27.155 -		case 0x00:
  27.156 -		  XG_System_reverb_type=(dta<<3)+dtb;
  27.157 -		  break;
  27.158 -		case 0x20:
  27.159 -		  XG_System_chorus_type=((dta-64)<<3)+dtb;
  27.160 -		  break;
  27.161 -		case 0x40:
  27.162 -		  XG_System_variation_type=dta;
  27.163 -		  break;
  27.164 -		case 0x5a:
  27.165 -		  /* dta==0 Insertion; dta==1 System */
  27.166 -		  break;
  27.167 -		default: break;
  27.168 -	      }
  27.169 -	 }
  27.170 -	else if (adhi == 8 && cd <= 40)
  27.171 -	 {
  27.172 -	    *sysa = dta & 0x7f;
  27.173 -	    switch (cd)
  27.174 -	      {
  27.175 -		case 0x01: /* bank select MSB */
  27.176 -		  return ME_TONE_KIT;
  27.177 -		  break;
  27.178 -		case 0x02: /* bank select LSB */
  27.179 -		  return ME_TONE_BANK;
  27.180 -		  break;
  27.181 -		case 0x03: /* program number */
  27.182 -	      		/** MIDIEVENT(d->at, ME_PROGRAM, lastchan, a, 0); **/
  27.183 -		  return ME_PROGRAM;
  27.184 -		  break;
  27.185 -		case 0x08: /*  */
  27.186 -		  /* d->channel[adlo&0x0f].transpose = (char)(dta-64); */
  27.187 -		  channel[ch].transpose = (char)(dta-64);
  27.188 -      	    	  ctl->cmsg(CMSG_TEXT, VERB_DEBUG, "transpose channel %d by %d",
  27.189 -			(adlo&0x0f)+1, dta-64);
  27.190 -		  break;
  27.191 -		case 0x0b: /* volume */
  27.192 -		  return ME_MAINVOLUME;
  27.193 -		  break;
  27.194 -		case 0x0e: /* pan */
  27.195 -		  return ME_PAN;
  27.196 -		  break;
  27.197 -		case 0x12: /* chorus send */
  27.198 -		  return ME_CHORUSDEPTH;
  27.199 -		  break;
  27.200 -		case 0x13: /* reverb send */
  27.201 -		  return ME_REVERBERATION;
  27.202 -		  break;
  27.203 -		case 0x14: /* variation send */
  27.204 -		  break;
  27.205 -		case 0x18: /* filter cutoff */
  27.206 -		  return ME_BRIGHTNESS;
  27.207 -		  break;
  27.208 -		case 0x19: /* filter resonance */
  27.209 -		  return ME_HARMONICCONTENT;
  27.210 -		  break;
  27.211 -		default: break;
  27.212 -	      }
  27.213 -	  }
  27.214 -      return 0;
  27.215 -    }
  27.216 -  else if (id==0x41 && model==0x42 && adhi==0x12 && adlo==0x40)
  27.217 -    {
  27.218 -	if (dtc<0) return 0;
  27.219 -	if (!cd && dta==0x7f && !dtb && dtc==0x41)
  27.220 -	  {
  27.221 -      	    ctl->cmsg(CMSG_TEXT, VERB_VERBOSE, "GS System On", len);
  27.222 -	    GS_System_On=1;
  27.223 -	    #ifdef tplus
  27.224 -	    vol_table = gs_vol_table;
  27.225 -	    #endif
  27.226 -	  }
  27.227 -	else if (dta==0x15 && (cd&0xf0)==0x10)
  27.228 -	  {
  27.229 -	    int chan=cd&0x0f;
  27.230 -	    if (!chan) chan=9;
  27.231 -	    else if (chan<10) chan--;
  27.232 -	    chan = MERGE_CHANNEL_PORT(chan);
  27.233 -	    channel[chan].kit=dtb;
  27.234 -	  }
  27.235 -	else if (cd==0x01) switch(dta)
  27.236 -	  {
  27.237 -	    case 0x30:
  27.238 -		switch(dtb)
  27.239 -		  {
  27.240 -		    case 0: XG_System_reverb_type=16+0; break;
  27.241 -		    case 1: XG_System_reverb_type=16+1; break;
  27.242 -		    case 2: XG_System_reverb_type=16+2; break;
  27.243 -		    case 3: XG_System_reverb_type= 8+0; break;
  27.244 -		    case 4: XG_System_reverb_type= 8+1; break;
  27.245 -		    case 5: XG_System_reverb_type=32+0; break;
  27.246 -		    case 6: XG_System_reverb_type=8*17; break;
  27.247 -		    case 7: XG_System_reverb_type=8*18; break;
  27.248 -		  }
  27.249 -		break;
  27.250 -	    case 0x38:
  27.251 -		switch(dtb)
  27.252 -		  {
  27.253 -		    case 0: XG_System_chorus_type= 8+0; break;
  27.254 -		    case 1: XG_System_chorus_type= 8+1; break;
  27.255 -		    case 2: XG_System_chorus_type= 8+2; break;
  27.256 -		    case 3: XG_System_chorus_type= 8+4; break;
  27.257 -		    case 4: XG_System_chorus_type=  -1; break;
  27.258 -		    case 5: XG_System_chorus_type= 8*3; break;
  27.259 -		    case 6: XG_System_chorus_type=  -1; break;
  27.260 -		    case 7: XG_System_chorus_type=  -1; break;
  27.261 -		  }
  27.262 -		break;
  27.263 -	  }
  27.264 -      return 0;
  27.265 -    }
  27.266 -  return 0;
  27.267 -}
  27.268 -
  27.269  /* Print a string from the file, followed by a newline. Any non-ASCII
  27.270     or unprintable characters will be converted to periods. */
  27.271 -static int dumpstring(int32 len, const char *label)
  27.272 +static int dumpstring(SDL_RWops *rw, Sint32 len, char *label)
  27.273  {
  27.274    signed char *s=safe_malloc(len+1);
  27.275 -  if (len != (int32)SDL_RWread(rw, s, 1, len))
  27.276 +  if (len != (Sint32) SDL_RWread(rw, s, 1, len))
  27.277      {
  27.278        free(s);
  27.279        return -1;
  27.280 @@ -259,7 +68,7 @@
  27.281        if (s[len]<32)
  27.282  	s[len]='.';
  27.283      }
  27.284 -  ctl->cmsg(CMSG_TEXT, VERB_VERBOSE, "%s%s", label, s);
  27.285 +  SNDDBG(("%s%s", label, s));
  27.286    free(s);
  27.287    return 0;
  27.288  }
  27.289 @@ -274,82 +83,54 @@
  27.290  
  27.291  /* Read a MIDI event, returning a freshly allocated element that can
  27.292     be linked to the event list */
  27.293 -static MidiEventList *read_midi_event(void)
  27.294 +static MidiEventList *read_midi_event(MidiSong *song)
  27.295  {
  27.296 -  static uint8 laststatus, lastchan;
  27.297 -  static uint8 nrpn=0, rpn_msb[16], rpn_lsb[16]; /* one per channel */
  27.298 -  uint8 me, type, a,b,c;
  27.299 -  int32 len;
  27.300 +  static Uint8 laststatus, lastchan;
  27.301 +  static Uint8 nrpn=0, rpn_msb[16], rpn_lsb[16]; /* one per channel */
  27.302 +  Uint8 me, type, a,b,c;
  27.303 +  Sint32 len;
  27.304    MidiEventList *new;
  27.305  
  27.306    for (;;)
  27.307      {
  27.308 -      at+=getvl();
  27.309 -      if (SDL_RWread(rw,&me,1,1)!=1)
  27.310 +      song->at += getvl(song->rw);
  27.311 +      if (SDL_RWread(song->rw, &me, 1, 1) != 1)
  27.312  	{
  27.313 -	  ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: read_midi_event: %s", 
  27.314 -	       current_filename, strerror(errno));
  27.315 +	  SNDDBG(("read_midi_event: SDL_RWread() failure\n"));
  27.316  	  return 0;
  27.317  	}
  27.318        
  27.319        if(me==0xF0 || me == 0xF7) /* SysEx event */
  27.320  	{
  27.321 -	  int32 sret;
  27.322 -	  uint8 sysa=0, sysb=0, syschan=0;
  27.323 -
  27.324 -	  len=getvl();
  27.325 -	  sret=sysex(len, &syschan, &sysa, &sysb, rw);
  27.326 -	  if (sret)
  27.327 -	   {
  27.328 -	     MIDIEVENT(at, sret, syschan, sysa, sysb);
  27.329 -	   }
  27.330 +	  len=getvl(song->rw);
  27.331 +	  SDL_RWseek(song->rw, len, RW_SEEK_CUR);
  27.332  	}
  27.333        else if(me==0xFF) /* Meta event */
  27.334  	{
  27.335 -	  SDL_RWread(rw,&type,1,1);
  27.336 -	  len=getvl();
  27.337 +	  SDL_RWread(song->rw, &type, 1, 1);
  27.338 +	  len=getvl(song->rw);
  27.339  	  if (type>0 && type<16)
  27.340  	    {
  27.341  	      static char *label[]={
  27.342  		"Text event: ", "Text: ", "Copyright: ", "Track name: ",
  27.343  		"Instrument: ", "Lyric: ", "Marker: ", "Cue point: "};
  27.344 -	      dumpstring(len, label[(type>7) ? 0 : type]);
  27.345 +	      dumpstring(song->rw, len, label[(type>7) ? 0 : type]);
  27.346  	    }
  27.347  	  else
  27.348  	    switch(type)
  27.349  	      {
  27.350 -
  27.351 -	      case 0x21: /* MIDI port number */
  27.352 -		if(len == 1)
  27.353 -		{
  27.354 -	  	    SDL_RWread(rw,&midi_port_number,1,1);
  27.355 -		    if(midi_port_number == EOF)
  27.356 -		    {
  27.357 -			    ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
  27.358 -				      "Warning: \"%s\": Short midi file.",
  27.359 -				      midi_name);
  27.360 -			    return 0;
  27.361 -		    }
  27.362 -		    midi_port_number &= 0x0f;
  27.363 -		    if (midi_port_number)
  27.364 -			ctl->cmsg(CMSG_INFO, VERB_VERBOSE,
  27.365 -			  "(MIDI port number %d)", midi_port_number);
  27.366 -		    midi_port_number &= 0x03;
  27.367 -		}
  27.368 -		else SDL_RWseek(rw, len, RW_SEEK_CUR);
  27.369 -		break;
  27.370 -
  27.371  	      case 0x2F: /* End of Track */
  27.372  		return MAGIC_EOT;
  27.373  
  27.374  	      case 0x51: /* Tempo */
  27.375 -		SDL_RWread(rw,&a,1,1); SDL_RWread(rw,&b,1,1); SDL_RWread(rw,&c,1,1);
  27.376 -		MIDIEVENT(at, ME_TEMPO, c, a, b);
  27.377 +		SDL_RWread(song->rw, &a, 1, 1);
  27.378 +		SDL_RWread(song->rw, &b, 1, 1);
  27.379 +		SDL_RWread(song->rw, &c, 1, 1);
  27.380 +		MIDIEVENT(song->at, ME_TEMPO, c, a, b);
  27.381  		
  27.382  	      default:
  27.383 -		ctl->cmsg(CMSG_INFO, VERB_DEBUG, 
  27.384 -		     "(Meta event type 0x%02x, length %ld)", type, len);
  27.385 -		SDL_RWseek(rw, len, RW_SEEK_CUR);
  27.386 +		SNDDBG(("(Meta event type 0x%02x, length %d)\n", type, len));
  27.387 +		SDL_RWseek(song->rw, len, RW_SEEK_CUR);
  27.388  		break;
  27.389  	      }
  27.390  	}
  27.391 @@ -360,30 +141,28 @@
  27.392  	    {
  27.393  	      lastchan=a & 0x0F;
  27.394  	      laststatus=(a>>4) & 0x07;
  27.395 -	      SDL_RWread(rw,&a, 1,1);
  27.396 +	      SDL_RWread(song->rw, &a, 1, 1);
  27.397  	      a &= 0x7F;
  27.398  	    }
  27.399  	  switch(laststatus)
  27.400  	    {
  27.401  	    case 0: /* Note off */
  27.402 -	      SDL_RWread(rw,&b, 1,1);
  27.403 +	      SDL_RWread(song->rw, &b, 1, 1);
  27.404  	      b &= 0x7F;
  27.405 -	      MIDIEVENT(at, ME_NOTEOFF, lastchan, a,b);
  27.406 +	      MIDIEVENT(song->at, ME_NOTEOFF, lastchan, a,b);
  27.407  
  27.408  	    case 1: /* Note on */
  27.409 -	      SDL_RWread(rw,&b, 1,1);
  27.410 +	      SDL_RWread(song->rw, &b, 1, 1);
  27.411  	      b &= 0x7F;
  27.412 -	      if (curr_track == curr_title_track && track_info > 1) title[0] = '\0';
  27.413 -	      MIDIEVENT(at, ME_NOTEON, lastchan, a,b);
  27.414 -
  27.415 +	      MIDIEVENT(song->at, ME_NOTEON, lastchan, a,b);
  27.416  
  27.417  	    case 2: /* Key Pressure */
  27.418 -	      SDL_RWread(rw,&b, 1,1);
  27.419 +	      SDL_RWread(song->rw, &b, 1, 1);
  27.420  	      b &= 0x7F;
  27.421 -	      MIDIEVENT(at, ME_KEYPRESSURE, lastchan, a, b);
  27.422 +	      MIDIEVENT(song->at, ME_KEYPRESSURE, lastchan, a, b);
  27.423  
  27.424  	    case 3: /* Control change */
  27.425 -	      SDL_RWread(rw,&b, 1,1);
  27.426 +	      SDL_RWread(song->rw, &b, 1, 1);
  27.427  	      b &= 0x7F;
  27.428  	      {
  27.429  		int control=255;
  27.430 @@ -393,14 +172,6 @@
  27.431  		  case 10: control=ME_PAN; break;
  27.432  		  case 11: control=ME_EXPRESSION; break;
  27.433  		  case 64: control=ME_SUSTAIN; break;
  27.434 -
  27.435 -		  case 71: control=ME_HARMONICCONTENT; break;
  27.436 -		  case 72: control=ME_RELEASETIME; break;
  27.437 -		  case 73: control=ME_ATTACKTIME; break;
  27.438 -		  case 74: control=ME_BRIGHTNESS; break;
  27.439 -		  case 91: control=ME_REVERBERATION; break;
  27.440 -		  case 93: control=ME_CHORUSDEPTH; break;
  27.441 -
  27.442  		  case 120: control=ME_ALL_SOUNDS_OFF; break;
  27.443  		  case 121: control=ME_RESET_CONTROLLERS; break;
  27.444  		  case 123: control=ME_ALL_NOTES_OFF; break;
  27.445 @@ -411,9 +182,13 @@
  27.446  		       Also, some MIDI files use 0 as some sort of
  27.447  		       continuous controller. This will cause lots of
  27.448  		       warnings about undefined tone banks. */
  27.449 -		  case 0: if (XG_System_On) control = ME_TONE_KIT; else control=ME_TONE_BANK; break;
  27.450 -
  27.451 -		  case 32: if (XG_System_On) control = ME_TONE_BANK; break;
  27.452 +		  case 0: control=ME_TONE_BANK; break;
  27.453 +		  case 32: 
  27.454 +		    if (b!=0)
  27.455 +		      SNDDBG(("(Strange: tone bank change 0x20%02x)\n", b));
  27.456 +		    else
  27.457 +		      control=ME_TONE_BANK;
  27.458 +		    break;
  27.459  
  27.460  		  case 100: nrpn=0; rpn_msb[lastchan]=b; break;
  27.461  		  case 101: nrpn=0; rpn_lsb[lastchan]=b; break;
  27.462 @@ -423,47 +198,8 @@
  27.463  		  case 6:
  27.464  		    if (nrpn)
  27.465  		      {
  27.466 -			if (rpn_msb[lastchan]==1) switch (rpn_lsb[lastchan])
  27.467 -			 {
  27.468 -#ifdef tplus
  27.469 -			   case 0x08: control=ME_VIBRATO_RATE; break;
  27.470 -			   case 0x09: control=ME_VIBRATO_DEPTH; break;
  27.471 -			   case 0x0a: control=ME_VIBRATO_DELAY; break;
  27.472 -#endif
  27.473 -			   case 0x20: control=ME_BRIGHTNESS; break;
  27.474 -			   case 0x21: control=ME_HARMONICCONTENT; break;
  27.475 -			/*
  27.476 -			   case 0x63: envelope attack rate
  27.477 -			   case 0x64: envelope decay rate
  27.478 -			   case 0x66: envelope release rate
  27.479 -			*/
  27.480 -			 }
  27.481 -			else switch (rpn_msb[lastchan])
  27.482 -			 {
  27.483 -			/*
  27.484 -			   case 0x14: filter cutoff frequency
  27.485 -			   case 0x15: filter resonance
  27.486 -			   case 0x16: envelope attack rate
  27.487 -			   case 0x17: envelope decay rate
  27.488 -			   case 0x18: pitch coarse
  27.489 -			   case 0x19: pitch fine
  27.490 -			*/
  27.491 -			   case 0x1a: drumvolume[lastchan][0x7f & rpn_lsb[lastchan]] = b; break;
  27.492 -			   case 0x1c:
  27.493 -			     if (!b) b=(int) (127.0*rand()/(RAND_MAX));
  27.494 -			     drumpanpot[lastchan][0x7f & rpn_lsb[lastchan]] = b;
  27.495 -			     break;
  27.496 -			   case 0x1d: drumreverberation[lastchan][0x7f & rpn_lsb[lastchan]] = b; break;
  27.497 -			   case 0x1e: drumchorusdepth[lastchan][0x7f & rpn_lsb[lastchan]] = b; break;
  27.498 -			/*
  27.499 -			   case 0x1f: variation send level
  27.500 -			*/
  27.501 -			 }
  27.502 -
  27.503 -			ctl->cmsg(CMSG_INFO, VERB_DEBUG, 
  27.504 -				  "(Data entry (MSB) for NRPN %02x,%02x: %ld)",
  27.505 -				  rpn_msb[lastchan], rpn_lsb[lastchan],
  27.506 -				  b);
  27.507 +			SNDDBG(("(Data entry (MSB) for NRPN %02x,%02x: %d)\n",