Here are patches for SDL12 and SDL_mixer for 4 or 6 channel
authorSam Lantinga <slouken@libsdl.org>
Sat, 21 Aug 2004 12:27:02 +0000
changeset 24563b3650714de
parent 244 bb93f431dfcc
child 246 9fa5d0f9d042
Here are patches for SDL12 and SDL_mixer for 4 or 6 channel
surround sound on Linux using the Alsa driver. To use them, naturally
you need a sound card that will do 4 or 6 channels and probably also a
recent version of the Alsa drivers and library. Since the only SDL
output driver that knows about surround sound is the Alsa driver,
you���ll want to choose it, using:

export SDL_AUDIODRIVER=alsa

There are no syntactic changes to the programming API. No new
library calls, no differences in arguments.

There are two semantic changes:

(1) For library calls with number of channels as an argument, formerly
you could use only 1 or 2 for the number of channels. Now you
can also use 4 or 6.

(2) The two "left" and "right" arguments to Mix_SetPanning, for the
case of 4 or 6 channels, no longer simply control the volumes of
the left and right channels. Now the "left" argument is converted
to an angle and Mix_SetPosition is called, and the "right" argu-
ment is ignored.

With two exceptions, so far as I know, the modified SDL12 and
SDL_mixer work the same way as the original versions, when opened for
1 or 2 channel output. The two exceptions are bugs which I fixed.
Well, the first, anyway, is a bug for sure. When rate conversions up
or down by a factor of two are applied (in src/audio/SDL_audiocvt.c),
streams with different numbers of channels (that is, mono and stereo)
are treated the same way: either each sample is copied or every other
sample is omitted. This is ok for mono, but for stereo, it is frames
that should be copied or omitted, where by "frame" I mean a portion of
the stream containing one sample for each channel. (In the SDL source,
confusingly, sometimes frames are called "samples".) So for these
rate conversions, stereo streams have to be treated differently, and
they are, in my modified version.

The other problem that might be characterized as a bug arises
when SDL_mixer is passed a multichannel chunk which does not have an
integral number of frames. Due to the way the effect_position code
loops over frames, when the chunk ends with a partial frame, memory
outside the chunk buffer will be accessed. In the case of stereo,
it���s possible that because malloc may give more memory than requested,
this potential problem never actually causes a segment fault. I don���t
know. For 6 channel chunks, I do know, and it does cause segment
faults.


If SDL_mixer is passed defective chunks and this causes a segment
fault, arguably, that���s not a bug in SDL_mixer. Still, whether or not
it counts as a bug, it���s easy to protect against, so why not? I added
code in mixer.c to discard any partial frame at the end of a chunk.

Then what about when SDL or SDL_mixer is opened for 4 or 6 chan-
nel output? What happens with the parts of the current library
designed for stereo? I don���t know whether I���ve covered all the bases,
but I���ve tried:

(1) For playing 2 channel waves, or other cases where SDL knows it has
to match up a 2 channel source with a 4 or 6 channel output, I���ve
added code in SDL_audiocvt.c to make the necessary conversions.

(2) For playing midis using timidity, I���ve converted timidity to do 4
or 6 channel output, upon request.

(3) For playing mods using mikmod, I put ad hoc code in music.c to
convert the stereo output that mikmod produces to 4 or 6 chan-
nels. Obviously it would be better to change the mikmod code to
mix down into 4 or 6 channels, but I have a hard time following
the code in mikmod, so I didn���t do that.

(4) For playing mp3s, I put ad hoc code in smpeg to copy channels in
the case when 4 or 6 channel output is needed.

(5) There seems to be no problem with .ogg files - stereo .oggs can be
up converted as .wavs are.

(6) The effect_position code in SDL_mixer is now generalized to in-
clude the cases of 4 and 6 channel streams.

I���ve done a very limited amount of compatibility testing for some
of the games using SDL I happen to have. For details, see the file
TESTS.

I���ve put into a separate archive, Surround-SDL-testfiles.tgz, a
couple of 6 channel wave files for testing and a 6 channel ogg file.
If you have the right hardware and version of Alsa, you should be able
to play the wave files with the Alsa utility aplay (and hear all
channels, except maybe lfe, for chan-id.wav, since it���s rather faint).
Don���t expect aplay to give good sound, though. There���s something
wrong with the current version of aplay.

The canyon.ogg file is to test loading of 6 channel oggs. After
patching and compiling, you can play it with playmus. (My version of
ogg123 will not play it, and I had to patch mplayer to get it to play
6 channel oggs.)

Greg Lee <greg@ling.lll.hawaii.edu>
Thus, July 1, 2004
CHANGES
effect_position.c
mixer.c
music.c
native_midi_gpl/native_midi_gpl.c
playmus.c
playwave.c
timidity/common.h
timidity/config.h
timidity/instrum.c
timidity/instrum.h
timidity/mix.c
timidity/playmidi.c
timidity/playmidi.h
timidity/readmidi.c
timidity/readmidi.h
timidity/resample.c
timidity/resample.h
timidity/sdl_c.c
timidity/tables.c
timidity/tables.h
timidity/timidity.c
     1.1 --- a/CHANGES	Fri Aug 20 19:32:09 2004 +0000
     1.2 +++ b/CHANGES	Sat Aug 21 12:27:02 2004 +0000
     1.3 @@ -1,4 +1,7 @@
     1.4  1.2.6:
     1.5 +Greg Lee - Wed, 14 Jul 2004 05:13:14 -1000
     1.6 + * Added 4 and 6 channel surround sound output support
     1.7 + * Added support for RMID format MIDI files
     1.8  Sam Lantinga - Wed Nov 19 00:23:44 PST 2003
     1.9   * Updated libtool support for new mingw32 DLL build process
    1.10  Ryan C. Gordon - Sun Nov  9 23:34:47 EST 2003
     2.1 --- a/effect_position.c	Fri Aug 20 19:32:09 2004 +0000
     2.2 +++ b/effect_position.c	Sat Aug 21 12:27:02 2004 +0000
     2.3 @@ -60,8 +60,17 @@
     2.4      volatile float right_f;
     2.5      volatile Uint8 left_u8;
     2.6      volatile Uint8 right_u8;
     2.7 +    volatile float left_rear_f;
     2.8 +    volatile float right_rear_f;
     2.9 +    volatile float center_f;
    2.10 +    volatile float lfe_f;
    2.11 +    volatile Uint8 left_rear_u8;
    2.12 +    volatile Uint8 right_rear_u8;
    2.13 +    volatile Uint8 center_u8;
    2.14 +    volatile Uint8 lfe_u8;
    2.15      volatile float distance_f;
    2.16      volatile Uint8 distance_u8;
    2.17 +    volatile Sint16 room_angle;
    2.18      volatile int in_use;
    2.19      volatile int channels;
    2.20  } position_args;
    2.21 @@ -104,9 +113,19 @@
    2.22          len--;
    2.23      }
    2.24  
    2.25 +    if (args->room_angle == 0)
    2.26      for (i = 0; i < len; i += sizeof (Uint8) * 2) {
    2.27          /* must adjust the sample so that 0 is the center */
    2.28          *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    2.29 +            * args->right_f) * args->distance_f) + 128);
    2.30 +        ptr++;
    2.31 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    2.32 +            * args->left_f) * args->distance_f) + 128);
    2.33 +        ptr++;
    2.34 +    }
    2.35 +    else for (i = 0; i < len; i += sizeof (Uint8) * 2) {
    2.36 +        /* must adjust the sample so that 0 is the center */
    2.37 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    2.38              * args->left_f) * args->distance_f) + 128);
    2.39          ptr++;
    2.40          *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    2.41 @@ -114,6 +133,202 @@
    2.42          ptr++;
    2.43      }
    2.44  }
    2.45 +static void _Eff_position_u8_c4(int chan, void *stream, int len, void *udata)
    2.46 +{
    2.47 +    volatile position_args *args = (volatile position_args *) udata;
    2.48 +    Uint8 *ptr = (Uint8 *) stream;
    2.49 +    int i;
    2.50 +
    2.51 +        /*
    2.52 +         * if there's only a mono channnel (the only way we wouldn't have
    2.53 +         *  a len divisible by 2 here), then left_f and right_f are always
    2.54 +         *  1.0, and are therefore throwaways.
    2.55 +         */
    2.56 +    if (len % sizeof (Uint16) != 0) {
    2.57 +        *ptr = (Uint8) (((float) *ptr) * args->distance_f);
    2.58 +        ptr++;
    2.59 +        len--;
    2.60 +    }
    2.61 +
    2.62 +    if (args->room_angle == 0)
    2.63 +    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
    2.64 +        /* must adjust the sample so that 0 is the center */
    2.65 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    2.66 +            * args->left_f) * args->distance_f) + 128);
    2.67 +        ptr++;
    2.68 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    2.69 +            * args->right_f) * args->distance_f) + 128);
    2.70 +        ptr++;
    2.71 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    2.72 +            * args->left_rear_f) * args->distance_f) + 128);
    2.73 +        ptr++;
    2.74 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    2.75 +            * args->right_rear_f) * args->distance_f) + 128);
    2.76 +        ptr++;
    2.77 +    }
    2.78 +    else if (args->room_angle == 90)
    2.79 +    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
    2.80 +        /* must adjust the sample so that 0 is the center */
    2.81 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    2.82 +            * args->right_f) * args->distance_f) + 128);
    2.83 +        ptr++;
    2.84 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    2.85 +            * args->right_rear_f) * args->distance_f) + 128);
    2.86 +        ptr++;
    2.87 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    2.88 +            * args->left_f) * args->distance_f) + 128);
    2.89 +        ptr++;
    2.90 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    2.91 +            * args->left_rear_f) * args->distance_f) + 128);
    2.92 +        ptr++;
    2.93 +    }
    2.94 +    else if (args->room_angle == 180)
    2.95 +    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
    2.96 +        /* must adjust the sample so that 0 is the center */
    2.97 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    2.98 +            * args->right_rear_f) * args->distance_f) + 128);
    2.99 +        ptr++;
   2.100 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.101 +            * args->left_rear_f) * args->distance_f) + 128);
   2.102 +        ptr++;
   2.103 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.104 +            * args->right_f) * args->distance_f) + 128);
   2.105 +        ptr++;
   2.106 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.107 +            * args->left_f) * args->distance_f) + 128);
   2.108 +        ptr++;
   2.109 +    }
   2.110 +    else if (args->room_angle == 270)
   2.111 +    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
   2.112 +        /* must adjust the sample so that 0 is the center */
   2.113 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.114 +            * args->left_rear_f) * args->distance_f) + 128);
   2.115 +        ptr++;
   2.116 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.117 +            * args->left_f) * args->distance_f) + 128);
   2.118 +        ptr++;
   2.119 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.120 +            * args->right_rear_f) * args->distance_f) + 128);
   2.121 +        ptr++;
   2.122 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.123 +            * args->right_f) * args->distance_f) + 128);
   2.124 +        ptr++;
   2.125 +    }
   2.126 +}
   2.127 +
   2.128 +
   2.129 +static void _Eff_position_u8_c6(int chan, void *stream, int len, void *udata)
   2.130 +{
   2.131 +    volatile position_args *args = (volatile position_args *) udata;
   2.132 +    Uint8 *ptr = (Uint8 *) stream;
   2.133 +    int i;
   2.134 +
   2.135 +        /*
   2.136 +         * if there's only a mono channnel (the only way we wouldn't have
   2.137 +         *  a len divisible by 2 here), then left_f and right_f are always
   2.138 +         *  1.0, and are therefore throwaways.
   2.139 +         */
   2.140 +    if (len % sizeof (Uint16) != 0) {
   2.141 +        *ptr = (Uint8) (((float) *ptr) * args->distance_f);
   2.142 +        ptr++;
   2.143 +        len--;
   2.144 +    }
   2.145 +
   2.146 +    if (args->room_angle == 0)
   2.147 +    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
   2.148 +        /* must adjust the sample so that 0 is the center */
   2.149 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.150 +            * args->left_f) * args->distance_f) + 128);
   2.151 +        ptr++;
   2.152 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.153 +            * args->right_f) * args->distance_f) + 128);
   2.154 +        ptr++;
   2.155 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.156 +            * args->left_rear_f) * args->distance_f) + 128);
   2.157 +        ptr++;
   2.158 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.159 +            * args->right_rear_f) * args->distance_f) + 128);
   2.160 +        ptr++;
   2.161 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.162 +            * args->center_f) * args->distance_f) + 128);
   2.163 +        ptr++;
   2.164 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.165 +            * args->lfe_f) * args->distance_f) + 128);
   2.166 +        ptr++;
   2.167 +    }
   2.168 +    else if (args->room_angle == 90)
   2.169 +    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
   2.170 +        /* must adjust the sample so that 0 is the center */
   2.171 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.172 +            * args->right_f) * args->distance_f) + 128);
   2.173 +        ptr++;
   2.174 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.175 +            * args->right_rear_f) * args->distance_f) + 128);
   2.176 +        ptr++;
   2.177 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.178 +            * args->left_f) * args->distance_f) + 128);
   2.179 +        ptr++;
   2.180 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.181 +            * args->left_rear_f) * args->distance_f) + 128);
   2.182 +        ptr++;
   2.183 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.184 +            * args->right_rear_f) * args->distance_f/2) + 128)
   2.185 +            + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.186 +            * args->right_f) * args->distance_f/2) + 128);
   2.187 +        ptr++;
   2.188 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.189 +            * args->lfe_f) * args->distance_f) + 128);
   2.190 +        ptr++;
   2.191 +    }
   2.192 +    else if (args->room_angle == 180)
   2.193 +    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
   2.194 +        /* must adjust the sample so that 0 is the center */
   2.195 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.196 +            * args->right_rear_f) * args->distance_f) + 128);
   2.197 +        ptr++;
   2.198 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.199 +            * args->left_rear_f) * args->distance_f) + 128);
   2.200 +        ptr++;
   2.201 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.202 +            * args->right_f) * args->distance_f) + 128);
   2.203 +        ptr++;
   2.204 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.205 +            * args->left_f) * args->distance_f) + 128);
   2.206 +        ptr++;
   2.207 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.208 +            * args->right_rear_f) * args->distance_f/2) + 128)
   2.209 +            + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.210 +            * args->left_rear_f) * args->distance_f/2) + 128);
   2.211 +        ptr++;
   2.212 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.213 +            * args->lfe_f) * args->distance_f) + 128);
   2.214 +        ptr++;
   2.215 +    }
   2.216 +    else if (args->room_angle == 270)
   2.217 +    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
   2.218 +        /* must adjust the sample so that 0 is the center */
   2.219 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.220 +            * args->left_rear_f) * args->distance_f) + 128);
   2.221 +        ptr++;
   2.222 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.223 +            * args->left_f) * args->distance_f) + 128);
   2.224 +        ptr++;
   2.225 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.226 +            * args->right_rear_f) * args->distance_f) + 128);
   2.227 +        ptr++;
   2.228 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.229 +            * args->right_f) * args->distance_f) + 128);
   2.230 +        ptr++;
   2.231 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.232 +            * args->left_f) * args->distance_f/2) + 128)
   2.233 +            + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.234 +            * args->left_rear_f) * args->distance_f/2) + 128);
   2.235 +        ptr++;
   2.236 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   2.237 +            * args->lfe_f) * args->distance_f) + 128);
   2.238 +        ptr++;
   2.239 +    }
   2.240 +}
   2.241  
   2.242  
   2.243  /*
   2.244 @@ -134,6 +349,11 @@
   2.245      Uint8 *r = ((Uint8 *) _Eff_volume_table) + (256 * args->right_u8);
   2.246      Uint8 *d = ((Uint8 *) _Eff_volume_table) + (256 * args->distance_u8);
   2.247  
   2.248 +    if (args->room_angle == 180) {
   2.249 +	    Uint8 *temp = l;
   2.250 +	    l = r;
   2.251 +	    r = temp;
   2.252 +    }
   2.253          /*
   2.254           * if there's only a mono channnel, then l[] and r[] are always
   2.255           *  volume 255, and are therefore throwaways. Still, we have to
   2.256 @@ -184,6 +404,14 @@
   2.257          len--;
   2.258      }
   2.259  
   2.260 +    if (args->room_angle == 180)
   2.261 +    for (i = 0; i < len; i += sizeof (Sint8) * 2) {
   2.262 +        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f);
   2.263 +        ptr++;
   2.264 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f);
   2.265 +        ptr++;
   2.266 +    }
   2.267 +    else
   2.268      for (i = 0; i < len; i += sizeof (Sint8) * 2) {
   2.269          *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f);
   2.270          ptr++;
   2.271 @@ -191,6 +419,109 @@
   2.272          ptr++;
   2.273      }
   2.274  }
   2.275 +static void _Eff_position_s8_c4(int chan, void *stream, int len, void *udata)
   2.276 +{
   2.277 +    volatile position_args *args = (volatile position_args *) udata;
   2.278 +    Sint8 *ptr = (Sint8 *) stream;
   2.279 +    int i;
   2.280 +
   2.281 +        /*
   2.282 +         * if there's only a mono channnel (the only way we wouldn't have
   2.283 +         *  a len divisible by 2 here), then left_f and right_f are always
   2.284 +         *  1.0, and are therefore throwaways.
   2.285 +         */
   2.286 +    if (len % sizeof (Sint16) != 0) {
   2.287 +        *ptr = (Sint8) (((float) *ptr) * args->distance_f);
   2.288 +        ptr++;
   2.289 +        len--;
   2.290 +    }
   2.291 +
   2.292 +    for (i = 0; i < len; i += sizeof (Sint8) * 4) {
   2.293 +      switch (args->room_angle) {
   2.294 +       case 0:
   2.295 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
   2.296 +        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
   2.297 +        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
   2.298 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
   2.299 +	break;
   2.300 +       case 90:
   2.301 +        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
   2.302 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
   2.303 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
   2.304 +        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
   2.305 +	break;
   2.306 +       case 180:
   2.307 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
   2.308 +        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
   2.309 +        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
   2.310 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
   2.311 +	break;
   2.312 +       case 270:
   2.313 +        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
   2.314 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
   2.315 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
   2.316 +        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
   2.317 +	break;
   2.318 +      }
   2.319 +    }
   2.320 +}
   2.321 +static void _Eff_position_s8_c6(int chan, void *stream, int len, void *udata)
   2.322 +{
   2.323 +    volatile position_args *args = (volatile position_args *) udata;
   2.324 +    Sint8 *ptr = (Sint8 *) stream;
   2.325 +    int i;
   2.326 +
   2.327 +        /*
   2.328 +         * if there's only a mono channnel (the only way we wouldn't have
   2.329 +         *  a len divisible by 2 here), then left_f and right_f are always
   2.330 +         *  1.0, and are therefore throwaways.
   2.331 +         */
   2.332 +    if (len % sizeof (Sint16) != 0) {
   2.333 +        *ptr = (Sint8) (((float) *ptr) * args->distance_f);
   2.334 +        ptr++;
   2.335 +        len--;
   2.336 +    }
   2.337 +
   2.338 +    for (i = 0; i < len; i += sizeof (Sint8) * 6) {
   2.339 +      switch (args->room_angle) {
   2.340 +       case 0:
   2.341 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
   2.342 +        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
   2.343 +        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
   2.344 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
   2.345 +        *ptr = (Sint8)((((float) *ptr) * args->center_f) * args->distance_f); ptr++;
   2.346 +        *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
   2.347 +	break;
   2.348 +       case 90:
   2.349 +        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
   2.350 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
   2.351 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
   2.352 +        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
   2.353 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f / 2)
   2.354 +           + (Sint8)((((float) *ptr) * args->right_f) * args->distance_f / 2); ptr++;
   2.355 +        *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
   2.356 +	break;
   2.357 +       case 180:
   2.358 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
   2.359 +        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
   2.360 +        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
   2.361 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
   2.362 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f / 2)
   2.363 +           + (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f / 2); ptr++;
   2.364 +        *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
   2.365 +	break;
   2.366 +       case 270:
   2.367 +        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
   2.368 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
   2.369 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
   2.370 +        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
   2.371 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f / 2)
   2.372 +           + (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f / 2); ptr++;
   2.373 +        *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
   2.374 +	break;
   2.375 +      }
   2.376 +    }
   2.377 +}
   2.378  
   2.379  
   2.380  /*
   2.381 @@ -211,6 +542,12 @@
   2.382      Sint8 *r = ((Sint8 *) _Eff_volume_table) + (256 * args->right_u8);
   2.383      Sint8 *d = ((Sint8 *) _Eff_volume_table) + (256 * args->distance_u8);
   2.384  
   2.385 +    if (args->room_angle == 180) {
   2.386 +	    Sint8 *temp = l;
   2.387 +	    l = r;
   2.388 +	    r = temp;
   2.389 +    }
   2.390 +
   2.391  
   2.392      while (len % sizeof (Uint32) != 0) {
   2.393          *ptr = d[l[*ptr]];
   2.394 @@ -259,8 +596,126 @@
   2.395          Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
   2.396                                      * args->distance_f) + 32768);
   2.397  
   2.398 -        *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   2.399 -        *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   2.400 +	if (args->room_angle == 180) {
   2.401 +        	*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   2.402 +        	*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   2.403 +	}
   2.404 +	else {
   2.405 +        	*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   2.406 +        	*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   2.407 +	}
   2.408 +    }
   2.409 +}
   2.410 +static void _Eff_position_u16lsb_c4(int chan, void *stream, int len, void *udata)
   2.411 +{
   2.412 +    volatile position_args *args = (volatile position_args *) udata;
   2.413 +    Uint16 *ptr = (Uint16 *) stream;
   2.414 +    int i;
   2.415 +
   2.416 +    for (i = 0; i < len; i += sizeof (Uint16) * 4) {
   2.417 +        Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
   2.418 +        Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
   2.419 +        Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768);
   2.420 +        Sint16 samprr = (Sint16) (SDL_SwapLE16(*(ptr+3)) - 32768);
   2.421 +        
   2.422 +        Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
   2.423 +                                    * args->distance_f) + 32768);
   2.424 +        Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
   2.425 +                                    * args->distance_f) + 32768);
   2.426 +        Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_f)
   2.427 +                                    * args->distance_f) + 32768);
   2.428 +        Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_f)
   2.429 +                                    * args->distance_f) + 32768);
   2.430 +
   2.431 +	switch (args->room_angle) {
   2.432 +		case 0:
   2.433 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   2.434 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   2.435 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
   2.436 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
   2.437 +			break;
   2.438 +		case 90:
   2.439 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   2.440 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
   2.441 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   2.442 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
   2.443 +			break;
   2.444 +		case 180:
   2.445 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
   2.446 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
   2.447 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   2.448 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   2.449 +			break;
   2.450 +		case 270:
   2.451 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
   2.452 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   2.453 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
   2.454 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   2.455 +			break;
   2.456 +	}
   2.457 +    }
   2.458 +}
   2.459 +static void _Eff_position_u16lsb_c6(int chan, void *stream, int len, void *udata)
   2.460 +{
   2.461 +    volatile position_args *args = (volatile position_args *) udata;
   2.462 +    Uint16 *ptr = (Uint16 *) stream;
   2.463 +    int i;
   2.464 +
   2.465 +    for (i = 0; i < len; i += sizeof (Uint16) * 6) {
   2.466 +        Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
   2.467 +        Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
   2.468 +        Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768);
   2.469 +        Sint16 samprr = (Sint16) (SDL_SwapLE16(*(ptr+3)) - 32768);
   2.470 +        Sint16 sampce = (Sint16) (SDL_SwapLE16(*(ptr+4)) - 32768);
   2.471 +        Sint16 sampwf = (Sint16) (SDL_SwapLE16(*(ptr+5)) - 32768);
   2.472 +        
   2.473 +        Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
   2.474 +                                    * args->distance_f) + 32768);
   2.475 +        Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
   2.476 +                                    * args->distance_f) + 32768);
   2.477 +        Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_f)
   2.478 +                                    * args->distance_f) + 32768);
   2.479 +        Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_f)
   2.480 +                                    * args->distance_f) + 32768);
   2.481 +        Uint16 swapce = (Uint16) ((Sint16) (((float) sampce * args->left_f)
   2.482 +                                    * args->distance_f) + 32768);
   2.483 +        Uint16 swapwf = (Uint16) ((Sint16) (((float) sampwf * args->right_f)
   2.484 +                                    * args->distance_f) + 32768);
   2.485 +
   2.486 +	switch (args->room_angle) {
   2.487 +		case 0:
   2.488 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   2.489 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   2.490 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
   2.491 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
   2.492 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapce);
   2.493 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
   2.494 +			break;
   2.495 +		case 90:
   2.496 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   2.497 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
   2.498 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   2.499 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
   2.500 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr)/2 + (Uint16) SDL_SwapLE16(swaprr)/2;
   2.501 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
   2.502 +			break;
   2.503 +		case 180:
   2.504 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
   2.505 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
   2.506 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   2.507 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   2.508 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr)/2 + (Uint16) SDL_SwapLE16(swaplr)/2;
   2.509 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
   2.510 +			break;
   2.511 +		case 270:
   2.512 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
   2.513 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   2.514 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
   2.515 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   2.516 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl)/2 + (Uint16) SDL_SwapLE16(swaplr)/2;
   2.517 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
   2.518 +			break;
   2.519 +	}
   2.520      }
   2.521  }
   2.522  
   2.523 @@ -271,13 +726,127 @@
   2.524      Sint16 *ptr = (Sint16 *) stream;
   2.525      int i;
   2.526  
   2.527 +#if 0
   2.528 +    if (len % (sizeof(Sint16) * 2)) {
   2.529 +	    fprintf(stderr,"Not an even number of frames! len=%d\n", len);
   2.530 +	    return;
   2.531 +    }
   2.532 +#endif
   2.533 +
   2.534      for (i = 0; i < len; i += sizeof (Sint16) * 2) {
   2.535          Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
   2.536                                      args->left_f) * args->distance_f);
   2.537          Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
   2.538                                      args->right_f) * args->distance_f);
   2.539 -        *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   2.540 -        *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   2.541 +	if (args->room_angle == 180) {
   2.542 +        	*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   2.543 +        	*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   2.544 +	}
   2.545 +	else {
   2.546 +        	*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   2.547 +        	*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   2.548 +	}
   2.549 +    }
   2.550 +}
   2.551 +static void _Eff_position_s16lsb_c4(int chan, void *stream, int len, void *udata)
   2.552 +{
   2.553 +    /* 16 signed bits (lsb) * 4 channels. */
   2.554 +    volatile position_args *args = (volatile position_args *) udata;
   2.555 +    Sint16 *ptr = (Sint16 *) stream;
   2.556 +    int i;
   2.557 +
   2.558 +    for (i = 0; i < len; i += sizeof (Sint16) * 4) {
   2.559 +        Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
   2.560 +                                    args->left_f) * args->distance_f);
   2.561 +        Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
   2.562 +                                    args->right_f) * args->distance_f);
   2.563 +        Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
   2.564 +                                    args->left_rear_f) * args->distance_f);
   2.565 +        Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+2))) *
   2.566 +                                    args->right_rear_f) * args->distance_f);
   2.567 +	switch (args->room_angle) {
   2.568 +		case 0:
   2.569 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   2.570 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   2.571 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
   2.572 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
   2.573 +			break;
   2.574 +		case 90:
   2.575 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   2.576 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
   2.577 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   2.578 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
   2.579 +			break;
   2.580 +		case 180:
   2.581 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
   2.582 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
   2.583 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   2.584 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   2.585 +			break;
   2.586 +		case 270:
   2.587 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
   2.588 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   2.589 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
   2.590 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   2.591 +			break;
   2.592 +	}
   2.593 +    }
   2.594 +}
   2.595 +
   2.596 +static void _Eff_position_s16lsb_c6(int chan, void *stream, int len, void *udata)
   2.597 +{
   2.598 +    /* 16 signed bits (lsb) * 6 channels. */
   2.599 +    volatile position_args *args = (volatile position_args *) udata;
   2.600 +    Sint16 *ptr = (Sint16 *) stream;
   2.601 +    int i;
   2.602 +
   2.603 +    for (i = 0; i < len; i += sizeof (Sint16) * 6) {
   2.604 +        Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
   2.605 +                                    args->left_f) * args->distance_f);
   2.606 +        Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
   2.607 +                                    args->right_f) * args->distance_f);
   2.608 +        Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+2))) *
   2.609 +                                    args->left_rear_f) * args->distance_f);
   2.610 +        Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+3))) *
   2.611 +                                    args->right_rear_f) * args->distance_f);
   2.612 +        Sint16 swapce = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+4))) *
   2.613 +                                    args->center_f) * args->distance_f);
   2.614 +        Sint16 swapwf = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+5))) *
   2.615 +                                    args->lfe_f) * args->distance_f);
   2.616 +	switch (args->room_angle) {
   2.617 +		case 0:
   2.618 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   2.619 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   2.620 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
   2.621 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
   2.622 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapce);
   2.623 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
   2.624 +			break;
   2.625 +		case 90:
   2.626 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   2.627 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
   2.628 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   2.629 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
   2.630 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr)/2 + (Sint16) SDL_SwapLE16(swaprr)/2;
   2.631 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
   2.632 +			break;
   2.633 +		case 180:
   2.634 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
   2.635 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
   2.636 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   2.637 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   2.638 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr)/2 + (Sint16) SDL_SwapLE16(swaplr)/2;
   2.639 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
   2.640 +			break;
   2.641 +		case 270:
   2.642 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
   2.643 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   2.644 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
   2.645 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   2.646 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl)/2 + (Sint16) SDL_SwapLE16(swaplr)/2;
   2.647 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
   2.648 +			break;
   2.649 +	}
   2.650      }
   2.651  }
   2.652  
   2.653 @@ -297,8 +866,128 @@
   2.654          Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
   2.655                                      * args->distance_f) + 32768);
   2.656  
   2.657 -        *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   2.658 -        *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   2.659 +	if (args->room_angle == 180) {
   2.660 +        	*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   2.661 +        	*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   2.662 +	}
   2.663 +	else {
   2.664 +        	*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   2.665 +        	*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   2.666 +	}
   2.667 +    }
   2.668 +}
   2.669 +static void _Eff_position_u16msb_c4(int chan, void *stream, int len, void *udata)
   2.670 +{
   2.671 +    /* 16 signed bits (lsb) * 4 channels. */
   2.672 +    volatile position_args *args = (volatile position_args *) udata;
   2.673 +    Uint16 *ptr = (Uint16 *) stream;
   2.674 +    int i;
   2.675 +
   2.676 +    for (i = 0; i < len; i += sizeof (Sint16) * 4) {
   2.677 +        Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
   2.678 +        Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
   2.679 +        Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768);
   2.680 +        Sint16 samprr = (Sint16) (SDL_SwapBE16(*(ptr+3)) - 32768);
   2.681 +        
   2.682 +        Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
   2.683 +                                    * args->distance_f) + 32768);
   2.684 +        Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
   2.685 +                                    * args->distance_f) + 32768);
   2.686 +        Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
   2.687 +                                    * args->distance_f) + 32768);
   2.688 +        Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
   2.689 +                                    * args->distance_f) + 32768);
   2.690 +
   2.691 +	switch (args->room_angle) {
   2.692 +		case 0:
   2.693 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   2.694 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   2.695 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
   2.696 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
   2.697 +			break;
   2.698 +		case 90:
   2.699 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   2.700 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
   2.701 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   2.702 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
   2.703 +			break;
   2.704 +		case 180:
   2.705 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
   2.706 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
   2.707 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   2.708 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   2.709 +			break;
   2.710 +		case 270:
   2.711 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
   2.712 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   2.713 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
   2.714 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   2.715 +			break;
   2.716 +	}
   2.717 +    }
   2.718 +}
   2.719 +static void _Eff_position_u16msb_c6(int chan, void *stream, int len, void *udata)
   2.720 +{
   2.721 +    /* 16 signed bits (lsb) * 6 channels. */
   2.722 +    volatile position_args *args = (volatile position_args *) udata;
   2.723 +    Uint16 *ptr = (Uint16 *) stream;
   2.724 +    int i;
   2.725 +
   2.726 +    for (i = 0; i < len; i += sizeof (Sint16) * 6) {
   2.727 +        Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
   2.728 +        Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
   2.729 +        Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768);
   2.730 +        Sint16 samprr = (Sint16) (SDL_SwapBE16(*(ptr+3)) - 32768);
   2.731 +        Sint16 sampce = (Sint16) (SDL_SwapBE16(*(ptr+4)) - 32768);
   2.732 +        Sint16 sampwf = (Sint16) (SDL_SwapBE16(*(ptr+5)) - 32768);
   2.733 +        
   2.734 +        Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
   2.735 +                                    * args->distance_f) + 32768);
   2.736 +        Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
   2.737 +                                    * args->distance_f) + 32768);
   2.738 +        Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
   2.739 +                                    * args->distance_f) + 32768);
   2.740 +        Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
   2.741 +                                    * args->distance_f) + 32768);
   2.742 +        Uint16 swapce = (Uint16) ((Sint16) (((float) sampce * args->center_f)
   2.743 +                                    * args->distance_f) + 32768);
   2.744 +        Uint16 swapwf = (Uint16) ((Sint16) (((float) sampwf * args->lfe_f)
   2.745 +                                    * args->distance_f) + 32768);
   2.746 +
   2.747 +	switch (args->room_angle) {
   2.748 +		case 0:
   2.749 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   2.750 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   2.751 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
   2.752 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
   2.753 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapce);
   2.754 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
   2.755 +			break;
   2.756 +		case 90:
   2.757 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   2.758 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
   2.759 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   2.760 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
   2.761 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr)/2 + (Uint16) SDL_SwapBE16(swaprr)/2;
   2.762 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
   2.763 +			break;
   2.764 +		case 180:
   2.765 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
   2.766 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
   2.767 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   2.768 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   2.769 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr)/2 + (Uint16) SDL_SwapBE16(swaplr)/2;
   2.770 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
   2.771 +			break;
   2.772 +		case 270:
   2.773 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
   2.774 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   2.775 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
   2.776 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   2.777 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl)/2 + (Uint16) SDL_SwapBE16(swaplr)/2;
   2.778 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
   2.779 +			break;
   2.780 +	}
   2.781      }
   2.782  }
   2.783  
   2.784 @@ -318,14 +1007,117 @@
   2.785          *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
   2.786      }
   2.787  }
   2.788 +static void _Eff_position_s16msb_c4(int chan, void *stream, int len, void *udata)
   2.789 +{
   2.790 +    /* 16 signed bits (lsb) * 4 channels. */
   2.791 +    volatile position_args *args = (volatile position_args *) udata;
   2.792 +    Sint16 *ptr = (Sint16 *) stream;
   2.793 +    int i;
   2.794  
   2.795 +    for (i = 0; i < len; i += sizeof (Sint16) * 4) {
   2.796 +        Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
   2.797 +                                    args->left_f) * args->distance_f);
   2.798 +        Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
   2.799 +                                    args->right_f) * args->distance_f);
   2.800 +        Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+2))) *
   2.801 +                                    args->left_rear_f) * args->distance_f);
   2.802 +        Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+3))) *
   2.803 +                                    args->right_rear_f) * args->distance_f);
   2.804 +	switch (args->room_angle) {
   2.805 +		case 0:
   2.806 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
   2.807 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
   2.808 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
   2.809 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
   2.810 +			break;
   2.811 +		case 90:
   2.812 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
   2.813 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
   2.814 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
   2.815 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
   2.816 +			break;
   2.817 +		case 180:
   2.818 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
   2.819 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
   2.820 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
   2.821 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
   2.822 +			break;
   2.823 +		case 270:
   2.824 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
   2.825 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
   2.826 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
   2.827 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
   2.828 +			break;
   2.829 +	}
   2.830 +    }
   2.831 +}
   2.832 +static void _Eff_position_s16msb_c6(int chan, void *stream, int len, void *udata)
   2.833 +{
   2.834 +    /* 16 signed bits (lsb) * 6 channels. */
   2.835 +    volatile position_args *args = (volatile position_args *) udata;
   2.836 +    Sint16 *ptr = (Sint16 *) stream;
   2.837 +    int i;
   2.838 +
   2.839 +    for (i = 0; i < len; i += sizeof (Sint16) * 6) {
   2.840 +        Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
   2.841 +                                    args->left_f) * args->distance_f);
   2.842 +        Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
   2.843 +                                    args->right_f) * args->distance_f);
   2.844 +        Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+2))) *
   2.845 +                                    args->left_rear_f) * args->distance_f);
   2.846 +        Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+3))) *
   2.847 +                                    args->right_rear_f) * args->distance_f);
   2.848 +        Sint16 swapce = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+4))) *
   2.849 +                                    args->center_f) * args->distance_f);
   2.850 +        Sint16 swapwf = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+5))) *
   2.851 +                                    args->lfe_f) * args->distance_f);
   2.852 +
   2.853 +	switch (args->room_angle) {
   2.854 +		case 0:
   2.855 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
   2.856 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
   2.857 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
   2.858 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
   2.859 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapce);
   2.860 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
   2.861 +			break;
   2.862 +		case 90:
   2.863 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
   2.864 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
   2.865 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
   2.866 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
   2.867 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr)/2 + (Sint16) SDL_SwapBE16(swaprr)/2;
   2.868 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
   2.869 +			break;
   2.870 +		case 180:
   2.871 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
   2.872 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
   2.873 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
   2.874 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
   2.875 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr)/2 + (Sint16) SDL_SwapBE16(swaplr)/2;
   2.876 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
   2.877 +			break;
   2.878 +		case 270:
   2.879 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
   2.880 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
   2.881 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
   2.882 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
   2.883 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl)/2 + (Sint16) SDL_SwapBE16(swaplr)/2;
   2.884 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
   2.885 +			break;
   2.886 +	}
   2.887 +    }
   2.888 +}
   2.889  
   2.890  static void init_position_args(position_args *args)
   2.891  {
   2.892      memset(args, '\0', sizeof (position_args));
   2.893      args->in_use = 0;
   2.894 +    args->room_angle = 0;
   2.895      args->left_u8 = args->right_u8 = args->distance_u8 = 255;
   2.896      args->left_f  = args->right_f  = args->distance_f  = 1.0f;
   2.897 +    args->left_rear_u8 = args->right_rear_u8 = args->center_u8 = args->lfe_u8 = 255;
   2.898 +    args->left_rear_f = args->right_rear_f = args->center_f = args->lfe_f = 1.0f;
   2.899      Mix_QuerySpec(NULL, NULL, (int *) &args->channels);
   2.900  }
   2.901  
   2.902 @@ -374,35 +1166,101 @@
   2.903  }
   2.904  
   2.905  
   2.906 -static Mix_EffectFunc_t get_position_effect_func(Uint16 format)
   2.907 +static Mix_EffectFunc_t get_position_effect_func(Uint16 format, int channels)
   2.908  {
   2.909      Mix_EffectFunc_t f = NULL;
   2.910  
   2.911      switch (format) {
   2.912          case AUDIO_U8:
   2.913 -            f = (_Eff_build_volume_table_u8()) ? _Eff_position_table_u8 :
   2.914 -                                                 _Eff_position_u8;
   2.915 +	    switch (channels) {
   2.916 +		    case 1:
   2.917 +		    case 2:
   2.918 +            		f = (_Eff_build_volume_table_u8()) ? _Eff_position_table_u8 :
   2.919 +                                                 		_Eff_position_u8;
   2.920 +	    		break;
   2.921 +	    	    case 4:
   2.922 +                        _Eff_position_u8_c4;
   2.923 +	    		break;
   2.924 +	    	    case 6:
   2.925 +                        _Eff_position_u8_c6;
   2.926 +	    		break;
   2.927 +	    }
   2.928              break;
   2.929  
   2.930          case AUDIO_S8:
   2.931 -            f = (_Eff_build_volume_table_s8()) ? _Eff_position_table_s8 :
   2.932 -                                                 _Eff_position_s8;
   2.933 +	    switch (channels) {
   2.934 +		    case 1:
   2.935 +		    case 2:
   2.936 +            		f = (_Eff_build_volume_table_s8()) ? _Eff_position_table_s8 :
   2.937 +                                                 		_Eff_position_s8;
   2.938 +	    		break;
   2.939 +	    	    case 4:
   2.940 +                        _Eff_position_s8_c4;
   2.941 +	    		break;
   2.942 +	    	    case 6:
   2.943 +                        _Eff_position_s8_c6;
   2.944 +	    		break;
   2.945 +	    }
   2.946              break;
   2.947  
   2.948          case AUDIO_U16LSB:
   2.949 -            f = _Eff_position_u16lsb;
   2.950 +	    switch (channels) {
   2.951 +		    case 1:
   2.952 +		    case 2:
   2.953 +            		f = _Eff_position_u16lsb;
   2.954 +	    		break;
   2.955 +	    	    case 4:
   2.956 +            		f = _Eff_position_u16lsb_c4;
   2.957 +	    		break;
   2.958 +	    	    case 6:
   2.959 +            		f = _Eff_position_u16lsb_c6;
   2.960 +	    		break;
   2.961 +	    }
   2.962              break;
   2.963  
   2.964          case AUDIO_S16LSB:
   2.965 -            f = _Eff_position_s16lsb;
   2.966 +	    switch (channels) {
   2.967 +		    case 1:
   2.968 +		    case 2:
   2.969 +            		f = _Eff_position_s16lsb;
   2.970 +	    		break;
   2.971 +	    	    case 4:
   2.972 +            		f = _Eff_position_s16lsb_c4;
   2.973 +	    		break;
   2.974 +	    	    case 6:
   2.975 +            		f = _Eff_position_s16lsb_c6;
   2.976 +	    		break;
   2.977 +	    }
   2.978              break;
   2.979  
   2.980          case AUDIO_U16MSB:
   2.981 -            f = _Eff_position_u16msb;
   2.982 +	    switch (channels) {
   2.983 +		    case 1:
   2.984 +		    case 2:
   2.985 +            		f = _Eff_position_u16msb;
   2.986 +	    		break;
   2.987 +	    	    case 4:
   2.988 +            		f = _Eff_position_u16msb_c4;
   2.989 +	    		break;
   2.990 +	    	    case 6:
   2.991 +            		f = _Eff_position_u16msb_c6;
   2.992 +	    		break;
   2.993 +	    }
   2.994              break;
   2.995  
   2.996          case AUDIO_S16MSB:
   2.997 -            f = _Eff_position_s16msb;
   2.998 +	    switch (channels) {
   2.999 +		    case 1:
  2.1000 +		    case 2:
  2.1001 +            		f = _Eff_position_s16msb;
  2.1002 +	    		break;
  2.1003 +	    	    case 4:
  2.1004 +            		f = _Eff_position_s16msb_c4;
  2.1005 +	    		break;
  2.1006 +	    	    case 6:
  2.1007 +            		f = _Eff_position_s16msb_c6;
  2.1008 +	    		break;
  2.1009 +	    }
  2.1010              break;
  2.1011  
  2.1012          default:
  2.1013 @@ -412,6 +1270,140 @@
  2.1014      return(f);
  2.1015  }
  2.1016  
  2.1017 +static Uint8 speaker_amplitude[6];
  2.1018 +
  2.1019 +static void set_amplitudes(int channels, int angle, int room_angle)
  2.1020 +{
  2.1021 +    int left = 255, right = 255;
  2.1022 +    int left_rear = 255, right_rear = 255, center = 255;
  2.1023 +
  2.1024 +        /* unwind the angle...it'll be between 0 and 359. */
  2.1025 +    while (angle >= 360) angle -= 360;
  2.1026 +    while (angle < 0) angle += 360;
  2.1027 +
  2.1028 +    if (channels == 2)
  2.1029 +    {
  2.1030 +        /*
  2.1031 +         * We only attenuate by position if the angle falls on the far side
  2.1032 +         *  of center; That is, an angle that's due north would not attenuate
  2.1033 +         *  either channel. Due west attenuates the right channel to 0.0, and
  2.1034 +         *  due east attenuates the left channel to 0.0. Slightly east of
  2.1035 +         *  center attenuates the left channel a little, and the right channel
  2.1036 +         *  not at all. I think of this as occlusion by one's own head.  :)
  2.1037 +         *
  2.1038 +         *   ...so, we split our angle circle into four quadrants...
  2.1039 +         */
  2.1040 +        if (angle < 90) {
  2.1041 +            left = 255 - ((int) (255.0f * (((float) angle) / 89.0f)));
  2.1042 +        } else if (angle < 180) {
  2.1043 +            left = (int) (255.0f * (((float) (angle - 90)) / 89.0f));
  2.1044 +        } else if (angle < 270) {
  2.1045 +            right = 255 - ((int) (255.0f * (((float) (angle - 180)) / 89.0f)));
  2.1046 +        } else {
  2.1047 +            right = (int) (255.0f * (((float) (angle - 270)) / 89.0f));
  2.1048 +        }
  2.1049 +    }
  2.1050 +
  2.1051 +    if (channels == 4 || channels == 6)
  2.1052 +    {
  2.1053 +        /*
  2.1054 +         *  An angle that's due north does not attenuate the center channel.
  2.1055 +         *  An angle in the first quadrant, 0-90, does not attenuate the RF.
  2.1056 +         *
  2.1057 +         *   ...so, we split our angle circle into 8 ...
  2.1058 +	 *
  2.1059 +	 *             CE
  2.1060 +	 *             0
  2.1061 +	 *     LF      |         RF
  2.1062 +	 *             |
  2.1063 +	 *  270<-------|----------->90
  2.1064 +	 *             |
  2.1065 +	 *     LR      |         RR
  2.1066 +	 *            180
  2.1067 +	 *   
  2.1068 +         */
  2.1069 +        if (angle < 45) {
  2.1070 +            left = ((int) (255.0f * (((float) (180 - angle)) / 179.0f)));
  2.1071 +            left_rear = 255 - ((int) (255.0f * (((float) (angle + 45)) / 89.0f)));
  2.1072 +            right_rear = 255 - ((int) (255.0f * (((float) (90 - angle)) / 179.0f)));
  2.1073 +        } else if (angle < 90) {
  2.1074 +            center = ((int) (255.0f * (((float) (225 - angle)) / 179.0f)));
  2.1075 +            left = ((int) (255.0f * (((float) (180 - angle)) / 179.0f)));
  2.1076 +            left_rear = 255 - ((int) (255.0f * (((float) (135 - angle)) / 89.0f)));
  2.1077 +            right_rear = ((int) (255.0f * (((float) (90 + angle)) / 179.0f)));
  2.1078 +        } else if (angle < 135) {
  2.1079 +            center = ((int) (255.0f * (((float) (225 - angle)) / 179.0f)));
  2.1080 +            left = 255 - ((int) (255.0f * (((float) (angle - 45)) / 89.0f)));
  2.1081 +            right = ((int) (255.0f * (((float) (270 - angle)) / 179.0f)));
  2.1082 +            left_rear = ((int) (255.0f * (((float) (angle)) / 179.0f)));
  2.1083 +        } else if (angle < 180) {
  2.1084 +            center = 255 - ((int) (255.0f * (((float) (angle - 90)) / 89.0f)));
  2.1085 +            left = 255 - ((int) (255.0f * (((float) (225 - angle)) / 89.0f)));
  2.1086 +            right = ((int) (255.0f * (((float) (270 - angle)) / 179.0f)));
  2.1087 +            left_rear = ((int) (255.0f * (((float) (angle)) / 179.0f)));
  2.1088 +        } else if (angle < 225) {
  2.1089 +            center = 255 - ((int) (255.0f * (((float) (270 - angle)) / 89.0f)));
  2.1090 +            left = ((int) (255.0f * (((float) (angle - 90)) / 179.0f)));
  2.1091 +            right = 255 - ((int) (255.0f * (((float) (angle - 135)) / 89.0f)));
  2.1092 +            right_rear = ((int) (255.0f * (((float) (360 - angle)) / 179.0f)));
  2.1093 +        } else if (angle < 270) {
  2.1094 +            center = ((int) (255.0f * (((float) (angle - 135)) / 179.0f)));
  2.1095 +            left = ((int) (255.0f * (((float) (angle - 90)) / 179.0f)));
  2.1096 +            right = 255 - ((int) (255.0f * (((float) (315 - angle)) / 89.0f)));
  2.1097 +            right_rear = ((int) (255.0f * (((float) (360 - angle)) / 179.0f)));
  2.1098 +        } else if (angle < 315) {
  2.1099 +            center = ((int) (255.0f * (((float) (angle - 135)) / 179.0f)));
  2.1100 +            right = ((int) (255.0f * (((float) (angle - 180)) / 179.0f)));
  2.1101 +            left_rear = ((int) (255.0f * (((float) (450 - angle)) / 179.0f)));
  2.1102 +            right_rear = 255 - ((int) (255.0f * (((float) (angle - 225)) / 89.0f)));
  2.1103 +        } else {
  2.1104 +            right = ((int) (255.0f * (((float) (angle - 180)) / 179.0f)));
  2.1105 +            left_rear = ((int) (255.0f * (((float) (450 - angle)) / 179.0f)));
  2.1106 +            right_rear = 255 - ((int) (255.0f * (((float) (405 - angle)) / 89.0f)));
  2.1107 +        }
  2.1108 +    }
  2.1109 +
  2.1110 +    if (left < 0) left = 0; if (left > 255) left = 255;
  2.1111 +    if (right < 0) right = 0; if (right > 255) right = 255;
  2.1112 +    if (left_rear < 0) left_rear = 0; if (left_rear > 255) left_rear = 255;
  2.1113 +    if (right_rear < 0) right_rear = 0; if (right_rear > 255) right_rear = 255;
  2.1114 +    if (center < 0) center = 0; if (center > 255) center = 255;
  2.1115 +
  2.1116 +    if (room_angle == 90) {
  2.1117 +    	speaker_amplitude[0] = (Uint8)left_rear;
  2.1118 +    	speaker_amplitude[1] = (Uint8)left;
  2.1119 +    	speaker_amplitude[2] = (Uint8)right_rear;
  2.1120 +    	speaker_amplitude[3] = (Uint8)right;
  2.1121 +    }
  2.1122 +    else if (room_angle == 180) {
  2.1123 +	if (channels == 2) {
  2.1124 +    	    speaker_amplitude[0] = (Uint8)right;
  2.1125 +    	    speaker_amplitude[1] = (Uint8)left;
  2.1126 +	}
  2.1127 +	else {
  2.1128 +    	    speaker_amplitude[0] = (Uint8)right_rear;
  2.1129 +    	    speaker_amplitude[1] = (Uint8)left_rear;
  2.1130 +    	    speaker_amplitude[2] = (Uint8)right;
  2.1131 +    	    speaker_amplitude[3] = (Uint8)left;
  2.1132 +	}
  2.1133 +    }
  2.1134 +    else if (room_angle == 270) {
  2.1135 +    	speaker_amplitude[0] = (Uint8)right;
  2.1136 +    	speaker_amplitude[1] = (Uint8)right_rear;
  2.1137 +    	speaker_amplitude[2] = (Uint8)left;
  2.1138 +    	speaker_amplitude[3] = (Uint8)left_rear;
  2.1139 +    }
  2.1140 +    else {
  2.1141 +    	speaker_amplitude[0] = (Uint8)left;
  2.1142 +    	speaker_amplitude[1] = (Uint8)right;
  2.1143 +    	speaker_amplitude[2] = (Uint8)left_rear;
  2.1144 +    	speaker_amplitude[3] = (Uint8)right_rear;
  2.1145 +    }
  2.1146 +    speaker_amplitude[4] = (Uint8)center;
  2.1147 +    speaker_amplitude[5] = 255;
  2.1148 +}
  2.1149 +
  2.1150 +int Mix_SetPosition(int channel, Sint16 angle, Uint8 distance);
  2.1151  
  2.1152  int Mix_SetPanning(int channel, Uint8 left, Uint8 right)
  2.1153  {
  2.1154 @@ -419,13 +1411,21 @@
  2.1155      int channels;
  2.1156      Uint16 format;
  2.1157      position_args *args = NULL;
  2.1158 -
  2.1159      Mix_QuerySpec(NULL, &format, &channels);
  2.1160  
  2.1161 -    if (channels != 2)    /* it's a no-op; we call that successful. */
  2.1162 +    if (channels != 2 && channels != 4 && channels != 6)    /* it's a no-op; we call that successful. */
  2.1163          return(1);
  2.1164  
  2.1165 -    f = get_position_effect_func(format);
  2.1166 +    if (channels > 2) {
  2.1167 +    	/* left = 255 =>  angle = -90;  left = 0 => angle = +89 */
  2.1168 +    	int angle = (int)left;
  2.1169 +    	angle = 127 - angle;
  2.1170 +	angle = -angle;
  2.1171 +    	angle = angle * 90 / 128; /* Make it larger for more effect? */
  2.1172 +	return( Mix_SetPosition(channel, angle, 0) );
  2.1173 +    }
  2.1174 +
  2.1175 +    f = get_position_effect_func(format, channels);
  2.1176      if (f == NULL)
  2.1177          return(0);
  2.1178  
  2.1179 @@ -441,9 +1441,11 @@
  2.1180      }
  2.1181  
  2.1182      args->left_u8 = left;
  2.1183 +    args->left_f = ((float) left) / 255.0f;
  2.1184      args->right_u8 = right;
  2.1185 -    args->left_f = ((float) left) / 255.0f;
  2.1186      args->right_f = ((float) right) / 255.0f;
  2.1187 +    args->room_angle = 0;
  2.1188 +
  2.1189      if (!args->in_use) {
  2.1190          args->in_use = 1;
  2.1191          return(Mix_RegisterEffect(channel, f, _Eff_PositionDone, (void *) args));
  2.1192 @@ -458,9 +1460,10 @@
  2.1193      Mix_EffectFunc_t f = NULL;
  2.1194      Uint16 format;
  2.1195      position_args *args = NULL;
  2.1196 +    int channels;
  2.1197  
  2.1198 -    Mix_QuerySpec(NULL, &format, NULL);
  2.1199 -    f = get_position_effect_func(format);
  2.1200 +    Mix_QuerySpec(NULL, &format, &channels);
  2.1201 +    f = get_position_effect_func(format, channels);
  2.1202      if (f == NULL)
  2.1203          return(0);
  2.1204  
  2.1205 @@ -494,10 +1497,10 @@
  2.1206      Uint16 format;
  2.1207      int channels;
  2.1208      position_args *args = NULL;
  2.1209 -    Uint8 left = 255, right = 255;
  2.1210 +    Sint16 room_angle;
  2.1211  
  2.1212      Mix_QuerySpec(NULL, &format, &channels);
  2.1213 -    f = get_position_effect_func(format);
  2.1214 +    f = get_position_effect_func(format, channels);
  2.1215      if (f == NULL)
  2.1216          return(0);
  2.1217  
  2.1218 @@ -515,35 +1518,40 @@
  2.1219  
  2.1220      if (channels == 2)
  2.1221      {
  2.1222 -        /*
  2.1223 -         * We only attenuate by position if the angle falls on the far side
  2.1224 -         *  of center; That is, an angle that's due north would not attenuate
  2.1225 -         *  either channel. Due west attenuates the right channel to 0.0, and
  2.1226 -         *  due east attenuates the left channel to 0.0. Slightly east of
  2.1227 -         *  center attenuates the left channel a little, and the right channel
  2.1228 -         *  not at all. I think of this as occlusion by one's own head.  :)
  2.1229 -         *
  2.1230 -         *   ...so, we split our angle circle into four quadrants...
  2.1231 -         */
  2.1232 -        if (angle < 90) {
  2.1233 -            left = 255 - ((Uint8) (255.0f * (((float) angle) / 89.0f)));
  2.1234 -        } else if (angle < 180) {
  2.1235 -            left = (Uint8) (255.0f * (((float) (angle - 90)) / 89.0f));
  2.1236 -        } else if (angle < 270) {
  2.1237 -            right = 255 - ((Uint8) (255.0f * (((float) (angle - 180)) / 89.0f)));
  2.1238 -        } else {
  2.1239 -            right = (Uint8) (255.0f * (((float) (angle - 270)) / 89.0f));
  2.1240 -        }
  2.1241 +	if (angle > 180)
  2.1242 +		room_angle = 180; /* exchange left and right channels */
  2.1243 +	else room_angle = 0;
  2.1244      }
  2.1245  
  2.1246 +    if (channels == 4 || channels == 6)
  2.1247 +    {
  2.1248 +	if (angle > 315) room_angle = 0;
  2.1249 +	else if (angle > 225) room_angle = 270;
  2.1250 +	else if (angle > 135) room_angle = 180;
  2.1251 +	else if (angle > 45) room_angle = 90;
  2.1252 +	else room_angle = 0;
  2.1253 +    }
  2.1254 +
  2.1255 +
  2.1256      distance = 255 - distance;  /* flip it to scale Mix_SetDistance() uses. */
  2.1257  
  2.1258 -    args->left_u8 = left;
  2.1259 -    args->left_f = ((float) left) / 255.0f;
  2.1260 -    args->right_u8 = right;
  2.1261 -    args->right_f = ((float) right) / 255.0f;
  2.1262 +    set_amplitudes(channels, angle, room_angle);
  2.1263 +
  2.1264 +    args->left_u8 = speaker_amplitude[0];
  2.1265 +    args->left_f = ((float) speaker_amplitude[0]) / 255.0f;
  2.1266 +    args->right_u8 = speaker_amplitude[1];
  2.1267 +    args->right_f = ((float) speaker_amplitude[1]) / 255.0f;
  2.1268 +    args->left_rear_u8 = speaker_amplitude[2];
  2.1269 +    args->left_rear_f = ((float) speaker_amplitude[2]) / 255.0f;
  2.1270 +    args->right_rear_u8 = speaker_amplitude[3];
  2.1271 +    args->right_rear_f = ((float) speaker_amplitude[3]) / 255.0f;
  2.1272 +    args->center_u8 = speaker_amplitude[4];
  2.1273 +    args->center_f = ((float) speaker_amplitude[4]) / 255.0f;
  2.1274 +    args->lfe_u8 = 255;
  2.1275 +    args->lfe_f = 255.0f;
  2.1276      args->distance_u8 = distance;
  2.1277      args->distance_f = ((float) distance) / 255.0f;
  2.1278 +    args->room_angle = room_angle;
  2.1279      if (!args->in_use) {
  2.1280          args->in_use = 1;
  2.1281          return(Mix_RegisterEffect(channel, f, _Eff_PositionDone, (void *) args));
     3.1 --- a/mixer.c	Fri Aug 20 19:32:09 2004 +0000
     3.2 +++ b/mixer.c	Sat Aug 21 12:27:02 2004 +0000
     3.3 @@ -260,6 +260,7 @@
     3.4  {
     3.5  	printf("%s: %d bit %s audio (%s) at %u Hz\n", title, (fmt->format&0xFF),
     3.6  			(fmt->format&0x8000) ? "signed" : "unsigned",
     3.7 +			(fmt->channels > 2) ? "surround" :
     3.8  			(fmt->channels > 1) ? "stereo" : "mono", fmt->freq);
     3.9  }
    3.10  
    3.11 @@ -635,6 +636,16 @@
    3.12  	return num;
    3.13  }
    3.14  
    3.15 +static int checkchunkintegral(Mix_Chunk *chunk)
    3.16 +{
    3.17 +	int frame_width = 1;
    3.18 +
    3.19 +	if ((mixer.format & 0xFF) == 16) frame_width = 2;
    3.20 +	frame_width *= mixer.channels;
    3.21 +	while (chunk->alen % frame_width) chunk->alen--;
    3.22 +	return chunk->alen;
    3.23 +}
    3.24 +
    3.25  /* Play an audio chunk on a specific channel.
    3.26     If the specified channel is -1, play on the first free channel.
    3.27     'ticks' is the number of milliseconds at most to play the sample, or -1
    3.28 @@ -650,6 +661,10 @@
    3.29  		Mix_SetError("Tried to play a NULL chunk");
    3.30  		return(-1);
    3.31  	}
    3.32 +	if ( !checkchunkintegral(chunk)) {
    3.33 +		Mix_SetError("Tried to play a chunk with a bad frame");
    3.34 +		return(-1);
    3.35 +	}
    3.36  
    3.37  	/* Lock the mixer while modifying the playing channels */
    3.38  	SDL_LockAudio();
    3.39 @@ -717,6 +732,10 @@
    3.40  	if ( chunk == NULL ) {
    3.41  		return(-1);
    3.42  	}
    3.43 +	if ( !checkchunkintegral(chunk)) {
    3.44 +		Mix_SetError("Tried to play a chunk with a bad frame");
    3.45 +		return(-1);
    3.46 +	}
    3.47  
    3.48  	/* Lock the mixer while modifying the playing channels */
    3.49  	SDL_LockAudio();
     4.1 --- a/music.c	Fri Aug 20 19:32:09 2004 +0000
     4.2 +++ b/music.c	Sat Aug 21 12:27:02 2004 +0000
     4.3 @@ -31,6 +31,14 @@
     4.4  
     4.5  #include "SDL_mixer.h"
     4.6  
     4.7 +#define SDL_SURROUND
     4.8 +
     4.9 +#ifdef SDL_SURROUND
    4.10 +#define MAX_OUTPUT_CHANNELS 6
    4.11 +#else
    4.12 +#define MAX_OUTPUT_CHANNELS 2
    4.13 +#endif
    4.14 +
    4.15  /* The music command hack is UNIX specific */
    4.16  #ifndef unix
    4.17  #undef CMD_MUSIC
    4.18 @@ -131,6 +139,10 @@
    4.19  #endif
    4.20  #endif
    4.21  
    4.22 +/* Reference for converting mikmod output to 4/6 channels */
    4.23 +static int current_output_channels;
    4.24 +static Uint16 current_output_format;
    4.25 +
    4.26  /* Used to calculate fading steps */
    4.27  static int ms_per_step;
    4.28  
    4.29 @@ -210,7 +222,57 @@
    4.30  #endif
    4.31  #ifdef MOD_MUSIC
    4.32  			case MUS_MOD:
    4.33 -				VC_WriteBytes((SBYTE *)stream, len);
    4.34 +				if (current_output_channels > 2) {
    4.35 +					int small_len = 2 * len / current_output_channels;
    4.36 +					int i;
    4.37 +					Uint8 *src, *dst;
    4.38 +
    4.39 +					VC_WriteBytes((SBYTE *)stream, small_len);
    4.40 +					/* and extend to len by copying channels */
    4.41 +					src = stream + small_len;
    4.42 +					dst = stream + len;
    4.43 +
    4.44 +					switch (current_output_format & 0xFF) {
    4.45 +						case 8:
    4.46 +							for ( i=small_len/2; i; --i ) {
    4.47 +								src -= 2;
    4.48 +								dst -= current_output_channels;
    4.49 +								dst[0] = src[0];
    4.50 +								dst[1] = src[1];
    4.51 +								dst[2] = src[0];
    4.52 +								dst[3] = src[1];
    4.53 +								if (current_output_channels == 6) {
    4.54 +									dst[4] = src[0];
    4.55 +									dst[5] = src[1];
    4.56 +								}
    4.57 +							}
    4.58 +							break;
    4.59 +						case 16:
    4.60 +							for ( i=small_len/4; i; --i ) {
    4.61 +								src -= 4;
    4.62 +								dst -= 2 * current_output_channels;
    4.63 +								dst[0] = src[0];
    4.64 +								dst[1] = src[1];
    4.65 +								dst[2] = src[2];
    4.66 +								dst[3] = src[3];
    4.67 +								dst[4] = src[0];
    4.68 +								dst[5] = src[1];
    4.69 +								dst[6] = src[2];
    4.70 +								dst[7] = src[3];
    4.71 +								if (current_output_channels == 6) {
    4.72 +									dst[8] = src[0];
    4.73 +									dst[9] = src[1];
    4.74 +									dst[10] = src[2];
    4.75 +									dst[11] = src[3];
    4.76 +								}
    4.77 +							}
    4.78 +							break;
    4.79 +					}
    4.80 +
    4.81 +
    4.82 +
    4.83 +				}
    4.84 +				else VC_WriteBytes((SBYTE *)stream, len);
    4.85  				if ( music_swap8 ) {
    4.86  					Uint8 *dst;
    4.87  					int i;
    4.88 @@ -306,8 +368,10 @@
    4.89  			++music_error;
    4.90  		}
    4.91  	}
    4.92 +	current_output_channels = mixer->channels;
    4.93 +	current_output_format = mixer->format;
    4.94  	if ( mixer->channels > 1 ) {
    4.95 -		if ( mixer->channels > 2 ) {
    4.96 +		if ( mixer->channels > MAX_OUTPUT_CHANNELS ) {
    4.97  			Mix_SetError("Hardware uses more channels than mixer");
    4.98  			++music_error;
    4.99  		}
   4.100 @@ -385,7 +449,7 @@
   4.101  {
   4.102  	FILE *fp;
   4.103  	char *ext;
   4.104 -	Uint8 magic[5];
   4.105 +	Uint8 magic[5], moremagic[9];
   4.106  	Mix_Music *music;
   4.107  
   4.108  	/* Figure out what kind of file this is */
   4.109 @@ -397,7 +461,12 @@
   4.110  		Mix_SetError("Couldn't read from '%s'", file);
   4.111  		return(NULL);
   4.112  	}
   4.113 +	if (!fread(moremagic, 8, 1, fp)) {
   4.114 +		Mix_SetError("Couldn't read from '%s'", file);
   4.115 +		return(NULL);
   4.116 +	}
   4.117  	magic[4] = '\0';
   4.118 +	moremagic[8] = '\0';
   4.119  	fclose(fp);
   4.120  
   4.121  	/* Figure out the file extension, so we can determine the type */
   4.122 @@ -426,7 +495,7 @@
   4.123  	   AIFF files have the magic 12 bytes "FORM" XXXX "AIFF"
   4.124  	 */
   4.125  	if ( (ext && MIX_string_equals(ext, "WAV")) ||
   4.126 -	     (strcmp((char *)magic, "RIFF") == 0) ||
   4.127 +	     ((strcmp((char *)magic, "RIFF") == 0) && (strcmp((char *)(moremagic+4), "WAVE") == 0)) ||
   4.128  	     (strcmp((char *)magic, "FORM") == 0) ) {
   4.129  		music->type = MUS_WAV;
   4.130  		music->data.wave = WAVStream_LoadSong(file, (char *)magic);
   4.131 @@ -440,7 +509,9 @@
   4.132  	/* MIDI files have the magic four bytes "MThd" */
   4.133  	if ( (ext && MIX_string_equals(ext, "MID")) ||
   4.134  	     (ext && MIX_string_equals(ext, "MIDI")) ||
   4.135 -	     strcmp((char *)magic, "MThd") == 0 ) {
   4.136 +	     strcmp((char *)magic, "MThd") == 0  ||
   4.137 +	     ( strcmp((char *)magic, "RIFF") == 0  &&
   4.138 +	  	strcmp((char *)(moremagic+4), "RMID") == 0 ) ) {
   4.139  		music->type = MUS_MID;
   4.140  #ifdef USE_NATIVE_MIDI
   4.141    		if ( native_midi_ok ) {
     5.1 --- a/native_midi_gpl/native_midi_gpl.c	Fri Aug 20 19:32:09 2004 +0000
     5.2 +++ b/native_midi_gpl/native_midi_gpl.c	Sat Aug 21 12:27:02 2004 +0000
     5.3 @@ -223,7 +223,6 @@
     5.4  
     5.5      int i, error = 0, j;
     5.6  
     5.7 -
     5.8      for (i = 0; i < 16; i++)
     5.9      {
    5.10  	useprog[i] = 0;	/* reset options */
    5.11 @@ -380,7 +379,7 @@
    5.12  	{
    5.13      	    if( gus_dev >= 0 )
    5.14  	    {
    5.15 -    		play_gus = 1;
    5.16 +    		play_gus = -1;
    5.17  	        awe_dev = -1;
    5.18  		sb_dev  = -1;
    5.19  	        ext_dev = -1;
    5.20 @@ -394,7 +393,7 @@
    5.21  	{
    5.22      	    if( awe_dev >= 0 )
    5.23  	    {
    5.24 -    		play_awe = 1;
    5.25 +    		play_awe = -1;
    5.26  	        gus_dev = -1;
    5.27  		sb_dev  = -1;
    5.28  	        ext_dev = -1;
    5.29 @@ -408,7 +407,7 @@
    5.30  	{
    5.31      	    if( sb_dev >= 0 && fm_patch_aviable )
    5.32  	    {
    5.33 -    		play_fm = 1;
    5.34 +    		play_fm = -1;
    5.35  		gus_dev = -1;
    5.36  	        awe_dev = -1;
    5.37  	        ext_dev = -1;
    5.38 @@ -423,7 +422,7 @@
    5.39  	{
    5.40      	    if( sb_dev >= 0 && opl3_patch_aviable )
    5.41  	    {
    5.42 -    		play_fm = 1;
    5.43 +    		play_fm = -1;
    5.44  		gus_dev = -1;
    5.45  	        awe_dev = -1;
    5.46  	        ext_dev = -1;
    5.47 @@ -438,7 +437,7 @@
    5.48  	{
    5.49      	    if( ext_dev >= 0 )
    5.50  	    {
    5.51 -    		play_ext = 1;
    5.52 +    		play_ext = -1;
    5.53  	        gus_dev = -1;
    5.54  	        awe_dev = -1;
    5.55  		sb_dev  = -1;
    5.56 @@ -453,7 +452,7 @@
    5.57      /* autoselect best device */
    5.58      if( gus_dev >= 0 )
    5.59      {
    5.60 -        play_gus = 1;
    5.61 +        play_gus = -1;
    5.62          awe_dev = -1;
    5.63          sb_dev  = -1;
    5.64          ext_dev = -1;
    5.65 @@ -461,7 +460,7 @@
    5.66          }
    5.67      if( awe_dev >= 0 )
    5.68      {
    5.69 -        play_awe = 1;
    5.70 +        play_awe = -1;
    5.71  	gus_dev = -1;
    5.72          sb_dev  = -1;
    5.73          ext_dev = -1;
    5.74 @@ -469,7 +468,7 @@
    5.75      }
    5.76      if( sb_dev >= 0 && fm_patch_aviable )
    5.77      {
    5.78 -        play_fm = 1;
    5.79 +        play_fm = -1;
    5.80  	gus_dev = -1;
    5.81          awe_dev = -1;
    5.82          ext_dev = -1;
    5.83 @@ -477,7 +476,7 @@
    5.84      }
    5.85      if( ext_dev >= 0 )
    5.86      {
    5.87 -        play_ext = 1;
    5.88 +        play_ext = -1;
    5.89  	gus_dev = -1;
    5.90          awe_dev = -1;
    5.91          sb_dev  = -1;
     6.1 --- a/playmus.c	Fri Aug 20 19:32:09 2004 +0000
     6.2 +++ b/playmus.c	Sat Aug 21 12:27:02 2004 +0000
     6.3 @@ -57,7 +57,7 @@
     6.4  
     6.5  void Usage(char *argv0)
     6.6  {
     6.7 -	fprintf(stderr, "Usage: %s [-i] [-l] [-8] [-r rate] [-b buffers] [-v N] <musicfile>\n", argv0);
     6.8 +	fprintf(stderr, "Usage: %s [-i] [-l] [-8] [-r rate] [-c channels] [-b buffers] [-v N] <musicfile>\n", argv0);
     6.9  }
    6.10  
    6.11  void Menu(void)
    6.12 @@ -114,6 +114,13 @@
    6.13  			++i;
    6.14  			audio_rate = atoi(argv[i]);
    6.15  		} else
    6.16 +		if ( strcmp(argv[i], "-m") == 0 ) {
    6.17 +			audio_channels = 1;
    6.18 +		} else
    6.19 +		if ( (strcmp(argv[i], "-c") == 0) && argv[i+1] ) {
    6.20 +			++i;
    6.21 +			audio_channels = atoi(argv[i]);
    6.22 +		} else
    6.23  		if ( (strcmp(argv[i], "-b") == 0) && argv[i+1] ) {
    6.24  			++i;
    6.25  			audio_buffers = atoi(argv[i]);
    6.26 @@ -122,9 +129,6 @@
    6.27  			++i;
    6.28  			audio_volume = atoi(argv[i]);
    6.29  		} else
    6.30 -		if ( strcmp(argv[i], "-m") == 0 ) {
    6.31 -			audio_channels = 1;
    6.32 -		} else
    6.33  		if ( strcmp(argv[i], "-l") == 0 ) {
    6.34  			looping = -1;
    6.35  		} else
    6.36 @@ -148,6 +152,7 @@
    6.37  		fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
    6.38  		return(255);
    6.39  	}
    6.40 +
    6.41  	atexit(CleanUp);
    6.42  	signal(SIGINT, IntHandler);
    6.43  	signal(SIGTERM, exit);
    6.44 @@ -160,7 +165,7 @@
    6.45  		Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels);
    6.46  		printf("Opened audio at %d Hz %d bit %s, %d bytes audio buffer\n", audio_rate,
    6.47  			(audio_format&0xFF),
    6.48 -			(audio_channels > 1) ? "stereo" : "mono", 
    6.49 +			(audio_channels > 2) ? "surround" : (audio_channels > 1) ? "stereo" : "mono", 
    6.50  			audio_buffers );
    6.51  	}
    6.52  	audio_open = 1;
     7.1 --- a/playwave.c	Fri Aug 20 19:32:09 2004 +0000
     7.2 +++ b/playwave.c	Sat Aug 21 12:27:02 2004 +0000
     7.3 @@ -266,7 +266,7 @@
     7.4  
     7.5  static void Usage(char *argv0)
     7.6  {
     7.7 -	fprintf(stderr, "Usage: %s [-8] [-r rate] [-f] [-F] [-l] [-m] <wavefile>\n", argv0);
     7.8 +	fprintf(stderr, "Usage: %s [-8] [-r rate] [-c channels] [-f] [-F] [-l] [-m] <wavefile>\n", argv0);
     7.9  }
    7.10  
    7.11  
    7.12 @@ -360,6 +360,10 @@
    7.13  		if ( strcmp(argv[i], "-m") == 0 ) {
    7.14  			audio_channels = 1;
    7.15  		} else
    7.16 +		if ( (strcmp(argv[i], "-c") == 0) && argv[i+1] ) {
    7.17 +			++i;
    7.18 +			audio_channels = atoi(argv[i]);
    7.19 +		} else
    7.20  		if ( strcmp(argv[i], "-l") == 0 ) {
    7.21  			loops = -1;
    7.22  		} else
    7.23 @@ -398,6 +402,7 @@
    7.24  		Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels);
    7.25  		printf("Opened audio at %d Hz %d bit %s", audio_rate,
    7.26  			(audio_format&0xFF),
    7.27 +			(audio_channels > 2) ? "surround" :
    7.28  			(audio_channels > 1) ? "stereo" : "mono");
    7.29  		if ( loops ) {
    7.30  		  printf(" (looping)\n");
     8.1 --- a/timidity/common.h	Fri Aug 20 19:32:09 2004 +0000
     8.2 +++ b/timidity/common.h	Sat Aug 21 12:27:02 2004 +0000
     8.3 @@ -25,6 +25,11 @@
     8.4  
     8.5  extern FILE *msgfp;
     8.6  
     8.7 +extern int num_ochannels;
     8.8 +
     8.9 +#define MULTICHANNEL_OUT
    8.10 +#define MAX_OUT_CHANNELS 6
    8.11 +
    8.12  typedef struct {
    8.13    char *path;
    8.14    void *next;
     9.1 --- a/timidity/config.h	Fri Aug 20 19:32:09 2004 +0000
     9.2 +++ b/timidity/config.h	Sat Aug 21 12:27:02 2004 +0000
     9.3 @@ -45,13 +45,20 @@
     9.4  #define MAX_OUTPUT_RATE 	65000
     9.5  
     9.6  /* In percent. */
     9.7 -#define DEFAULT_AMPLIFICATION 	70
     9.8 +/* #define DEFAULT_AMPLIFICATION 	70 */
     9.9 +/* #define DEFAULT_AMPLIFICATION 	50 */
    9.10 +#define DEFAULT_AMPLIFICATION 	30
    9.11  
    9.12  /* Default sampling rate, default polyphony, and maximum polyphony.
    9.13     All but the last can be overridden from the command line. */
    9.14  #define DEFAULT_RATE	32000
    9.15 -#define DEFAULT_VOICES	32
    9.16 -#define MAX_VOICES	48
    9.17 +/* #define DEFAULT_VOICES	32 */
    9.18 +/* #define MAX_VOICES	48 */
    9.19 +#define DEFAULT_VOICES	256
    9.20 +#define MAX_VOICES	256
    9.21 +#define MAXCHAN		16
    9.22 +/* #define MAXCHAN		64 */
    9.23 +#define MAXNOTE		128
    9.24  
    9.25  /* 1000 here will give a control ratio of 22:1 with 22 kHz output.
    9.26     Higher CONTROLS_PER_SECOND values allow more accurate rendering
    9.27 @@ -79,7 +86,7 @@
    9.28  /* Make envelopes twice as fast. Saves ~20% CPU time (notes decay
    9.29     faster) and sounds more like a GUS. There is now a command line
    9.30     option to toggle this as well. */
    9.31 -#define FAST_DECAY
    9.32 +/* #define FAST_DECAY */
    9.33  
    9.34  /* How many bits to use for the fractional part of sample positions.
    9.35     This affects tonal accuracy. The entire position counter must fit
    9.36 @@ -89,6 +96,10 @@
    9.37     "The GUS does not SUCK!!!" -- a happy user :) */
    9.38  #define FRACTION_BITS 12
    9.39  
    9.40 +#define MAX_SAMPLE_SIZE (1 << (32-FRACTION_BITS))
    9.41 +
    9.42 +typedef double FLOAT_T;
    9.43 +
    9.44  /* For some reason the sample volume is always set to maximum in all
    9.45     patch files. Define this for a crude adjustment that may help
    9.46     equalize instrument volumes. */
    9.47 @@ -236,6 +247,8 @@
    9.48  #  define MAX_AMP_VALUE ((1<<(AMP_BITS+1))-1)
    9.49  #endif
    9.50  
    9.51 +typedef int16 resample_t;
    9.52 +
    9.53  #ifdef USE_LDEXP
    9.54  #  define FSCALE(a,b) ldexp((a),(b))
    9.55  #  define FSCALENEG(a,b) ldexp((a),-(b))
    10.1 --- a/timidity/instrum.c	Fri Aug 20 19:32:09 2004 +0000
    10.2 +++ b/timidity/instrum.c	Sat Aug 21 12:27:02 2004 +0000
    10.3 @@ -41,11 +41,11 @@
    10.4     available. */
    10.5  static ToneBank standard_tonebank, standard_drumset;
    10.6  ToneBank 
    10.7 -  *tonebank[128]={&standard_tonebank},
    10.8 -  *drumset[128]={&standard_drumset};
    10.9 +  *tonebank[MAXBANK]={&standard_tonebank},
   10.10 +  *drumset[MAXBANK]={&standard_drumset};
   10.11  
   10.12  /* This is a special instrument, used for all melodic programs */
   10.13 -Instrument *default_instrument=0;
   10.14 +InstrumentLayer *default_instrument=0;
   10.15  
   10.16  /* This is only used for tracks that don't specify a program */
   10.17  int default_program=DEFAULT_PROGRAM;
   10.18 @@ -57,35 +57,107 @@
   10.19  int fast_decay=0;
   10.20  #endif
   10.21  
   10.22 +
   10.23 +int current_tune_number = 0;
   10.24 +int last_tune_purged = 0;
   10.25 +int current_patch_memory = 0;
   10.26 +int max_patch_memory = 60000000;
   10.27 +
   10.28 +static void purge_as_required(void);
   10.29 +
   10.30  static void free_instrument(Instrument *ip)
   10.31  {
   10.32    Sample *sp;
   10.33    int i;
   10.34    if (!ip) return;
   10.35 +
   10.36 +  if (!ip->contents)
   10.37    for (i=0; i<ip->samples; i++)
   10.38      {
   10.39        sp=&(ip->sample[i]);
   10.40 -      free(sp->data);
   10.41 +      if (sp->data) free(sp->data);
   10.42      }
   10.43    free(ip->sample);
   10.44 +
   10.45 +  if (!ip->contents)
   10.46 +  for (i=0; i<ip->right_samples; i++)
   10.47 +    {
   10.48 +      sp=&(ip->right_sample[i]);
   10.49 +      if (sp->data) free(sp->data);
   10.50 +    }
   10.51 +  if (ip->right_sample)
   10.52 +    free(ip->right_sample);
   10.53    free(ip);
   10.54  }
   10.55  
   10.56 +
   10.57 +static void free_layer(InstrumentLayer *lp)
   10.58 +{
   10.59 +  InstrumentLayer *next;
   10.60 +
   10.61 +  current_patch_memory -= lp->size;
   10.62 +
   10.63 +  for (; lp; lp = next)
   10.64 +   {
   10.65 +     next = lp->next;
   10.66 +     free_instrument(lp->instrument);
   10.67 +     free(lp);
   10.68 +   }
   10.69 +}
   10.70 +
   10.71  static void free_bank(int dr, int b)
   10.72  {
   10.73    int i;
   10.74    ToneBank *bank=((dr) ? drumset[b] : tonebank[b]);
   10.75 -  for (i=0; i<128; i++)
   10.76 -    if (bank->tone[i].instrument)
   10.77 +  for (i=0; i<MAXPROG; i++)
   10.78 +    if (bank->tone[i].layer)
   10.79        {
   10.80  	/* Not that this could ever happen, of course */
   10.81 -	if (bank->tone[i].instrument != MAGIC_LOAD_INSTRUMENT)
   10.82 -	  free_instrument(bank->tone[i].instrument);
   10.83 -	bank->tone[i].instrument=0;
   10.84 +	if (bank->tone[i].layer != MAGIC_LOAD_INSTRUMENT)
   10.85 +	  {
   10.86 +	    free_layer(bank->tone[i].layer);
   10.87 +	    bank->tone[i].layer=0;
   10.88 +	    bank->tone[i].last_used=-1;
   10.89 +	  }
   10.90        }
   10.91  }
   10.92  
   10.93 -static int32 convert_envelope_rate(uint8 rate)
   10.94 +
   10.95 +static void free_old_bank(int dr, int b, int how_old)
   10.96 +{
   10.97 +  int i;
   10.98 +  ToneBank *bank=((dr) ? drumset[b] : tonebank[b]);
   10.99 +  for (i=0; i<MAXPROG; i++)
  10.100 +    if (bank->tone[i].layer && bank->tone[i].last_used < how_old)
  10.101 +      {
  10.102 +	if (bank->tone[i].layer != MAGIC_LOAD_INSTRUMENT)
  10.103 +	  {
  10.104 +	    ctl->cmsg(CMSG_INFO, VERB_DEBUG,
  10.105 +		"Unloading %s %s[%d,%d] - last used %d.",
  10.106 +		(dr)? "drum" : "inst", bank->tone[i].name,
  10.107 +		i, b, bank->tone[i].last_used);
  10.108 +	    free_layer(bank->tone[i].layer);
  10.109 +	    bank->tone[i].layer=0;
  10.110 +	    bank->tone[i].last_used=-1;
  10.111 +	  }
  10.112 +      }
  10.113 +}
  10.114 +
  10.115 +
  10.116 +int32 convert_envelope_rate_attack(uint8 rate, uint8 fastness)
  10.117 +{
  10.118 +  int32 r;
  10.119 +
  10.120 +  r=3-((rate>>6) & 0x3);
  10.121 +  r*=3;
  10.122 +  r = (int32)(rate & 0x3f) << r; /* 6.9 fixed point */
  10.123 +
  10.124 +  /* 15.15 fixed point. */
  10.125 +  return (((r * 44100) / play_mode->rate) * control_ratio) 
  10.126 +    << 10;
  10.127 +}
  10.128 +
  10.129 +int32 convert_envelope_rate(uint8 rate)
  10.130  {
  10.131    int32 r;
  10.132  
  10.133 @@ -98,7 +170,7 @@
  10.134      << ((fast_decay) ? 10 : 9);
  10.135  }
  10.136  
  10.137 -static int32 convert_envelope_offset(uint8 offset)
  10.138 +int32 convert_envelope_offset(uint8 offset)
  10.139  {
  10.140    /* This is not too good... Can anyone tell me what these values mean?
  10.141       Are they GUS-style "exponential" volumes? And what does that mean? */
  10.142 @@ -107,7 +179,7 @@
  10.143    return offset << (7+15);
  10.144  }
  10.145  
  10.146 -static int32 convert_tremolo_sweep(uint8 sweep)
  10.147 +int32 convert_tremolo_sweep(uint8 sweep)
  10.148  {
  10.149    if (!sweep)
  10.150      return 0;
  10.151 @@ -117,7 +189,7 @@
  10.152        (play_mode->rate * sweep);
  10.153  }
  10.154  
  10.155 -static int32 convert_vibrato_sweep(uint8 sweep, int32 vib_control_ratio)
  10.156 +int32 convert_vibrato_sweep(uint8 sweep, int32 vib_control_ratio)
  10.157  {
  10.158    if (!sweep)
  10.159      return 0;
  10.160 @@ -132,14 +204,14 @@
  10.161        (play_mode->rate * sweep); */
  10.162  }
  10.163  
  10.164 -static int32 convert_tremolo_rate(uint8 rate)
  10.165 +int32 convert_tremolo_rate(uint8 rate)
  10.166  {
  10.167    return
  10.168      ((SINE_CYCLE_LENGTH * control_ratio * rate) << RATE_SHIFT) /
  10.169        (TREMOLO_RATE_TUNING * play_mode->rate);
  10.170  }
  10.171  
  10.172 -static int32 convert_vibrato_rate(uint8 rate)
  10.173 +int32 convert_vibrato_rate(uint8 rate)
  10.174  {
  10.175    /* Return a suitable vibrato_control_ratio value */
  10.176    return
  10.177 @@ -171,19 +243,23 @@
  10.178     undefined.
  10.179  
  10.180     TODO: do reverse loops right */
  10.181 -static Instrument *load_instrument(char *name, int percussion,
  10.182 -				   int panning, int amp, int note_to_use,
  10.183 +static InstrumentLayer *load_instrument(char *name, int font_type, int percussion,
  10.184 +				   int panning, int amp, int cfg_tuning, int note_to_use,
  10.185  				   int strip_loop, int strip_envelope,
  10.186 -				   int strip_tail)
  10.187 +				   int strip_tail, int bank, int gm_num, int sf_ix)
  10.188  {
  10.189 +  InstrumentLayer *lp, *lastlp, *headlp;
  10.190    Instrument *ip;
  10.191 -  Sample *sp;
  10.192    FILE *fp;
  10.193    uint8 tmp[1024];
  10.194    int i,j,noluck=0;
  10.195  #ifdef PATCH_EXT_LIST
  10.196    static char *patch_ext[] = PATCH_EXT_LIST;
  10.197  #endif
  10.198 +  int sf2flag = 0;
  10.199 +  int right_samples = 0;
  10.200 +  int stereo_channels = 1, stereo_layer;
  10.201 +  int vlayer_list[19][4], vlayer, vlayer_count;
  10.202  
  10.203    if (!name) return 0;
  10.204    
  10.205 @@ -217,7 +293,7 @@
  10.206        return 0;
  10.207      }
  10.208        
  10.209 -  ctl->cmsg(CMSG_INFO, VERB_NOISY, "Loading instrument %s", current_filename);
  10.210 +  /*ctl->cmsg(CMSG_INFO, VERB_NOISY, "Loading instrument %s", current_filename);*/
  10.211    
  10.212    /* Read some headers and do cursory sanity checks. There are loads
  10.213       of magic offsets. This could be rewritten... */
  10.214 @@ -230,7 +306,41 @@
  10.215        ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: not an instrument", name);
  10.216        return 0;
  10.217      }
  10.218 -  
  10.219 +
  10.220 +/* patch layout:
  10.221 + * bytes:  info:		starts at offset:
  10.222 + * 22	id (see above)		0
  10.223 + * 60	copyright		22
  10.224 + *  1	instruments		82
  10.225 + *  1	voices			83
  10.226 + *  1	channels		84
  10.227 + *  2	number of waveforms	85
  10.228 + *  2	master volume		87
  10.229 + *  4	datasize		89
  10.230 + * 36   reserved, but now:	93
  10.231 + * 	7 "SF2EXT\0" id			93
  10.232 + * 	1 right samples		       100
  10.233 + *     28 reserved		       101
  10.234 + *  2	instrument number	129
  10.235 + * 16	instrument name		131
  10.236 + *  4	instrument size		147
  10.237 + *  1	number of layers	151
  10.238 + * 40	reserved		152
  10.239 + *  1	layer duplicate		192
  10.240 + *  1	layer number		193
  10.241 + *  4	layer size		194
  10.242 + *  1	number of samples	198
  10.243 + * 40	reserved		199
  10.244 + * 				239
  10.245 + * THEN, for each sample, see below
  10.246 + */
  10.247 +
  10.248 +  if (!memcmp(tmp + 93, "SF2EXT", 6))
  10.249 +    {
  10.250 +	    sf2flag = 1;
  10.251 +	    vlayer_count = tmp[152];
  10.252 +    }
  10.253 +
  10.254    if (tmp[82] != 1 && tmp[82] != 0) /* instruments. To some patch makers, 
  10.255  				       0 means 1 */
  10.256      {
  10.257 @@ -246,16 +356,84 @@
  10.258        return 0;
  10.259      }
  10.260    
  10.261 -  ip=safe_malloc(sizeof(Instrument));
  10.262 -  ip->samples = tmp[198];
  10.263 -  ip->sample = safe_malloc(sizeof(Sample) * ip->samples);
  10.264 -  for (i=0; i<ip->samples; i++)
  10.265 +
  10.266 +  if (sf2flag && vlayer_count > 0) {
  10.267 +	for (i = 0; i < 9; i++)
  10.268 +	  for (j = 0; j < 4; j++)
  10.269 +	    vlayer_list[i][j] = tmp[153+i*4+j];
  10.270 +	for (i = 9; i < 19; i++)
  10.271 +	  for (j = 0; j < 4; j++)
  10.272 +	    vlayer_list[i][j] = tmp[199+(i-9)*4+j];
  10.273 +  }
  10.274 +  else {
  10.275 +	for (i = 0; i < 19; i++)
  10.276 +	  for (j = 0; j < 4; j++)
  10.277 +	    vlayer_list[i][j] = 0;
  10.278 +	vlayer_list[0][0] = 0;
  10.279 +	vlayer_list[0][1] = 127;
  10.280 +	vlayer_list[0][2] = tmp[198];
  10.281 +	vlayer_list[0][3] = 0;
  10.282 +	vlayer_count = 1;
  10.283 +  }
  10.284 +
  10.285 +  lastlp = 0;
  10.286 +
  10.287 +  for (vlayer = 0; vlayer < vlayer_count; vlayer++) {
  10.288 +
  10.289 +  lp=(InstrumentLayer *)safe_malloc(sizeof(InstrumentLayer));
  10.290 +  lp->size = sizeof(InstrumentLayer);
  10.291 +  lp->lo = vlayer_list[vlayer][0];
  10.292 +  lp->hi = vlayer_list[vlayer][1];
  10.293 +  ip=(Instrument *)safe_malloc(sizeof(Instrument));
  10.294 +  lp->size += sizeof(Instrument);
  10.295 +  lp->instrument = ip;
  10.296 +  lp->next = 0;
  10.297 +
  10.298 +  if (lastlp) lastlp->next = lp;
  10.299 +  else headlp = lp;
  10.300 +
  10.301 +  lastlp = lp;
  10.302 +
  10.303 +  if (sf2flag) ip->type = INST_SF2;
  10.304 +  else ip->type = INST_GUS;
  10.305 +  ip->samples = vlayer_list[vlayer][2];
  10.306 +  ip->sample = (Sample *)safe_malloc(sizeof(Sample) * ip->samples);
  10.307 +  lp->size += sizeof(Sample) * ip->samples;
  10.308 +  ip->left_samples = ip->samples;
  10.309 +  ip->left_sample = ip->sample;
  10.310 +  right_samples = vlayer_list[vlayer][3];
  10.311 +  ip->right_samples = right_samples;
  10.312 +  if (right_samples)
  10.313      {
  10.314 +      ip->right_sample = (Sample *)safe_malloc(sizeof(Sample) * right_samples);
  10.315 +      lp->size += sizeof(Sample) * right_samples;
  10.316 +      stereo_channels = 2;
  10.317 +    }
  10.318 +  else ip->right_sample = 0;
  10.319 +  ip->contents = 0;
  10.320  
  10.321 +  ctl->cmsg(CMSG_INFO, VERB_NOISY, "%s%s[%d,%d] %s(%d-%d layer %d of %d)",
  10.322 +	(percussion)? "   ":"", name,
  10.323 +	(percussion)? note_to_use : gm_num, bank,
  10.324 +	(right_samples)? "(2) " : "",
  10.325 +	lp->lo, lp->hi, vlayer+1, vlayer_count);
  10.326 +
  10.327 + for (stereo_layer = 0; stereo_layer < stereo_channels; stereo_layer++)
  10.328 + {
  10.329 +  int sample_count;
  10.330 +
  10.331 +  if (stereo_layer == 0) sample_count = ip->left_samples;
  10.332 +  else if (stereo_layer == 1) sample_count = ip->right_samples;
  10.333 +
  10.334 +  for (i=0; i < sample_count; i++)
  10.335 +    {
  10.336        uint8 fractions;
  10.337        int32 tmplong;
  10.338        uint16 tmpshort;
  10.339 +      uint16 sample_volume;
  10.340        uint8 tmpchar;
  10.341 +      Sample *sp;
  10.342 +      uint8 sf2delay;
  10.343  
  10.344  #define READ_CHAR(thing) \
  10.345        if (1 != fread(&tmpchar, 1, 1, fp)) goto fail; \
  10.346 @@ -267,21 +445,53 @@
  10.347        if (1 != fread(&tmplong, 4, 1, fp)) goto fail; \
  10.348        thing = LE_LONG(tmplong);
  10.349  
  10.350 +/*
  10.351 + *  7	sample name
  10.352 + *  1	fractions
  10.353 + *  4	length
  10.354 + *  4	loop start
  10.355 + *  4	loop end
  10.356 + *  2	sample rate
  10.357 + *  4	low frequency
  10.358 + *  4	high frequency
  10.359 + *  2	finetune
  10.360 + *  1	panning
  10.361 + *  6	envelope rates			|
  10.362 + *  6	envelope offsets		|  18 bytes
  10.363 + *  3	tremolo sweep, rate, depth	|
  10.364 + *  3	vibrato sweep, rate, depth	|
  10.365 + *  1	sample mode
  10.366 + *  2	scale frequency
  10.367 + *  2	scale factor
  10.368 + *  2	sample volume (??)
  10.369 + * 34	reserved
  10.370 + * Now: 1	delay
  10.371 + * 	33	reserved
  10.372 + */
  10.373        skip(fp, 7); /* Skip the wave name */
  10.374  
  10.375        if (1 != fread(&fractions, 1, 1, fp))
  10.376  	{
  10.377  	fail:
  10.378  	  ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Error reading sample %d", i);
  10.379 +	  if (stereo_layer == 1)
  10.380 +	     {
  10.381 +	       for (j=0; j<i; j++)
  10.382 +	         free(ip->right_sample[j].data);
  10.383 +	       free(ip->right_sample);
  10.384 +	       i = ip->left_samples;
  10.385 +	     }
  10.386  	  for (j=0; j<i; j++)
  10.387 -	    free(ip->sample[j].data);
  10.388 -	  free(ip->sample);
  10.389 +	    free(ip->left_sample[j].data);
  10.390 +	  free(ip->left_sample);
  10.391  	  free(ip);
  10.392 +	  free(lp);
  10.393  	  return 0;
  10.394  	}
  10.395  
  10.396 -      sp=&(ip->sample[i]);
  10.397 -      
  10.398 +      if (stereo_layer == 0) sp=&(ip->left_sample[i]);
  10.399 +      else if (stereo_layer == 1) sp=&(ip->right_sample[i]);
  10.400 +
  10.401        READ_LONG(sp->data_length);
  10.402        READ_LONG(sp->loop_start);
  10.403        READ_LONG(sp->loop_end);
  10.404 @@ -298,6 +508,23 @@
  10.405        else
  10.406  	sp->panning=(uint8)(panning & 0x7F);
  10.407  
  10.408 +      sp->resonance=0;
  10.409 +      sp->cutoff_freq=0;
  10.410 +      sp->reverberation=0;
  10.411 +      sp->chorusdepth=0;
  10.412 +      sp->exclusiveClass=0;
  10.413 +      sp->keyToModEnvHold=0;
  10.414 +      sp->keyToModEnvDecay=0;
  10.415 +      sp->keyToVolEnvHold=0;
  10.416 +      sp->keyToVolEnvDecay=0;
  10.417 +
  10.418 +      if (cfg_tuning)
  10.419 +	{
  10.420 +	  double tune_factor = (double)(cfg_tuning)/1200.0;
  10.421 +	  tune_factor = pow(2.0, tune_factor);
  10.422 +	  sp->root_freq = (uint32)( tune_factor * (double)sp->root_freq );
  10.423 +	}
  10.424 +
  10.425        /* envelope, tremolo, and vibrato */
  10.426        if (18 != fread(tmp, 1, 18, fp)) goto fail; 
  10.427  
  10.428 @@ -338,9 +565,20 @@
  10.429  	}
  10.430  
  10.431        READ_CHAR(sp->modes);
  10.432 +      READ_SHORT(sp->freq_center);
  10.433 +      READ_SHORT(sp->freq_scale);
  10.434  
  10.435 -      skip(fp, 40); /* skip the useless scale frequency, scale factor
  10.436 -		       (what's it mean?), and reserved space */
  10.437 +      if (sf2flag)
  10.438 +        {
  10.439 +          READ_SHORT(sample_volume);
  10.440 +	  READ_CHAR(sf2delay);
  10.441 +          READ_CHAR(sp->exclusiveClass);
  10.442 +          skip(fp, 32);
  10.443 +	}
  10.444 +      else
  10.445 +        {
  10.446 +          skip(fp, 36);
  10.447 +        }
  10.448  
  10.449        /* Mark this as a fixed-pitch instrument if such a deed is desired. */
  10.450        if (note_to_use!=-1)
  10.451 @@ -403,16 +641,47 @@
  10.452  	    }
  10.453  	}
  10.454  
  10.455 -      for (j=0; j<6; j++)
  10.456 +      sp->attenuation = 0;
  10.457 +
  10.458 +      for (j=ATTACK; j<DELAY; j++)
  10.459  	{
  10.460  	  sp->envelope_rate[j]=
  10.461 -	    convert_envelope_rate(tmp[j]);
  10.462 +	    (j<3)? convert_envelope_rate_attack(tmp[j], 11) : convert_envelope_rate(tmp[j]);
  10.463  	  sp->envelope_offset[j]= 
  10.464  	    convert_envelope_offset(tmp[6+j]);
  10.465  	}
  10.466 +      if (sf2flag)
  10.467 +	{
  10.468 +	  if (sf2delay > 5) sf2delay = 5;
  10.469 +	  sp->envelope_rate[DELAY] = (int32)( (sf2delay*play_mode->rate) / 1000 );
  10.470 +	}
  10.471 +      else
  10.472 +	{
  10.473 +          sp->envelope_rate[DELAY]=0;
  10.474 +	}
  10.475 +      sp->envelope_offset[DELAY]=0;
  10.476 +
  10.477 +      for (j=ATTACK; j<DELAY; j++)
  10.478 +	{
  10.479 +	  sp->modulation_rate[j]=sp->envelope_rate[j];
  10.480 +	  sp->modulation_offset[j]=sp->envelope_offset[j];
  10.481 +	}
  10.482 +      sp->modulation_rate[DELAY] = sp->modulation_offset[DELAY] = 0;
  10.483 +      sp->modEnvToFilterFc=0;
  10.484 +      sp->modEnvToPitch=0;
  10.485 +      sp->lfo_sweep_increment = 0;
  10.486 +      sp->lfo_phase_increment = 0;
  10.487 +      sp->modLfoToFilterFc = 0;
  10.488 +      sp->vibrato_delay = 0;
  10.489  
  10.490        /* Then read the sample data */
  10.491 -      sp->data = safe_malloc(sp->data_length);
  10.492 +      if (sp->data_length/2 > MAX_SAMPLE_SIZE)
  10.493 +        {
  10.494 +	  goto fail;
  10.495 +	}
  10.496 +      sp->data = safe_malloc(sp->data_length + 1);
  10.497 +      lp->size += sp->data_length + 1;
  10.498 +
  10.499        if (1 != fread(sp->data, sp->data_length, 1, fp))
  10.500  	goto fail;
  10.501        
  10.502 @@ -420,12 +689,12 @@
  10.503  	{
  10.504  	  int32 i=sp->data_length;
  10.505  	  uint8 *cp=(uint8 *)(sp->data);
  10.506 -	  uint16 *tmp,*new;
  10.507 -	  tmp=new=safe_malloc(sp->data_length*2);
  10.508 +	  uint16 *tmp,*newdta;
  10.509 +	  tmp=newdta=safe_malloc(sp->data_length*2 + 2);
  10.510  	  while (i--)
  10.511  	    *tmp++ = (uint16)(*cp++) << 8;
  10.512  	  cp=(uint8 *)(sp->data);
  10.513 -	  sp->data = (sample_t *)new;
  10.514 +	  sp->data = (sample_t *)newdta;
  10.515  	  free(cp);
  10.516  	  sp->data_length *= 2;
  10.517  	  sp->loop_start *= 2;
  10.518 @@ -478,15 +747,19 @@
  10.519  
  10.520  #ifdef ADJUST_SAMPLE_VOLUMES
  10.521        if (amp!=-1)
  10.522 -	sp->volume=(float)((amp) / 100.0);
  10.523 +	sp->volume=(FLOAT_T)((amp) / 100.0);
  10.524 +      else if (sf2flag)
  10.525 +	sp->volume=(FLOAT_T)((sample_volume) / 255.0);
  10.526        else
  10.527  	{
  10.528  	  /* Try to determine a volume scaling factor for the sample.
  10.529  	     This is a very crude adjustment, but things sound more
  10.530  	     balanced with it. Still, this should be a runtime option. */
  10.531 -	  int32 i=sp->data_length/2;
  10.532 +	  uint32 i, numsamps=sp->data_length/2;
  10.533 +	  uint32 higher=0, highcount=0;
  10.534  	  int16 maxamp=0,a;
  10.535  	  int16 *tmp=(int16 *)sp->data;
  10.536 +	  i = numsamps;
  10.537  	  while (i--)
  10.538  	    {
  10.539  	      a=*tmp++;
  10.540 @@ -494,7 +767,21 @@
  10.541  	      if (a>maxamp)
  10.542  		maxamp=a;
  10.543  	    }
  10.544 -	  sp->volume=(float)(32768.0 / maxamp);
  10.545 +	  tmp=(int16 *)sp->data;
  10.546 +	  i = numsamps;
  10.547 +	  while (i--)
  10.548 +	    {
  10.549 +	      a=*tmp++;
  10.550 +	      if (a<0) a=-a;
  10.551 +	      if (a > 3*maxamp/4)
  10.552 +		{
  10.553 +		   higher += a;
  10.554 +		   highcount++;
  10.555 +		}
  10.556 +	    }
  10.557 +	  if (highcount) higher /= highcount;
  10.558 +	  else higher = 10000;
  10.559 +	  sp->volume = (32768.0 * 0.875) /  (double)higher ;
  10.560  	  ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * volume comp: %f", sp->volume);
  10.561  	}
  10.562  #else
  10.563 @@ -505,14 +792,28 @@
  10.564  #endif
  10.565  
  10.566        sp->data_length /= 2; /* These are in bytes. Convert into samples. */
  10.567 +
  10.568        sp->loop_start /= 2;
  10.569        sp->loop_end /= 2;
  10.570 +      sp->data[sp->data_length] = sp->data[sp->data_length-1];
  10.571  
  10.572        /* Then fractional samples */
  10.573        sp->data_length <<= FRACTION_BITS;
  10.574        sp->loop_start <<= FRACTION_BITS;
  10.575        sp->loop_end <<= FRACTION_BITS;
  10.576  
  10.577 +    /* trim off zero data at end */
  10.578 +    {
  10.579 +	int ls = sp->loop_start>>FRACTION_BITS;
  10.580 +	int le = sp->loop_end>>FRACTION_BITS;
  10.581 +	int se = sp->data_length>>FRACTION_BITS;
  10.582 +	while (se > 1 && !sp->data[se-1]) se--;
  10.583 +	if (le > se) le = se;
  10.584 +	if (ls >= le) sp->modes &= ~MODES_LOOPING;
  10.585 +	sp->loop_end = le<<FRACTION_BITS;
  10.586 +	sp->data_length = se<<FRACTION_BITS;
  10.587 +    }
  10.588 +
  10.589        /* Adjust for fractional loop points. This is a guess. Does anyone
  10.590  	 know what "fractions" really stands for? */
  10.591        sp->loop_start |=
  10.592 @@ -546,10 +847,13 @@
  10.593  	  ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Stripping tail");
  10.594  	  sp->data_length = sp->loop_end;
  10.595  	}
  10.596 -    }
  10.597 +    } /* end of sample loop */
  10.598 + } /* end of stereo layer loop */
  10.599 + } /* end of vlayer loop */
  10.600 +
  10.601  
  10.602    close_file(fp);
  10.603 -  return ip;
  10.604 +  return headlp;
  10.605  }
  10.606  
  10.607  static int fill_bank(int dr, int b)
  10.608 @@ -563,9 +867,9 @@
  10.609  	   (dr) ? "drumset" : "tone bank", b);
  10.610        return 0;
  10.611      }
  10.612 -  for (i=0; i<128; i++)
  10.613 +  for (i=0; i<MAXPROG; i++)
  10.614      {
  10.615 -      if (bank->tone[i].instrument==MAGIC_LOAD_INSTRUMENT)
  10.616 +      if (bank->tone[i].layer==MAGIC_LOAD_INSTRUMENT)
  10.617  	{
  10.618  	  if (!(bank->tone[i].name))
  10.619  	    {
  10.620 @@ -579,35 +883,41 @@
  10.621  		     bank / drumset for loading (if it isn't already) */
  10.622  		  if (!dr)
  10.623  		    {
  10.624 -		      if (!(standard_tonebank.tone[i].instrument))
  10.625 -			standard_tonebank.tone[i].instrument=
  10.626 +		      if (!(standard_tonebank.tone[i].layer))
  10.627 +			standard_tonebank.tone[i].layer=
  10.628  			  MAGIC_LOAD_INSTRUMENT;
  10.629  		    }
  10.630  		  else
  10.631  		    {
  10.632 -		      if (!(standard_drumset.tone[i].instrument))
  10.633 -			standard_drumset.tone[i].instrument=
  10.634 +		      if (!(standard_drumset.tone[i].layer))
  10.635 +			standard_drumset.tone[i].layer=
  10.636  			  MAGIC_LOAD_INSTRUMENT;
  10.637  		    }
  10.638  		}
  10.639 -	      bank->tone[i].instrument=0;
  10.640 +	      bank->tone[i].layer=0;
  10.641  	      errors++;
  10.642  	    }
  10.643 -	  else if (!(bank->tone[i].instrument=
  10.644 +	  else if (!(bank->tone[i].layer=
  10.645  		     load_instrument(bank->tone[i].name, 
  10.646 +			     	     bank->tone[i].font_type,
  10.647  				     (dr) ? 1 : 0,
  10.648  				     bank->tone[i].pan,
  10.649  				     bank->tone[i].amp,
  10.650 +				     bank->tone[i].tuning,
  10.651  				     (bank->tone[i].note!=-1) ? 
  10.652 -				     bank->tone[i].note :
  10.653 -				     ((dr) ? i : -1),
  10.654 +				       bank->tone[i].note :
  10.655 +				       ((dr) ? i : -1),
  10.656  				     (bank->tone[i].strip_loop!=-1) ?
  10.657  				     bank->tone[i].strip_loop :
  10.658  				     ((dr) ? 1 : -1),
  10.659  				     (bank->tone[i].strip_envelope != -1) ? 
  10.660  				     bank->tone[i].strip_envelope :
  10.661  				     ((dr) ? 1 : -1),
  10.662 -				     bank->tone[i].strip_tail )))
  10.663 +				     bank->tone[i].strip_tail,
  10.664 +				     b,
  10.665 +				     ((dr) ? i + 128 : i),
  10.666 +				     bank->tone[i].sf_ix
  10.667 +			    			 )))
  10.668  	    {
  10.669  	      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
  10.670  		   "Couldn't load instrument %s (%s %d, program %d)",
  10.671 @@ -615,14 +925,63 @@
  10.672  		   (dr)? "drum set" : "tone bank", b, i);
  10.673  	      errors++;
  10.674  	    }
  10.675 +	  else
  10.676 +	    { /* it's loaded now */
  10.677 +		bank->tone[i].last_used = current_tune_number;
  10.678 +		current_patch_memory += bank->tone[i].layer->size;
  10.679 +		purge_as_required();
  10.680 +		if (current_patch_memory > max_patch_memory) {
  10.681 +	      		ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
  10.682 +		   		"Not enough memory to load instrument %s (%s %d, program %d)",
  10.683 +		   		bank->tone[i].name,
  10.684 +		   		(dr)? "drum set" : "tone bank", b, i);
  10.685 +	      		errors++;
  10.686 +	    		free_layer(bank->tone[i].layer);
  10.687 +	    		bank->tone[i].layer=0;
  10.688 +	    		bank->tone[i].last_used=-1;
  10.689 +		}
  10.690 +#if 0
  10.691 +  	        if (check_for_rc()) {
  10.692 +	    		free_layer(bank->tone[i].layer);
  10.693 +	    		bank->tone[i].layer=0;
  10.694 +	    		bank->tone[i].last_used=-1;
  10.695 +			return 0;
  10.696 +		}
  10.697 +#endif
  10.698 +	    }
  10.699  	}
  10.700      }
  10.701    return errors;
  10.702  }
  10.703  
  10.704 +static void free_old_instruments(int how_old)
  10.705 +{
  10.706 +  int i=MAXBANK;
  10.707 +  while(i--)
  10.708 +    {
  10.709 +      if (tonebank[i])
  10.710 +	free_old_bank(0, i, how_old);
  10.711 +      if (drumset[i])
  10.712 +	free_old_bank(1, i, how_old);
  10.713 +    }
  10.714 +}
  10.715 +
  10.716 +static void purge_as_required(void)
  10.717 +{
  10.718 +  if (!max_patch_memory) return;
  10.719 +
  10.720 +  while (last_tune_purged < current_tune_number
  10.721 +	&& current_patch_memory > max_patch_memory)
  10.722 +    {
  10.723 +	last_tune_purged++;
  10.724 +	free_old_instruments(last_tune_purged);
  10.725 +    }
  10.726 +}
  10.727 +
  10.728 +
  10.729  int load_missing_instruments(void)
  10.730  {
  10.731 -  int i=128,errors=0;
  10.732 +  int i=MAXBANK,errors=0;
  10.733    while (i--)
  10.734      {
  10.735        if (tonebank[i])
  10.736 @@ -630,6 +989,7 @@
  10.737        if (drumset[i])
  10.738  	errors+=fill_bank(1,i);
  10.739      }
  10.740 +  current_tune_number++;
  10.741    return errors;
  10.742  }
  10.743  
  10.744 @@ -647,12 +1007,13 @@
  10.745  
  10.746  int set_default_instrument(char *name)
  10.747  {
  10.748 -  Instrument *ip;
  10.749 -  if (!(ip=load_instrument(name, 0, -1, -1, -1, 0, 0, 0)))
  10.750 +  InstrumentLayer *lp;
  10.751 +/*  if (!(lp=load_instrument(name, 0, -1, -1, -1, 0, 0, 0))) */
  10.752 +  if (!(lp=load_instrument(name, FONT_NORMAL, 0, -1, -1, 0, -1, -1, -1, -1, 0, -1, -1)))
  10.753      return -1;
  10.754    if (default_instrument)
  10.755 -    free_instrument(default_instrument);
  10.756 -  default_instrument=ip;
  10.757 +    free_layer(default_instrument);
  10.758 +  default_instrument=lp;
  10.759    default_program=SPECIAL_PROGRAM;
  10.760    return 0;
  10.761  }
    11.1 --- a/timidity/instrum.h	Fri Aug 20 19:32:09 2004 +0000
    11.2 +++ b/timidity/instrum.h	Sat Aug 21 12:27:02 2004 +0000
    11.3 @@ -21,23 +21,38 @@
    11.4  
    11.5     */
    11.6  
    11.7 +
    11.8  typedef struct {
    11.9    int32
   11.10      loop_start, loop_end, data_length,
   11.11      sample_rate, low_freq, high_freq, root_freq;
   11.12 +  uint8
   11.13 +    root_tune, fine_tune;
   11.14    int32
   11.15 -    envelope_rate[6], envelope_offset[6];
   11.16 -  float
   11.17 -    volume;
   11.18 +    envelope_rate[7], envelope_offset[7],
   11.19 +    modulation_rate[7], modulation_offset[7];
   11.20 +  FLOAT_T
   11.21 +    volume, resonance,
   11.22 +    modEnvToFilterFc, modEnvToPitch, modLfoToFilterFc;
   11.23    sample_t *data;
   11.24    int32 
   11.25      tremolo_sweep_increment, tremolo_phase_increment, 
   11.26 -    vibrato_sweep_increment, vibrato_control_ratio;
   11.27 +    lfo_sweep_increment, lfo_phase_increment,
   11.28 +    vibrato_sweep_increment, vibrato_control_ratio,
   11.29 +    cutoff_freq;
   11.30    uint8
   11.31 +    reverberation, chorusdepth,
   11.32      tremolo_depth, vibrato_depth,
   11.33      modes;
   11.34 +  uint8
   11.35 +    attenuation, freq_center;
   11.36    int8
   11.37 -    panning, note_to_use;
   11.38 +    panning, note_to_use, exclusiveClass;
   11.39 +  int16
   11.40 +    scale_tuning, keyToModEnvHold, keyToModEnvDecay,
   11.41 +    keyToVolEnvHold, keyToVolEnvDecay;
   11.42 +  int32
   11.43 +    freq_scale, vibrato_delay;
   11.44  } Sample;
   11.45  
   11.46  /* Bits in modes: */
   11.47 @@ -48,29 +63,96 @@
   11.48  #define MODES_REVERSE	(1<<4)
   11.49  #define MODES_SUSTAIN	(1<<5)
   11.50  #define MODES_ENVELOPE	(1<<6)
   11.51 +#define MODES_FAST_RELEASE	(1<<7)
   11.52  
   11.53 +#if 0
   11.54  typedef struct {
   11.55    int samples;
   11.56    Sample *sample;
   11.57  } Instrument;
   11.58 +#endif
   11.59  
   11.60 +#define INST_GUS	0
   11.61 +#define INST_SF2	1
   11.62 +
   11.63 +typedef struct {
   11.64 +  int type;
   11.65 +  int samples;
   11.66 +  Sample *sample;
   11.67 +  int left_samples;
   11.68 +  Sample *left_sample;
   11.69 +  int right_samples;
   11.70 +  Sample *right_sample;
   11.71 +  unsigned char *contents;
   11.72 +} Instrument;
   11.73 +
   11.74 +
   11.75 +typedef struct _InstrumentLayer {
   11.76 +  uint8 lo, hi;
   11.77 +  int size;
   11.78 +  Instrument *instrument;
   11.79 +  struct _InstrumentLayer *next;
   11.80 +} InstrumentLayer;
   11.81 +
   11.82 +struct cfg_type {
   11.83 +	int font_code;
   11.84 +	int num;
   11.85 +	const char *name;
   11.86 +};
   11.87 +
   11.88 +#define FONT_NORMAL 0
   11.89 +#define FONT_FFF    1
   11.90 +#define FONT_SBK    2
   11.91 +#define FONT_TONESET 3
   11.92 +#define FONT_DRUMSET 4
   11.93 +#define FONT_PRESET 5
   11.94 +
   11.95 +
   11.96 +typedef struct {
   11.97 +  char *name;
   11.98 +  InstrumentLayer *layer;
   11.99 +  int font_type, sf_ix, last_used, tuning;
  11.100 +  int note, amp, pan, strip_loop, strip_envelope, strip_tail;
  11.101 +} ToneBankElement;
  11.102 +
  11.103 +#if 0
  11.104  typedef struct {
  11.105    char *name;
  11.106    Instrument *instrument;
  11.107    int note, amp, pan, strip_loop, strip_envelope, strip_tail;
  11.108  } ToneBankElement;
  11.109 -
  11.110 +#endif
  11.111  /* A hack to delay instrument loading until after reading the
  11.112     entire MIDI file. */
  11.113 -#define MAGIC_LOAD_INSTRUMENT ((Instrument *)(-1))
  11.114 +#define MAGIC_LOAD_INSTRUMENT ((InstrumentLayer *)(-1))
  11.115  
  11.116 +#define MAXPROG 128
  11.117 +#define MAXBANK 130
  11.118 +#define SFXBANK (MAXBANK-1)
  11.119 +#define SFXDRUM1 (MAXBANK-2)
  11.120 +#define SFXDRUM2 (MAXBANK-1)
  11.121 +#define XGDRUM 1
  11.122 +
  11.123 +#if 0
  11.124  typedef struct {
  11.125    ToneBankElement tone[128];
  11.126  } ToneBank;
  11.127 +#endif
  11.128 +
  11.129 +typedef struct {
  11.130 +  char *name;
  11.131 +  ToneBankElement tone[MAXPROG];
  11.132 +} ToneBank;
  11.133 +
  11.134 +
  11.135 +extern char *sf_file;
  11.136  
  11.137  extern ToneBank *tonebank[], *drumset[];
  11.138  
  11.139 +#if 0
  11.140  extern Instrument *default_instrument;
  11.141 +#endif
  11.142 +extern InstrumentLayer *default_instrument;
  11.143  extern int default_program;
  11.144  extern int antialiasing_allowed;
  11.145  extern int fast_decay;
  11.146 @@ -80,5 +162,22 @@
  11.147  
  11.148  extern int load_missing_instruments(void);
  11.149  extern void free_instruments(void);
  11.150 +extern void end_soundfont(void);
  11.151  extern int set_default_instrument(char *name);
  11.152  
  11.153 +
  11.154 +extern int32 convert_tremolo_sweep(uint8 sweep);
  11.155 +extern int32 convert_vibrato_sweep(uint8 sweep, int32 vib_control_ratio);
  11.156 +extern int32 convert_tremolo_rate(uint8 rate);
  11.157 +extern int32 convert_vibrato_rate(uint8 rate);
  11.158 +
  11.159 +extern int init_soundfont(char *fname, int oldbank, int newbank, int level);
  11.160 +extern InstrumentLayer *load_sbk_patch(const char *name, int gm_num, int bank, int percussion,
  11.161 + int panning, int amp, int note_to_use, int sf_ix);
  11.162 +extern int current_tune_number;
  11.163 +extern int max_patch_memory;
  11.164 +extern int current_patch_memory;
  11.165 +#define XMAPMAX 800
  11.166 +extern int xmap[XMAPMAX][5];
  11.167 +extern void pcmap(int *b, int *v, int *p, int *drums);
  11.168 +
    12.1 --- a/timidity/mix.c	Fri Aug 20 19:32:09 2004 +0000
    12.2 +++ b/timidity/mix.c	Sat Aug 21 12:27:02 2004 +0000
    12.3 @@ -77,41 +77,64 @@
    12.4  
    12.5  void apply_envelope_to_amp(int v)
    12.6  {
    12.7 -  float lamp=voice[v].left_amp, ramp;
    12.8 -  int32 la,ra;
    12.9 +  FLOAT_T lamp=voice[v].left_amp, ramp, lramp, rramp, ceamp, lfeamp;
   12.10 +  int32 la,ra, lra, rra, cea, lfea;
   12.11    if (voice[v].panned == PANNED_MYSTERY)
   12.12      {
   12.13 +      lramp=voice[v].lr_amp;
   12.14        ramp=voice[v].right_amp;
   12.15 +      ceamp=voice[v].ce_amp;
   12.16 +      rramp=voice[v].rr_amp;
   12.17 +      lfeamp=voice[v].lfe_amp;
   12.18 +
   12.19        if (voice[v].tremolo_phase_increment)
   12.20  	{
   12.21 -	  lamp *= voice[v].tremolo_volume;
   12.22 -	  ramp *= voice[v].tremolo_volume;
   12.23 +	  FLOAT_T tv = voice[v].tremolo_volume;
   12.24 +	  lramp *= tv;
   12.25 +	  lamp *= tv;
   12.26 +	  ceamp *= tv;
   12.27 +	  ramp *= tv;
   12.28 +	  rramp *= tv;
   12.29 +	  lfeamp *= tv;
   12.30  	}
   12.31        if (voice[v].sample->modes & MODES_ENVELOPE)
   12.32  	{
   12.33 -	  lamp *= (float)vol_table[voice[v].envelope_volume>>23];
   12.34 -	  ramp *= (float)vol_table[voice[v].envelope_volume>>23];
   12.35 +	  FLOAT_T ev = (FLOAT_T)vol_table[voice[v].envelope_volume>>23];
   12.36 +	  lramp *= ev;
   12.37 +	  lamp *= ev;
   12.38 +	  ceamp *= ev;
   12.39 +	  ramp *= ev;
   12.40 +	  rramp *= ev;
   12.41 +	  lfeamp *= ev;
   12.42  	}
   12.43  
   12.44        la = (int32)FSCALE(lamp,AMP_BITS);
   12.45 +      ra = (int32)FSCALE(ramp,AMP_BITS);
   12.46 +      lra = (int32)FSCALE(lramp,AMP_BITS);
   12.47 +      rra = (int32)FSCALE(rramp,AMP_BITS);
   12.48 +      cea = (int32)FSCALE(ceamp,AMP_BITS);
   12.49 +      lfea = (int32)FSCALE(lfeamp,AMP_BITS);
   12.50        
   12.51 -      if (la>MAX_AMP_VALUE)
   12.52 -	la=MAX_AMP_VALUE;
   12.53 +      if (la>MAX_AMP_VALUE) la=MAX_AMP_VALUE;
   12.54 +      if (ra>MAX_AMP_VALUE) ra=MAX_AMP_VALUE;
   12.55 +      if (lra>MAX_AMP_VALUE) lra=MAX_AMP_VALUE;
   12.56 +      if (rra>MAX_AMP_VALUE) rra=MAX_AMP_VALUE;
   12.57 +      if (cea>MAX_AMP_VALUE) cea=MAX_AMP_VALUE;
   12.58 +      if (lfea>MAX_AMP_VALUE) lfea=MAX_AMP_VALUE;
   12.59  
   12.60 -      ra = (int32)FSCALE(ramp,AMP_BITS);
   12.61 -      if (ra>MAX_AMP_VALUE)
   12.62 -	ra=MAX_AMP_VALUE;
   12.63 -
   12.64 -      
   12.65 +      voice[v].lr_mix=FINAL_VOLUME(lra);
   12.66        voice[v].left_mix=FINAL_VOLUME(la);
   12.67 +      voice[v].ce_mix=FINAL_VOLUME(cea);
   12.68        voice[v].right_mix=FINAL_VOLUME(ra);
   12.69 +      voice[v].rr_mix=FINAL_VOLUME(rra);
   12.70 +      voice[v].lfe_mix=FINAL_VOLUME(lfea);
   12.71      }
   12.72    else
   12.73      {
   12.74        if (voice[v].tremolo_phase_increment)
   12.75  	lamp *= voice[v].tremolo_volume;
   12.76        if (voice[v].sample->modes & MODES_ENVELOPE)
   12.77 -	lamp *= (float)vol_table[voice[v].envelope_volume>>23];
   12.78 +	lamp *= (FLOAT_T)vol_table[voice[v].envelope_volume>>23];
   12.79  
   12.80        la = (int32)FSCALE(lamp,AMP_BITS);
   12.81  
   12.82 @@ -162,7 +185,7 @@
   12.83    /* if (voice[v].tremolo_phase >= (SINE_CYCLE_LENGTH<<RATE_SHIFT))
   12.84       voice[v].tremolo_phase -= SINE_CYCLE_LENGTH<<RATE_SHIFT;  */
   12.85  
   12.86 -  voice[v].tremolo_volume = (float) 
   12.87 +  voice[v].tremolo_volume = (FLOAT_T) 
   12.88      (1.0 - FSCALENEG((sine(voice[v].tremolo_phase >> RATE_SHIFT) + 1.0)
   12.89  		    * depth * TREMOLO_AMPLITUDE_TUNING,
   12.90  		    17));
   12.91 @@ -190,22 +213,36 @@
   12.92  #  define MIXATION(a)	*lp++ += (a)*s;
   12.93  #endif
   12.94  
   12.95 -static void mix_mystery_signal(sample_t *sp, int32 *lp, int v, int count)
   12.96 +#define MIXSKIP lp++
   12.97 +#define MIXMAX(a,b) *lp++ += ((a>b)?a:b) * s
   12.98 +#define MIXCENT(a,b) *lp++ += (a/2+b/2) * s
   12.99 +#define MIXHALF(a)	*lp++ += (a>>1)*s;
  12.100 +
  12.101 +static void mix_mystery_signal(resample_t *sp, int32 *lp, int v, int count)
  12.102  {
  12.103    Voice *vp = voice + v;
  12.104    final_volume_t 
  12.105 +    left_rear=vp->lr_mix, 
  12.106      left=vp->left_mix, 
  12.107 -    right=vp->right_mix;
  12.108 +    center=vp->ce_mix, 
  12.109 +    right=vp->right_mix, 
  12.110 +    right_rear=vp->rr_mix, 
  12.111 +    lfe=vp->lfe_mix;
  12.112    int cc;
  12.113 -  sample_t s;
  12.114 +  resample_t s;
  12.115  
  12.116    if (!(cc = vp->control_counter))
  12.117      {
  12.118        cc = control_ratio;
  12.119        if (update_signal(v))
  12.120  	return;	/* Envelope ran out */
  12.121 -      left = vp->left_mix;
  12.122 -      right = vp->right_mix;
  12.123 +
  12.124 +	left_rear = vp->lr_mix;
  12.125 +	left = vp->left_mix;
  12.126 +	center = vp->ce_mix;
  12.127 +	right = vp->right_mix;
  12.128 +	right_rear = vp->rr_mix;
  12.129 +	lfe = vp->lfe_mix;
  12.130      }
  12.131    
  12.132    while (count)
  12.133 @@ -215,14 +252,26 @@
  12.134  	while (cc--)
  12.135  	  {
  12.136  	    s = *sp++;
  12.137 -	    MIXATION(left);
  12.138 -	    MIXATION(right);
  12.139 +	      	MIXATION(left);
  12.140 +	      	MIXATION(right);
  12.141 +		if (num_ochannels >= 4) {
  12.142 +			MIXATION(left_rear);
  12.143 +			MIXATION(right_rear);
  12.144 +		}
  12.145 +		if (num_ochannels == 6) {
  12.146 +			MIXATION(center);
  12.147 +			MIXATION(lfe);
  12.148 +		}
  12.149  	  }
  12.150  	cc = control_ratio;
  12.151  	if (update_signal(v))
  12.152  	  return;	/* Envelope ran out */
  12.153 +	left_rear = vp->lr_mix;
  12.154  	left = vp->left_mix;
  12.155 +	center = vp->ce_mix;
  12.156  	right = vp->right_mix;
  12.157 +	right_rear = vp->rr_mix;
  12.158 +	lfe = vp->lfe_mix;
  12.159        }
  12.160      else
  12.161        {
  12.162 @@ -230,20 +279,28 @@
  12.163  	while (count--)
  12.164  	  {
  12.165  	    s = *sp++;
  12.166 -	    MIXATION(left);
  12.167 -	    MIXATION(right);
  12.168 +	      	MIXATION(left);
  12.169 +	      	MIXATION(right);
  12.170 +		if (num_ochannels >= 4) {
  12.171 +			MIXATION(left_rear);
  12.172 +			MIXATION(right_rear);
  12.173 +		}
  12.174 +		if (num_ochannels == 6) {
  12.175 +			MIXATION(center);
  12.176 +			MIXATION(lfe);
  12.177 +		}
  12.178  	  }
  12.179  	return;
  12.180        }
  12.181  }
  12.182  
  12.183 -static void mix_center_signal(sample_t *sp, int32 *lp, int v, int count)
  12.184 +static void mix_center_signal(resample_t *sp, int32 *lp, int v, int count)
  12.185  {
  12.186    Voice *vp = voice + v;
  12.187    final_volume_t 
  12.188      left=vp->left_mix;
  12.189    int cc;
  12.190 -  sample_t s;
  12.191 +  resample_t s;
  12.192  
  12.193    if (!(cc = vp->control_counter))
  12.194      {
  12.195 @@ -260,8 +317,24 @@
  12.196  	while (cc--)
  12.197  	  {
  12.198  	    s = *sp++;
  12.199 -	    MIXATION(left);
  12.200 -	    MIXATION(left);
  12.201 +		if (num_ochannels == 2) {
  12.202 +	    		MIXATION(left);
  12.203 +	    		MIXATION(left);
  12.204 +		}
  12.205 +		else if (num_ochannels == 4) {
  12.206 +			MIXATION(left);
  12.207 +			MIXSKIP;
  12.208 +			MIXATION(left);
  12.209 +			MIXSKIP;
  12.210 +		}
  12.211 +		else if (num_ochannels == 6) {
  12.212 +			MIXSKIP;
  12.213 +			MIXSKIP;
  12.214 +			MIXSKIP;
  12.215 +			MIXSKIP;
  12.216 +			MIXATION(left);
  12.217 +			MIXATION(left);
  12.218 +		}
  12.219  	  }
  12.220  	cc = control_ratio;
  12.221  	if (update_signal(v))
  12.222 @@ -274,20 +347,36 @@
  12.223  	while (count--)
  12.224  	  {
  12.225  	    s = *sp++;
  12.226 -	    MIXATION(left);
  12.227 -	    MIXATION(left);
  12.228 +		if (num_ochannels == 2) {
  12.229 +	    		MIXATION(left);
  12.230 +	    		MIXATION(left);
  12.231 +		}
  12.232 +		else if (num_ochannels == 4) {
  12.233 +			MIXATION(left);
  12.234 +			MIXSKIP;
  12.235 +			MIXATION(left);
  12.236 +			MIXSKIP;
  12.237 +		}
  12.238 +		else if (num_ochannels == 6) {
  12.239 +			MIXSKIP;
  12.240 +			MIXSKIP;
  12.241 +			MIXSKIP;
  12.242 +			MIXSKIP;
  12.243 +			MIXATION(left);
  12.244 +			MIXATION(left);
  12.245 +		}
  12.246  	  }
  12.247  	return;
  12.248        }
  12.249  }
  12.250  
  12.251 -static void mix_single_signal(sample_t *sp, int32 *lp, int v, int count)
  12.252 +static void mix_single_left_signal(resample_t *sp, int32 *lp, int v, int count)
  12.253  {
  12.254    Voice *vp = voice + v;
  12.255    final_volume_t 
  12.256      left=vp->left_mix;
  12.257    int cc;
  12.258 -  sample_t s;
  12.259 +  resample_t s;
  12.260    
  12.261    if (!(cc = vp->control_counter))
  12.262      {
  12.263 @@ -304,8 +393,20 @@
  12.264  	while (cc--)
  12.265  	  {
  12.266  	    s = *sp++;
  12.267 -	    MIXATION(left);
  12.268 -	    lp++;
  12.269 +		if (num_ochannels == 2) {
  12.270 +			MIXATION(left);
  12.271 +	    		MIXSKIP;
  12.272 +		}
  12.273 +		if (num_ochannels >= 4) {
  12.274 +			MIXHALF(left);
  12.275 +	    		MIXSKIP;
  12.276 +			MIXATION(left);
  12.277 +	    		MIXSKIP;
  12.278 +		}
  12.279 +		if (num_ochannels == 6) {
  12.280 +	    		MIXSKIP;
  12.281 +			MIXATION(left);
  12.282 +		}
  12.283  	  }
  12.284  	cc = control_ratio;
  12.285  	if (update_signal(v))
  12.286 @@ -318,20 +419,98 @@
  12.287  	while (count--)
  12.288  	  {
  12.289  	    s = *sp++;
  12.290 -	    MIXATION(left);
  12.291 -	    lp++;
  12.292 +		if (num_ochannels == 2) {
  12.293 +			MIXATION(left);
  12.294 +	    		MIXSKIP;
  12.295 +		}
  12.296 +		if (num_ochannels >= 4) {
  12.297 +			MIXHALF(left);
  12.298 +	    		MIXSKIP;
  12.299 +			MIXATION(left);
  12.300 +	    		MIXSKIP;
  12.301 +		}
  12.302 +		if (num_ochannels == 6) {
  12.303 +	    		MIXSKIP;
  12.304 +			MIXATION(left);
  12.305 +		}
  12.306  	  }
  12.307  	return;
  12.308        }
  12.309  }
  12.310  
  12.311 -static void mix_mono_signal(sample_t *sp, int32 *lp, int v, int count)
  12.312 +static void mix_single_right_signal(resample_t *sp, int32 *lp, int v, int count)
  12.313  {
  12.314    Voice *vp = voice + v;
  12.315    final_volume_t 
  12.316      left=vp->left_mix;
  12.317    int cc;
  12.318 -  sample_t s;
  12.319 +  resample_t s;
  12.320 +  
  12.321 +  if (!(cc = vp->control_counter))
  12.322 +    {
  12.323 +      cc = control_ratio;
  12.324 +      if (update_signal(v))
  12.325 +	return;	/* Envelope ran out */
  12.326 +      left = vp->left_mix;
  12.327 +    }
  12.328 +  
  12.329 +  while (count)
  12.330 +    if (cc < count)
  12.331 +      {
  12.332 +	count -= cc;
  12.333 +	while (cc--)
  12.334 +	  {
  12.335 +	    s = *sp++;
  12.336 +		if (num_ochannels == 2) {
  12.337 +	    		MIXSKIP;
  12.338 +			MIXATION(left);
  12.339 +		}
  12.340 +		if (num_ochannels >= 4) {
  12.341 +	    		MIXSKIP;
  12.342 +			MIXHALF(left);
  12.343 +	    		MIXSKIP;
  12.344 +			MIXATION(left);
  12.345 +		} if (num_ochannels == 6) {
  12.346 +	    		MIXSKIP;
  12.347 +			MIXATION(left);
  12.348 +		}
  12.349 +	  }
  12.350 +	cc = control_ratio;
  12.351 +	if (update_signal(v))
  12.352 +	  return;	/* Envelope ran out */
  12.353 +	left = vp->left_mix;
  12.354 +      }
  12.355 +    else
  12.356 +      {
  12.357 +	vp->control_counter = cc - count;
  12.358 +	while (count--)
  12.359 +	  {
  12.360 +	    s = *sp++;
  12.361 +		if (num_ochannels == 2) {
  12.362 +	    		MIXSKIP;
  12.363 +			MIXATION(left);
  12.364 +		}
  12.365 +		if (num_ochannels >= 4) {
  12.366 +	    		MIXSKIP;
  12.367 +			MIXHALF(left);
  12.368 +	    		MIXSKIP;
  12.369 +			MIXATION(left);
  12.370 +		} if (num_ochannels == 6) {
  12.371 +	    		MIXSKIP;
  12.372 +			MIXATION(left);
  12.373 +		}
  12.374 +	  }
  12.375 +	return;
  12.376 +      }
  12.377 +}
  12.378 +
  12.379 +static void mix_mono_signal(resample_t *sp, int32 *lp, int v, int count)
  12.380 +{
  12.381 +  Voice *vp = voice + v;
  12.382 +  final_volume_t 
  12.383 +    left=vp->left_mix;
  12.384 +  int cc;
  12.385 +  resample_t s;
  12.386    
  12.387    if (!(cc = vp->control_counter))
  12.388      {
  12.389 @@ -367,54 +546,119 @@
  12.390        }
  12.391  }
  12.392  
  12.393 -static void mix_mystery(sample_t *sp, int32 *lp, int v, int count)
  12.394 +static void mix_mystery(resample_t *sp, int32 *lp, int v, int count)
  12.395  {
  12.396    final_volume_t 
  12.397 +    left_rear=voice[v].lr_mix, 
  12.398      left=voice[v].left_mix, 
  12.399 -    right=voice[v].right_mix;
  12.400 -  sample_t s;
  12.401 +    center=voice[v].ce_mix, 
  12.402 +    right=voice[v].right_mix, 
  12.403 +    right_rear=voice[v].rr_mix, 
  12.404 +    lfe=voice[v].lfe_mix;
  12.405 +  resample_t s;
  12.406    
  12.407    while (count--)
  12.408      {
  12.409        s = *sp++;
  12.410 -      MIXATION(left);
  12.411 -      MIXATION(right);
  12.412 +	      	MIXATION(left);
  12.413 +	      	MIXATION(right);
  12.414 +		if (num_ochannels >= 4) {
  12.415 +			MIXATION(left_rear);
  12.416 +			MIXATION(right_rear);
  12.417 +		}
  12.418 +		if (num_ochannels == 6) {
  12.419 +			MIXATION(center);
  12.420 +			MIXATION(lfe);
  12.421 +		}
  12.422      }
  12.423  }
  12.424  
  12.425 -static void mix_center(sample_t *sp, int32 *lp, int v, int count)
  12.426 +static void mix_center(resample_t *sp, int32 *lp, int v, int count)
  12.427  {
  12.428    final_volume_t 
  12.429      left=voice[v].left_mix;
  12.430 -  sample_t s;
  12.431 +  resample_t s;
  12.432    
  12.433    while (count--)
  12.434      {
  12.435        s = *sp++;
  12.436 -      MIXATION(left);
  12.437 -      MIXATION(left);
  12.438 +		if (num_ochannels == 2) {
  12.439 +      			MIXATION(left);
  12.440 +      			MIXATION(left);
  12.441 +		}
  12.442 +		else if (num_ochannels == 4) {
  12.443 +      			MIXATION(left);
  12.444 +      			MIXATION(left);
  12.445 +			MIXSKIP;
  12.446 +			MIXSKIP;
  12.447 +		}
  12.448 +		else if (num_ochannels == 6) {
  12.449 +			MIXSKIP;
  12.450 +			MIXSKIP;
  12.451 +			MIXSKIP;
  12.452 +			MIXSKIP;
  12.453 +			MIXATION(left);
  12.454 +			MIXATION(left);
  12.455 +		}
  12.456      }
  12.457  }
  12.458  
  12.459 -static void mix_single(sample_t *sp, int32 *lp, int v, int count)
  12.460 +static void mix_single_left(resample_t *sp, int32 *lp, int v, int count)
  12.461  {
  12.462    final_volume_t 
  12.463      left=voice[v].left_mix;
  12.464 -  sample_t s;
  12.465 +  resample_t s;
  12.466    
  12.467    while (count--)
  12.468      {
  12.469        s = *sp++;
  12.470 -      MIXATION(left);
  12.471 -      lp++;
  12.472 +		if (num_ochannels == 2) {
  12.473 +			MIXATION(left);
  12.474 +      			MIXSKIP;
  12.475 +		}
  12.476 +		if (num_ochannels >= 4) {
  12.477 +			MIXHALF(left);
  12.478 +      			MIXSKIP;
  12.479 +			MIXATION(left);
  12.480 +      			MIXSKIP;
  12.481 +		}
  12.482 +	       	if (num_ochannels == 6) {
  12.483 +      			MIXSKIP;
  12.484 +			MIXATION(left);
  12.485 +		}
  12.486 +    }
  12.487 +}
  12.488 +static void mix_single_right(resample_t *sp, int32 *lp, int v, int count)
  12.489 +{
  12.490 +  final_volume_t 
  12.491 +    left=voice[v].left_mix;
  12.492 +  resample_t s;
  12.493 +  
  12.494 +  while (count--)
  12.495 +    {
  12.496 +      s = *sp++;
  12.497 +		if (num_ochannels == 2) {
  12.498 +      			MIXSKIP;
  12.499 +			MIXATION(left);
  12.500 +		}
  12.501 +		if (num_ochannels >= 4) {
  12.502 +      			MIXSKIP;
  12.503 +			MIXHALF(left);
  12.504 +      			MIXSKIP;
  12.505 +			MIXATION(left);
  12.506 +		}
  12.507 +	       	if (num_ochannels == 6) {
  12.508 +      			MIXSKIP;
  12.509 +			MIXATION(left);
  12.510 +		}
  12.511      }
  12.512  }
  12.513  
  12.514 -static void mix_mono(sample_t *sp, int32 *lp, int v, int count)
  12.515 +static void mix_mono(resample_t *sp, int32 *lp, int v, int count)
  12.516  {
  12.517    final_volume_t 
  12.518      left=voice[v].left_mix;
  12.519 -  sample_t s;
  12.520 +  resample_t s;
  12.521    
  12.522    while (count--)
  12.523      {
  12.524 @@ -424,20 +668,20 @@
  12.525  }
  12.526  
  12.527  /* Ramp a note out in c samples */
  12.528 -static void ramp_out(sample_t *sp, int32 *lp, int v, int32 c)
  12.529 +static void ramp_out(resample_t *sp, int32 *lp, int v, int32 c)
  12.530  {
  12.531  
  12.532    /* should be final_volume_t, but uint8 gives trouble. */
  12.533 -  int32 left, right, li, ri;
  12.534 +  int32 left_rear, left, center, right, right_rear, lfe, li, ri;
  12.535  
  12.536 -  sample_t s=0; /* silly warning about uninitialized s */
  12.537 +  resample_t s = 0; /* silly warning about uninitialized s */
  12.538  
  12.539    /* Fix by James Caldwell */
  12.540    if ( c == 0 ) c = 1;
  12.541  
  12.542 -  left=voice[v].left_mix;
  12.543 -  li=-(left/c);
  12.544 -  if (!li) li=-1;
  12.545 +  left = voice[v].left_mix;
  12.546 +  li = -(left/c);
  12.547 +  if (!li) li = -1;
  12.548  
  12.549    /* printf("Ramping out: left=%d, c=%d, li=%d\n", left, c, li); */
  12.550  
  12.551 @@ -445,19 +689,32 @@
  12.552      {
  12.553        if (voice[v].panned==PANNED_MYSTERY)
  12.554  	{
  12.555 +	  left_rear = voice[v].lr_mix;
  12.556 +	  center=voice[v].ce_mix;
  12.557  	  right=voice[v].right_mix;
  12.558 +	  right_rear = voice[v].rr_mix;
  12.559 +	  lfe = voice[v].lfe_mix;
  12.560 +
  12.561  	  ri=-(right/c);
  12.562  	  while (c--)
  12.563  	    {
  12.564 -	      left += li;
  12.565 -	      if (left<0)
  12.566 -		left=0;
  12.567 -	      right += ri;
  12.568 -	      if (right<0)
  12.569 -		right=0;
  12.570 +	      left_rear += li; if (left_rear<0) left_rear=0;
  12.571 +	      left += li; if (left<0) left=0;
  12.572 +	      center += li; if (center<0) center=0;
  12.573 +	      right += ri; if (right<0) right=0;
  12.574 +	      right_rear += ri; if (right_rear<0) right_rear=0;
  12.575 +	      lfe += li; if (lfe<0) lfe=0;
  12.576  	      s=*sp++;
  12.577 -	      MIXATION(left);
  12.578 -	      MIXATION(right);
  12.579 +	      	MIXATION(left);
  12.580 +	      	MIXATION(right);
  12.581 +		if (num_ochannels >= 4) {
  12.582 +			MIXATION(left_rear);
  12.583 +			MIXATION(right_rear);
  12.584 +		}
  12.585 +		if (num_ochannels == 6) {
  12.586 +			MIXATION(center);
  12.587 +			MIXATION(lfe);
  12.588 +		}
  12.589  	    }
  12.590  	}
  12.591        else if (voice[v].panned==PANNED_CENTER)
  12.592 @@ -468,8 +725,24 @@
  12.593  	      if (left<0)
  12.594  		return;
  12.595  	      s=*sp++;	
  12.596 -	      MIXATION(left);
  12.597 -	      MIXATION(left);
  12.598 +		if (num_ochannels == 2) {
  12.599 +	      		MIXATION(left);
  12.600 +	      		MIXATION(left);
  12.601 +		}
  12.602 +		else if (num_ochannels == 4) {
  12.603 +			MIXATION(left);
  12.604 +	      		MIXATION(left);
  12.605 +			MIXSKIP;
  12.606 +			MIXSKIP;
  12.607 +		}
  12.608 +		else if (num_ochannels == 6) {
  12.609 +			MIXSKIP;
  12.610 +			MIXSKIP;
  12.611 +			MIXSKIP;
  12.612 +			MIXSKIP;
  12.613 +	      		MIXATION(left);
  12.614 +	      		MIXATION(left);
  12.615 +		}
  12.616  	    }
  12.617  	}
  12.618        else if (voice[v].panned==PANNED_LEFT)
  12.619 @@ -481,7 +754,14 @@
  12.620  		return;
  12.621  	      s=*sp++;
  12.622  	      MIXATION(left);
  12.623 -	      lp++;
  12.624 +	      MIXSKIP;
  12.625 +		if (num_ochannels >= 4) {
  12.626 +			MIXATION(left);
  12.627 +	      		MIXSKIP;
  12.628 +		} if (num_ochannels == 6) {
  12.629 +			MIXATION(left);
  12.630 +			MIXATION(left);
  12.631 +		}
  12.632  	    }
  12.633  	}
  12.634        else if (voice[v].panned==PANNED_RIGHT)
  12.635 @@ -492,8 +772,15 @@
  12.636  	      if (left<0)
  12.637  		return;
  12.638  	      s=*sp++;
  12.639 -	      lp++;
  12.640 +	      MIXSKIP;
  12.641  	      MIXATION(left);
  12.642 +		if (num_ochannels >= 4) {
  12.643 +	      		MIXSKIP;
  12.644 +			MIXATION(left);
  12.645 +		} if (num_ochannels == 6) {
  12.646 +			MIXATION(left);
  12.647 +			MIXATION(left);
  12.648 +		}
  12.649  	    }
  12.650  	}
  12.651      }
  12.652 @@ -517,52 +804,62 @@
  12.653  void mix_voice(int32 *buf, int v, int32 c)
  12.654  {
  12.655    Voice *vp=voice+v;
  12.656 -  sample_t *sp;
  12.657 +  int32 count=c;
  12.658 +  resample_t *sp;
  12.659 +  if (c<0) return;
  12.660    if (vp->status==VOICE_DIE)
  12.661      {
  12.662 -      if (c>=MAX_DIE_TIME)
  12.663 -	c=MAX_DIE_TIME;
  12.664 -      sp=resample_voice(v, &c);
  12.665 -      ramp_out(sp, buf, v, c);
  12.666 +      if (count>=MAX_DIE_TIME)
  12.667 +	count=MAX_DIE_TIME;
  12.668 +      sp=resample_voice(v, &count);
  12.669 +      ramp_out(sp, buf, v, count);
  12.670        vp->status=VOICE_FREE;
  12.671      }
  12.672    else
  12.673      {
  12.674 -      sp=resample_voice(v, &c);
  12.675 +      sp=resample_voice(v, &count);
  12.676 +      if (count<0) return;
  12.677        if (play_mode->encoding & PE_MONO)
  12.678  	{
  12.679  	  /* Mono output. */
  12.680  	  if (vp->envelope_increment || vp->tremolo_phase_increment)
  12.681 -	    mix_mono_signal(sp, buf, v, c);
  12.682 +	    mix_mono_signal(sp, buf, v, count);
  12.683  	  else
  12.684 -	    mix_mono(sp, buf, v, c);
  12.685 +	    mix_mono(sp, buf, v, count);
  12.686  	}
  12.687        else
  12.688  	{
  12.689  	  if (vp->panned == PANNED_MYSTERY)
  12.690  	    {
  12.691  	      if (vp->envelope_increment || vp->tremolo_phase_increment)
  12.692 -		mix_mystery_signal(sp, buf, v, c);
  12.693 +		mix_mystery_signal(sp, buf, v, count);
  12.694  	      else
  12.695 -		mix_mystery(sp, buf, v, c);
  12.696 +		mix_mystery(sp, buf, v, count);
  12.697  	    }
  12.698  	  else if (vp->panned == PANNED_CENTER)
  12.699  	    {
  12.700  	      if (vp->envelope_increment || vp->tremolo_phase_increment)
  12.701 -		mix_center_signal(sp, buf, v, c);
  12.702 +		mix_center_signal(sp, buf, v, count);
  12.703  	      else
  12.704 -		mix_center(sp, buf, v, c);
  12.705 +		mix_center(sp, buf, v, count);
  12.706  	    }
  12.707  	  else
  12.708  	    { 
  12.709  	      /* It's either full left or full right. In either case,
  12.710  		 every other sample is 0. Just get the offset right: */
  12.711 -	      if (vp->panned == PANNED_RIGHT) buf++;
  12.712  	      
  12.713  	      if (vp->envelope_increment || vp->tremolo_phase_increment)
  12.714 -		mix_single_signal(sp, buf, v, c);
  12.715 +	      {
  12.716 +	        if (vp->panned == PANNED_RIGHT)
  12.717 +			mix_single_right_signal(sp, buf, v, count);
  12.718 +		else mix_single_left_signal(sp, buf, v, count);
  12.719 +	      }
  12.720  	      else 
  12.721 -		mix_single(sp, buf, v, c);
  12.722 +	      {
  12.723 +	        if (vp->panned == PANNED_RIGHT)
  12.724 +			mix_single_right(sp, buf, v, count);
  12.725 +		else mix_single_left(sp, buf, v, count);
  12.726 +	      }
  12.727  	    }
  12.728  	}
  12.729      }
    13.1 --- a/timidity/playmidi.c	Fri Aug 20 19:32:09 2004 +0000
    13.2 +++ b/timidity/playmidi.c	Sat Aug 21 12:27:02 2004 +0000
    13.3 @@ -37,8 +37,27 @@
    13.4  
    13.5  #include "tables.h"
    13.6  
    13.7 -Channel channel[16];
    13.8 +
    13.9 +static int dont_cspline=0;
   13.10 +static int opt_dry = 1;
   13.11 +static int opt_expression_curve = 2;
   13.12 +static int opt_volume_curve = 2;
   13.13 +static int opt_stereo_surround = 0;
   13.14 +static int dont_filter_melodic=1;
   13.15 +static int dont_filter_drums=1;
   13.16 +static int dont_chorus=0;
   13.17 +static int dont_reverb=0;
   13.18 +static int current_interpolation=1;
   13.19 +static int dont_keep_looping=0;
   13.20 +static int voice_reserve=0;
   13.21 +
   13.22 +
   13.23 +Channel channel[MAXCHAN];
   13.24  Voice voice[MAX_VOICES];
   13.25 +signed char drumvolume[MAXCHAN][MAXNOTE];
   13.26 +signed char drumpanpot[MAXCHAN][MAXNOTE];
   13.27 +signed char drumreverberation[MAXCHAN][MAXNOTE];
   13.28 +signed char drumchorusdepth[MAXCHAN][MAXNOTE];
   13.29  
   13.30  int
   13.31      voices=DEFAULT_VOICES;
   13.32 @@ -47,7 +66,7 @@
   13.33      control_ratio=0,
   13.34      amplification=DEFAULT_AMPLIFICATION;
   13.35  
   13.36 -float
   13.37 +FLOAT_T
   13.38      master_volume;
   13.39  
   13.40  int32 drumchannels=DEFAULT_DRUMCHANNELS;
   13.41 @@ -66,11 +85,28 @@
   13.42  static MidiEvent *event_list, *current_event;
   13.43  static int32 sample_count, current_sample;
   13.44  
   13.45 +int GM_System_On=0;
   13.46 +int XG_System_On=0;
   13.47 +int GS_System_On=0;
   13.48 +int XG_System_reverb_type;
   13.49 +int XG_System_chorus_type;
   13.50 +int XG_System_variation_type;
   13.51 +
   13.52 +
   13.53  static void adjust_amplification(void)
   13.54  { 
   13.55 -  master_volume = (float)(amplification) / (float)100.0;
   13.56 +  master_volume = (FLOAT_T)(amplification) / (FLOAT_T)100.0;
   13.57 +  master_volume /= 2;
   13.58  }
   13.59  
   13.60 +
   13.61 +static void adjust_master_volume(int32 vol)
   13.62 +{ 
   13.63 +  master_volume = (double)(vol*amplification) / 1638400.0L;
   13.64 +  master_volume /= 2;
   13.65 +}
   13.66 +
   13.67 +
   13.68  static void reset_voices(void)
   13.69  {
   13.70    int i;
   13.71 @@ -86,6 +122,9 @@
   13.72    channel[c].sustain=0;
   13.73    channel[c].pitchbend=0x2000;
   13.74    channel[c].pitchfactor=0; /* to be computed */
   13.75 +
   13.76 +  channel[c].reverberation = 0;
   13.77 +  channel[c].chorusdepth = 0;
   13.78  }
   13.79  
   13.80  static void redraw_controllers(int c)
   13.81 @@ -99,7 +138,7 @@
   13.82  static void reset_midi(void)
   13.83  {
   13.84    int i;
   13.85 -  for (i=0; i<16; i++)
   13.86 +  for (i=0; i<MAXCHAN; i++)
   13.87      {
   13.88        reset_controllers(i);
   13.89        /* The rest of these are unaffected by the Reset All Controllers event */
   13.90 @@ -107,13 +146,18 @@
   13.91        channel[i].panning=NO_PANNING;
   13.92        channel[i].pitchsens=2;
   13.93        channel[i].bank=0; /* tone bank or drum set */
   13.94 +      channel[i].harmoniccontent=64,
   13.95 +      channel[i].releasetime=64,
   13.96 +      channel[i].attacktime=64,
   13.97 +      channel[i].brightness=64,
   13.98 +      channel[i].sfx=0;
   13.99      }
  13.100    reset_voices();
  13.101  }
  13.102  
  13.103  static void select_sample(int v, Instrument *ip)
  13.104  {
  13.105 -  int32 f, cdiff, diff;
  13.106 +  int32 f, cdiff, diff, midfreq;
  13.107    int s,i;
  13.108    Sample *sp, *closest;
  13.109  
  13.110 @@ -127,16 +171,6 @@
  13.111      }
  13.112  
  13.113    f=voice[v].orig_frequency;
  13.114 -  for (i=0; i<s; i++)
  13.115 -    {
  13.116 -      if (sp->low_freq <= f && sp->high_freq >= f)
  13.117 -	{
  13.118 -	  voice[v].sample=sp;
  13.119 -	  return;
  13.120 -	}
  13.121 -      sp++;
  13.122 -    }
  13.123 -
  13.124    /* 
  13.125       No suitable sample found! We'll select the sample whose root
  13.126       frequency is closest to the one we want. (Actually we should
  13.127 @@ -145,9 +179,14 @@
  13.128  
  13.129    cdiff=0x7FFFFFFF;
  13.130    closest=sp=ip->sample;
  13.131 +  midfreq = (sp->low_freq + sp->high_freq) / 2;
  13.132    for(i=0; i<s; i++)
  13.133      {
  13.134        diff=sp->root_freq - f;
  13.135 +  /*  But the root freq. can perfectly well lie outside the keyrange
  13.136 +   *  frequencies, so let's try:
  13.137 +   */
  13.138 +      /* diff=midfreq - f; */
  13.139        if (diff<0) diff=-diff;
  13.140        if (diff<cdiff)
  13.141  	{
  13.142 @@ -160,6 +199,44 @@
  13.143    return;
  13.144  }
  13.145  
  13.146 +
  13.147 +
  13.148 +static void select_stereo_samples(int v, InstrumentLayer *lp)
  13.149 +{
  13.150 +  Instrument *ip;
  13.151 +  InstrumentLayer *nlp, *bestvel;
  13.152 +  int diffvel, midvel, mindiff;
  13.153 +
  13.154 +/* select closest velocity */
  13.155 +  bestvel = lp;
  13.156 +  mindiff = 500;
  13.157 +  for (nlp = lp; nlp; nlp = nlp->next) {
  13.158 +	midvel = (nlp->hi + nlp->lo)/2;
  13.159 +	if (!midvel) diffvel = 127;
  13.160 +	else if (voice[v].velocity < nlp->lo || voice[v].velocity > nlp->hi)
  13.161 +		diffvel = 200;
  13.162 +	else diffvel = voice[v].velocity - midvel;
  13.163 +	if (diffvel < 0) diffvel = -diffvel;
  13.164 +	if (diffvel < mindiff) {
  13.165 +		mindiff = diffvel;
  13.166 +		bestvel = nlp;
  13.167 +	}
  13.168 +  }
  13.169 +  ip = bestvel->instrument;
  13.170 +
  13.171 +  if (ip->right_sample) {
  13.172 +    ip->sample = ip->right_sample;
  13.173 +    ip->samples = ip->right_samples;
  13.174 +    select_sample(v, ip);
  13.175 +    voice[v].right_sample = voice[v].sample;
  13.176 +  }
  13.177 +  else voice[v].right_sample = 0;
  13.178 +  ip->sample = ip->left_sample;
  13.179 +  ip->samples = ip->left_samples;
  13.180 +  select_sample(v, ip);
  13.181 +}
  13.182 +
  13.183 +
  13.184  static void recompute_freq(int v)
  13.185  {
  13.186    int 
  13.187 @@ -192,7 +269,7 @@
  13.188  	  if (pb<0)
  13.189  	    i=-i;
  13.190  	  channel[voice[v].channel].pitchfactor=
  13.191 -	    (float)(bend_fine[(i>>5) & 0xFF] * bend_coarse[i>>13]);
  13.192 +	    (FLOAT_T)(bend_fine[(i>>5) & 0xFF] * bend_coarse[i>>13]);
  13.193  	}
  13.194        if (pb>0)
  13.195  	voice[v].frequency=
  13.196 @@ -216,27 +293,90 @@
  13.197    voice[v].sample_increment = (int32)(a);
  13.198  }
  13.199  
  13.200 +static int expr_curve[128] = {
  13.201 +	7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 11, 
  13.202 +	11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 
  13.203 +	15, 16, 16, 17, 17, 17, 18, 18, 19, 19, 19, 20, 20, 21, 21, 22, 
  13.204 +	22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 28, 28, 29, 30, 30, 31, 
  13.205 +	32, 32, 33, 34, 35, 35, 36, 37, 38, 39, 39, 40, 41, 42, 43, 44, 
  13.206 +	45, 46, 47, 48, 49, 50, 51, 53, 54, 55, 56, 57, 59, 60, 61, 63, 
  13.207 +	64, 65, 67, 68, 70, 71, 73, 75, 76, 78, 80, 82, 83, 85, 87, 89, 
  13.208 +	91, 93, 95, 97, 99, 102, 104, 106, 109, 111, 113, 116, 118, 121,
  13.209 +	124, 127 
  13.210 +};
  13.211 +
  13.212 +static int panf(int pan, int speaker, int separation)
  13.213 +{
  13.214 +	int val;
  13.215 +	val = abs(pan - speaker);
  13.216 +	val = (val * 127) / separation;
  13.217 +	val = 127 - val;
  13.218 +	if (val < 0) val = 0;
  13.219 +	if (val > 127) val = 127;
  13.220 +	return expr_curve[val];
  13.221 +}
  13.222 +
  13.223 +
  13.224 +static int vcurve[128] = {
  13.225 +0,0,18,29,36,42,47,51,55,58,
  13.226 +60,63,65,67,69,71,73,74,76,77,
  13.227 +79,80,81,82,83,84,85,86,87,88,
  13.228 +89,90,91,92,92,93,94,95,95,96,
  13.229 +97,97,98,99,99,100,100,101,101,102,
  13.230 +103,103,104,104,105,105,106,106,106,107,
  13.231 +107,108,108,109,109,109,110,110,111,111,
  13.232 +111,112,112,112,113,113,114,114,114,115,
  13.233 +115,115,116,116,116,116,117,117,117,118,
  13.234 +118,118,119,119,119,119,120,120,120,120,
  13.235 +121,121,121,122,122,122,122,123,123,123,
  13.236 +123,123,124,124,124,124,125,125,125,125,
  13.237 +126,126,126,126,126,127,127,127
  13.238 +};
  13.239 +
  13.240  static void recompute_amp(int v)
  13.241  {
  13.242    int32 tempamp;
  13.243 +  int chan = voice[v].channel;
  13.244 +  int panning = voice[v].panning;
  13.245 +  int vol = channel[chan].volume;
  13.246 +  int expr = channel[chan].expression;
  13.247 +  int vel = vcurve[voice[v].velocity];
  13.248 +  int drumpan = NO_PANNING;
  13.249 +  FLOAT_T curved_expression, curved_volume;
  13.250 +
  13.251 +  if (channel[chan].kit)
  13.252 +   {
  13.253 +    int note = voice[v].sample->note_to_use;
  13.254 +    if (note>0 && drumvolume[chan][note]>=0) vol = drumvolume[chan][note];
  13.255 +    if (note>0 && drumpanpot[chan][note]>=0) panning = drumvolume[chan][note];
  13.256 +   }
  13.257 +
  13.258 +  if (opt_expression_curve == 2) curved_expression = 127.0 * vol_table[expr];
  13.259 +  else if (opt_expression_curve == 1) curved_expression = 127.0 * expr_table[expr];
  13.260 +  else curved_expression = (FLOAT_T)expr;
  13.261 +
  13.262 +  if (opt_volume_curve == 2) curved_volume = 127.0 * vol_table[vol];
  13.263 +  else if (opt_volume_curve == 1) curved_volume = 127.0 * expr_table[vol];
  13.264 +  else curved_volume = (FLOAT_T)vol;
  13.265 +
  13.266 +  tempamp= (int32)((FLOAT_T)vel * curved_volume * curved_expression); /* 21 bits */
  13.267  
  13.268    /* TODO: use fscale */
  13.269  
  13.270 -  tempamp= (voice[v].velocity *
  13.271 -	    channel[voice[v].channel].volume * 
  13.272 -	    channel[voice[v].channel].expression); /* 21 bits */
  13.273 -
  13.274 -  if (!(play_mode->encoding & PE_MONO))
  13.275 +  if (num_ochannels > 1)
  13.276      {
  13.277 -      if (voice[v].panning > 60 && voice[v].panning < 68)
  13.278 +      if (panning > 60 && panning < 68)
  13.279  	{
  13.280  	  voice[v].panned=PANNED_CENTER;
  13.281  
  13.282 -	  voice[v].left_amp=
  13.283 -	    FSCALENEG((double)(tempamp) * voice[v].sample->volume * master_volume,
  13.284 -		      21);
  13.285 +	  if (num_ochannels == 6) voice[v].left_amp =
  13.286 +		FSCALENEG((double) (tempamp) * voice[v].sample->volume *
  13.287 +			    master_volume, 20);
  13.288 +	  else voice[v].left_amp=
  13.289 +	        FSCALENEG((double)(tempamp) * voice[v].sample->volume *
  13.290 +			    master_volume, 21);
  13.291  	}
  13.292 -      else if (voice[v].panning<5)
  13.293 +      else if (panning<5)
  13.294  	{
  13.295  	  voice[v].panned = PANNED_LEFT;
  13.296  
  13.297 @@ -244,7 +384,7 @@
  13.298  	    FSCALENEG((double)(tempamp) * voice[v].sample->volume * master_volume,
  13.299  		      20);
  13.300  	}
  13.301 -      else if (voice[v].panning>123)
  13.302 +      else if (panning>123)
  13.303  	{
  13.304  	  voice[v].panned = PANNED_RIGHT;
  13.305  
  13.306 @@ -254,13 +394,39 @@
  13.307  	}
  13.308        else
  13.309  	{
  13.310 +	  FLOAT_T refv = (double)(tempamp) * voice[v].sample->volume * master_volume;
  13.311 +	  int wide_panning = 64;
  13.312 +
  13.313 +	  if (num_ochannels == 4) wide_panning = 95;
  13.314 +
  13.315  	  voice[v].panned = PANNED_MYSTERY;
  13.316 +	  voice[v].lfe_amp = FSCALENEG(refv * 64, 27);
  13.317  
  13.318 -	  voice[v].left_amp=
  13.319 -	    FSCALENEG((double)(tempamp) * voice[v].sample->volume * master_volume,
  13.320 -		      27);
  13.321 -	  voice[v].right_amp=voice[v].left_amp * (voice[v].panning);
  13.322 -	  voice[v].left_amp *= (float)(127-voice[v].panning);
  13.323 +		switch (num_ochannels)
  13.324 +		{
  13.325 +		    case 2:
  13.326 +		      voice[v].lr_amp = 0;
  13.327 +		      voice[v].left_amp = FSCALENEG(refv * (128-panning), 27);
  13.328 +		      voice[v].ce_amp = 0;
  13.329 +		      voice[v].right_amp = FSCALENEG(refv * panning, 27);
  13.330 +		      voice[v].rr_amp = 0;
  13.331 +		      break;
  13.332 +		    case 4:
  13.333 +		      voice[v].lr_amp = FSCALENEG(refv * panf(panning, 0, wide_panning), 27);
  13.334 +		      voice[v].left_amp = FSCALENEG(refv * panf(panning, 32, wide_panning), 27);
  13.335 +		      voice[v].ce_amp = 0;
  13.336 +		      voice[v].right_amp = FSCALENEG(refv * panf(panning, 95, wide_panning), 27);
  13.337 +		      voice[v].rr_amp = FSCALENEG(refv * panf(panning, 128, wide_panning), 27);
  13.338 +		      break;
  13.339 +		    case 6:
  13.340 +		      voice[v].lr_amp = FSCALENEG(refv * panf(panning, 0, wide_panning), 27);
  13.341 +		      voice[v].left_amp = FSCALENEG(refv * panf(panning, 32, wide_panning), 27);
  13.342 +		      voice[v].ce_amp = FSCALENEG(refv * panf(panning, 64, wide_panning), 27);
  13.343 +		      voice[v].right_amp = FSCALENEG(refv * panf(panning, 95, wide_panning), 27);
  13.344 +		      voice[v].rr_amp = FSCALENEG(refv * panf(panning, 128, wide_panning), 27);
  13.345 +		      break;
  13.346 +		}
  13.347 +
  13.348  	}
  13.349      }
  13.350    else
  13.351 @@ -273,54 +439,406 @@
  13.352      }
  13.353  }
  13.354  
  13.355 +
  13.356 +#define NOT_CLONE 0
  13.357 +#define STEREO_CLONE 1
  13.358 +#define REVERB_CLONE 2
  13.359 +#define CHORUS_CLONE 3
  13.360 +
  13.361 +
  13.362 +/* just a variant of note_on() */
  13.363 +static int vc_alloc(int j)
  13.364 +{
  13.365 +  int i=voices; 
  13.366 +
  13.367 +  while (i--)
  13.368 +    {
  13.369 +      if (i == j) continue;
  13.370 +      if (voice[i].status & VOICE_FREE) {
  13.371 +	return i;
  13.372 +      }
  13.373 +    }
  13.374 +  return -1;
  13.375 +}
  13.376 +
  13.377 +static void kill_note(int i);
  13.378 +
  13.379 +static void kill_others(int i)
  13.380 +{
  13.381 +  int j=voices; 
  13.382 +
  13.383 +  if (!voice[i].sample->exclusiveClass) return;
  13.384 +
  13.385 +  while (j--)
  13.386 +    {
  13.387 +      if (voice[j].status & (VOICE_FREE|VOICE_OFF|VOICE_DIE)) continue;
  13.388 +      if (i == j) continue;
  13.389 +      if (voice[i].channel != voice[j].channel) continue;
  13.390 +      if (voice[j].sample->note_to_use)
  13.391 +      {
  13.392 +    	if (voice[j].sample->exclusiveClass != voice[i].sample->exclusiveClass) continue;
  13.393 +        kill_note(j);
  13.394 +      }
  13.395 +    }
  13.396 +}
  13.397 +
  13.398 +
  13.399 +static void clone_voice(Instrument *ip, int v, MidiEvent *e, int clone_type, int variationbank)
  13.400 +{
  13.401 +  int w, k, played_note, chorus=0, reverb=0, milli;
  13.402 +  int chan = voice[v].channel;
  13.403 +
  13.404 +  if (clone_type == STEREO_CLONE) {
  13.405 +	if (!voice[v].right_sample && variationbank != 3) return;
  13.406 +	if (variationbank == 6) return;
  13.407 +  }
  13.408 +
  13.409 +  if (channel[chan].kit) {
  13.410 +	reverb = drumreverberation[chan][voice[v].note];
  13.411 +	chorus = drumchorusdepth[chan][voice[v].note];
  13.412 +  }
  13.413 +  else {
  13.414 +	reverb = channel[chan].reverberation;
  13.415 +	chorus = channel[chan].chorusdepth;
  13.416 +  }
  13.417 +
  13.418 +  if (clone_type == REVERB_CLONE) chorus = 0;
  13.419 +  else if (clone_type == CHORUS_CLONE) reverb = 0;
  13.420 +  else if (clone_type == STEREO_CLONE) reverb = chorus = 0;
  13.421 +
  13.422 +  if (reverb > 127) reverb = 127;
  13.423 +  if (chorus > 127) chorus = 127;
  13.424 +
  13.425 +  if (clone_type == CHORUS_CLONE) {
  13.426 +	 if (variationbank == 32) chorus = 30;
  13.427 +	 else if (variationbank == 33) chorus = 60;
  13.428 +	 else if (variationbank == 34) chorus = 90;
  13.429 +  }
  13.430 +
  13.431 +  chorus /= 2;  /* This is an ad hoc adjustment. */
  13.432 +
  13.433 +  if (!reverb && !chorus && clone_type != STEREO_CLONE) return;
  13.434 +
  13.435 +  if ( (w = vc_alloc(v)) < 0 ) return;
  13.436 +
  13.437 +  voice[w] = voice[v];
  13.438 +  if (clone_type==STEREO_CLONE) voice[v].clone_voice = w;
  13.439 +  voice[w].clone_voice = v;
  13.440 +  voice[w].clone_type = clone_type;
  13.441 +
  13.442 +  voice[w].sample = voice[v].right_sample;
  13.443 +  voice[w].velocity= e->b;
  13.444 +
  13.445 +  milli = play_mode->rate/1000;
  13.446 +
  13.447 +  if (clone_type == STEREO_CLONE) {
  13.448 +    int left, right, leftpan, rightpan;
  13.449 +    int panrequest = voice[v].panning;
  13.450 +    if (variationbank == 3) {
  13.451 +	voice[v].panning = 0;
  13.452 +	voice[w].panning = 127;
  13.453 +    }
  13.454 +    else {
  13.455 +	if (voice[v].sample->panning > voice[w].sample->panning) {
  13.456 +	  left = w;
  13.457 +	  right = v;
  13.458 +	}
  13.459 +	else {
  13.460 +	  left = v;
  13.461 +	  right = w;
  13.462 +	}
  13.463 +#define INSTRUMENT_SEPARATION 12
  13.464 +	leftpan = panrequest - INSTRUMENT_SEPARATION / 2;
  13.465 +	rightpan = leftpan + INSTRUMENT_SEPARATION;
  13.466 +	if (leftpan < 0) {
  13.467 +		leftpan = 0;
  13.468 +		rightpan = leftpan + INSTRUMENT_SEPARATION;
  13.469 +	}
  13.470 +	if (rightpan > 127) {
  13.471 +		rightpan = 127;
  13.472 +		leftpan = rightpan - INSTRUMENT_SEPARATION;
  13.473 +	}
  13.474 +	voice[left].panning = leftpan;
  13.475 +	voice[right].panning = rightpan;
  13.476 +	voice[right].echo_delay = 20 * milli;
  13.477 +    }
  13.478 +  }
  13.479 +
  13.480 +  voice[w].volume = voice[w].sample->volume;
  13.481 +
  13.482 +  if (reverb) {
  13.483 +	if (opt_stereo_surround) {
  13.484 +		if (voice[w].panning > 64) voice[w].panning = 127;
  13.485 +		else voice[w].panning = 0;
  13.486 +	}
  13.487 +	else {
  13.488 +		if (voice[v].panning < 64) voice[w].panning = 64 + reverb/2;
  13.489 +		else voice[w].panning = 64 - reverb/2;
  13.490 +	}
  13.491 +
  13.492 +/* try 98->99 for melodic instruments ? (bit much for percussion) */
  13.493 +	voice[w].volume *= vol_table[(127-reverb)/8 + 98];
  13.494 +
  13.495 +	voice[w].echo_delay += reverb * milli;
  13.496 +	voice[w].envelope_rate[DECAY] *= 2;
  13.497 +	voice[w].envelope_rate[RELEASE] /= 2;
  13.498 +
  13.499 +	if (XG_System_reverb_type >= 0) {
  13.500 +	    int subtype = XG_System_reverb_type & 0x07;
  13.501 +	    int rtype = XG_System_reverb_type >>3;
  13.502 +	    switch (rtype) {
  13.503 +		case 0: /* no effect */
  13.504 +		  break;
  13.505 +		case 1: /* hall */
  13.506 +		  if (subtype) voice[w].echo_delay += 100 * milli;
  13.507 +		  break;
  13.508 +		case 2: /* room */
  13.509 +		  voice[w].echo_delay /= 2;
  13.510 +		  break;
  13.511 +		case 3: /* stage */
  13.512 +		  voice[w].velocity = voice[v].velocity;
  13.513 +		  break;
  13.514 +		case 4: /* plate */
  13.515 +		  voice[w].panning = voice[v].panning;
  13.516 +		  break;
  13.517 +		case 16: /* white room */
  13.518 +		  voice[w].echo_delay = 0;
  13.519 +		  break;
  13.520 +		case 17: /* tunnel */
  13.521 +		  voice[w].echo_delay *= 2;
  13.522 +		  voice[w].velocity /= 2;
  13.523 +		  break;
  13.524 +		case 18: /* canyon */
  13.525 +		  voice[w].echo_delay *= 2;
  13.526 +		  break;
  13.527 +		case 19: /* basement */
  13.528 +		  voice[w].velocity /= 2;
  13.529 +		  break;
  13.530 +	        default: break;
  13.531 +	    }
  13.532 +	}
  13.533 +  }
  13.534 +  played_note = voice[w].sample->note_to_use;
  13.535 +  if (!played_note) {
  13.536 +	played_note = e->a & 0x7f;
  13.537 +	if (variationbank == 35) played_note += 12;
  13.538 +	else if (variationbank == 36) played_note -= 12;
  13.539 +	else if (variationbank == 37) played_note += 7;
  13.540 +	else if (variationbank == 36) played_note -= 7;
  13.541 +  }
  13.542 +#if 0
  13.543 +  played_note = ( (played_note - voice[w].sample->freq_center) * voice[w].sample->freq_scale ) / 1024 +
  13.544 +		voice[w].sample->freq_center;
  13.545 +#endif
  13.546 +  voice[w].note = played_note;
  13.547 +  voice[w].orig_frequency = freq_table[played_note];
  13.548 +
  13.549 +  if (chorus) {
  13.550 +	if (opt_stereo_surround) {
  13.551 +	  if (voice[v].panning < 64) voice[w].panning = voice[v].panning + 32;
  13.552 +	  else voice[w].panning = voice[v].panning - 32;
  13.553 +	}
  13.554 +
  13.555 +	if (!voice[w].vibrato_control_ratio) {
  13.556 +		voice[w].vibrato_control_ratio = 100;
  13.557 +		voice[w].vibrato_depth = 6;
  13.558 +		voice[w].vibrato_sweep = 74;
  13.559 +	}
  13.560 +	voice[w].volume *= 0.40;
  13.561 +	voice[v].volume = voice[w].volume;
  13.562 +	recompute_amp(v);
  13.563 +        apply_envelope_to_amp(v);
  13.564 +	voice[w].vibrato_sweep = chorus/2;
  13.565 +	voice[w].vibrato_depth /= 2;
  13.566 +	if (!voice[w].vibrato_depth) voice[w].vibrato_depth = 2;
  13.567 +	voice[w].vibrato_control_ratio /= 2;
  13.568 +	voice[w].echo_delay += 30 * milli;
  13.569 +
  13.570 +	if (XG_System_chorus_type >= 0) {
  13.571 +	    int subtype = XG_System_chorus_type & 0x07;
  13.572 +	    int chtype = 0x0f & (XG_System_chorus_type >> 3);
  13.573 +	    switch (chtype) {
  13.574 +		case 0: /* no effect */
  13.575 +		  break;
  13.576 +		case 1: /* chorus */
  13.577 +		  chorus /= 3;
  13.578 +		  if(channel[ voice[w].channel ].pitchbend + chorus < 0x2000)
  13.579 +            		voice[w].orig_frequency =
  13.580 +				(uint32)( (FLOAT_T)voice[w].orig_frequency * bend_fine[chorus] );
  13.581 +        	  else voice[w].orig_frequency =
  13.582 +			(uint32)( (FLOAT_T)voice[w].orig_frequency / bend_fine[chorus] );
  13.583 +		  if (subtype) voice[w].vibrato_depth *= 2;
  13.584 +		  break;
  13.585 +		case 2: /* celeste */
  13.586 +		  voice[w].orig_frequency += (voice[w].orig_frequency/128) * chorus;
  13.587 +		  break;
  13.588 +		case 3: /* flanger */
  13.589 +		  voice[w].vibrato_control_ratio = 10;
  13.590 +		  voice[w].vibrato_depth = 100;
  13.591 +		  voice[w].vibrato_sweep = 8;
  13.592 +		  voice[w].echo_delay += 200 * milli;
  13.593 +		  break;
  13.594 +		case 4: /* symphonic : cf Children of the Night /128 bad, /1024 ok */
  13.595 +		  voice[w].orig_frequency += (voice[w].orig_frequency/512) * chorus;
  13.596 +		  voice[v].orig_frequency -= (voice[v].orig_frequency/512) * chorus;
  13.597 +		  recompute_freq(v);
  13.598 +		  break;
  13.599 +		case 8: /* phaser */
  13.600 +		  break;
  13.601 +	      default:
  13.602 +		  break;
  13.603 +	    }
  13.604 +	}
  13.605 +	else {
  13.606 +	    chorus /= 3;
  13.607 +	    if(channel[ voice[w].channel ].pitchbend + chorus < 0x2000)
  13.608 +          	voice[w].orig_frequency =
  13.609 +			(uint32)( (FLOAT_T)voice[w].orig_frequency * bend_fine[chorus] );
  13.610 +            else voice[w].orig_frequency =
  13.611 +		(uint32)( (FLOAT_T)voice[w].orig_frequency / bend_fine[chorus] );
  13.612 +	}
  13.613 +  }
  13.614 +#if 0
  13.615 +  voice[w].loop_start = voice[w].sample->loop_start;
  13.616 +  voice[w].loop_end = voice[w].sample->loop_end;
  13.617 +#endif
  13.618 +  voice[w].echo_delay_count = voice[w].echo_delay;
  13.619 +  if (reverb) voice[w].echo_delay *= 2;
  13.620 +
  13.621 +  recompute_freq(w);
  13.622 +  recompute_amp(w);
  13.623 +  if (voice[w].sample->modes & MODES_ENVELOPE)
  13.624 +    {
  13.625 +      /* Ramp up from 0 */
  13.626 +      voice[w].envelope_stage=ATTACK;
  13.627 +      voice[w].modulation_stage=ATTACK;
  13.628 +      voice[w].envelope_volume=0;
  13.629 +      voice[w].modulation_volume=0;
  13.630 +      voice[w].control_counter=0;
  13.631 +      voice[w].modulation_counter=0;
  13.632 +      recompute_envelope(w);
  13.633 +      /*recompute_modulation(w);*/
  13.634 +    }
  13.635 +  else
  13.636 +    {
  13.637 +      voice[w].envelope_increment=0;
  13.638 +      voice[w].modulation_increment=0;
  13.639 +    }
  13.640 +  apply_envelope_to_amp(w);
  13.641 +}
  13.642 +
  13.643 +
  13.644 +static void xremap(int *banknumpt, int *this_notept, int this_kit) {
  13.645 +	int i, newmap;
  13.646 +	int banknum = *banknumpt;
  13.647 +	int this_note = *this_notept;
  13.648 +	int newbank, newnote;
  13.649 +
  13.650 +	if (!this_kit) {
  13.651 +		if (banknum == SFXBANK && tonebank[SFXBANK]) return;
  13.652 +		if (banknum == SFXBANK && tonebank[120]) *banknumpt = 120;
  13.653 +		return;
  13.654 +	}
  13.655 +
  13.656 +	if (this_kit != 127 && this_kit != 126) return;
  13.657 +
  13.658 +	for (i = 0; i < XMAPMAX; i++) {
  13.659 +		newmap = xmap[i][0];
  13.660 +		if (!newmap) return;
  13.661 +		if (this_kit == 127 && newmap != XGDRUM) continue;
  13.662 +		if (this_kit == 126 && newmap != SFXDRUM1) continue;
  13.663 +		if (xmap[i][1] != banknum) continue;
  13.664 +		if (xmap[i][3] != this_note) continue;
  13.665 +		newbank = xmap[i][2];
  13.666 +		newnote = xmap[i][4];
  13.667 +		if (newbank == banknum && newnote == this_note) return;
  13.668 +		if (!drumset[newbank]) return;
  13.669 +		if (!drumset[newbank]->tone[newnote].layer) return;
  13.670 +		if (drumset[newbank]->tone[newnote].layer == MAGIC_LOAD_INSTRUMENT) return;
  13.671 +		*banknumpt = newbank;
  13.672 +		*this_notept = newnote;
  13.673 +		return;
  13.674 +	}
  13.675 +}
  13.676 +
  13.677 +
  13.678  static void start_note(MidiEvent *e, int i)
  13.679  {
  13.680 +  InstrumentLayer *lp;
  13.681    Instrument *ip;
  13.682 -  int j;
  13.683 +  int j, banknum, ch=e->channel;
  13.684 +  int played_note, drumpan=NO_PANNING;
  13.685 +  int32 rt;
  13.686 +  int attacktime, releasetime, decaytime, variationbank;
  13.687 +  int brightness = channel[ch].brightness;
  13.688 +  int harmoniccontent = channel[ch].harmoniccontent;
  13.689 +  int this_note = e->a;
  13.690 +  int this_velocity = e->b;
  13.691 +  int drumsflag = channel[ch].kit;
  13.692 +  int this_prog = channel[ch].program;
  13.693  
  13.694 -  if (ISDRUMCHANNEL(e->channel))
  13.695 +  if (channel[ch].sfx) banknum=channel[ch].sfx;
  13.696 +  else banknum=channel[ch].bank;
  13.697 +
  13.698 +  voice[i].velocity=this_velocity;
  13.699 +
  13.700 +  if (XG_System_On) xremap(&banknum, &this_note, drumsflag);
  13.701 +  /*   if (current_config_pc42b) pcmap(&banknum, &this_note, &this_prog, &drumsflag); */
  13.702 +
  13.703 +  if (drumsflag)
  13.704      {
  13.705 -      if (!(ip=drumset[channel[e->channel].bank]->tone[e->a].instrument))
  13.706 +      if (!(lp=drumset[banknum]->tone[this_note].layer))
  13.707  	{
  13.708 -	  if (!(ip=drumset[0]->tone[e->a].instrument))
  13.709 +	  if (!(lp=drumset[0]->tone[this_note].layer))
  13.710  	    return; /* No instrument? Then we can't play. */
  13.711  	}
  13.712 -      if (ip->samples != 1)
  13.713 +      ip = lp->instrument;
  13.714 +      if (ip->type == INST_GUS && ip->samples != 1)
  13.715  	{
  13.716  	  ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, 
  13.717  	       "Strange: percussion instrument with %d samples!", ip->samples);
  13.718  	}
  13.719  
  13.720        if (ip->sample->note_to_use) /* Do we have a fixed pitch? */
  13.721 -	voice[i].orig_frequency=freq_table[(int)(ip->sample->note_to_use)];
  13.722 +	{
  13.723 +	  voice[i].orig_frequency=freq_table[(int)(ip->sample->note_to_use)];
  13.724 +	  drumpan=drumpanpot[ch][(int)ip->sample->note_to_use];
  13.725 +	}
  13.726        else
  13.727 -	voice[i].orig_frequency=freq_table[e->a & 0x7F];
  13.728 -      
  13.729 -      /* drums are supposed to have only one sample */
  13.730 -      voice[i].sample=ip->sample;
  13.731 +	voice[i].orig_frequency=freq_table[this_note & 0x7F];
  13.732 +
  13.733      }
  13.734    else
  13.735      {
  13.736 -      if (channel[e->channel].program==SPECIAL_PROGRAM)
  13.737 -	ip=default_instrument;
  13.738 -      else if (!(ip=tonebank[channel[e->channel].bank]->
  13.739 -		 tone[channel[e->channel].program].instrument))
  13.740 +      if (channel[ch].program==SPECIAL_PROGRAM)
  13.741 +	lp=default_instrument;
  13.742 +      else if (!(lp=tonebank[channel[ch].bank]->
  13.743 +		 tone[channel[ch].program].layer))
  13.744  	{
  13.745 -	  if (!(ip=tonebank[0]->tone[channel[e->channel].program].instrument))
  13.746 +	  if (!(lp=tonebank[0]->tone[this_prog].layer))
  13.747  	    return; /* No instrument? Then we can't play. */
  13.748  	}
  13.749 -
  13.750 +      ip = lp->instrument;
  13.751        if (ip->sample->note_to_use) /* Fixed-pitch instrument? */
  13.752  	voice[i].orig_frequency=freq_table[(int)(ip->sample->note_to_use)];
  13.753        else
  13.754 -	voice[i].orig_frequency=freq_table[e->a & 0x7F];
  13.755 -      select_sample(i, ip);
  13.756 +	voice[i].orig_frequency=freq_table[this_note & 0x7F];
  13.757      }
  13.758  
  13.759 +    select_stereo_samples(i, lp);
  13.760 +
  13.761 +  voice[i].starttime = e->time;
  13.762 +  played_note = voice[i].sample->note_to_use;
  13.763 +
  13.764 +  if (!played_note || !drumsflag) played_note = this_note & 0x7f;
  13.765 +#if 0
  13.766 +  played_note = ( (played_note - voice[i].sample->freq_center) * voice[i].sample->freq_scale ) / 1024 +
  13.767 +		voice[i].sample->freq_center;
  13.768 +#endif
  13.769    voice[i].status=VOICE_ON;
  13.770 -  voice[i].channel=e->channel;
  13.771 -  voice[i].note=e->a;
  13.772 -  voice[i].velocity=e->b;
  13.773 +  voice[i].channel=ch;
  13.774 +  voice[i].note=played_note;
  13.775 +  voice[i].velocity=this_velocity;
  13.776    voice[i].sample_offset=0;
  13.777    voice[i].sample_increment=0; /* make sure it isn't negative */
  13.778  
  13.779 @@ -331,41 +849,169 @@
  13.780  
  13.781    voice[i].vibrato_sweep=voice[i].sample->vibrato_sweep_increment;
  13.782    voice[i].vibrato_sweep_position=0;
  13.783 +  voice[i].vibrato_depth=voice[i].sample->vibrato_depth;
  13.784    voice[i].vibrato_control_ratio=voice[i].sample->vibrato_control_ratio;
  13.785    voice[i].vibrato_control_counter=voice[i].vibrato_phase=0;
  13.786 +  voice[i].vibrato_delay = voice[i].sample->vibrato_delay;
  13.787 +
  13.788 +  kill_others(i);
  13.789 +
  13.790    for (j=0; j<VIBRATO_SAMPLE_INCREMENTS; j++)
  13.791      voice[i].vibrato_sample_increment[j]=0;
  13.792  
  13.793 -  if (channel[e->channel].panning != NO_PANNING)
  13.794 -    voice[i].panning=channel[e->channel].panning;
  13.795 +
  13.796 +  attacktime = channel[ch].attacktime;
  13.797 +  releasetime = channel[ch].releasetime;
  13.798 +  decaytime = 64;
  13.799 +  variationbank = channel[ch].variationbank;
  13.800 +
  13.801 +  switch (variationbank) {
  13.802 +	case  8:
  13.803 +		attacktime = 64+32;
  13.804 +		break;
  13.805 +	case 12:
  13.806 +		decaytime = 64-32;
  13.807 +		break;
  13.808 +	case 16:
  13.809 +		brightness = 64+16;
  13.810 +		break;
  13.811 +	case 17:
  13.812 +		brightness = 64+32;
  13.813 +		break;
  13.814 +	case 18:
  13.815 +		brightness = 64-16;
  13.816 +		break;
  13.817 +	case 19:
  13.818 +		brightness = 64-32;
  13.819 +		break;
  13.820 +	case 20:
  13.821 +		harmoniccontent = 64+16;
  13.822 +		break;
  13.823 +#if 0
  13.824 +	case 24:
  13.825 +		voice[i].modEnvToFilterFc=2.0;
  13.826 +      		voice[i].sample->cutoff_freq = 800;
  13.827 +		break;
  13.828 +	case 25:
  13.829 +		voice[i].modEnvToFilterFc=-2.0;
  13.830 +      		voice[i].sample->cutoff_freq = 800;
  13.831 +		break;
  13.832 +	case 27:
  13.833 +		voice[i].modLfoToFilterFc=2.0;
  13.834 +		voice[i].lfo_phase_increment=109;
  13.835 +		voice[i].lfo_sweep=122;
  13.836 +      		voice[i].sample->cutoff_freq = 800;
  13.837 +		break;
  13.838 +	case 28:
  13.839 +		voice[i].modLfoToFilterFc=-2.0;
  13.840 +		voice[i].lfo_phase_increment=109;
  13.841 +		voice[i].lfo_sweep=122;
  13.842 +      		voice[i].sample->cutoff_freq = 800;
  13.843 +		break;
  13.844 +#endif
  13.845 +	default:
  13.846 +		break;
  13.847 +  }
  13.848 +
  13.849 +
  13.850 +  for (j=ATTACK; j<MAXPOINT; j++)
  13.851 +    {
  13.852 +	voice[i].envelope_rate[j]=voice[i].sample->envelope_rate[j];
  13.853 +	voice[i].envelope_offset[j]=voice[i].sample->envelope_offset[j];
  13.854 +    }
  13.855 +
  13.856 +  voice[i].echo_delay=voice[i].envelope_rate[DELAY];
  13.857 +  voice[i].echo_delay_count = voice[i].echo_delay;
  13.858 +
  13.859 +  if (attacktime!=64)
  13.860 +    {
  13.861 +	rt = voice[i].envelope_rate[ATTACK];
  13.862 +	rt = rt + ( (64-attacktime)*rt ) / 100;
  13.863 +	if (rt > 1000) voice[i].envelope_rate[ATTACK] = rt;
  13.864 +    }
  13.865 +  if (releasetime!=64)
  13.866 +    {
  13.867 +	rt = voice[i].envelope_rate[RELEASE];
  13.868 +	rt = rt + ( (64-releasetime)*rt ) / 100;
  13.869 +	if (rt > 1000) voice[i].envelope_rate[RELEASE] = rt;
  13.870 +    }
  13.871 +  if (decaytime!=64)
  13.872 +    {
  13.873 +	rt = voice[i].envelope_rate[DECAY];
  13.874 +	rt = rt + ( (64-decaytime)*rt ) / 100;
  13.875 +	if (rt > 1000) voice[i].envelope_rate[DECAY] = rt;
  13.876 +    }
  13.877 +
  13.878 +  if (channel[ch].panning != NO_PANNING)
  13.879 +    voice[i].panning=channel[ch].panning;
  13.880    else
  13.881      voice[i].panning=voice[i].sample->panning;
  13.882 +  if (drumpan != NO_PANNING)
  13.883 +    voice[i].panning=drumpan;
  13.884 +
  13.885 +  if (variationbank == 1) {
  13.886 +    int pan = voice[i].panning;
  13.887 +    int disturb = 0;
  13.888 +    /* If they're close up (no reverb) and you are behind the pianist,
  13.889 +     * high notes come from the right, so we'll spread piano etc. notes
  13.890 +     * out horizontally according to their pitches.
  13.891 +     */
  13.892 +    if (this_prog < 21) {
  13.893 +	    int n = voice[i].velocity - 32;
  13.894 +	    if (n < 0) n = 0;
  13.895 +	    if (n > 64) n = 64;
  13.896 +	    pan = pan/2 + n;
  13.897 +	}
  13.898 +    /* For other types of instruments, the music sounds more alive if
  13.899 +     * notes come from slightly different directions.  However, instruments
  13.900 +     * do drift around in a sometimes disconcerting way, so the following
  13.901 +     * might not be such a good idea.
  13.902 +     */
  13.903 +    else disturb = (voice[i].velocity/32 % 8) +
  13.904 +	(voice[i].note % 8); /* /16? */
  13.905 +
  13.906 +    if (pan < 64) pan += disturb;
  13.907 +    else pan -= disturb;
  13.908 +    if (pan < 0) pan = 0;
  13.909 +    else if (pan > 127) pan = 127;
  13.910 +    voice[i].panning = pan;
  13.911 +  }
  13.912  
  13.913    recompute_freq(i);
  13.914    recompute_amp(i);
  13.915    if (voice[i].sample->modes & MODES_ENVELOPE)
  13.916      {
  13.917        /* Ramp up from 0 */
  13.918 -      voice[i].envelope_stage=0;
  13.919 +      voice[i].envelope_stage=ATTACK;
  13.920        voice[i].envelope_volume=0;
  13.921        voice[i].control_counter=0;
  13.922        recompute_envelope(i);
  13.923 -      apply_envelope_to_amp(i);
  13.924      }
  13.925    else
  13.926      {
  13.927        voice[i].envelope_increment=0;
  13.928 -      apply_envelope_to_amp(i);
  13.929      }
  13.930 +  apply_envelope_to_amp(i);
  13.931 +
  13.932 +  voice[i].clone_voice = -1;
  13.933 +  voice[i].clone_type = NOT_CLONE;
  13.934 +
  13.935 +  clone_voice(ip, i, e, STEREO_CLONE, variationbank);
  13.936 +  clone_voice(ip, i, e, CHORUS_CLONE, variationbank);
  13.937 +  clone_voice(ip, i, e, REVERB_CLONE, variationbank);
  13.938 +
  13.939    ctl->note(i);
  13.940  }
  13.941  
  13.942  static void kill_note(int i)
  13.943  {
  13.944    voice[i].status=VOICE_DIE;
  13.945 +  if (voice[i].clone_voice >= 0)
  13.946 +	voice[ voice[i].clone_voice ].status=VOICE_DIE;
  13.947    ctl->note(i);
  13.948  }
  13.949  
  13.950 +
  13.951  /* Only one instance of a note can be playing on a single channel. */
  13.952  static void note_on(MidiEvent *e)
  13.953  {
  13.954 @@ -388,12 +1034,12 @@
  13.955        return;
  13.956      }
  13.957    
  13.958 +#if 0
  13.959    /* Look for the decaying note with the lowest volume */
  13.960    i=voices;
  13.961    while (i--)
  13.962      {
  13.963 -      if ((voice[i].status!=VOICE_ON) &&
  13.964 -	  (voice[i].status!=VOICE_DIE))
  13.965 +      if (voice[i].status & ~(VOICE_ON | VOICE_DIE | VOICE_FREE))
  13.966  	{
  13.967  	  v=voice[i].left_mix;
  13.968  	  if ((voice[i].panned==PANNED_MYSTERY) && (voice[i].right_mix>v))
  13.969 @@ -405,14 +1051,45 @@
  13.970  	    }
  13.971  	}
  13.972      }
  13.973 +#endif
  13.974 +
  13.975 +  /* Look for the decaying note with the lowest volume */
  13.976 +  if (lowest==-1)
  13.977 +   {
  13.978 +   i=voices;
  13.979 +   while (i--)
  13.980 +    {
  13.981 +      if ( (voice[i].status & ~(VOICE_ON | VOICE_DIE | VOICE_FREE)) &&
  13.982 +	  (!voice[i].clone_type))
  13.983 +	{
  13.984 +	  v=voice[i].left_mix;
  13.985 +	  if ((voice[i].panned==PANNED_MYSTERY) && (voice[i].right_mix>v))
  13.986 +	    v=voice[i].right_mix;
  13.987 +	  if (v<lv)
  13.988 +	    {
  13.989 +	      lv=v;
  13.990 +	      lowest=i;
  13.991 +	    }
  13.992 +	}
  13.993 +    }
  13.994 +   }
  13.995  
  13.996    if (lowest != -1)
  13.997      {
  13.998 +      int cl = voice[lowest].clone_voice;
  13.999 +
 13.1000        /* This can still cause a click, but if we had a free voice to
 13.1001  	 spare for ramping down this note, we wouldn't need to kill it
 13.1002  	 in the first place... Still, this needs to be fixed. Perhaps
 13.1003  	 we could use a reserve of voices to play dying notes only. */
 13.1004 -      
 13.1005 +
 13.1006 +      if (cl >= 0) {
 13.1007 +	if (voice[cl].clone_type==STEREO_CLONE ||
 13.1008 +		       	(!voice[cl].clone_type && voice[lowest].clone_type==STEREO_CLONE))
 13.1009 +	   voice[cl].status=VOICE_FREE;
 13.1010 +	else if (voice[cl].clone_voice==lowest) voice[cl].clone_voice=-1;
 13.1011 +      }
 13.1012 +
 13.1013        cut_notes++;
 13.1014        voice[lowest].status=VOICE_FREE;
 13.1015        ctl->note(lowest);
 13.1016 @@ -440,11 +1117,19 @@
 13.1017           hits the end of its data (ofs>=data_length). */
 13.1018        voice[i].status=VOICE_OFF;
 13.1019      }
 13.1020 +
 13.1021 +  { int v;
 13.1022 +    if ( (v=voice[i].clone_voice) >= 0)
 13.1023 +      {
 13.1024 +	voice[i].clone_voice = -1;
 13.1025 +        finish_note(v);
 13.1026 +      }
 13.1027 +  }
 13.1028  }
 13.1029  
 13.1030  static void note_off(MidiEvent *e)
 13.1031  {
 13.1032 -  int i=voices;
 13.1033 +  int i=voices, v;
 13.1034    while (i--)
 13.1035      if (voice[i].status==VOICE_ON &&
 13.1036  	voice[i].channel==e->channel &&
 13.1037 @@ -453,6 +1138,13 @@
 13.1038  	if (channel[e->channel].sustain)
 13.1039  	  {
 13.1040  	    voice[i].status=VOICE_SUSTAINED;
 13.1041 +
 13.1042 +    	    if ( (v=voice[i].clone_voice) >= 0)
 13.1043 +	      {
 13.1044 +		if (voice[v].status == VOICE_ON)
 13.1045 +		  voice[v].status=VOICE_SUSTAINED;
 13.1046 +	      }
 13.1047 +
 13.1048  	    ctl->note(i);
 13.1049  	  }
 13.1050  	else
 13.1051 @@ -515,6 +1207,7 @@
 13.1052      if ((voice[i].channel==c) &&
 13.1053  	(voice[i].status==VOICE_ON || voice[i].status==VOICE_SUSTAINED))
 13.1054        {
 13.1055 +	if (voice[i].clone_type != NOT_CLONE) continue;
 13.1056  	voice[i].panning=channel[c].panning;
 13.1057  	recompute_amp(i);
 13.1058  	apply_envelope_to_amp(i);
 13.1059 @@ -576,6 +1269,10 @@
 13.1060  	  channel[current_event->channel].volume=current_event->a;
 13.1061  	  break;
 13.1062  	  
 13.1063 +	case ME_MASTERVOLUME:
 13.1064 +	  adjust_master_volume(current_event->a + (current_event->b <<7));
 13.1065 +	  break;
 13.1066 +	  
 13.1067  	case ME_PAN:
 13.1068  	  channel[current_event->channel].panning=current_event->a;
 13.1069  	  break;
 13.1070 @@ -585,7 +1282,8 @@
 13.1071  	  break;
 13.1072  	  
 13.1073  	case ME_PROGRAM:
 13.1074 -	  if (ISDRUMCHANNEL(current_event->channel))
 13.1075 +	  /* if (ISDRUMCHANNEL(current_event->channel)) */
 13.1076 +	  if (channel[current_event->channel].kit)
 13.1077  	    /* Change drum set */
 13.1078  	    channel[current_event->channel].bank=current_event->a;
 13.1079  	  else
 13.1080 @@ -596,6 +1294,45 @@
 13.1081  	  channel[current_event->channel].sustain=current_event->a;
 13.1082  	  break;
 13.1083  
 13.1084 +
 13.1085 +	case ME_REVERBERATION:
 13.1086 +	  channel[current_event->channel].reverberation=current_event->a;
 13.1087 +	  break;
 13.1088 +
 13.1089 +	case ME_CHORUSDEPTH:
 13.1090 +	  channel[current_event->channel].chorusdepth=current_event->a;
 13.1091 +	  break;
 13.1092 +
 13.1093 +	case ME_HARMONICCONTENT:
 13.1094 +	  channel[current_event->channel].harmoniccontent=current_event->a;
 13.1095 +	  break;
 13.1096 +
 13.1097 +	case ME_RELEASETIME:
 13.1098 +	  channel[current_event->channel].releasetime=current_event->a;
 13.1099 +	  break;
 13.1100 +
 13.1101 +	case ME_ATTACKTIME:
 13.1102 +	  channel[current_event->channel].attacktime=current_event->a;
 13.1103 +	  break;
 13.1104 +
 13.1105 +	case ME_BRIGHTNESS:
 13.1106 +	  channel[current_event->channel].brightness=current_event->a;
 13.1107 +	  break;
 13.1108 +
 13.1109 +	case ME_TONE_KIT:
 13.1110 +	  if (current_event->a==SFX_BANKTYPE)
 13.1111 +		{
 13.1112 +		    channel[current_event->channel].sfx=SFXBANK;
 13.1113 +		    channel[current_event->channel].kit=0;
 13.1114 +		}
 13.1115 +	  else
 13.1116 +		{
 13.1117 +		    channel[current_event->channel].sfx=0;
 13.1118 +		    channel[current_event->channel].kit=current_event->a;
 13.1119 +		}
 13.1120 +	  break;
 13.1121 +
 13.1122 +
 13.1123  	case ME_RESET_CONTROLLERS:
 13.1124  	  reset_controllers(current_event->channel);
 13.1125  	  break;
 13.1126 @@ -702,19 +1439,31 @@
 13.1127      return rc;
 13.1128  }
 13.1129  
 13.1130 -static void do_compute_data(int32 count)
 13.1131 +static void do_compute_data(uint32 count)
 13.1132  {
 13.1133    int i;
 13.1134 -  memset(buffer_pointer, 0, 
 13.1135 -	 (play_mode->encoding & PE_MONO) ? (count * 4) : (count * 8));
 13.1136 +  if (!count) return; /* (gl) */
 13.1137 +  memset(buffer_pointer, 0, count * num_ochannels * 4);
 13.1138    for (i=0; i<voices; i++)
 13.1139      {
 13.1140        if(voice[i].status != VOICE_FREE)
 13.1141 -	mix_voice(buffer_pointer, i, count);
 13.1142 +	{
 13.1143 +	  if (!voice[i].sample_offset && voice[i].echo_delay_count)
 13.1144 +	    {
 13.1145 +		if (voice[i].echo_delay_count >= count) voice[i].echo_delay_count -= count;
 13.1146 +		else
 13.1147 +		  {
 13.1148 +	            mix_voice(buffer_pointer+voice[i].echo_delay_count, i, count-voice[i].echo_delay_count);
 13.1149 +		    voice[i].echo_delay_count = 0;
 13.1150 +		  }
 13.1151 +	    }
 13.1152 +	  else mix_voice(buffer_pointer, i, count);
 13.1153 +	}
 13.1154      }
 13.1155    current_sample += count;
 13.1156  }
 13.1157  
 13.1158 +
 13.1159  /* count=0 means flush remaining buffered data to output device, then
 13.1160     flush the device itself */
 13.1161  static int compute_data(void *stream, int32 count)
 13.1162 @@ -724,7 +1473,7 @@
 13.1163    if ( play_mode->encoding & PE_MONO )
 13.1164      channels = 1;
 13.1165    else
 13.1166 -    channels = 2;
 13.1167 +    channels = num_ochannels;
 13.1168  
 13.1169    if (!count)
 13.1170      {
 13.1171 @@ -751,7 +1500,7 @@
 13.1172      {
 13.1173        do_compute_data(count);
 13.1174        buffered_count += count;
 13.1175 -      buffer_pointer += (play_mode->encoding & PE_MONO) ? count : count*2;
 13.1176 +      buffer_pointer += count * channels;
 13.1177      }
 13.1178    return RC_NONE;
 13.1179  }
 13.1180 @@ -773,6 +1522,7 @@
 13.1181          /* Effects affecting a single note */
 13.1182  
 13.1183          case ME_NOTEON:
 13.1184 +	  current_event->a += channel[current_event->channel].transpose;
 13.1185            if (!(current_event->b)) /* Velocity 0? */
 13.1186              note_off(current_event);
 13.1187            else
 13.1188 @@ -780,6 +1530,7 @@
 13.1189            break;
 13.1190    
 13.1191          case ME_NOTEOFF:
 13.1192 +	  current_event->a += channel[current_event->channel].transpose;
 13.1193            note_off(current_event);
 13.1194            break;
 13.1195    
 13.1196 @@ -809,7 +1560,19 @@
 13.1197            adjust_volume(current_event->channel);
 13.1198            ctl->volume(current_event->channel, current_event->a);
 13.1199            break;
 13.1200 -          
 13.1201 +
 13.1202 +	case ME_MASTERVOLUME:
 13.1203 +	  adjust_master_volume(current_event->a + (current_event->b <<7));
 13.1204 +	  break;
 13.1205 +	      
 13.1206 +	case ME_REVERBERATION:
 13.1207 +	  channel[current_event->channel].reverberation=current_event->a;
 13.1208 +	  break;
 13.1209 +
 13.1210 +	case ME_CHORUSDEPTH:
 13.1211 +	  channel[current_event->channel].chorusdepth=current_event->a;
 13.1212 +	  break;
 13.1213 +
 13.1214          case ME_PAN:
 13.1215            channel[current_event->channel].panning=current_event->a;
 13.1216            if (adjust_panning_immediately)
 13.1217 @@ -824,7 +1587,8 @@
 13.1218            break;
 13.1219    
 13.1220          case ME_PROGRAM:
 13.1221 -          if (ISDRUMCHANNEL(current_event->channel)) {
 13.1222 +          /* if (ISDRUMCHANNEL(current_event->channel)) { */
 13.1223 +	  if (channel[current_event->channel].kit) {
 13.1224              /* Change drum set */
 13.1225              channel[current_event->channel].bank=current_event->a;
 13.1226            }
 13.1227 @@ -854,11 +1618,41 @@
 13.1228          case ME_ALL_SOUNDS_OFF:
 13.1229            all_sounds_off(current_event->channel);
 13.1230            break;
 13.1231 -          
 13.1232 +
 13.1233 +	case ME_HARMONICCONTENT:
 13.1234 +	  channel[current_event->channel].harmoniccontent=current_event->a;
 13.1235 +	  break;
 13.1236 +
 13.1237 +	case ME_RELEASETIME:
 13.1238 +	  channel[current_event->channel].releasetime=current_event->a;
 13.1239 +	  break;
 13.1240 +
 13.1241 +	case ME_ATTACKTIME:
 13.1242 +	  channel[current_event->channel].attacktime=current_event->a;
 13.1243 +	  break;
 13.1244 +
 13.1245 +	case ME_BRIGHTNESS:
 13.1246 +	  channel[current_event->channel].brightness=current_event->a;
 13.1247 +	  break;
 13.1248 +
 13.1249          case ME_TONE_BANK:
 13.1250            channel[current_event->channel].bank=current_event->a;
 13.1251            break;
 13.1252 -  
 13.1253 +
 13.1254 +
 13.1255 +	case ME_TONE_KIT:
 13.1256 +	  if (current_event->a==SFX_BANKTYPE)
 13.1257 +	  {
 13.1258 +	    channel[current_event->channel].sfx=SFXBANK;
 13.1259 +	    channel[current_event->channel].kit=0;
 13.1260 +	  }
 13.1261 +	  else
 13.1262 +	  {
 13.1263 +	    channel[current_event->channel].sfx=0;
 13.1264 +	    channel[current_event->channel].kit=current_event->a;
 13.1265 +	  }
 13.1266 +	  break;
 13.1267 +
 13.1268          case ME_EOT:
 13.1269            /* Give the last notes a couple of seconds to decay  */
 13.1270            ctl->cmsg(CMSG_INFO, VERB_VERBOSE,
 13.1271 @@ -916,11 +1710,12 @@
 13.1272  
 13.1273    /* Open the file */
 13.1274    fp = open_file(midifile, 1, OF_VERBOSE);
 13.1275 +  strcpy(midi_name, midifile);
 13.1276    if ( fp != NULL ) {
 13.1277      song->events=read_midi_file(fp, &events, &song->samples);
 13.1278      close_file(fp);
 13.1279    }
 13.1280 -  
 13.1281 +
 13.1282    /* Make sure everything is okay */
 13.1283    if (!song->events) {
 13.1284      free(song);
    14.1 --- a/timidity/playmidi.h	Fri Aug 20 19:32:09 2004 +0000
    14.2 +++ b/timidity/playmidi.h	Sat Aug 21 12:27:02 2004 +0000
    14.3 @@ -46,45 +46,83 @@
    14.4  #define ME_TONE_BANK	15
    14.5  
    14.6  #define ME_LYRIC	16
    14.7 +#define ME_TONE_KIT	17
    14.8 +#define ME_MASTERVOLUME	18
    14.9 +#define ME_CHANNEL_PRESSURE 19
   14.10 +
   14.11 +#define ME_HARMONICCONTENT	71
   14.12 +#define ME_RELEASETIME		72
   14.13 +#define ME_ATTACKTIME		73
   14.14 +#define ME_BRIGHTNESS		74
   14.15 +
   14.16 +#define ME_REVERBERATION	91
   14.17 +#define ME_CHORUSDEPTH		93
   14.18  
   14.19  #define ME_EOT		99
   14.20  
   14.21 +
   14.22 +#define SFX_BANKTYPE	64
   14.23 +
   14.24  typedef struct {
   14.25    int
   14.26      bank, program, volume, sustain, panning, pitchbend, expression, 
   14.27      mono, /* one note only on this channel -- not implemented yet */
   14.28 +    /* new stuff */
   14.29 +    variationbank, reverberation, chorusdepth, harmoniccontent,
   14.30 +    releasetime, attacktime, brightness, kit, sfx,
   14.31 +    /* end new */
   14.32      pitchsens;
   14.33 -  /* chorus, reverb... Coming soon to a 300-MHz, eight-way superscalar
   14.34 -     processor near you */
   14.35 -  float
   14.36 +  FLOAT_T
   14.37      pitchfactor; /* precomputed pitch bend factor to save some fdiv's */
   14.38 +  char transpose;
   14.39 +  char *name;
   14.40  } Channel;
   14.41  
   14.42  /* Causes the instrument's default panning to be used. */
   14.43  #define NO_PANNING -1
   14.44 +/* envelope points */
   14.45 +#define MAXPOINT 7
   14.46  
   14.47  typedef struct {
   14.48    uint8
   14.49 -    status, channel, note, velocity;
   14.50 +    status, channel, note, velocity, clone_type;
   14.51    Sample *sample;
   14.52 +  Sample *left_sample;
   14.53 +  Sample *right_sample;
   14.54 +  int32 clone_voice;
   14.55    int32
   14.56      orig_frequency, frequency,
   14.57 -    sample_offset, sample_increment,
   14.58 -    envelope_volume, envelope_target, envelope_increment,
   14.59 -    tremolo_sweep, tremolo_sweep_position,
   14.60 -    tremolo_phase, tremolo_phase_increment,
   14.61 -    vibrato_sweep, vibrato_sweep_position;
   14.62 +    sample_offset, loop_start, loop_end;
   14.63 +  int32
   14.64 +    envelope_volume, modulation_volume;
   14.65 +  int32
   14.66 +    envelope_target, modulation_target;
   14.67 +  int32
   14.68 +    tremolo_sweep, tremolo_sweep_position, tremolo_phase,
   14.69 +    lfo_sweep, lfo_sweep_position, lfo_phase,
   14.70 +    vibrato_sweep, vibrato_sweep_position, vibrato_depth, vibrato_delay,
   14.71 +    starttime, echo_delay_count;
   14.72 +  int32
   14.73 +    echo_delay,
   14.74 +    sample_increment,
   14.75 +    envelope_increment,
   14.76 +    modulation_increment,
   14.77 +    tremolo_phase_increment,
   14.78 +    lfo_phase_increment;
   14.79    
   14.80 -  final_volume_t left_mix, right_mix;
   14.81 +  final_volume_t left_mix, right_mix, lr_mix, rr_mix, ce_mix, lfe_mix;
   14.82  
   14.83 -  float
   14.84 -    left_amp, right_amp, tremolo_volume;
   14.85 +  FLOAT_T
   14.86 +    left_amp, right_amp, lr_amp, rr_amp, ce_amp, lfe_amp,
   14.87 +    volume, tremolo_volume, lfo_volume;
   14.88    int32
   14.89      vibrato_sample_increment[VIBRATO_SAMPLE_INCREMENTS];
   14.90 -  int
   14.91 +  int32
   14.92 +    envelope_rate[MAXPOINT], envelope_offset[MAXPOINT];
   14.93 +  int32
   14.94      vibrato_phase, vibrato_control_ratio, vibrato_control_counter,
   14.95 -    envelope_stage, control_counter, panning, panned;
   14.96 -
   14.97 +    envelope_stage, modulation_stage, control_counter,
   14.98 +    modulation_delay, modulation_counter, panning, panned;
   14.99  } Voice;
  14.100  
  14.101  /* Voice status options: */
  14.102 @@ -101,8 +139,21 @@
  14.103  #define PANNED_CENTER 3
  14.104  /* Anything but PANNED_MYSTERY only uses the left volume */
  14.105  
  14.106 +/* Envelope stages: */
  14.107 +#define ATTACK 0
  14.108 +#define HOLD 1
  14.109 +#define DECAY 2
  14.110 +#define RELEASE 3
  14.111 +#define RELEASEB 4
  14.112 +#define RELEASEC 5
  14.113 +#define DELAY 6
  14.114 +
  14.115  extern Channel channel[16];
  14.116  extern Voice voice[MAX_VOICES];
  14.117 +extern signed char drumvolume[MAXCHAN][MAXNOTE];
  14.118 +extern signed char drumpanpot[MAXCHAN][MAXNOTE];
  14.119 +extern signed char drumreverberation[MAXCHAN][MAXNOTE];
  14.120 +extern signed char drumchorusdepth[MAXCHAN][MAXNOTE];
  14.121  
  14.122  extern int32 control_ratio, amp_with_poly, amplification;
  14.123  extern int32 drumchannels;
  14.124 @@ -111,6 +162,14 @@
  14.125  
  14.126  #define ISDRUMCHANNEL(c) ((drumchannels & (1<<(c))))
  14.127  
  14.128 +extern int GM_System_On;
  14.129 +extern int XG_System_On;
  14.130 +extern int GS_System_On;
  14.131 +
  14.132 +extern int XG_System_reverb_type;
  14.133 +extern int XG_System_chorus_type;
  14.134 +extern int XG_System_variation_type;
  14.135 +
  14.136  extern int play_midi(MidiEvent *el, int32 events, int32 samples);
  14.137  extern int play_midi_file(char *fn);
  14.138  extern void dumb_pass_playing_list(int number_of_files, char *list_of_files[]);
    15.1 --- a/timidity/readmidi.c	Fri Aug 20 19:32:09 2004 +0000
    15.2 +++ b/timidity/readmidi.c	Sat Aug 21 12:27:02 2004 +0000
    15.3 @@ -34,6 +34,18 @@
    15.4  
    15.5  int32 quietchannels=0;
    15.6  
    15.7 +static int midi_port_number;
    15.8 +char midi_name[FILENAME_MAX+1];
    15.9 +
   15.10 +static int track_info, curr_track, curr_title_track;
   15.11 +static char title[128];
   15.12 +
   15.13 +#if MAXCHAN <= 16
   15.14 +#define MERGE_CHANNEL_PORT(ch) ((int)(ch))
   15.15 +#else
   15.16 +#define MERGE_CHANNEL_PORT(ch) ((int)(ch) | (midi_port_number << 4))
   15.17 +#endif
   15.18 +
   15.19  /* to avoid some unnecessary parameter passing */
   15.20  static MidiEventList *evlist;
   15.21  static int32 event_count;
   15.22 @@ -72,6 +84,176 @@
   15.23      }
   15.24  }
   15.25  
   15.26 +
   15.27 +static int sysex(uint32 len, uint8 *syschan, uint8 *sysa, uint8 *sysb, FILE *fp)
   15.28 +{
   15.29 +  unsigned char *s=(unsigned char *)safe_malloc(len);
   15.30 +  int id, model, ch, port, adhi, adlo, cd, dta, dtb, dtc;
   15.31 +  if (len != fread(s, 1, len, fp))
   15.32 +    {
   15.33 +      free(s);
   15.34 +      return 0;
   15.35 +    }
   15.36 +  if (len<5) { free(s); return 0; }
   15.37 +  if (curr_track == curr_title_track && track_info > 1) title[0] = '\0';
   15.38 +  id=s[0]; port=s[1]; model=s[2]; adhi=s[3]; adlo=s[4];
   15.39 +  if (id==0x7e && port==0x7f && model==0x09 && adhi==0x01)
   15.40 +    {
   15.41 +      ctl->cmsg(CMSG_TEXT, VERB_VERBOSE, "GM System On", len);
   15.42 +      GM_System_On=1;
   15.43 +      free(s);
   15.44 +      return 0;
   15.45 +    }
   15.46 +  ch = adlo & 0x0f;
   15.47 +  *syschan=(uint8)ch;
   15.48 +  if (id==0x7f && len==7 && port==0x7f && model==0x04 && adhi==0x01)
   15.49 +    {
   15.50 +      ctl->cmsg(CMSG_TEXT, VERB_DEBUG, "Master Volume %d", s[4]+(s[5]<<7));
   15.51 +      free(s);
   15.52 +      *sysa = s[4];
   15.53 +      *sysb = s[5];
   15.54 +      return ME_MASTERVOLUME;
   15.55 +      /** return s[4]+(s[5]<<7); **/
   15.56 +    }
   15.57 +  if (len<8) { free(s); return 0; }
   15.58 +  port &=0x0f;
   15.59 +  ch = (adlo & 0x0f) | ((port & 0x03) << 4);
   15.60 +  *syschan=(uint8)ch;
   15.61 +  cd=s[5]; dta=s[6];
   15.62 +  if (len >= 8) dtb=s[7];
   15.63 +  else dtb=-1;
   15.64 +  if (len >= 9) dtc=s[8];
   15.65 +  else dtc=-1;
   15.66 +  free(s);
   15.67 +  if (id==0x43 && model==0x4c)
   15.68 +    {
   15.69 +	if (!adhi && !adlo && cd==0x7e && !dta)
   15.70 +	  {
   15.71 +      	    ctl->cmsg(CMSG_TEXT, VERB_VERBOSE, "XG System On", len);
   15.72 +	    XG_System_On=1;
   15.73 +	    #ifdef tplus
   15.74 +	    vol_table = xg_vol_table;
   15.75 +	    #endif
   15.76 +	  }
   15.77 +	else if (adhi == 2 && adlo == 1)
   15.78 +	 {
   15.79 +	    if (dtb==8) dtb=3;
   15.80 +	    switch (cd)
   15.81 +	      {
   15.82 +		case 0x00:
   15.83 +		  XG_System_reverb_type=(dta<<3)+dtb;
   15.84 +		  break;
   15.85 +		case 0x20:
   15.86 +		  XG_System_chorus_type=((dta-64)<<3)+dtb;
   15.87 +		  break;
   15.88 +		case 0x40:
   15.89 +		  XG_System_variation_type=dta;
   15.90 +		  break;
   15.91 +		case 0x5a:
   15.92 +		  /* dta==0 Insertion; dta==1 System */
   15.93 +		  break;
   15.94 +		default: break;
   15.95 +	      }
   15.96 +	 }
   15.97 +	else if (adhi == 8 && cd <= 40)
   15.98 +	 {
   15.99 +	    *sysa = dta & 0x7f;
  15.100 +	    switch (cd)
  15.101 +	      {
  15.102 +		case 0x01: /* bank select MSB */
  15.103 +		  return ME_TONE_KIT;
  15.104 +		  break;
  15.105 +		case 0x02: /* bank select LSB */
  15.106 +		  return ME_TONE_BANK;
  15.107 +		  break;
  15.108 +		case 0x03: /* program number */
  15.109 +	      		/** MIDIEVENT(d->at, ME_PROGRAM, lastchan, a, 0); **/
  15.110 +		  return ME_PROGRAM;
  15.111 +		  break;
  15.112 +		case 0x08: /*  */
  15.113 +		  /* d->channel[adlo&0x0f].transpose = (char)(dta-64); */
  15.114 +		  channel[ch].transpose = (char)(dta-64);
  15.115 +      	    	  ctl->cmsg(CMSG_TEXT, VERB_DEBUG, "transpose channel %d by %d",
  15.116 +			(adlo&0x0f)+1, dta-64);
  15.117 +		  break;
  15.118 +		case 0x0b: /* volume */
  15.119 +		  return ME_MAINVOLUME;
  15.120 +		  break;
  15.121 +		case 0x0e: /* pan */
  15.122 +		  return ME_PAN;
  15.123 +		  break;
  15.124 +		case 0x12: /* chorus send */
  15.125 +		  return ME_CHORUSDEPTH;
  15.126 +		  break;
  15.127 +		case 0x13: /* reverb send */
  15.128 +		  return ME_REVERBERATION;
  15.129 +		  break;
  15.130 +		case 0x14: /* variation send */
  15.131 +		  break;
  15.132 +		case 0x18: /* filter cutoff */
  15.133 +		  return ME_BRIGHTNESS;
  15.134 +		  break;
  15.135 +		case 0x19: /* filter resonance */
  15.136 +		  return ME_HARMONICCONTENT;
  15.137 +		  break;
  15.138 +		default: break;
  15.139 +	      }
  15.140 +	  }
  15.141 +      return 0;
  15.142 +    }
  15.143 +  else if (id==0x41 && model==0x42 && adhi==0x12 && adlo==0x40)
  15.144 +    {
  15.145 +	if (dtc<0) return 0;
  15.146 +	if (!cd && dta==0x7f && !dtb && dtc==0x41)
  15.147 +	  {
  15.148 +      	    ctl->cmsg(CMSG_TEXT, VERB_VERBOSE, "GS System On", len);
  15.149 +	    GS_System_On=1;
  15.150 +	    #ifdef tplus
  15.151 +	    vol_table = gs_vol_table;
  15.152 +	    #endif
  15.153 +	  }
  15.154 +	else if (dta==0x15 && (cd&0xf0)==0x10)
  15.155 +	  {
  15.156 +	    int chan=cd&0x0f;
  15.157 +	    if (!chan) chan=9;
  15.158 +	    else if (chan<10) chan--;
  15.159 +	    chan = MERGE_CHANNEL_PORT(chan);
  15.160 +	    channel[chan].kit=dtb;
  15.161 +	  }
  15.162 +	else if (cd==0x01) switch(dta)
  15.163 +	  {
  15.164 +	    case 0x30:
  15.165 +		switch(dtb)
  15.166 +		  {
  15.167 +		    case 0: XG_System_reverb_type=16+0; break;
  15.168 +		    case 1: XG_System_reverb_type=16+1; break;
  15.169 +		    case 2: XG_System_reverb_type=16+2; break;
  15.170 +		    case 3: XG_System_reverb_type= 8+0; break;
  15.171 +		    case 4: XG_System_reverb_type= 8+1; break;
  15.172 +		    case 5: XG_System_reverb_type=32+0; break;
  15.173 +		    case 6: XG_System_reverb_type=8*17; break;
  15.174 +		    case 7: XG_System_reverb_type=8*18; break;
  15.175 +		  }
  15.176 +		break;
  15.177 +	    case 0x38:
  15.178 +		switch(dtb)
  15.179 +		  {
  15.180 +		    case 0: XG_System_chorus_type= 8+0; break;
  15.181 +		    case 1: XG_System_chorus_type= 8+1; break;
  15.182 +		    case 2: XG_System_chorus_type= 8+2; break;
  15.183 +		    case 3: XG_System_chorus_type= 8+4; break;
  15.184 +		    case 4: XG_System_chorus_type=  -1; break;
  15.185 +		    case 5: XG_System_chorus_type= 8*3; break;
  15.186 +		    case 6: XG_System_chorus_type=  -1; break;
  15.187 +		    case 7: XG_System_chorus_type=  -1; break;
  15.188 +		  }
  15.189 +		break;
  15.190 +	  }
  15.191 +      return 0;
  15.192 +    }
  15.193 +  return 0;
  15.194 +}
  15.195 +
  15.196  /* Print a string from the file, followed by a newline. Any non-ASCII
  15.197     or unprintable characters will be converted to periods. */
  15.198  static int dumpstring(int32 len, char *label)
  15.199 @@ -123,8 +305,15 @@
  15.200        
  15.201        if(me==0xF0 || me == 0xF7) /* SysEx event */
  15.202  	{
  15.203 +	  int32 sret;
  15.204 +	  uint8 sysa=0, sysb=0, syschan=0;
  15.205 +
  15.206  	  len=getvl();
  15.207 -	  skip(fp, len);
  15.208 +	  sret=sysex(len, &syschan, &sysa, &sysb, fp);
  15.209 +	  if (sret)
  15.210 +	   {
  15.211 +	     MIDIEVENT(at, sret, syschan, sysa, sysb);
  15.212 +	   }
  15.213  	}
  15.214        else if(me==0xFF) /* Meta event */
  15.215  	{
  15.216 @@ -140,6 +329,27 @@
  15.217  	  else
  15.218  	    switch(type)
  15.219  	      {
  15.220 +
  15.221 +	      case 0x21: /* MIDI port number */
  15.222 +		if(len == 1)
  15.223 +		{
  15.224 +	  	    fread(&midi_port_number,1,1,fp);
  15.225 +		    if(midi_port_number == EOF)
  15.226 +		    {
  15.227 +			    ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
  15.228 +				      "Warning: \"%s\": Short midi file.",
  15.229 +				      midi_name);
  15.230 +			    return 0;
  15.231 +		    }
  15.232 +		    midi_port_number &= 0x0f;
  15.233 +		    if (midi_port_number)
  15.234 +			ctl->cmsg(CMSG_INFO, VERB_VERBOSE,
  15.235 +			  "(MIDI port number %d)", midi_port_number);
  15.236 +		    midi_port_number &= 0x03;
  15.237 +		}
  15.238 +		else skip(fp, len);
  15.239 +		break;
  15.240 +
  15.241  	      case 0x2F: /* End of Track */
  15.242  		return MAGIC_EOT;
  15.243  
  15.244 @@ -174,8 +384,10 @@
  15.245  	    case 1: /* Note on */
  15.246  	      fread(&b, 1,1, fp);
  15.247  	      b &= 0x7F;
  15.248 +	      if (curr_track == curr_title_track && track_info > 1) title[0] = '\0';
  15.249  	      MIDIEVENT(at, ME_NOTEON, lastchan, a,b);
  15.250  
  15.251 +
  15.252  	    case 2: /* Key Pressure */
  15.253  	      fread(&b, 1,1, fp);
  15.254  	      b &= 0x7F;
  15.255 @@ -192,6 +404,14 @@
  15.256  		  case 10: control=ME_PAN; break;
  15.257  		  case 11: control=ME_EXPRESSION; break;
  15.258  		  case 64: control=ME_SUSTAIN; break;
  15.259 +
  15.260 +		  case 71: control=ME_HARMONICCONTENT; break;
  15.261 +		  case 72: control=ME_RELEASETIME; break;
  15.262 +		  case 73: control=ME_ATTACKTIME; break;
  15.263 +		  case 74: control=ME_BRIGHTNESS; break;
  15.264 +		  case 91: control=ME_REVERBERATION; break;
  15.265 +		  case 93: control=ME_CHORUSDEPTH; break;
  15.266 +
  15.267  		  case 120: control=ME_ALL_SOUNDS_OFF; break;
  15.268  		  case 121: control=ME_RESET_CONTROLLERS; break;
  15.269  		  case 123: control=ME_ALL_NOTES_OFF; break;
  15.270 @@ -202,14 +422,9 @@
  15.271  		       Also, some MIDI files use 0 as some sort of
  15.272  		       continuous controller. This will cause lots of
  15.273  		       warnings about undefined tone banks. */
  15.274 -		  case 0: control=ME_TONE_BANK; break;
  15.275 -		  case 32: 
  15.276 -		    if (b!=0)
  15.277 -		      ctl->cmsg(CMSG_INFO, VERB_DEBUG, 
  15.278 -				"(Strange: tone bank change 0x20%02x)", b);
  15.279 -		    else
  15.280 -		      control=ME_TONE_BANK;
  15.281 -		    break;
  15.282 +		  case 0: if (XG_System_On) control = ME_TONE_KIT; else control=ME_TONE_BANK; break;
  15.283 +
  15.284 +		  case 32: if (XG_System_On) control = ME_TONE_BANK; break;
  15.285  
  15.286  		  case 100: nrpn=0; rpn_msb[lastchan]=b; break;
  15.287  		  case 101: nrpn=0; rpn_lsb[lastchan]=b; break;
  15.288 @@ -219,6 +434,43 @@
  15.289  		  case 6:
  15.290  		    if (nrpn)
  15.291  		      {
  15.292 +			if (rpn_msb[lastchan]==1) switch (rpn_lsb[lastchan])
  15.293 +			 {
  15.294 +#ifdef tplus
  15.295 +			   case 0x08: control=ME_VIBRATO_RATE; break;
  15.296 +			   case 0x09: control=ME_VIBRATO_DEPTH; break;
  15.297 +			   case 0x0a: control=ME_VIBRATO_DELAY; break;
  15.298 +#endif
  15.299 +			   case 0x20: control=ME_BRIGHTNESS; break;
  15.300 +			   case 0x21: control=ME_HARMONICCONTENT; break;
  15.301 +			/*
  15.302 +			   case 0x63: envelope attack rate
  15.303 +			   case 0x64: envelope decay rate
  15.304 +			   case 0x66: envelope release rate
  15.305 +			*/
  15.306 +			 }
  15.307 +			else switch (rpn_msb[lastchan])
  15.308 +			 {
  15.309 +			/*
  15.310 +			   case 0x14: filter cutoff frequency
  15.311 +			   case 0x15: filter resonance
  15.312 +			   case 0x16: envelope attack rate
  15.313 +			   case 0x17: envelope decay rate
  15.314 +			   case 0x18: pitch coarse
  15.315 +			   case 0x19: pitch fine
  15.316 +			*/
  15.317 +			   case 0x1a: drumvolume[lastchan][0x7f & rpn_lsb[lastchan]] = b; break;
  15.318 +			   case 0x1c:
  15.319 +			     if (!b) b=(int) (127.0*rand()/(RAND_MAX));
  15.320 +			     drumpanpot[lastchan][0x7f & rpn_lsb[lastchan]] = b;
  15.321 +			     break;
  15.322 +			   case 0x1d: drumreverberation[lastchan][0x7f & rpn_lsb[lastchan]] = b; break;
  15.323 +			   case 0x1e: drumchorusdepth[lastchan][0x7f & rpn_lsb[lastchan]] = b; break;
  15.324 +			/*
  15.325 +			   case 0x1f: variation send level
  15.326 +			*/
  15.327 +			 }
  15.328 +
  15.329  			ctl->cmsg(CMSG_INFO, VERB_DEBUG, 
  15.330  				  "(Data entry (MSB) for NRPN %02x,%02x: %ld)",
  15.331  				  rpn_msb[lastchan], rpn_lsb[lastchan],
  15.332 @@ -304,7 +556,6 @@
  15.333      at=0;
  15.334  
  15.335    /* Check the formalities */
  15.336 -  
  15.337    if ((fread(tmp,1,4,fp) != 4) || (fread(&len,4,1,fp) != 1))
  15.338      {
  15.339        ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
  15.340 @@ -312,6 +563,7 @@
  15.341        return -1;
  15.342      }
  15.343    len=BE_LONG(len);
  15.344 +
  15.345    if (memcmp(tmp, "MTrk", 4))
  15.346      {
  15.347        ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
  15.348 @@ -358,6 +610,32 @@
  15.349    evlist=0;
  15.350  }
  15.351  
  15.352 +
  15.353 +static void xremap_percussion(int *banknumpt, int *this_notept, int this_kit) {
  15.354 +        int i, newmap;
  15.355 +        int banknum = *banknumpt;
  15.356 +        int this_note = *this_notept;
  15.357 +        int newbank, newnote;
  15.358 +
  15.359 +        if (this_kit != 127 && this_kit != 126) return;
  15.360 +
  15.361 +        for (i = 0; i < XMAPMAX; i++) {
  15.362 +                newmap = xmap[i][0];
  15.363 +                if (!newmap) return;
  15.364 +                if (this_kit == 127 && newmap != XGDRUM) continue;
  15.365 +                if (this_kit == 126 && newmap != SFXDRUM1) continue;
  15.366 +                if (xmap[i][1] != banknum) continue;
  15.367 +                if (xmap[i][3] != this_note) continue;
  15.368 +                newbank = xmap[i][2];
  15.369 +                newnote = xmap[i][4];
  15.370 +                if (newbank == banknum && newnote == this_note) return;
  15.371 +                if (!drumset[newbank]) return;
  15.372 +                *banknumpt = newbank;
  15.373 +                *this_notept = newnote;
  15.374 +                return;
  15.375 +        }
  15.376 +}
  15.377 +
  15.378  /* Allocate an array of MidiEvents and fill it from the linked list of
  15.379     events, marking used instruments for loading. Convert event times to
  15.380     samples: handle tempo changes. Strip unnecessary events from the list.
  15.381 @@ -369,13 +647,17 @@
  15.382    int32 i, our_event_count, tempo, skip_this_event, new_value;
  15.383    int32 sample_cum, samples_to_do, at, st, dt, counting_time;
  15.384  
  15.385 -  int current_bank[16], current_set[16], current_program[16]; 
  15.386 +  int current_bank[MAXCHAN], current_banktype[MAXCHAN], current_set[MAXCHAN],
  15.387 +    current_kit[MAXCHAN], current_program[MAXCHAN];
  15.388    /* Or should each bank have its own current program? */
  15.389 +  int dset, dnote, drumsflag, mprog;
  15.390  
  15.391 -  for (i=0; i<16; i++)
  15.392 +  for (i=0; i<MAXCHAN; i++)
  15.393      {
  15.394        current_bank[i]=0;
  15.395 +      current_banktype[i]=0;
  15.396        current_set[i]=0;
  15.397 +      current_kit[i]=channel[i].kit;
  15.398        current_program[i]=default_program;
  15.399      }
  15.400  
  15.401 @@ -410,15 +692,44 @@
  15.402        else switch (meep->event.type)
  15.403  	{
  15.404  	case ME_PROGRAM:
  15.405 -	  if (ISDRUMCHANNEL(meep->event.channel))
  15.406 +
  15.407 +	  if (current_kit[meep->event.channel])
  15.408  	    {
  15.409 +	      if (current_kit[meep->event.channel]==126)
  15.410 +		{
  15.411 +		  /* note request for 2nd sfx rhythm kit */
  15.412 +		  if (meep->event.a && drumset[SFXDRUM2])
  15.413 +		  {
  15.414 +			 current_kit[meep->event.channel]=125;
  15.415 +			 current_set[meep->event.channel]=SFXDRUM2;
  15.416 +		         new_value=SFXDRUM2;
  15.417 +		  }
  15.418 +		  else if (!meep->event.a && drumset[SFXDRUM1])
  15.419 +		  {
  15.420 +			 current_set[meep->event.channel]=SFXDRUM1;
  15.421 +		         new_value=SFXDRUM1;
  15.422 +		  }
  15.423 +		  else
  15.424 +		  {
  15.425 +		  	ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
  15.426 +		       		"XG SFX drum set is undefined");
  15.427 +			skip_this_event=1;
  15.428 +		  	break;
  15.429 +		  }
  15.430 +		}
  15.431  	      if (drumset[meep->event.a]) /* Is this a defined drumset? */
  15.432  		new_value=meep->event.a;
  15.433  	      else
  15.434  		{
  15.435  		  ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
  15.436  		       "Drum set %d is undefined", meep->event.a);
  15.437 -		  new_value=meep->event.a=0;
  15.438 +		  if (drumset[0])
  15.439 +		      new_value=meep->event.a=0;
  15.440 +		  else
  15.441 +		    {
  15.442 +			skip_this_event=1;
  15.443 +			break;
  15.444 +		    }
  15.445  		}
  15.446  	      if (current_set[meep->event.channel] != new_value)
  15.447  		current_set[meep->event.channel]=new_value;
  15.448 @@ -439,35 +750,141 @@
  15.449  	case ME_NOTEON:
  15.450  	  if (counting_time)
  15.451  	    counting_time=1;
  15.452 -	  if (ISDRUMCHANNEL(meep->event.channel))
  15.453 +
  15.454 +	  drumsflag = current_kit[meep->event.channel];
  15.455 +
  15.456 +	  if (drumsflag) /* percussion channel? */
  15.457  	    {
  15.458 +	      dset = current_set[meep->event.channel];
  15.459 +	      dnote=meep->event.a;
  15.460 +	      if (XG_System_On) xremap_percussion(&dset, &dnote, drumsflag);
  15.461 +
  15.462 +	      /*if (current_config_pc42b) pcmap(&dset, &dnote, &mprog, &drumsflag);*/
  15.463 +
  15.464 +	     if (drumsflag)
  15.465 +	     {
  15.466  	      /* Mark this instrument to be loaded */
  15.467 -	      if (!(drumset[current_set[meep->event.channel]]
  15.468 -		    ->tone[meep->event.a].instrument))
  15.469 -		drumset[current_set[meep->event.channel]]
  15.470 -		  ->tone[meep->event.a].instrument=
  15.471 +	      if (!(drumset[dset]->tone[dnote].layer))
  15.472 +	       {
  15.473 +		drumset[dset]->tone[dnote].layer=
  15.474  		    MAGIC_LOAD_INSTRUMENT;
  15.475 +	       }
  15.476 +	      else drumset[dset]->tone[dnote].last_used
  15.477 +		 = current_tune_number;
  15.478 +	      if (!channel[meep->event.channel].name) channel[meep->event.channel].name=
  15.479 +		    drumset[dset]->name;
  15.480 +	     }
  15.481  	    }
  15.482 -	  else
  15.483 +
  15.484 +	  if (!drumsflag) /* not percussion */
  15.485  	    {
  15.486 -	      if (current_program[meep->event.channel]==SPECIAL_PROGRAM)
  15.487 +	      int chan=meep->event.channel;
  15.488 +	      int banknum;
  15.489 +
  15.490 +	      if (current_banktype[chan]) banknum=SFXBANK;
  15.491 +	      else banknum=current_bank[chan];
  15.492 +
  15.493 +	      mprog = current_program[chan];
  15.494 +
  15.495 +	      if (mprog==SPECIAL_PROGRAM)
  15.496  		break;
  15.497 +
  15.498 +	      if (XG_System_On && banknum==SFXBANK && !tonebank[SFXBANK] && tonebank[120]) 
  15.499 +		      banknum = 120;
  15.500 +
  15.501 +	      /*if (current_config_pc42b) pcmap(&banknum, &dnote, &mprog, &drumsflag);*/
  15.502 +
  15.503 +	     if (drumsflag)
  15.504 +	     {
  15.505  	      /* Mark this instrument to be loaded */
  15.506 -	      if (!(tonebank[current_bank[meep->event.channel]]
  15.507 -		    ->tone[current_program[meep->event.channel]].instrument))
  15.508 -		tonebank[current_bank[meep->event.channel]]
  15.509 -		  ->tone[current_program[meep->event.channel]].instrument=
  15.510 -		    MAGIC_LOAD_INSTRUMENT;
  15.511 +	      if (!(drumset[dset]->tone[dnote].layer))
  15.512 +	       {
  15.513 +		drumset[dset]->tone[dnote].layer=MAGIC_LOAD_INSTRUMENT;
  15.514 +	       }
  15.515 +	      else drumset[dset]->tone[dnote].last_used = current_tune_number;
  15.516 +	      if (!channel[meep->event.channel].name) channel[meep->event.channel].name=
  15.517 +		    drumset[dset]->name;
  15.518 +	     }
  15.519 +	     if (!drumsflag)
  15.520 +	     {
  15.521 +	      /* Mark this instrument to be loaded */
  15.522 +	      if (!(tonebank[banknum]->tone[mprog].layer))
  15.523 +		{
  15.524 +		  tonebank[banknum]->tone[mprog].layer=MAGIC_LOAD_INSTRUMENT;
  15.525 +		}
  15.526 +	      else tonebank[banknum]->tone[mprog].last_used = current_tune_number;
  15.527 +	      if (!channel[meep->event.channel].name) channel[meep->event.channel].name=
  15.528 +		    tonebank[banknum]->tone[mprog].name;
  15.529 +	     }
  15.530  	    }
  15.531  	  break;
  15.532  
  15.533 -	case ME_TONE_BANK:
  15.534 -	  if (ISDRUMCHANNEL(meep->event.channel))
  15.535 +	case ME_TONE_KIT:
  15.536 +	  if (!meep->event.a || meep->event.a == 127)
  15.537 +	    {
  15.538 +	      new_value=meep->event.a;
  15.539 +	      if (current_kit[meep->event.channel] != new_value)
  15.540 +		current_kit[meep->event.channel]=new_value;
  15.541 +	      else 
  15.542 +		skip_this_event=1;
  15.543 +	      break;
  15.544 +	    }
  15.545 +	  else if (meep->event.a == 126)
  15.546 +	    {
  15.547 +	      if (drumset[SFXDRUM1]) /* Is this a defined tone bank? */
  15.548 +	        new_value=meep->event.a;
  15.549 +	      else
  15.550 +		{
  15.551 +	          ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
  15.552 +		   "XG rhythm kit %d is undefined", meep->event.a);
  15.553 +	          skip_this_event=1;
  15.554 +	          break;
  15.555 +		}
  15.556 +	      current_set[meep->event.channel]=SFXDRUM1;
  15.557 +	      current_kit[meep->event.channel]=new_value;
  15.558 +	      break;
  15.559 +	    }
  15.560 +	  else if (meep->event.a != SFX_BANKTYPE)
  15.561 +	    {
  15.562 +	      ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
  15.563 +		   "XG kit %d is impossible", meep->event.a);
  15.564 +	      skip_this_event=1;
  15.565 +	      break;
  15.566 +	    }
  15.567 +
  15.568 +	  if (current_kit[meep->event.channel])
  15.569  	    {
  15.570  	      skip_this_event=1;
  15.571  	      break;
  15.572  	    }
  15.573 -	  if (tonebank[meep->event.a]) /* Is this a defined tone bank? */
  15.574 +	  if (tonebank[SFXBANK] || tonebank[120]) /* Is this a defined tone bank? */
  15.575 +	    new_value=SFX_BANKTYPE;
  15.576 +	  else 
  15.577 +	    {
  15.578 +	      ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
  15.579 +		   "XG Sfx bank is undefined");
  15.580 +	      skip_this_event=1;
  15.581 +	      break;
  15.582 +	    }
  15.583 +	  if (current_banktype[meep->event.channel]!=new_value)
  15.584 +	    current_banktype[meep->event.channel]=new_value;
  15.585 +	  else
  15.586 +	    skip_this_event=1;
  15.587 +	  break;
  15.588 +
  15.589 +	case ME_TONE_BANK:
  15.590 +	  if (current_kit[meep->event.channel])
  15.591 +	    {
  15.592 +	      skip_this_event=1;
  15.593 +	      break;
  15.594 +	    }
  15.595 +	  if (XG_System_On && meep->event.a > 0 && meep->event.a < 48) {
  15.596 +	      channel[meep->event.channel].variationbank=meep->event.a;
  15.597 +	      ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
  15.598 +		   "XG variation bank %d", meep->event.a);
  15.599 +	      new_value=meep->event.a=0;
  15.600 +	  }
  15.601 +	  else if (tonebank[meep->event.a]) /* Is this a defined tone bank? */
  15.602  	    new_value=meep->event.a;
  15.603  	  else 
  15.604  	    {
  15.605 @@ -475,11 +892,20 @@
  15.606  		   "Tone bank %d is undefined", meep->event.a);
  15.607  	      new_value=meep->event.a=0;
  15.608  	    }
  15.609 +
  15.610  	  if (current_bank[meep->event.channel]!=new_value)
  15.611  	    current_bank[meep->event.channel]=new_value;
  15.612  	  else
  15.613  	    skip_this_event=1;
  15.614  	  break;
  15.615 +
  15.616 +	case ME_HARMONICCONTENT:
  15.617 +	  channel[meep->event.channel].harmoniccontent=meep->event.a;
  15.618 +	  break;
  15.619 +	case ME_BRIGHTNESS:
  15.620 +	  channel[meep->event.channel].brightness=meep->event.a;
  15.621 +	  break;
  15.622 +
  15.623  	}
  15.624  
  15.625        /* Recompute time in samples*/
  15.626 @@ -529,6 +955,28 @@
  15.627    at=0;
  15.628    evlist=0;
  15.629  
  15.630 +  GM_System_On=GS_System_On=XG_System_On=0;
  15.631 +  /* vol_table = def_vol_table; */
  15.632 +  XG_System_reverb_type=XG_System_chorus_type=XG_System_variation_type=0;
  15.633 +  memset(&drumvolume,-1,sizeof(drumvolume));
  15.634 +  memset(&drumchorusdepth,-1,sizeof(drumchorusdepth));
  15.635 +  memset(&drumreverberation,-1,sizeof(drumreverberation));
  15.636 +  memset(&drumpanpot,NO_PANNING,sizeof(drumpanpot));
  15.637 +
  15.638 +  for (i=0; i<MAXCHAN; i++)
  15.639 +     {
  15.640 +	if (ISDRUMCHANNEL(i)) channel[i].kit = 127;
  15.641 +	else channel[i].kit = 0;
  15.642 +	channel[i].brightness = 64;
  15.643 +	channel[i].harmoniccontent = 64;
  15.644 +	channel[i].variationbank = 0;
  15.645 +	channel[i].chorusdepth = 0;
  15.646 +	channel[i].reverberation = 0;
  15.647 +	channel[i].transpose = 0;
  15.648 +     }
  15.649 +
  15.650 +past_riff:
  15.651 +
  15.652    if ((fread(tmp,1,4,fp) != 4) || (fread(&len,4,1,fp) != 1))
  15.653      {
  15.654        if (ferror(fp))
  15.655 @@ -542,6 +990,12 @@
  15.656        return 0;
  15.657      }
  15.658    len=BE_LONG(len);
  15.659 +
  15.660 +  if (!memcmp(tmp, "RIFF", 4))
  15.661 +    {
  15.662 +      fread(tmp,1,12,fp);
  15.663 +      goto past_riff;
  15.664 +    }
  15.665    if (memcmp(tmp, "MThd", 4) || len < 6)
  15.666      {
  15.667        ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
  15.668 @@ -554,6 +1008,9 @@
  15.669    fread(&divisions_tmp, 2, 1, fp);
  15.670    format=BE_SHORT(format);
  15.671    tracks=BE_SHORT(tracks);
  15.672 +  track_info = tracks;
  15.673 +  curr_track = 0;
  15.674 +  curr_title_track = -1;
  15.675    divisions_tmp=BE_SHORT(divisions_tmp);
  15.676  
  15.677    if (divisions_tmp<0)
  15.678 @@ -595,6 +1052,7 @@
  15.679  	  free_midi_list();
  15.680  	  return 0;
  15.681  	}
  15.682 +      else curr_track++;
  15.683        break;
  15.684  
  15.685      case 1:
  15.686 @@ -613,6 +1071,7 @@
  15.687  	    free_midi_list();
  15.688  	    return 0;
  15.689  	  }
  15.690 +         else curr_track++;
  15.691        break;
  15.692      }
  15.693    return groom_list(divisions, count, sp);
    16.1 --- a/timidity/readmidi.h	Fri Aug 20 19:32:09 2004 +0000
    16.2 +++ b/timidity/readmidi.h	Sat Aug 21 12:27:02 2004 +0000
    16.3 @@ -29,3 +29,5 @@
    16.4  extern int32 quietchannels;
    16.5  
    16.6  extern MidiEvent *read_midi_file(FILE *mfp, int32 *count, int32 *sp);
    16.7 +
    16.8 +extern char midi_name[FILENAME_MAX+1];
    17.1 --- a/timidity/resample.c	Fri Aug 20 19:32:09 2004 +0000
    17.2 +++ b/timidity/resample.c	Sat Aug 21 12:27:02 2004 +0000
    17.3 @@ -56,11 +56,11 @@
    17.4  #define FINALINTERP if (ofs == le) *dest++=src[ofs>>FRACTION_BITS];
    17.5  /* So it isn't interpolation. At least it's final. */
    17.6  
    17.7 -extern sample_t *resample_buffer;
    17.8 +extern resample_t *resample_buffer;
    17.9  
   17.10  /*************** resampling with fixed increment *****************/
   17.11  
   17.12 -static sample_t *rs_plain(int v, int32 *countptr)
   17.13 +static resample_t *rs_plain(int v, int32 *countptr)
   17.14  {
   17.15  
   17.16    /* Play sample until end, then free the voice. */
   17.17 @@ -68,8 +68,9 @@
   17.18    INTERPVARS;
   17.19    Voice 
   17.20      *vp=&voice[v];
   17.21 +  resample_t 
   17.22 +    *dest=resample_buffer;
   17.23    sample_t 
   17.24 -    *dest=resample_buffer,
   17.25      *src=vp->sample->data;
   17.26    int32 
   17.27      ofs=vp->sample_offset,
   17.28 @@ -78,7 +79,7 @@
   17.29      count=*countptr;
   17.30  
   17.31  #ifdef PRECALC_LOOPS
   17.32 -  int32 i;
   17.33 +  int32 i, j;
   17.34  
   17.35    if (incr<0) incr = -incr; /* In case we're coming out of a bidir loop */
   17.36  
   17.37 @@ -93,7 +94,7 @@
   17.38      } 
   17.39    else count -= i;
   17.40  
   17.41 -  while (i--) 
   17.42 +  for(j = 0; j < i; j++)
   17.43      {
   17.44        RESAMPLATION;
   17.45        ofs += incr;
   17.46 @@ -127,7 +128,7 @@
   17.47    return resample_buffer;
   17.48  }
   17.49  
   17.50 -static sample_t *rs_loop(Voice *vp, int32 count)
   17.51 +static resample_t *rs_loop(Voice *vp, int32 count)
   17.52  {
   17.53  
   17.54    /* Play sample until end-of-loop, skip back and continue. */
   17.55 @@ -138,13 +139,16 @@
   17.56      incr=vp->sample_increment,
   17.57      le=vp->sample->loop_end, 
   17.58      ll=le - vp->sample->loop_start;
   17.59 +  resample_t
   17.60 +    *dest=resample_buffer;
   17.61    sample_t
   17.62 -    *dest=resample_buffer,
   17.63      *src=vp->sample->data;
   17.64  
   17.65  #ifdef PRECALC_LOOPS
   17.66    int32 i;
   17.67 -  
   17.68 + 
   17.69 +  if (ofs < 0 || le < 0) return resample_buffer;
   17.70 +
   17.71    while (count) 
   17.72      {
   17.73        if (ofs >= le)
   17.74 @@ -158,6 +162,7 @@
   17.75  	  count = 0;
   17.76  	} 
   17.77        else count -= i;
   17.78 +      if (i > 0)
   17.79        while (i--) 
   17.80  	{
   17.81  	  RESAMPLATION;
   17.82 @@ -178,7 +183,7 @@
   17.83    return resample_buffer;
   17.84  }
   17.85  
   17.86 -static sample_t *rs_bidir(Voice *vp, int32 count)
   17.87 +static resample_t *rs_bidir(Voice *vp, int32 count)
   17.88  {
   17.89    INTERPVARS;
   17.90    int32 
   17.91 @@ -186,8 +191,9 @@
   17.92      incr=vp->sample_increment,
   17.93      le=vp->sample->loop_end,
   17.94      ls=vp->sample->loop_start;
   17.95 +  resample_t 
   17.96 +    *dest=resample_buffer; 
   17.97    sample_t 
   17.98 -    *dest=resample_buffer, 
   17.99      *src=vp->sample->data;
  17.100  
  17.101  #ifdef PRECALC_LOOPS
  17.102 @@ -362,15 +368,16 @@
  17.103    return (int32) a;
  17.104  }
  17.105  
  17.106 -static sample_t *rs_vib_plain(int v, int32 *countptr)
  17.107 +static resample_t *rs_vib_plain(int v, int32 *countptr)
  17.108  {
  17.109  
  17.110    /* Play sample until end, then free the voice. */
  17.111  
  17.112    INTERPVARS;
  17.113    Voice *vp=&voice[v];
  17.114 +  resample_t 
  17.115 +    *dest=resample_buffer; 
  17.116    sample_t 
  17.117 -    *dest=resample_buffer, 
  17.118      *src=vp->sample->data;
  17.119    int32 
  17.120      le=vp->sample->data_length,
  17.121 @@ -409,7 +416,7 @@
  17.122    return resample_buffer;
  17.123  }
  17.124  
  17.125 -static sample_t *rs_vib_loop(Voice *vp, int32 count)
  17.126 +static resample_t *rs_vib_loop(Voice *vp, int32 count)
  17.127  {
  17.128  
  17.129    /* Play sample until end-of-loop, skip back and continue. */
  17.130 @@ -420,8 +427,9 @@
  17.131      incr=vp->sample_increment, 
  17.132      le=vp->sample->loop_end,
  17.133      ll=le - vp->sample->loop_start;
  17.134 +  resample_t 
  17.135 +    *dest=resample_buffer; 
  17.136    sample_t 
  17.137 -    *dest=resample_buffer, 
  17.138      *src=vp->sample->data;
  17.139    int 
  17.140      cc=vp->vibrato_control_counter;
  17.141 @@ -481,7 +489,7 @@
  17.142    return resample_buffer;
  17.143  }
  17.144  
  17.145 -static sample_t *rs_vib_bidir(Voice *vp, int32 count)
  17.146 +static resample_t *rs_vib_bidir(Voice *vp, int32 count)
  17.147  {
  17.148    INTERPVARS;
  17.149    int32 
  17.150 @@ -489,8 +497,9 @@
  17.151      incr=vp->sample_increment,
  17.152      le=vp->sample->loop_end, 
  17.153      ls=vp->sample->loop_start;
  17.154 +  resample_t 
  17.155 +    *dest=resample_buffer; 
  17.156    sample_t 
  17.157 -    *dest=resample_buffer, 
  17.158      *src=vp->sample->data;
  17.159    int 
  17.160      cc=vp->vibrato_control_counter;
  17.161 @@ -617,7 +626,7 @@
  17.162    return resample_buffer;
  17.163  }
  17.164  
  17.165 -sample_t *resample_voice(int v, int32 *countptr)
  17.166 +resample_t *resample_voice(int v, int32 *countptr)
  17.167  {
  17.168    int32 ofs;
  17.169    uint8 modes;
  17.170 @@ -641,7 +650,7 @@
  17.171        else
  17.172  	vp->sample_offset += *countptr << FRACTION_BITS;
  17.173        
  17.174 -      return vp->sample->data+ofs;
  17.175 +      return (resample_t *)vp->sample->data+ofs;
  17.176      }
  17.177  
  17.178    /* Need to resample. Use the proper function. */
  17.179 @@ -681,7 +690,8 @@
  17.180  {
  17.181    double a, xdiff;
  17.182    int32 incr, ofs, newlen, count;
  17.183 -  int16 *newdata, *dest, *src = (int16 *) sp->data;
  17.184 +  int16 *src = (int16 *) sp->data;
  17.185 +  resample_t *newdata, *dest;
  17.186    int16 v1, v2, v3, v4, *vptr;
  17.187    static const char note_name[12][3] =
  17.188    {
  17.189 @@ -694,7 +704,9 @@
  17.190  
  17.191    a = ((double) (sp->sample_rate) * freq_table[(int) (sp->note_to_use)]) /
  17.192      ((double) (sp->root_freq) * play_mode->rate);
  17.193 +  if (a <= 0) return;
  17.194    newlen = (int32)(sp->data_length / a);
  17.195 +  if (newlen < 0 || (newlen >> FRACTION_BITS) > MAX_SAMPLE_SIZE) return;
  17.196    dest = newdata = safe_malloc(newlen >> (FRACTION_BITS - 1));
  17.197  
  17.198    count = (newlen >> FRACTION_BITS) - 1;
    18.1 --- a/timidity/resample.h	Fri Aug 20 19:32:09 2004 +0000
    18.2 +++ b/timidity/resample.h	Sat Aug 21 12:27:02 2004 +0000
    18.3 @@ -20,5 +20,5 @@
    18.4      resample.h
    18.5  */
    18.6  
    18.7 -extern sample_t *resample_voice(int v, int32 *countptr);
    18.8 +extern resample_t *resample_voice(int v, int32 *countptr);
    18.9  extern void pre_resample(Sample *sp);
    19.1 --- a/timidity/sdl_c.c	Fri Aug 20 19:32:09 2004 +0000
    19.2 +++ b/timidity/sdl_c.c	Sat Aug 21 12:27:02 2004 +0000
    19.3 @@ -84,6 +84,32 @@
    19.4  
    19.5  static int cmsg(int type, int verbosity_level, char *fmt, ...)
    19.6  {
    19.7 +#ifdef GREGS_DEBUG
    19.8 +  va_list ap;
    19.9 +  int flag_newline = 1;
   19.10 +  if ((type==CMSG_TEXT || type==CMSG_INFO || type==CMSG_WARNING) &&
   19.11 +      ctl.verbosity<verbosity_level-1)
   19.12 +    return 0;
   19.13 +  if (*fmt == '~')
   19.14 +    {
   19.15 +      flag_newline = 0;
   19.16 +      fmt++;
   19.17 +    }
   19.18 +  va_start(ap, fmt);
   19.19 +  if (!ctl.opened)
   19.20 +    {
   19.21 +      vfprintf(stderr, fmt, ap);
   19.22 +      if (flag_newline) fprintf(stderr, "\n");
   19.23 +    }
   19.24 +  else
   19.25 +    {
   19.26 +      vfprintf(stderr, fmt, ap);
   19.27 +      if (flag_newline) fprintf(stderr, "\n");
   19.28 +    }
   19.29 +  va_end(ap);
   19.30 +  if (!flag_newline) fflush(stderr);
   19.31 +  return 0;
   19.32 +#else
   19.33    va_list ap;
   19.34    if ((type==CMSG_TEXT || type==CMSG_INFO || type==CMSG_WARNING) &&
   19.35        ctl.verbosity<verbosity_level)
   19.36 @@ -92,6 +118,7 @@
   19.37    vsprintf(timidity_error, fmt, ap);
   19.38    va_end(ap);
   19.39    return 0;
   19.40 +#endif
   19.41  }
   19.42  
   19.43  static void ctl_refresh(void) { }
    20.1 --- a/timidity/tables.c	Fri Aug 20 19:32:09 2004 +0000
    20.2 +++ b/timidity/tables.c	Sat Aug 21 12:27:02 2004 +0000
    20.3 @@ -34,6 +34,7 @@
    20.4  #include "config.h"
    20.5  #include "common.h"
    20.6  #include "tables.h"
    20.7 +#include "instrum.h"
    20.8  
    20.9  int32 freq_table[128]=
   20.10  {
   20.11 @@ -118,6 +119,43 @@
   20.12   0.90643012614631979, 0.93660445864574493, 0.96778327049280244, 1
   20.13  };
   20.14  
   20.15 +
   20.16 +/* v=2.^((x/127-1) * 4) */
   20.17 +FLOAT_T expr_table[128] = {
   20.18 +0.062500000000000000, 0.063879466007418617, 0.065289378838287213, 0.066730410498333517,
   20.19 +0.068203247825430205, 0.069708592816961873, 0.071247162964417632, 0.072819691595368496,
   20.20 +0.074426928222992794, 0.076069638903316056, 0.077748606600335793, 0.079464631559205010,
   20.21 +0.081218531687652529, 0.083011142945821639, 0.084843319744713291, 0.086715935353423396,
   20.22 +0.088629882315368322, 0.090586072873697340, 0.092585439406094330, 0.094628934869176312,
   20.23 +0.096717533252700480, 0.098852230043796174, 0.101034042701443255, 0.103264011141422821,
   20.24 +0.105543198231971461, 0.107872690300375454, 0.110253597650746091, 0.112687055093223104,
   20.25 +0.115174222484858521, 0.117716285282438229, 0.120314455107505686, 0.122969970323856051,
   20.26 +0.125684096627776631, 0.128458127651314785, 0.131293385578860888, 0.134191221777339997,
   20.27 +0.137153017440313080, 0.140180184246293943, 0.143274165031597039, 0.146436434478035005,
   20.28 +0.149668499815795553, 0.152971901541831212, 0.156348214154105547, 0.159799046902044661,
   20.29 +0.163326044553552957, 0.166930888178957210, 0.170615295952254331, 0.174381023970043153,
   20.30 +0.178229867088531585, 0.182163659779017467, 0.186184277002251486, 0.190293635102098180,
   20.31 +0.194493692718921724, 0.198786451723130919, 0.203173958169329677, 0.207658303271526207,
   20.32 +0.212241624399866963, 0.216926106099369798, 0.221713981131142046, 0.226607531536579865,
   20.33 +0.231609089725056033, 0.236721039585614190, 0.241945817623200610, 0.247285914119973582,
   20.34 +0.252743874322244710, 0.258322299653617804, 0.264023848954903828, 0.269851239751401739,
   20.35 +0.275807249548151001, 0.281894717153771790, 0.288116544033524102, 0.294475695692230921,
   20.36 +0.300975203087725074, 0.307618164075491973, 0.314407744885198681, 0.321347181629811129,
   20.37 +0.328439781848020751, 0.335688926080714045, 0.343098069482237422, 0.350670743467224599,
   20.38 +0.358410557393772644, 0.366321200283767356, 0.374406442581179333, 0.382670137949167655,
   20.39 +0.391116225106848792, 0.399748729706605410, 0.408571766252830038, 0.417589540063018294,
   20.40 +0.426806349272146446, 0.436226586881288292, 0.445854742851448105, 0.455695406243607215,
   20.41 +0.465753267406005200, 0.476033120209697069, 0.486539864333452310, 0.497278507599085373,
   20.42 +0.508254168358330150, 0.519472077932396359, 0.530937583105370092, 0.542656148672647887,
   20.43 +0.554633360045617918, 0.566874925913830707, 0.579386680965928047, 0.592174588670625557,
   20.44 +0.605244744119077360, 0.618603376929974136, 0.632256854218762432, 0.646211683632397893,
   20.45 +0.660474516451080240, 0.675052150758448599, 0.689951534681746304, 0.705179769703502823,
   20.46 +0.720744114046307338, 0.736651986132290215, 0.752910968118960744, 0.769528809513084777,
   20.47 +0.786513430864326790, 0.803872927540415394, 0.821615573585632974, 0.839749825664467098,
   20.48 +0.858284327092304622, 0.877227911955088646, 0.896589609319902503, 0.916378647538487301,
   20.49 +0.936604458645744820, 0.957276682855321193, 0.978405173154415220, 1.000000000000000000
   20.50 +};
   20.51 +
   20.52  double bend_fine[256] = {
   20.53   1, 1.0002256593050698, 1.0004513695322617, 1.0006771306930664, 
   20.54   1.0009029427989777, 1.0011288058614922, 1.0013547198921082, 1.0015806849023274,
   20.55 @@ -293,7 +331,7 @@
   20.56  /*
   20.57     looks up sin(2 * Pi * x / 1024)
   20.58  */
   20.59 -float sine(int x)
   20.60 +FLOAT_T sine(int x)
   20.61  {
   20.62    int xx = x & 0xFF;
   20.63    switch ((x>>8) & 0x03)
   20.64 @@ -899,3 +937,200 @@
   20.65  };
   20.66  
   20.67  uint8 *_l2u = _l2u_ + 4096;
   20.68 +
   20.69 +
   20.70 +/*	$Id$   Greg Lee */
   20.71 +int xmap[XMAPMAX][5] = {
   20.72 +{ SFXBANK, 0, 0, 120, 0 },
   20.73 +{ SFXBANK, 0, 1, 120, 1 },
   20.74 +{ SFXBANK, 0, 2, 120, 2 },
   20.75 +{ SFXBANK, 0, 3, 120, 3 },
   20.76 +{ SFXBANK, 0, 4, 120, 4 },
   20.77 +{ SFXBANK, 0, 5, 120, 5 },
   20.78 +{ SFXBANK, 0, 16, 120, 16 },
   20.79 +{ SFXBANK, 0, 32, 120, 32 },
   20.80 +{ SFXBANK, 0, 33, 120, 33 },
   20.81 +{ SFXBANK, 0, 34, 120, 34 },
   20.82 +{ SFXBANK, 0, 35, 120, 35 },
   20.83 +{ SFXBANK, 0, 36, 120, 36 },
   20.84 +{ SFXBANK, 0, 48, 120, 48 },
   20.85 +{ SFXBANK, 0, 49, 120, 49 },
   20.86 +{ SFXBANK, 0, 50, 120, 50 },
   20.87 +{ SFXBANK, 0, 51, 120, 51 },
   20.88 +{ SFXBANK, 0, 52, 120, 52 },
   20.89 +{ SFXBANK, 0, 54, 120, 54 },
   20.90 +{ SFXBANK, 0, 55, 120, 55 },
   20.91 +{ SFXBANK, 0, 64, 120, 64 },
   20.92 +{ SFXBANK, 0, 65, 120, 65 },
   20.93 +{ SFXBANK, 0, 66, 120, 66 },
   20.94 +{ SFXBANK, 0, 67, 120, 67 },
   20.95 +{ SFXBANK, 0, 68, 120, 68 },
   20.96 +{ SFXBANK, 0, 69, 120, 69 },
   20.97 +{ SFXBANK, 0, 70, 120, 70 },
   20.98 +{ SFXBANK, 0, 80, 120, 80 },
   20.99 +{ SFXBANK, 0, 81, 120, 81 },
  20.100 +{ SFXBANK, 0, 82, 120, 82 },
  20.101 +{ SFXBANK, 0, 83, 120, 83 },
  20.102 +{ SFXBANK, 0, 84, 120, 84 },
  20.103 +{ SFXBANK, 0, 85, 120, 85 },
  20.104 +{ SFXBANK, 0, 86, 120, 86 },
  20.105 +{ SFXBANK, 0, 87, 120, 87 },
  20.106 +{ SFXBANK, 0, 88, 120, 88 },
  20.107 +{ SFXBANK, 0, 89, 120, 89 },
  20.108 +{ SFXBANK, 0, 90, 120, 90 },
  20.109 +{ SFXBANK, 0, 96, 120, 96 },
  20.110 +{ SFXBANK, 0, 97, 120, 97 },
  20.111 +{ SFXBANK, 0, 98, 120, 98 },
  20.112 +{ SFXBANK, 0, 99, 120, 99 },
  20.113 +{ SFXBANK, 0, 100, 120, 100 },
  20.114 +{ SFXBANK, 0, 101, 120, 101 },
  20.115 +{ SFXBANK, 0, 112, 120, 112 },
  20.116 +{ SFXBANK, 0, 113, 120, 113 },
  20.117 +{ SFXBANK, 0, 114, 120, 114 },
  20.118 +{ SFXBANK, 0, 115, 120, 115 },
  20.119 +{ SFXDRUM1, 0, 36, 121, 36 },
  20.120 +{ SFXDRUM1, 0, 37, 121, 37 },
  20.121 +{ SFXDRUM1, 0, 38, 121, 38 },
  20.122 +{ SFXDRUM1, 0, 39, 121, 39 },
  20.123 +{ SFXDRUM1, 0, 40, 121, 40 },
  20.124 +{ SFXDRUM1, 0, 41, 121, 41 },
  20.125 +{ SFXDRUM1, 0, 52, 121, 52 },
  20.126 +{ SFXDRUM1, 0, 68, 121, 68 },
  20.127 +{ SFXDRUM1, 0, 69, 121, 69 },
  20.128 +{ SFXDRUM1, 0, 70, 121, 70 },
  20.129 +{ SFXDRUM1, 0, 71, 121, 71 },
  20.130 +{ SFXDRUM1, 0, 72, 121, 72 },
  20.131 +{ SFXDRUM1, 0, 84, 121, 84 },
  20.132 +{ SFXDRUM1, 0, 85, 121, 85 },
  20.133 +{ SFXDRUM1, 0, 86, 121, 86 },
  20.134 +{ SFXDRUM1, 0, 87, 121, 87 },
  20.135 +{ SFXDRUM1, 0, 88, 121, 88 },
  20.136 +{ SFXDRUM1, 0, 90, 121, 90 },
  20.137 +{ SFXDRUM1, 0, 91, 121, 91 },
  20.138 +{ SFXDRUM1, 1, 36, 122, 36 },
  20.139 +{ SFXDRUM1, 1, 37, 122, 37 },
  20.140 +{ SFXDRUM1, 1, 38, 122, 38 },
  20.141 +{ SFXDRUM1, 1, 39, 122, 39 },
  20.142 +{ SFXDRUM1, 1, 40, 122, 40 },
  20.143 +{ SFXDRUM1, 1, 41, 122, 41 },
  20.144 +{ SFXDRUM1, 1, 42, 122, 42 },
  20.145 +{ SFXDRUM1, 1, 52, 122, 52 },
  20.146 +{ SFXDRUM1, 1, 53, 122, 53 },
  20.147 +{ SFXDRUM1, 1, 54, 122, 54 },
  20.148 +{ SFXDRUM1, 1, 55, 122, 55 },
  20.149 +{ SFXDRUM1, 1, 56, 122, 56 },
  20.150 +{ SFXDRUM1, 1, 57, 122, 57 },
  20.151 +{ SFXDRUM1, 1, 58, 122, 58 },
  20.152 +{ SFXDRUM1, 1, 59, 122, 59 },
  20.153 +{ SFXDRUM1, 1, 60, 122, 60 },
  20.154 +{ SFXDRUM1, 1, 61, 122, 61 },
  20.155 +{ SFXDRUM1, 1, 62, 122, 62 },
  20.156 +{ SFXDRUM1, 1, 68, 122, 68 },
  20.157 +{ SFXDRUM1, 1, 69, 122, 69 },
  20.158 +{ SFXDRUM1, 1, 70, 122, 70 },
  20.159 +{ SFXDRUM1, 1, 71, 122, 71 },
  20.160 +{ SFXDRUM1, 1, 72, 122, 72 },
  20.161 +{ SFXDRUM1, 1, 73, 122, 73 },
  20.162 +{ SFXDRUM1, 1, 84, 122, 84 },
  20.163 +{ SFXDRUM1, 1, 85, 122, 85 },
  20.164 +{ SFXDRUM1, 1, 86, 122, 86 },
  20.165 +{ SFXDRUM1, 1, 87, 122, 87 },
  20.166 +{ XGDRUM, 0, 25, 40, 38 },
  20.167 +{ XGDRUM, 0, 26, 40, 40 },
  20.168 +{ XGDRUM, 0, 27, 40, 39 },
  20.169 +{ XGDRUM, 0, 28, 40, 30 },
  20.170 +{ XGDRUM, 0, 29, 0, 25 },
  20.171 +{ XGDRUM, 0, 30, 0, 85 },
  20.172 +{ XGDRUM, 0, 31, 0, 38 },
  20.173 +{ XGDRUM, 0, 32, 0, 37 },
  20.174 +{ XGDRUM, 0, 33, 0, 36 },
  20.175 +{ XGDRUM, 0, 34, 0, 38 },
  20.176 +{ XGDRUM, 0, 62, 0, 101 },
  20.177 +{ XGDRUM, 0, 63, 0, 102 },
  20.178 +{ XGDRUM, 0, 64, 0, 103 },
  20.179 +{ XGDRUM, 8, 25, 40, 38 },
  20.180 +{ XGDRUM, 8, 26, 40, 40 },
  20.181 +{ XGDRUM, 8, 27, 40, 39 },
  20.182 +{ XGDRUM, 8, 28, 40, 40 },
  20.183 +{ XGDRUM, 8, 29, 8, 25 },
  20.184 +{ XGDRUM, 8, 30, 8, 85 },
  20.185 +{ XGDRUM, 8, 31, 8, 38 },
  20.186 +{ XGDRUM, 8, 32, 8, 37 },
  20.187 +{ XGDRUM, 8, 33, 8, 36 },
  20.188 +{ XGDRUM, 8, 34, 8, 38 },
  20.189 +{ XGDRUM, 8, 62, 8, 101 },
  20.190 +{ XGDRUM, 8, 63, 8, 102 },
  20.191 +{ XGDRUM, 8, 64, 8, 103 },
  20.192 +{ XGDRUM, 16, 25, 40, 38 },
  20.193 +{ XGDRUM, 16, 26, 40, 40 },
  20.194 +{ XGDRUM, 16, 27, 40, 39 },
  20.195 +{ XGDRUM, 16, 28, 40, 40 },
  20.196 +{ XGDRUM, 16, 29, 16, 25 },
  20.197 +{ XGDRUM, 16, 30, 16, 85 },
  20.198 +{ XGDRUM, 16, 31, 16, 38 },
  20.199 +{ XGDRUM, 16, 32, 16, 37 },
  20.200 +{ XGDRUM, 16, 33, 16, 36 },
  20.201 +{ XGDRUM, 16, 34, 16, 38 },
  20.202 +{ XGDRUM, 16, 62, 16, 101 },
  20.203 +{ XGDRUM, 16, 63, 16, 102 },
  20.204 +{ XGDRUM, 16, 64, 16, 103 },
  20.205 +{ XGDRUM, 24, 25, 40, 38 },
  20.206 +{ XGDRUM, 24, 26, 40, 40 },
  20.207 +{ XGDRUM, 24, 27, 40, 39 },
  20.208 +{ XGDRUM, 24, 28, 24, 100 },
  20.209 +{ XGDRUM, 24, 29, 24, 25 },
  20.210 +{ XGDRUM, 24, 30, 24, 15 },
  20.211 +{ XGDRUM, 24, 31, 24, 38 },
  20.212 +{ XGDRUM, 24, 32, 24, 37 },
  20.213 +{ XGDRUM, 24, 33, 24, 36 },
  20.214 +{ XGDRUM, 24, 34, 24, 38 },
  20.215 +{ XGDRUM, 24, 62, 24, 101 },
  20.216 +{ XGDRUM, 24, 63, 24, 102 },
  20.217 +{ XGDRUM, 24, 64, 24, 103 },
  20.218 +{ XGDRUM, 24, 78, 0, 17 },
  20.219 +{ XGDRUM, 24, 79, 0, 18 },
  20.220 +{ XGDRUM, 25, 25, 40, 38 },
  20.221 +{ XGDRUM, 25, 26, 40, 40 },
  20.222 +{ XGDRUM, 25, 27, 40, 39 },
  20.223 +{ XGDRUM, 25, 28, 25, 100 },
  20.224 +{ XGDRUM, 25, 29, 25, 25 },
  20.225 +{ XGDRUM, 25, 30, 25, 15 },
  20.226 +{ XGDRUM, 25, 31, 25, 38 },
  20.227 +{ XGDRUM, 25, 32, 25, 37 },
  20.228 +{ XGDRUM, 25, 33, 25, 36 },
  20.229 +{ XGDRUM, 25, 34, 25, 38 },
  20.230 +{ XGDRUM, 25, 78, 0, 17 },
  20.231 +{ XGDRUM, 25, 79, 0, 18 },
  20.232 +{ XGDRUM, 32, 25, 40, 38 },
  20.233 +{ XGDRUM, 32, 26, 40, 40 },
  20.234 +{ XGDRUM, 32, 27, 40, 39 },
  20.235 +{ XGDRUM, 32, 28, 40, 40 },
  20.236 +{ XGDRUM, 32, 29, 32, 25 },
  20.237 +{ XGDRUM, 32, 30, 32, 85 },
  20.238 +{ XGDRUM, 32, 31, 32, 38 },
  20.239 +{ XGDRUM, 32, 32, 32, 37 },
  20.240 +{ XGDRUM, 32, 33, 32, 36 },
  20.241 +{ XGDRUM, 32, 34, 32, 38 },
  20.242 +{ XGDRUM, 32, 62, 32, 101 },
  20.243 +{ XGDRUM, 32, 63, 32, 102 },
  20.244 +{ XGDRUM, 32, 64, 32, 103 },
  20.245 +{ XGDRUM, 40, 25, 40, 38 },
  20.246 +{ XGDRUM, 40, 26, 40, 40 },
  20.247 +{ XGDRUM, 40, 27, 40, 39 },
  20.248 +{ XGDRUM, 40, 28, 40, 40 },
  20.249 +{ XGDRUM, 40, 29, 40, 25 },
  20.250 +{ XGDRUM, 40, 30, 40, 85 },
  20.251 +{ XGDRUM, 40, 31, 40, 39 },
  20.252 +{ XGDRUM, 40, 32, 40, 37 },
  20.253 +{ XGDRUM, 40, 33, 40, 36 },
  20.254 +{ XGDRUM, 40, 34, 40, 38 },
  20.255 +{ XGDRUM, 40, 38, 40, 39 },
  20.256 +{ XGDRUM, 40, 39, 0, 39 },
  20.257 +{ XGDRUM, 40, 40, 40, 38 },
  20.258 +{ XGDRUM, 40, 42, 0, 42 },
  20.259 +{ XGDRUM, 40, 46, 0, 46 },
  20.260 +{ XGDRUM, 40, 62, 40, 101 },
  20.261 +{ XGDRUM, 40, 63, 40, 102 },
  20.262 +{ XGDRUM, 40, 64, 40, 103 },
  20.263 +{ XGDRUM, 40, 87, 40, 87 }
  20.264 +};
    21.1 --- a/timidity/tables.h	Fri Aug 20 19:32:09 2004 +0000
    21.2 +++ b/timidity/tables.h	Sat Aug 21 12:27:02 2004 +0000
    21.3 @@ -21,7 +21,7 @@
    21.4  */
    21.5  
    21.6  #ifdef LOOKUP_SINE
    21.7 -extern float sine(int x);
    21.8 +extern FLOAT_T sine(int x);
    21.9  #else
   21.10  #include <math.h>
   21.11  #define sine(x) (sin((2*PI/1024.0) * (x)))
   21.12 @@ -30,6 +30,7 @@
   21.13  #define SINE_CYCLE_LENGTH 1024
   21.14  extern int32 freq_table[];
   21.15  extern double vol_table[];
   21.16 +extern double expr_table[];
   21.17  extern double bend_fine[];
   21.18  extern double bend_coarse[];
   21.19  extern uint8 *_l2u; /* 13-bit PCM to 8-bit u-law */
   21.20 @@ -43,3 +44,7 @@
   21.21  #endif
   21.22  
   21.23  extern void init_tables(void);
   21.24 +
   21.25 +#define XMAPMAX 800
   21.26 +extern int xmap[XMAPMAX][5];
   21.27 +
    22.1 --- a/timidity/timidity.c	Fri Aug 20 19:32:09 2004 +0000
    22.2 +++ b/timidity/timidity.c	Sat Aug 21 12:27:02 2004 +0000
    22.3 @@ -39,8 +39,9 @@
    22.4  static char def_instr_name[256]="";
    22.5  
    22.6  int AUDIO_BUFFER_SIZE;
    22.7 -sample_t *resample_buffer;
    22.8 +resample_t *resample_buffer;
    22.9  int32 *common_buffer;
   22.10 +int num_ochannels;
   22.11  
   22.12  #define MAXWORDS 10
   22.13  
   22.14 @@ -63,24 +64,28 @@
   22.15     return -1;
   22.16  
   22.17    while (fgets(tmp, sizeof(tmp), fp))
   22.18 -   {
   22.19 -      line++;
   22.20 +  {
   22.21 +    line++;
   22.22      w[words=0]=strtok(tmp, " \t\r\n\240");
   22.23      if (!w[0] || (*w[0]=='#')) continue;
   22.24 -      while (w[words] && (words < MAXWORDS))
   22.25 -  w[++words]=strtok(0," \t\r\n\240");
   22.26 -      if (!strcmp(w[0], "dir"))
   22.27 -  {
   22.28 -    if (words < 2)
   22.29 -     {
   22.30 +    while (w[words] && (words < MAXWORDS))
   22.31 +      {
   22.32 +        w[++words]=strtok(0," \t\r\n\240");
   22.33 +        if (w[words] && w[words][0]=='#') break;
   22.34 +      }
   22.35 +    if (!strcmp(w[0], "map")) continue;
   22.36 +    if (!strcmp(w[0], "dir"))
   22.37 +    {
   22.38 +      if (words < 2)
   22.39 +       {
   22.40          ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
   22.41            "%s: line %d: No directory given\n", name, line);
   22.42          return -2;
   22.43 -     }
   22.44 -    for (i=1; i<words; i++)
   22.45 -      add_to_pathlist(w[i]);
   22.46 -  }
   22.47 -    else if (!strcmp(w[0], "source"))
   22.48 +       }
   22.49 +      for (i=1; i<words; i++)
   22.50 +        add_to_pathlist(w[i]);
   22.51 +    }
   22.52 +  else if (!strcmp(w[0], "source"))
   22.53    {
   22.54      if (words < 2)
   22.55        {
   22.56 @@ -293,6 +298,10 @@
   22.57      return(-1);
   22.58    }
   22.59  
   22.60 +  if (channels < 1 || channels == 3 || channels == 5 || channels > 6) return(-1);
   22.61 +
   22.62 +  num_ochannels = channels;
   22.63 +
   22.64    /* Set play mode parameters */
   22.65    play_mode->rate = rate;
   22.66    play_mode->encoding = 0;
   22.67 @@ -331,8 +340,8 @@
   22.68    AUDIO_BUFFER_SIZE = samples;
   22.69  
   22.70    /* Allocate memory for mixing (WARNING:  Memory leak!) */
   22.71 -  resample_buffer = safe_malloc(AUDIO_BUFFER_SIZE*sizeof(sample_t));
   22.72 -  common_buffer = safe_malloc(AUDIO_BUFFER_SIZE*2*sizeof(int32));
   22.73 +  resample_buffer = safe_malloc(AUDIO_BUFFER_SIZE*sizeof(resample_t)+100);
   22.74 +  common_buffer = safe_malloc(AUDIO_BUFFER_SIZE*num_ochannels*sizeof(int32));
   22.75  
   22.76    init_tables();
   22.77