fix line endings
[drnoksnes] / sounduxnew.cpp
1 /*
2  * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3  *
4  * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and
5  *                           Jerremy Koot (jkoot@snes9x.com)
6  *
7  * Super FX C emulator code 
8  * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and
9  *                           Gary Henderson.
10  * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
11  *
12  * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson.
13  * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_.
14  * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com).
15  *
16  * DOS port code contains the works of other authors. See headers in
17  * individual files.
18  *
19  * Snes9x homepage: http://www.snes9x.com
20  *
21  * Permission to use, copy, modify and distribute Snes9x in both binary and
22  * source form, for non-commercial purposes, is hereby granted without fee,
23  * providing that this license information and copyright notice appear with
24  * all copies and any derived work.
25  *
26  * This software is provided 'as-is', without any express or implied
27  * warranty. In no event shall the authors be held liable for any damages
28  * arising from the use of this software.
29  *
30  * Snes9x is freeware for PERSONAL USE only. Commercial users should
31  * seek permission of the copyright holders first. Commercial use includes
32  * charging money for Snes9x or software derived from Snes9x.
33  *
34  * The copyright holders request that bug fixes and improvements to the code
35  * should be forwarded to them so everyone can benefit from the modifications
36  * in future versions.
37  *
38  * Super NES and Super Nintendo Entertainment System are trademarks of
39  * Nintendo Co., Limited and its subsidiary companies.
40  */
41 #ifdef __DJGPP__
42 //#include <allegro.h>
43 #undef TRUE
44 #endif
45
46 #include <stdlib.h>
47 #include <stdio.h>
48 #include <string.h>
49 #ifndef _SNESPPC
50 #include <errno.h>
51 #include <fcntl.h>
52 #endif
53
54 #define CLIP16(v) \
55 if ((v) < -32768) \
56     (v) = -32768; \
57 else \
58 if ((v) > 32767) \
59     (v) = 32767
60
61 #define CLIP16_latch(v,l) \
62 if ((v) < -32768) \
63 { (v) = -32768; (l)++; }\
64 else \
65 if ((v) > 32767) \
66 { (v) = 32767; (l)++; }
67
68 #define CLIP24(v) \
69 if ((v) < -8388608) \
70     (v) = -8388608; \
71 else \
72 if ((v) > 8388607) \
73     (v) = 8388607
74
75 #define CLIP8(v) \
76 if ((v) < -128) \
77     (v) = -128; \
78 else \
79 if ((v) > 127) \
80     (v) = 127
81
82 #include "snes9x.h"
83 #include "soundux.h"
84 #include "apu.h"
85 #include "memmap.h"
86 #include "cpuexec.h"
87
88
89 extern int Echo [24000];
90 extern int DummyEchoBuffer [SOUND_BUFFER_SIZE];
91 extern int MixBuffer [SOUND_BUFFER_SIZE];
92 extern int EchoBuffer [SOUND_BUFFER_SIZE];
93 extern int FilterTaps [8];
94 extern unsigned long Z;
95 extern int Loop [16];
96
97 extern long FilterValues[4][2];
98 extern int NoiseFreq [32];
99
100 #undef ABS
101 #define ABS(a) ((a) < 0 ? -(a) : (a))
102
103 #define FIXED_POINT 0x10000UL
104 #define FIXED_POINT_REMAINDER 0xffffUL
105 #define FIXED_POINT_SHIFT 16
106
107 #define VOL_DIV8  0x8000
108 #define VOL_DIV16 0x0080
109 #define ENVX_SHIFT 24
110
111 extern "C" void DecodeBlockAsm (int8 *, int16 *, int32 *, int32 *);
112 extern "C" void DecodeBlockAsm2 (int8 *, int16 *, int32 *, int32 *);
113
114 // F is channel's current frequency and M is the 16-bit modulation waveform
115 // from the previous channel multiplied by the current envelope volume level.
116 #define PITCH_MOD(F,M) ((F) * ((((unsigned long) (M)) + 0x800000) >> 16) >> 7)
117 //#define PITCH_MOD(F,M) ((F) * ((((M) & 0x7fffff) >> 14) + 1) >> 8)
118
119 #define LAST_SAMPLE 0xffffff
120 #define JUST_PLAYED_LAST_SAMPLE(c) ((c)->sample_pointer >= LAST_SAMPLE)
121
122 STATIC INLINE uint8 *S9xGetSampleAddress (int sample_number)
123 {
124     uint32 addr = (((APU.DSP[APU_DIR] << 8) + (sample_number << 2)) & 0xffff);
125     return (IAPU.RAM + addr);
126 }
127
128 void S9xAPUSetEndOfSample (int i, Channel *ch)
129 {
130     ch->state = SOUND_SILENT;
131     ch->mode = MODE_NONE;
132     APU.DSP [APU_ENDX] |= 1 << i;
133     APU.DSP [APU_KON] &= ~(1 << i);
134     APU.DSP [APU_KOFF] &= ~(1 << i);
135     APU.KeyedChannels &= ~(1 << i);
136 }
137 #ifdef __DJGPP
138 END_OF_FUNCTION (S9xAPUSetEndOfSample)
139 #endif
140
141 void S9xAPUSetEndX (int ch)
142 {
143     APU.DSP [APU_ENDX] |= 1 << ch;
144 }
145 #ifdef __DJGPP
146 END_OF_FUNCTION (S9xAPUSetEndX)
147 #endif
148
149 void S9xSetEnvRate (Channel *ch, unsigned long rate, int direction, int target)
150 {
151     ch->envx_target = target;
152
153     if (rate == ~0UL)
154     {
155         ch->direction = 0;
156         rate = 0;
157     }
158     else
159         ch->direction = direction;
160
161     static int steps [] =
162     {
163 //      0, 64, 1238, 1238, 256, 1, 64, 109, 64, 1238
164         0, 64, 619, 619, 128, 1, 64, 55, 64, 619
165     };
166
167     if (rate == 0 || so.playback_rate == 0)
168         ch->erate = 0;
169     else
170     {
171         ch->erate = (unsigned long)
172                     (((int64) FIXED_POINT * 1000 * steps [ch->state]) /
173                       (rate * so.playback_rate));
174     }
175 }
176
177 #ifdef __DJGPP
178 END_OF_FUNCTION(S9xSetEnvRate);
179 #endif
180
181 void S9xSetEnvelopeRate (int channel, unsigned long rate, int direction,
182                          int target)
183 {
184     S9xSetEnvRate (&SoundData.channels [channel], rate, direction, target);
185 }
186
187 #ifdef __DJGPP
188 END_OF_FUNCTION(S9xSetEnvelopeRate);
189 #endif
190
191 void S9xSetSoundVolume (int channel, short volume_left, short volume_right)
192 {
193     Channel *ch = &SoundData.channels[channel];
194     if (!so.stereo)
195         volume_left = (ABS(volume_right) + ABS(volume_left)) / 2;
196
197     ch->volume_left = volume_left;
198     ch->volume_right = volume_right;
199     ch-> left_vol_level = (ch->envx * volume_left) / 128;
200     ch->right_vol_level = (ch->envx * volume_right) / 128;
201 }
202
203 void S9xSetMasterVolume (short volume_left, short volume_right)
204 {
205     if (Settings.DisableMasterVolume)
206     {
207         SoundData.master_volume_left = 127;
208         SoundData.master_volume_right = 127;
209         SoundData.master_volume [0] = SoundData.master_volume [1] = 127;
210     }
211     else
212     {
213         if (!so.stereo)
214             volume_left = (ABS (volume_right) + ABS (volume_left)) / 2;
215         SoundData.master_volume_left = volume_left;
216         SoundData.master_volume_right = volume_right;
217         SoundData.master_volume [Settings.ReverseStereo] = volume_left;
218         SoundData.master_volume [1 ^ Settings.ReverseStereo] = volume_right;
219     }
220 }
221
222 void S9xSetEchoVolume (short volume_left, short volume_right)
223 {
224     if (!so.stereo)
225         volume_left = (ABS (volume_right) + ABS (volume_left)) / 2;
226     SoundData.echo_volume_left = volume_left;
227     SoundData.echo_volume_right = volume_right;
228     SoundData.echo_volume [Settings.ReverseStereo] = volume_left;
229     SoundData.echo_volume [1 ^ Settings.ReverseStereo] = volume_right;
230 }
231
232 void S9xSetEchoEnable (uint8 byte)
233 {
234     SoundData.echo_channel_enable = byte;
235     if (!SoundData.echo_write_enabled || Settings.DisableSoundEcho)
236         byte = 0;
237     if (byte && !SoundData.echo_enable)
238     {
239         memset (Echo, 0, sizeof (Echo));
240         memset (Loop, 0, sizeof (Loop));
241     }
242
243     SoundData.echo_enable = byte;
244     for (int i = 0; i < 8; i++)
245     {
246         if (byte & (1 << i))
247             SoundData.channels [i].echo_buf_ptr = EchoBuffer;
248         else
249             SoundData.channels [i].echo_buf_ptr = DummyEchoBuffer;
250     }
251 }
252
253 void S9xSetEchoFeedback (int feedback)
254 {
255     CLIP8(feedback);
256     SoundData.echo_feedback = feedback;
257 }
258
259 void S9xSetEchoDelay (int delay)
260 {
261     SoundData.echo_buffer_size = (512 * delay * so.playback_rate) / 32000;
262     if (so.stereo)
263         SoundData.echo_buffer_size <<= 1;
264     if (SoundData.echo_buffer_size)
265         SoundData.echo_ptr %= SoundData.echo_buffer_size;
266     else
267         SoundData.echo_ptr = 0;
268     S9xSetEchoEnable (APU.DSP [APU_EON]);
269 }
270
271 void S9xSetEchoWriteEnable (uint8 byte)
272 {
273     SoundData.echo_write_enabled = byte;
274     S9xSetEchoDelay (APU.DSP [APU_EDL] & 15);
275 }
276
277 void S9xSetFrequencyModulationEnable (uint8 byte)
278 {
279     SoundData.pitch_mod = byte & ~1;
280 }
281
282 void S9xSetSoundKeyOff (int channel)
283 {
284     Channel *ch = &SoundData.channels[channel];
285
286     if (ch->state != SOUND_SILENT)
287     {
288         ch->state = SOUND_RELEASE;
289         ch->mode = MODE_RELEASE;
290         S9xSetEnvRate (ch, 8, -1, 0);
291     }
292 }
293
294 void S9xFixSoundAfterSnapshotLoad ()
295 {
296     SoundData.echo_write_enabled = !(APU.DSP [APU_FLG] & 0x20);
297     SoundData.echo_channel_enable = APU.DSP [APU_EON];
298     S9xSetEchoDelay (APU.DSP [APU_EDL] & 0xf);
299     S9xSetEchoFeedback ((signed char) APU.DSP [APU_EFB]);
300
301     S9xSetFilterCoefficient (0, (signed char) APU.DSP [APU_C0]);
302     S9xSetFilterCoefficient (1, (signed char) APU.DSP [APU_C1]);
303     S9xSetFilterCoefficient (2, (signed char) APU.DSP [APU_C2]);
304     S9xSetFilterCoefficient (3, (signed char) APU.DSP [APU_C3]);
305     S9xSetFilterCoefficient (4, (signed char) APU.DSP [APU_C4]);
306     S9xSetFilterCoefficient (5, (signed char) APU.DSP [APU_C5]);
307     S9xSetFilterCoefficient (6, (signed char) APU.DSP [APU_C6]);
308     S9xSetFilterCoefficient (7, (signed char) APU.DSP [APU_C7]);
309     for (int i = 0; i < 8; i++)
310     {
311         SoundData.channels[i].needs_decode = TRUE;
312         S9xSetSoundFrequency (i, SoundData.channels[i].hertz);
313         SoundData.channels [i].envxx = SoundData.channels [i].envx << ENVX_SHIFT;
314         SoundData.channels [i].next_sample = 0;
315         SoundData.channels [i].interpolate = 0;
316         SoundData.channels [i].previous [0] = (int32) SoundData.channels [i].previous16 [0];
317         SoundData.channels [i].previous [1] = (int32) SoundData.channels [i].previous16 [1];
318     }
319     SoundData.master_volume [Settings.ReverseStereo] = SoundData.master_volume_left;
320     SoundData.master_volume [1 ^ Settings.ReverseStereo] = SoundData.master_volume_right;
321     SoundData.echo_volume [Settings.ReverseStereo] = SoundData.echo_volume_left;
322     SoundData.echo_volume [1 ^ Settings.ReverseStereo] = SoundData.echo_volume_right;
323     IAPU.Scanline = 0;
324 }
325
326 void S9xSetFilterCoefficient (int tap, int value)
327 {
328     FilterTaps [tap & 7] = value;
329     SoundData.no_filter = (FilterTaps [0] == 127 || FilterTaps [0] == 0) && 
330                            FilterTaps [1] == 0   &&
331                            FilterTaps [2] == 0   &&
332                            FilterTaps [3] == 0   &&
333                            FilterTaps [4] == 0   &&
334                            FilterTaps [5] == 0   &&
335                            FilterTaps [6] == 0   &&
336                            FilterTaps [7] == 0;
337 }
338
339 void S9xSetSoundADSR (int channel, int attack_rate, int decay_rate,
340                       int sustain_rate, int sustain_level, int release_rate)
341 {
342     SoundData.channels[channel].attack_rate = attack_rate;
343     SoundData.channels[channel].decay_rate = decay_rate;
344     SoundData.channels[channel].sustain_rate = sustain_rate;
345     SoundData.channels[channel].release_rate = release_rate;
346     SoundData.channels[channel].sustain_level = sustain_level + 1;
347
348     switch (SoundData.channels[channel].state)
349     {
350     case SOUND_ATTACK:
351         S9xSetEnvelopeRate (channel, attack_rate, 1, 127);
352         break;
353
354     case SOUND_DECAY:
355         S9xSetEnvelopeRate (channel, decay_rate, -1,
356                             (MAX_ENVELOPE_HEIGHT * (sustain_level + 1)) >> 3);
357         break;
358     case SOUND_SUSTAIN:
359         S9xSetEnvelopeRate (channel, sustain_rate, -1, 0);
360         break;
361     }
362 }
363
364 void S9xSetEnvelopeHeight (int channel, int level)
365 {
366     Channel *ch = &SoundData.channels[channel];
367
368     ch->envx = level;
369     ch->envxx = level << ENVX_SHIFT;
370
371     ch->left_vol_level = (level * ch->volume_left) / 128;
372     ch->right_vol_level = (level * ch->volume_right) / 128;
373
374     if (ch->envx == 0 && ch->state != SOUND_SILENT && ch->state != SOUND_GAIN)
375     {
376         S9xAPUSetEndOfSample (channel, ch);
377     }
378 }
379
380 int S9xGetEnvelopeHeight (int channel)
381 {
382     if ((Settings.SoundEnvelopeHeightReading ||
383          SNESGameFixes.SoundEnvelopeHeightReading2) &&
384         SoundData.channels[channel].state != SOUND_SILENT &&
385         SoundData.channels[channel].state != SOUND_GAIN)
386     {
387         return (SoundData.channels[channel].envx);
388     }
389
390     //siren fix from XPP
391     if (SNESGameFixes.SoundEnvelopeHeightReading2 &&
392         SoundData.channels[channel].state != SOUND_SILENT)
393     {
394         return (SoundData.channels[channel].envx);
395     }
396
397     return (0);
398 }
399
400 #if 1
401 void S9xSetSoundSample (int, uint16) 
402 {
403 }
404 #else
405 void S9xSetSoundSample (int channel, uint16 sample_number)
406 {
407     register Channel *ch = &SoundData.channels[channel];
408
409     if (ch->state != SOUND_SILENT && 
410         sample_number != ch->sample_number)
411     {
412         int keep = ch->state;
413         ch->state = SOUND_SILENT;
414         ch->sample_number = sample_number;
415         ch->loop = FALSE;
416         ch->needs_decode = TRUE;
417         ch->last_block = FALSE;
418         ch->previous [0] = ch->previous[1] = 0;
419         uint8 *dir = S9xGetSampleAddress (sample_number);
420         ch->block_pointer = READ_WORD (dir);
421         ch->sample_pointer = 0;
422         ch->state = keep;
423     }
424 }
425 #endif
426
427 void S9xSetSoundFrequency (int channel, int hertz)
428 {
429     if (so.playback_rate)
430     {
431         if (SoundData.channels[channel].type == SOUND_NOISE)
432             hertz = NoiseFreq [APU.DSP [APU_FLG] & 0x1f];
433         SoundData.channels[channel].frequency = (int)
434             (((int64) hertz * FIXED_POINT) / so.playback_rate);
435         if (Settings.FixFrequency)
436         {
437             SoundData.channels[channel].frequency = 
438                 (unsigned long) ((double)  SoundData.channels[channel].frequency * 0.980);
439         }
440     }
441 }
442
443 void S9xSetSoundHertz (int channel, int hertz)
444 {
445     SoundData.channels[channel].hertz = hertz;
446     S9xSetSoundFrequency (channel, hertz);
447 }
448
449 void S9xSetSoundType (int channel, int type_of_sound)
450 {
451     SoundData.channels[channel].type = type_of_sound;
452 }
453
454 bool8_32 S9xSetSoundMute (bool8_32 mute)
455 {
456     bool8_32 old = so.mute_sound;
457     so.mute_sound = mute;
458     return (old);
459 }
460
461 void AltDecodeBlock_PPC (Channel *ch, struct SIAPU * iapu)
462 {
463     if (ch->block_pointer >= 0x10000 - 9)
464     {
465         ch->last_block = TRUE;
466         ch->loop = FALSE;
467         ch->block = ch->decoded;
468         memset ((void *) ch->decoded, 0, sizeof (int16) * 16);
469         return;
470     }
471     signed char *compressed = (signed char *) &iapu->RAM [ch->block_pointer];
472
473     unsigned char filter = *compressed;
474     if ((ch->last_block = filter & 1))
475         ch->loop = (filter & 2) != 0;
476
477 #if (defined (__i386__) || defined (__i486__) ||\
478      defined (__i586__) || defined (__WIN32__) || defined (__DJGPP))
479     int16 *raw = ch->block = ch->decoded;
480
481     if (Settings.AltSampleDecode == 1)
482         DecodeBlockAsm (compressed, raw, &ch->previous [0], &ch->previous [1]);
483     else
484         DecodeBlockAsm2 (compressed, raw, &ch->previous [0], &ch->previous [1]);
485 #else
486     int32 out;
487     unsigned char shift;
488     signed char sample1, sample2;
489     unsigned int i;
490
491     compressed++;
492     signed short *raw = ch->block = ch->decoded;
493     
494     int32 prev0 = ch->previous [0];
495     int32 prev1 = ch->previous [1];
496     shift = filter >> 4;
497
498     switch ((filter >> 2) & 3)
499     {
500     case 0:
501         for (i = 8; i != 0; i--)
502         {
503             sample1 = *compressed++;
504             sample2 = sample1 << 4;
505             sample2 >>= 4;
506             sample1 >>= 4;
507             *raw++ = ((int32) sample1 << shift);
508             *raw++ = ((int32) sample2 << shift);
509         }
510         prev1 = *(raw - 2);
511         prev0 = *(raw - 1);
512         break;
513     case 1:
514         for (i = 8; i != 0; i--)
515         {
516             sample1 = *compressed++;
517             sample2 = sample1 << 4;
518             sample2 >>= 4;
519             sample1 >>= 4;
520             prev0 = (int16) prev0;
521             *raw++ = prev1 = ((int32) sample1 << shift) + prev0 - (prev0 >> 4);
522             prev1 = (int16) prev1;
523             *raw++ = prev0 = ((int32) sample2 << shift) + prev1 - (prev1 >> 4);
524         }
525         break;
526     case 2:
527         for (i = 8; i != 0; i--)
528         {
529             sample1 = *compressed++;
530             sample2 = sample1 << 4;
531             sample2 >>= 4;
532             sample1 >>= 4;
533             
534             out = (sample1 << shift) - prev1 + (prev1 >> 4);
535             prev1 = (int16) prev0;
536             prev0 &= ~3;
537             *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) - 
538                              (prev0 >> 4);
539
540             out = (sample2 << shift) - prev1 + (prev1 >> 4);
541             prev1 = (int16) prev0;
542             prev0 &= ~3;
543             *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) -
544                              (prev0 >> 4);
545         }
546         break;
547     case 3:
548         for (i = 8; i != 0; i--)
549         {
550             sample1 = *compressed++;
551             sample2 = sample1 << 4;
552             sample2 >>= 4;
553             sample1 >>= 4;
554             out = (sample1 << shift);
555
556             out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);
557             prev1 = (int16) prev0;
558             prev0 &= ~3;
559             *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - 
560                              (prev0 >> 4) - (prev1 >> 6);
561
562             out = (sample2 << shift);
563             out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);
564             prev1 = (int16) prev0;
565             prev0 &= ~3;
566             *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - 
567                              (prev0 >> 4) - (prev1 >> 6);
568         }
569         break;
570     }
571     ch->previous [0] = prev0;
572     ch->previous [1] = prev1;
573 #endif
574
575     ch->block_pointer += 9;
576 }
577
578 void AltDecodeBlock (Channel *ch, struct SIAPU * iapu)
579 {
580     if (ch->block_pointer >= 0x10000 - 9)
581     {
582         ch->last_block = TRUE;
583         ch->loop = FALSE;
584         ch->block = ch->decoded;
585         memset ((void *) ch->decoded, 0, sizeof (int16) * 16);
586         return;
587     }
588     signed char *compressed = (signed char *) &iapu->RAM [ch->block_pointer];
589
590     unsigned char filter = *compressed;
591     if ((ch->last_block = filter & 1))
592         ch->loop = (filter & 2) != 0;
593
594 #if (defined (__i386__) || defined (__i486__) ||\
595      defined (__i586__) || defined (__WIN32__) || defined (__DJGPP))
596     int16 *raw = ch->block = ch->decoded;
597
598     if (Settings.AltSampleDecode == 1)
599         DecodeBlockAsm (compressed, raw, &ch->previous [0], &ch->previous [1]);
600     else
601         DecodeBlockAsm2 (compressed, raw, &ch->previous [0], &ch->previous [1]);
602 #else
603     int32 out;
604     unsigned char shift;
605     signed char sample1, sample2;
606     unsigned int i;
607
608     compressed++;
609     signed short *raw = ch->block = ch->decoded;
610     
611     int32 prev0 = ch->previous [0];
612     int32 prev1 = ch->previous [1];
613     shift = filter >> 4;
614
615     switch ((filter >> 2) & 3)
616     {
617     case 0:
618         for (i = 8; i != 0; i--)
619         {
620             sample1 = *compressed++;
621             sample2 = sample1 << 4;
622             sample2 >>= 4;
623             sample1 >>= 4;
624             *raw++ = ((int32) sample1 << shift);
625             *raw++ = ((int32) sample2 << shift);
626         }
627         prev1 = *(raw - 2);
628         prev0 = *(raw - 1);
629         break;
630     case 1:
631         for (i = 8; i != 0; i--)
632         {
633             sample1 = *compressed++;
634             sample2 = sample1 << 4;
635             sample2 >>= 4;
636             sample1 >>= 4;
637             prev0 = (int16) prev0;
638             *raw++ = prev1 = ((int32) sample1 << shift) + prev0 - (prev0 >> 4);
639             prev1 = (int16) prev1;
640             *raw++ = prev0 = ((int32) sample2 << shift) + prev1 - (prev1 >> 4);
641         }
642         break;
643     case 2:
644         for (i = 8; i != 0; i--)
645         {
646             sample1 = *compressed++;
647             sample2 = sample1 << 4;
648             sample2 >>= 4;
649             sample1 >>= 4;
650             
651             out = (sample1 << shift) - prev1 + (prev1 >> 4);
652             prev1 = (int16) prev0;
653             prev0 &= ~3;
654             *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) - 
655                              (prev0 >> 4);
656
657             out = (sample2 << shift) - prev1 + (prev1 >> 4);
658             prev1 = (int16) prev0;
659             prev0 &= ~3;
660             *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) -
661                              (prev0 >> 4);
662         }
663         break;
664     case 3:
665         for (i = 8; i != 0; i--)
666         {
667             sample1 = *compressed++;
668             sample2 = sample1 << 4;
669             sample2 >>= 4;
670             sample1 >>= 4;
671             out = (sample1 << shift);
672
673             out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);
674             prev1 = (int16) prev0;
675             prev0 &= ~3;
676             *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - 
677                              (prev0 >> 4) - (prev1 >> 6);
678
679             out = (sample2 << shift);
680             out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);
681             prev1 = (int16) prev0;
682             prev0 &= ~3;
683             *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - 
684                              (prev0 >> 4) - (prev1 >> 6);
685         }
686         break;
687     }
688     ch->previous [0] = prev0;
689     ch->previous [1] = prev1;
690 #endif
691
692     ch->block_pointer += 9;
693 }
694
695 void AltDecodeBlock2 (Channel *ch)
696 {
697     int32 out;
698     unsigned char filter;
699     unsigned char shift;
700     signed char sample1, sample2;
701     unsigned char i;
702
703     if (ch->block_pointer > 0x10000 - 9)
704     {
705         ch->last_block = TRUE;
706         ch->loop = FALSE;
707         ch->block = ch->decoded;
708         memset ((void *) ch->decoded, 0, sizeof (int16) * 16);
709         return;
710     }
711
712     signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer];
713
714     filter = *compressed;
715     if ((ch->last_block = filter & 1))
716     ch->loop = (filter & 2) != 0;
717
718     compressed++;
719     signed short *raw = ch->block = ch->decoded;
720     
721     shift = filter >> 4;
722     int32 prev0 = ch->previous [0];
723     int32 prev1 = ch->previous [1];
724
725     if(shift > 12)
726         shift -= 4;
727
728     switch ((filter >> 2) & 3)
729     {
730     case 0:
731         for (i = 8; i != 0; i--)
732         {
733             sample1 = *compressed++;
734             sample2 = sample1 << 4;
735             //Sample 2 = Bottom Nibble, Sign Extended.
736             sample2 >>= 4;
737             //Sample 1 = Top Nibble, shifted down and Sign Extended.
738             sample1 >>= 4;
739
740             out = (int32)(sample1 << shift);
741
742             prev1 = prev0;
743             prev0 = out;
744             CLIP16(out);
745             *raw++ = (int16)out;
746
747             out = (int32)(sample2 << shift);
748
749             prev1 = prev0;
750             prev0 = out;
751             CLIP16(out);
752             *raw++ = (int16)out;
753         }
754         break;
755     case 1:
756         for (i = 8; i != 0; i--)
757         {
758             sample1 = *compressed++;
759             sample2 = sample1 << 4;
760             //Sample 2 = Bottom Nibble, Sign Extended.
761             sample2 >>= 4;
762             //Sample 1 = Top Nibble, shifted down and Sign Extended.
763             sample1 >>= 4;
764             out = (int32)(sample1 << shift);
765             out += (int32)((double)prev0 * 15/16);
766
767             prev1 = prev0;
768             prev0 = out;
769             CLIP16(out);
770             *raw++ = (int16)out;
771
772             out = (int32)(sample2 << shift);
773             out += (int32)((double)prev0 * 15/16);
774
775             prev1 = prev0;
776             prev0 = out;
777             CLIP16(out);
778             *raw++ = (int16)out;
779         }
780         break;
781     case 2:
782         for (i = 8; i != 0; i--)
783         {
784             sample1 = *compressed++;
785             sample2 = sample1 << 4;
786             //Sample 2 = Bottom Nibble, Sign Extended.
787             sample2 >>= 4;
788             //Sample 1 = Top Nibble, shifted down and Sign Extended.
789             sample1 >>= 4;
790
791             out = ((sample1 << shift) * 256 + (prev0 & ~0x2) * 488 - prev1 * 240) >> 8;
792
793             prev1 = prev0;
794             prev0 = (int16)out;
795             *raw++ = (int16)out;
796
797             out = ((sample2 << shift) * 256 + (prev0 & ~0x2) * 488 - prev1 * 240) >> 8;
798
799             prev1 = prev0;
800             prev0 = (int16)out;
801             *raw++ = (int16)out;
802         }
803         break;
804
805     case 3:
806         for (i = 8; i != 0; i--)
807         {
808             sample1 = *compressed++;
809             sample2 = sample1 << 4;
810             //Sample 2 = Bottom Nibble, Sign Extended.
811             sample2 >>= 4;
812             //Sample 1 = Top Nibble, shifted down and Sign Extended.
813             sample1 >>= 4;
814             out = (int32)(sample1 << shift);
815             out += (int32)((double)prev0 * 115/64 - (double)prev1 * 13/16);
816
817             prev1 = prev0;
818             prev0 = out;
819
820             CLIP16(out);
821             *raw++ = (int16)out;
822
823             out = (int32)(sample2 << shift);
824             out += (int32)((double)prev0 * 115/64 - (double)prev1 * 13/16);
825
826             prev1 = prev0;
827             prev0 = out;
828
829             CLIP16(out);
830             *raw++ = (int16)out;
831         }
832         break;
833     }
834     ch->previous [0] = prev0;
835     ch->previous [1] = prev1;
836     ch->block_pointer += 9;
837 }
838
839 void DecodeBlock (Channel *ch)
840 {
841     int32 out;
842     unsigned char filter;
843     unsigned char shift;
844     signed char sample1, sample2;
845     unsigned char i;
846
847     if (Settings.AltSampleDecode)
848     {
849                 if (Settings.AltSampleDecode < 3)
850                         AltDecodeBlock (ch, &IAPU);
851                 else
852                         AltDecodeBlock2 (ch);
853                         return;
854     }
855     if (ch->block_pointer > 0x10000 - 9)
856     {
857         ch->last_block = TRUE;
858         ch->loop = FALSE;
859         ch->block = ch->decoded;
860         return;
861     }
862     signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer];
863
864     filter = *compressed;
865     if ((ch->last_block = filter & 1))
866         ch->loop = (filter & 2) != 0;
867
868     // If enabled, results in 'tick' sound on some samples that repeat by
869     // re-using part of the original sample but generate a slightly different
870     // waveform.
871     if (!Settings.DisableSampleCaching &&
872         memcmp ((uint8 *) compressed, &IAPU.ShadowRAM [ch->block_pointer], 9) == 0)
873     {
874         ch->block = (signed short *) (IAPU.CachedSamples + (ch->block_pointer << 2));
875         ch->previous [0] = ch->block [15];
876         ch->previous [1] = ch->block [14];
877     }
878     else
879     {
880         if (!Settings.DisableSampleCaching)
881             memcpy (&IAPU.ShadowRAM [ch->block_pointer], (uint8 *) compressed, 9);
882         compressed++;
883         signed short *raw = ch->block = ch->decoded;
884
885         shift = filter >> 4;
886         filter = ((filter >> 2) & 3);
887         int32 prev0 = ch->previous [0];
888         int32 prev1 = ch->previous [1];
889         int32 f0 = FilterValues[filter][0];
890         int32 f1 = FilterValues[filter][1];
891
892         for (i = 8; i != 0; i--)
893         {
894             sample1 = *compressed++;
895             sample2 = sample1 << 4;
896             //Sample 2 = Bottom Nibble, Sign Extended.
897             sample2 >>= 4;
898             //Sample 1 = Top Nibble, shifted down and Sign Extended.
899             sample1 >>= 4;
900             out = (sample1 << shift);
901             out += (prev0 * f0 + prev1 * f1) / 256;
902
903             CLIP16 (out);
904             prev1 = prev0;
905             prev0 = out;
906             *raw++ = (signed short) out;
907
908             out = (sample2 << shift);
909             out += (prev0 * f0 + prev1 * f1) / 256;
910
911             CLIP16 (out);
912             prev1 = prev0;
913             prev0 = out;
914             *raw++ = (signed short) out;
915         }
916         ch->previous [0] = prev0;
917         ch->previous [1] = prev1;
918
919         if (!Settings.DisableSampleCaching)
920         {
921             memcpy (IAPU.CachedSamples + (ch->block_pointer << 2),
922                     (uint8 *) ch->decoded, 32);
923         }
924     }
925     ch->block_pointer += 9;
926 }
927
928 void MixStereo (int sample_count)
929 {
930         struct SIAPU * iapu = &IAPU;
931 #if defined(TARGET_OS_MAC) && TARGET_OS_MAC
932     static int wave[SOUND_BUFFER_SIZE];
933 #else
934     int wave[SOUND_BUFFER_SIZE];
935 #endif
936     int pitch_mod = SoundData.pitch_mod & ~APU.DSP[APU_NON];
937
938     for (uint32 J = 0; J < NUM_CHANNELS; J++) 
939     {
940         int32 VL, VR;
941         Channel *ch = &SoundData.channels[J];
942         unsigned long freq0 = ch->frequency;
943
944         if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J)))
945             continue;
946
947 //      freq0 = (unsigned long) ((double) freq0 * 0.985);
948
949         bool8_32 mod = pitch_mod & (1 << J);
950
951         if (ch->needs_decode) 
952         {
953                 AltDecodeBlock(ch, iapu);
954             //DecodeBlock(ch);
955             ch->needs_decode = FALSE;
956             ch->sample = ch->block[0];
957             ch->sample_pointer = freq0 >> FIXED_POINT_SHIFT;
958             if (ch->sample_pointer == 0)
959                 ch->sample_pointer = 1;
960             if (ch->sample_pointer > SOUND_DECODE_LENGTH)
961                 ch->sample_pointer = SOUND_DECODE_LENGTH - 1;
962
963             ch->next_sample = ch->block[ch->sample_pointer];
964             ch->interpolate = 0;
965
966             if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod)
967                 ch->interpolate = ((ch->next_sample - ch->sample) * 
968                                    (long) freq0) / (long) FIXED_POINT;
969         }
970         VL = (ch->sample * ch-> left_vol_level) / 128;
971         VR = (ch->sample * ch->right_vol_level) / 128;
972
973         for (uint32 I = 0; I < (uint32) sample_count; I += 2)
974         {
975             unsigned long freq = freq0;
976
977             if (mod)
978                 freq = PITCH_MOD(freq, wave [I / 2]);
979
980             ch->env_error += ch->erate;
981             if (ch->env_error >= FIXED_POINT) 
982             {
983                 uint32 step = ch->env_error >> FIXED_POINT_SHIFT;
984
985                 switch (ch->state)
986                 {
987                 case SOUND_ATTACK:
988                     ch->env_error &= FIXED_POINT_REMAINDER;
989                     ch->envx += step << 1;
990                     ch->envxx = ch->envx << ENVX_SHIFT;
991
992                     if (ch->envx >= 126)
993                     {
994                         ch->envx = 127;
995                         ch->envxx = 127 << ENVX_SHIFT;
996                         ch->state = SOUND_DECAY;
997                         if (ch->sustain_level != 8) 
998                         {
999                             S9xSetEnvRate (ch, ch->decay_rate, -1,
1000                                                 (MAX_ENVELOPE_HEIGHT * ch->sustain_level)
1001                                                 >> 3);
1002                             break;
1003                         }
1004                         ch->state = SOUND_SUSTAIN;
1005                         S9xSetEnvRate (ch, ch->sustain_rate, -1, 0);
1006                     }
1007                     break;
1008                 
1009                 case SOUND_DECAY:
1010                     while (ch->env_error >= FIXED_POINT)
1011                     {
1012                         ch->envxx = (ch->envxx >> 8) * 255;
1013                         ch->env_error -= FIXED_POINT;
1014                     }
1015                     ch->envx = ch->envxx >> ENVX_SHIFT;
1016                     if (ch->envx <= ch->envx_target)
1017                     {
1018                         if (ch->envx <= 0)
1019                         {
1020                             S9xAPUSetEndOfSample (J, ch);
1021                             goto stereo_exit;
1022                         }
1023                         ch->state = SOUND_SUSTAIN;
1024                         S9xSetEnvRate (ch, ch->sustain_rate, -1, 0);
1025                     }
1026                     break;
1027
1028                 case SOUND_SUSTAIN:
1029                     while (ch->env_error >= FIXED_POINT)
1030                     {
1031                         ch->envxx = (ch->envxx >> 8) * 255;
1032                         ch->env_error -= FIXED_POINT;
1033                     }
1034                     ch->envx = ch->envxx >> ENVX_SHIFT;
1035                     if (ch->envx <= 0)
1036                     {
1037                         S9xAPUSetEndOfSample (J, ch);
1038                         goto stereo_exit;
1039                     }
1040                     break;
1041                     
1042                 case SOUND_RELEASE:
1043                     while (ch->env_error >= FIXED_POINT)
1044                     {
1045                         ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
1046                         ch->env_error -= FIXED_POINT;
1047                     }
1048                     ch->envx = ch->envxx >> ENVX_SHIFT;
1049                     if (ch->envx <= 0)
1050                     {
1051                         S9xAPUSetEndOfSample (J, ch);
1052                         goto stereo_exit;
1053                     }
1054                     break;
1055                 
1056                 case SOUND_INCREASE_LINEAR:
1057                     ch->env_error &= FIXED_POINT_REMAINDER;
1058                     ch->envx += step << 1;
1059                     ch->envxx = ch->envx << ENVX_SHIFT;
1060
1061                     if (ch->envx >= 126)
1062                     {
1063                         ch->envx = 127;
1064                         ch->envxx = 127 << ENVX_SHIFT;
1065                         ch->state = SOUND_GAIN;
1066                         ch->mode = MODE_GAIN;
1067                         S9xSetEnvRate (ch, 0, -1, 0);
1068                     }
1069                     break;
1070
1071                 case SOUND_INCREASE_BENT_LINE:
1072                     if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4)
1073                     {
1074                         while (ch->env_error >= FIXED_POINT)
1075                         {
1076                             ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
1077                             ch->env_error -= FIXED_POINT;
1078                         }
1079                         ch->envx = ch->envxx >> ENVX_SHIFT;
1080                     }
1081                     else
1082                     {
1083                         ch->env_error &= FIXED_POINT_REMAINDER;
1084                         ch->envx += step << 1;
1085                         ch->envxx = ch->envx << ENVX_SHIFT;
1086                     }
1087
1088                     if (ch->envx >= 126)
1089                     {
1090                         ch->envx = 127;
1091                         ch->envxx = 127 << ENVX_SHIFT;
1092                         ch->state = SOUND_GAIN;
1093                         ch->mode = MODE_GAIN;
1094                         S9xSetEnvRate (ch, 0, -1, 0);
1095                     }
1096                     break;
1097
1098                 case SOUND_DECREASE_LINEAR:
1099                     ch->env_error &= FIXED_POINT_REMAINDER;
1100                     ch->envx -= step << 1;
1101                     ch->envxx = ch->envx << ENVX_SHIFT;
1102                     if (ch->envx <= 0)
1103                     {
1104                         S9xAPUSetEndOfSample (J, ch);
1105                         goto stereo_exit;
1106                     }
1107                     break;
1108
1109                 case SOUND_DECREASE_EXPONENTIAL:
1110                     while (ch->env_error >= FIXED_POINT)
1111                     {
1112                         ch->envxx = (ch->envxx >> 8) * 255;
1113                         ch->env_error -= FIXED_POINT;
1114                     }
1115                     ch->envx = ch->envxx >> ENVX_SHIFT;
1116                     if (ch->envx <= 0)
1117                     {
1118                         S9xAPUSetEndOfSample (J, ch);
1119                         goto stereo_exit;
1120                     }
1121                     break;
1122                 
1123                 case SOUND_GAIN:
1124                     S9xSetEnvRate (ch, 0, -1, 0);
1125                     break;
1126                 }
1127                 ch-> left_vol_level = (ch->envx * ch->volume_left) / 128;
1128                 ch->right_vol_level = (ch->envx * ch->volume_right) / 128;
1129                 VL = (ch->sample * ch-> left_vol_level) / 128;
1130                 VR = (ch->sample * ch->right_vol_level) / 128;
1131             }
1132
1133             ch->count += freq;
1134             if (ch->count >= FIXED_POINT)
1135             {
1136                 VL = ch->count >> FIXED_POINT_SHIFT;
1137                 ch->sample_pointer += VL;
1138                 ch->count &= FIXED_POINT_REMAINDER;
1139
1140                 ch->sample = ch->next_sample;
1141                 if (ch->sample_pointer >= SOUND_DECODE_LENGTH)
1142                 {
1143                     if (JUST_PLAYED_LAST_SAMPLE(ch))
1144                     {
1145                         S9xAPUSetEndOfSample (J, ch);
1146                         goto stereo_exit;
1147                     }
1148                     do
1149                     {
1150                         ch->sample_pointer -= SOUND_DECODE_LENGTH;
1151                         if (ch->last_block)
1152                         {
1153                             if (!ch->loop)
1154                             {
1155                                 ch->sample_pointer = LAST_SAMPLE;
1156                                 ch->next_sample = ch->sample;
1157                                 break;
1158                             }
1159                             else
1160                             {
1161                                 S9xAPUSetEndX (J);
1162                                 ch->last_block = FALSE;
1163                                 uint8 *dir = S9xGetSampleAddress (ch->sample_number);
1164                                 ch->block_pointer = READ_WORD(dir + 2);
1165                             }
1166                         }
1167                         AltDecodeBlock(ch, iapu);
1168                         //DecodeBlock (ch);
1169                     } while (ch->sample_pointer >= SOUND_DECODE_LENGTH);
1170                     if (!JUST_PLAYED_LAST_SAMPLE (ch))
1171                         ch->next_sample = ch->block [ch->sample_pointer];
1172                 }
1173                 else
1174                     ch->next_sample = ch->block [ch->sample_pointer];
1175
1176                 if (ch->type == SOUND_SAMPLE)
1177                 {
1178                     if (Settings.InterpolatedSound && freq < FIXED_POINT && !mod)
1179                     {
1180                         ch->interpolate = ((ch->next_sample - ch->sample) * 
1181                                            (long) freq) / (long) FIXED_POINT;
1182                         ch->sample = (int16) (ch->sample + (((ch->next_sample - ch->sample) * 
1183                                            (long) (ch->count)) / (long) FIXED_POINT));
1184                     }             
1185                     else
1186                         ch->interpolate = 0;
1187                 }
1188                 else
1189                 {
1190                     for (;VL > 0; VL--)
1191                         if ((so.noise_gen <<= 1) & 0x80000000L)
1192                             so.noise_gen ^= 0x0040001L;
1193                     ch->sample = (so.noise_gen << 17) >> 17;
1194                     ch->interpolate = 0;
1195                 }
1196
1197                 VL = (ch->sample * ch-> left_vol_level) / 128;
1198                 VR = (ch->sample * ch->right_vol_level) / 128;
1199             }
1200             else
1201             {
1202                 if (ch->interpolate)
1203                 {
1204                     int32 s = (int32) ch->sample + ch->interpolate;
1205                     
1206                     CLIP16(s);
1207                     ch->sample = (int16) s;
1208                     VL = (ch->sample * ch-> left_vol_level) / 128;
1209                     VR = (ch->sample * ch->right_vol_level) / 128;
1210                 }
1211             }
1212
1213             if (pitch_mod & (1 << (J + 1)))
1214                 wave [I / 2] = ch->sample * ch->envx;
1215
1216             MixBuffer [I      ^ Settings.ReverseStereo] += VL;
1217             MixBuffer [I + (1 ^ Settings.ReverseStereo)] += VR;
1218             ch->echo_buf_ptr [I      ^ Settings.ReverseStereo] += VL;
1219             ch->echo_buf_ptr [I + (1 ^ Settings.ReverseStereo)] += VR;
1220         }
1221 stereo_exit: ;
1222     }
1223 }
1224
1225 #ifdef __DJGPP
1226 END_OF_FUNCTION(MixStereo);
1227 #endif
1228
1229 void MixMono (int sample_count)
1230 {
1231         struct SIAPU * iapu = &IAPU;
1232 #if defined(TARGET_OS_MAC) && TARGET_OS_MAC
1233     static int wave[SOUND_BUFFER_SIZE];
1234 #else
1235 #ifdef _SNESPPC
1236     static int wave[SOUND_BUFFER_SIZE];
1237 #else
1238     int wave[SOUND_BUFFER_SIZE];
1239 #endif
1240 #endif
1241     int pitch_mod = SoundData.pitch_mod & (~APU.DSP[APU_NON]);
1242
1243     for (uint32 J = 0; J < NUM_CHANNELS; J++) 
1244     {
1245         Channel *ch = &SoundData.channels[J];
1246         unsigned long freq0 = ch->frequency;
1247
1248         if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J)))
1249             continue;
1250
1251 //      freq0 = (unsigned long) ((double) freq0 * 0.985);
1252
1253         bool8_32 mod = pitch_mod & (1 << J);
1254
1255         if (ch->needs_decode) 
1256         {
1257                 AltDecodeBlock(ch, iapu);
1258             //DecodeBlock(ch);
1259             ch->needs_decode = FALSE;
1260             ch->sample = ch->block[0];
1261             ch->sample_pointer = freq0 >> FIXED_POINT_SHIFT;
1262             if (ch->sample_pointer == 0)
1263                 ch->sample_pointer = 1;
1264             if (ch->sample_pointer > SOUND_DECODE_LENGTH)
1265                 ch->sample_pointer = SOUND_DECODE_LENGTH - 1;
1266             ch->next_sample = ch->block[ch->sample_pointer];
1267             ch->interpolate = 0;
1268
1269             if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod)
1270                 ch->interpolate = ((ch->next_sample - ch->sample) * 
1271                                    (long) freq0) / (long) FIXED_POINT;
1272         }
1273         int32 V = (ch->sample * ch->left_vol_level) / 128;
1274
1275         for (uint32 I = 0; I < (uint32) sample_count; I++)
1276         {
1277             unsigned long freq = freq0;
1278
1279             if (mod)
1280                 freq = PITCH_MOD(freq, wave [I]);
1281
1282             ch->env_error += ch->erate;
1283             if (ch->env_error >= FIXED_POINT) 
1284             {
1285                 uint32 step = ch->env_error >> FIXED_POINT_SHIFT;
1286
1287                 switch (ch->state)
1288                 {
1289                 case SOUND_ATTACK:
1290                     ch->env_error &= FIXED_POINT_REMAINDER;
1291                     ch->envx += step << 1;
1292                     ch->envxx = ch->envx << ENVX_SHIFT;
1293
1294                     if (ch->envx >= 126)
1295                     {
1296                         ch->envx = 127;
1297                         ch->envxx = 127 << ENVX_SHIFT;
1298                         ch->state = SOUND_DECAY;
1299                         if (ch->sustain_level != 8) 
1300                         {
1301                             S9xSetEnvRate (ch, ch->decay_rate, -1,
1302                                                 (MAX_ENVELOPE_HEIGHT * ch->sustain_level)
1303                                                 >> 3);
1304                             break;
1305                         }
1306                         ch->state = SOUND_SUSTAIN;
1307                         S9xSetEnvRate (ch, ch->sustain_rate, -1, 0);
1308                     }
1309                     break;
1310                 
1311                 case SOUND_DECAY:
1312                     while (ch->env_error >= FIXED_POINT)
1313                     {
1314                         ch->envxx = (ch->envxx >> 8) * 255;
1315                         ch->env_error -= FIXED_POINT;
1316                     }
1317                     ch->envx = ch->envxx >> ENVX_SHIFT;
1318                     if (ch->envx <= ch->envx_target)
1319                     {
1320                         if (ch->envx <= 0)
1321                         {
1322                             S9xAPUSetEndOfSample (J, ch);
1323                             goto mono_exit;
1324                         }
1325                         ch->state = SOUND_SUSTAIN;
1326                         S9xSetEnvRate (ch, ch->sustain_rate, -1, 0);
1327                     }
1328                     break;
1329
1330                 case SOUND_SUSTAIN:
1331                     while (ch->env_error >= FIXED_POINT)
1332                     {
1333                         ch->envxx = (ch->envxx >> 8) * 255;
1334                         ch->env_error -= FIXED_POINT;
1335                     }
1336                     ch->envx = ch->envxx >> ENVX_SHIFT;
1337                     if (ch->envx <= 0)
1338                     {
1339                         S9xAPUSetEndOfSample (J, ch);
1340                         goto mono_exit;
1341                     }
1342                     break;
1343                     
1344                 case SOUND_RELEASE:
1345                     while (ch->env_error >= FIXED_POINT)
1346                     {
1347                         ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
1348                         ch->env_error -= FIXED_POINT;
1349                     }
1350                     ch->envx = ch->envxx >> ENVX_SHIFT;
1351                     if (ch->envx <= 0)
1352                     {
1353                         S9xAPUSetEndOfSample (J, ch);
1354                         goto mono_exit;
1355                     }
1356                     break;
1357                 
1358                 case SOUND_INCREASE_LINEAR:
1359                     ch->env_error &= FIXED_POINT_REMAINDER;
1360                     ch->envx += step << 1;
1361                     ch->envxx = ch->envx << ENVX_SHIFT;
1362
1363                     if (ch->envx >= 126)
1364                     {
1365                         ch->envx = 127;
1366                         ch->envxx = 127 << ENVX_SHIFT;
1367                         ch->state = SOUND_GAIN;
1368                         ch->mode = MODE_GAIN;
1369                         S9xSetEnvRate (ch, 0, -1, 0);
1370                     }
1371                     break;
1372
1373                 case SOUND_INCREASE_BENT_LINE:
1374                     if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4)
1375                     {
1376                         while (ch->env_error >= FIXED_POINT)
1377                         {
1378                             ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
1379                             ch->env_error -= FIXED_POINT;
1380                         }
1381                         ch->envx = ch->envxx >> ENVX_SHIFT;
1382                     }
1383                     else
1384                     {
1385                         ch->env_error &= FIXED_POINT_REMAINDER;
1386                         ch->envx += step << 1;
1387                         ch->envxx = ch->envx << ENVX_SHIFT;
1388                     }
1389
1390                     if (ch->envx >= 126)
1391                     {
1392                         ch->envx = 127;
1393                         ch->envxx = 127 << ENVX_SHIFT;
1394                         ch->state = SOUND_GAIN;
1395                         ch->mode = MODE_GAIN;
1396                         S9xSetEnvRate (ch, 0, -1, 0);
1397                     }
1398                     break;
1399
1400                 case SOUND_DECREASE_LINEAR:
1401                     ch->env_error &= FIXED_POINT_REMAINDER;
1402                     ch->envx -= step << 1;
1403                     ch->envxx = ch->envx << ENVX_SHIFT;
1404                     if (ch->envx <= 0)
1405                     {
1406                         S9xAPUSetEndOfSample (J, ch);
1407                         goto mono_exit;
1408                     }
1409                     break;
1410
1411                 case SOUND_DECREASE_EXPONENTIAL:
1412                     while (ch->env_error >= FIXED_POINT)
1413                     {
1414                         ch->envxx = (ch->envxx >> 8) * 255;
1415                         ch->env_error -= FIXED_POINT;
1416                     }
1417                     ch->envx = ch->envxx >> ENVX_SHIFT;
1418                     if (ch->envx <= 0)
1419                     {
1420                         S9xAPUSetEndOfSample (J, ch);
1421                         goto mono_exit;
1422                     }
1423                     break;
1424                 
1425                 case SOUND_GAIN:
1426                     S9xSetEnvRate (ch, 0, -1, 0);
1427                     break;
1428                 }
1429                 ch->left_vol_level = (ch->envx * ch->volume_left) / 128;
1430                 V = (ch->sample * ch->left_vol_level) / 128;
1431             }
1432
1433             ch->count += freq;
1434             if (ch->count >= FIXED_POINT)
1435             {
1436                 V = ch->count >> FIXED_POINT_SHIFT;
1437                 ch->sample_pointer += V;
1438                 ch->count &= FIXED_POINT_REMAINDER;
1439
1440                 ch->sample = ch->next_sample;
1441                 if (ch->sample_pointer >= SOUND_DECODE_LENGTH)
1442                 {
1443                     if (JUST_PLAYED_LAST_SAMPLE(ch))
1444                     {
1445                         S9xAPUSetEndOfSample (J, ch);
1446                         goto mono_exit;
1447                     }
1448                     do
1449                     {
1450                         ch->sample_pointer -= SOUND_DECODE_LENGTH;
1451                         if (ch->last_block)
1452                         {
1453                             if (!ch->loop)
1454                             {
1455                                 ch->sample_pointer = LAST_SAMPLE;
1456                                 ch->next_sample = ch->sample;
1457                                 break;
1458                             }
1459                             else
1460                             {
1461                                 ch->last_block = FALSE;
1462                                 uint8 *dir = S9xGetSampleAddress (ch->sample_number);
1463                                 ch->block_pointer = READ_WORD(dir + 2);
1464                                 S9xAPUSetEndX (J);
1465                             }
1466                         }
1467                         AltDecodeBlock(ch, iapu);
1468                         //DecodeBlock (ch);
1469                     } while (ch->sample_pointer >= SOUND_DECODE_LENGTH);
1470                     if (!JUST_PLAYED_LAST_SAMPLE (ch))
1471                         ch->next_sample = ch->block [ch->sample_pointer];
1472                 }
1473                 else
1474                     ch->next_sample = ch->block [ch->sample_pointer];
1475
1476                 if (ch->type == SOUND_SAMPLE)
1477                 {
1478                     if (Settings.InterpolatedSound && freq < FIXED_POINT && !mod)
1479                     {
1480                         ch->interpolate = ((ch->next_sample - ch->sample) * 
1481                                            (long) freq) / (long) FIXED_POINT;
1482                         ch->sample = (int16) (ch->sample + (((ch->next_sample - ch->sample) * 
1483                                            (long) (ch->count)) / (long) FIXED_POINT));
1484                     }             
1485                     else
1486                         ch->interpolate = 0;
1487                 }
1488                 else
1489                 {
1490                     for (;V > 0; V--)
1491                         if ((so.noise_gen <<= 1) & 0x80000000L)
1492                             so.noise_gen ^= 0x0040001L;
1493                     ch->sample = (so.noise_gen << 17) >> 17;
1494                     ch->interpolate = 0;
1495                 }
1496                 V = (ch->sample * ch-> left_vol_level) / 128;
1497             }
1498             else
1499             {
1500                 if (ch->interpolate)
1501                 {
1502                     int32 s = (int32) ch->sample + ch->interpolate;
1503
1504                     CLIP16(s);
1505                     ch->sample = (int16) s;
1506                     V = (ch->sample * ch-> left_vol_level) / 128;
1507                 }
1508             }
1509
1510             MixBuffer [I] += V;
1511             ch->echo_buf_ptr [I] += V;
1512
1513             if (pitch_mod & (1 << (J + 1)))
1514                 wave [I] = ch->sample * ch->envx;
1515         }
1516 mono_exit: ;
1517     }
1518 }
1519 #ifdef __DJGPP
1520 END_OF_FUNCTION(MixMono);
1521 #endif
1522
1523 #ifdef __sun
1524 extern uint8 int2ulaw (int);
1525 #endif
1526
1527 // For backwards compatibility with older port specific code
1528 void S9xMixSamples (uint8 *buffer, int sample_count)
1529 {
1530     S9xMixSamplesO (buffer, sample_count, 0);
1531 }
1532 #ifdef __DJGPP
1533 END_OF_FUNCTION(S9xMixSamples);
1534 #endif
1535
1536 void S9xMixSamplesO (uint8 *buffer, int sample_count, int byte_offset)
1537 {
1538     int J;
1539     int I;
1540
1541     if (!so.mute_sound)
1542     {
1543             memset (MixBuffer, 0, sample_count * sizeof (MixBuffer [0]));
1544             if (SoundData.echo_enable)
1545                 memset (EchoBuffer, 0, sample_count * sizeof (EchoBuffer [0]));
1546
1547             if (so.stereo)
1548                 MixStereo (sample_count);
1549             else
1550                 MixMono (sample_count);
1551     }
1552
1553     /* Mix and convert waveforms */
1554     if (so.sixteen_bit)
1555     {
1556             int byte_count = sample_count << 1;
1557         
1558             // 16-bit sound
1559             if (so.mute_sound)
1560             {
1561                 memset (buffer + byte_offset, 0, byte_count);
1562             }
1563             else
1564             {
1565                 int O = byte_offset >> 1;
1566                 if (SoundData.echo_enable && SoundData.echo_buffer_size)
1567                 {
1568                         if (so.stereo)
1569                         {
1570                             // 16-bit stereo sound with echo enabled ...
1571                             if (SoundData.no_filter)
1572                             {
1573                                     // ... but no filter defined.
1574                                     for (J = 0; J < sample_count; J++)
1575                                     {
1576                                         int E = Echo [SoundData.echo_ptr];
1577
1578                                         Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 + EchoBuffer [J];
1579
1580                                         if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
1581                                 SoundData.echo_ptr = 0;
1582
1583                                         I = (MixBuffer [J] * SoundData.master_volume [J & 1] + E * SoundData.echo_volume [J & 1]) / VOL_DIV16;
1584
1585                                         CLIP16(I);
1586                                         ((signed short *) buffer)[J + O] = I;
1587                                     }
1588                             }
1589                             else
1590                             {
1591                                     // ... with filter defined.
1592                                     for (J = 0; J < sample_count; J++)
1593                                     {
1594                                         int E = Echo [SoundData.echo_ptr];
1595
1596                                         Loop [(Z - 0) & 15] = E;
1597                                         E =  E                    * FilterTaps [0];
1598                                         E += Loop [(Z -  2) & 15] * FilterTaps [1];
1599                                         E += Loop [(Z -  4) & 15] * FilterTaps [2];
1600                                         E += Loop [(Z -  6) & 15] * FilterTaps [3];
1601                                         E += Loop [(Z -  8) & 15] * FilterTaps [4];
1602                                         E += Loop [(Z - 10) & 15] * FilterTaps [5];
1603                                         E += Loop [(Z - 12) & 15] * FilterTaps [6];
1604                                         E += Loop [(Z - 14) & 15] * FilterTaps [7];
1605                                         E /= 128;
1606                                         Z++;
1607
1608                                         Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
1609                                                                     EchoBuffer [J];
1610
1611                                         if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
1612                                             SoundData.echo_ptr = 0;
1613
1614                                         I = (MixBuffer [J] * 
1615                                              SoundData.master_volume [J & 1] +
1616                                              E * SoundData.echo_volume [J & 1]) / VOL_DIV16;
1617
1618                                         CLIP16(I);
1619                                         ((signed short *) buffer)[J + O] = I;
1620                                     }
1621                             }
1622                         }
1623                         else
1624                         {
1625                             // 16-bit mono sound with echo enabled...
1626                             if (SoundData.no_filter)
1627                             {
1628                                     // ... no filter defined
1629                                     for (J = 0; J < sample_count; J++)
1630                                     {
1631                                         int E = Echo [SoundData.echo_ptr];
1632
1633                                         Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
1634                                                                      EchoBuffer [J];
1635
1636                                         if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
1637                                             SoundData.echo_ptr = 0;
1638
1639                                         I = (MixBuffer [J] *
1640                                              SoundData.master_volume [0] +
1641                                              E * SoundData.echo_volume [0]) / VOL_DIV16;
1642                                         CLIP16(I);
1643                                         ((signed short *) buffer)[J + O] = I;
1644                                     }
1645                             }
1646                             else
1647                             {
1648                                     // ... with filter defined
1649                                     for (J = 0; J < sample_count; J++)
1650                                     {
1651                                         int E = Echo [SoundData.echo_ptr];
1652
1653                                         Loop [(Z - 0) & 7] = E;
1654                                         E =  E                  * FilterTaps [0];
1655                                         E += Loop [(Z - 1) & 7] * FilterTaps [1];
1656                                         E += Loop [(Z - 2) & 7] * FilterTaps [2];
1657                                         E += Loop [(Z - 3) & 7] * FilterTaps [3];
1658                                         E += Loop [(Z - 4) & 7] * FilterTaps [4];
1659                                         E += Loop [(Z - 5) & 7] * FilterTaps [5];
1660                                         E += Loop [(Z - 6) & 7] * FilterTaps [6];
1661                                         E += Loop [(Z - 7) & 7] * FilterTaps [7];
1662                                         E /= 128;
1663                                         Z++;
1664
1665                                         Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
1666                                                                      EchoBuffer [J];
1667
1668                                         if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
1669                                             SoundData.echo_ptr = 0;
1670
1671                                         I = (MixBuffer [J] * SoundData.master_volume [0] +
1672                                              E * SoundData.echo_volume [0]) / VOL_DIV16;
1673                                         CLIP16(I);
1674                                         ((signed short *) buffer)[J + O] = I;
1675                                     }
1676                             }
1677                         }
1678                 }
1679                 else
1680                 {
1681                         // 16-bit mono or stereo sound, no echo
1682                         for (J = 0; J < sample_count; J++)
1683                         {
1684                             I = (MixBuffer [J] * 
1685                                  SoundData.master_volume [J & 1]) / VOL_DIV16;
1686
1687                             CLIP16(I);
1688                             ((signed short *) buffer)[J + O] = I;
1689                         }
1690                 }
1691             }
1692     }
1693     else
1694     {
1695             int O = byte_offset;
1696
1697             // 8-bit sound
1698             if (so.mute_sound)
1699             {
1700              memset (buffer + O, 128, sample_count);
1701             }
1702             else
1703 #ifdef __sun
1704                 if (so.encoded)
1705                 {
1706                     for (J = 0; J < sample_count; J++)
1707                     {
1708                         I = (MixBuffer [J] * SoundData.master_volume_left) / VOL_DIV16;
1709                         CLIP16(I);
1710                         buffer[J + O] = int2ulaw (I);
1711                     }
1712                 }
1713                 else
1714 #endif
1715             {
1716                 if (SoundData.echo_enable && SoundData.echo_buffer_size)
1717                 {
1718                         if (so.stereo)
1719                         {
1720                             // 8-bit stereo sound with echo enabled...
1721                             if (SoundData.no_filter)
1722                             {
1723                                     // ... but no filter
1724                                     for (J = 0; J < sample_count; J++)
1725                                     {
1726                                         int E = Echo [SoundData.echo_ptr];
1727
1728                                         Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 + 
1729                                                                     EchoBuffer [J];
1730
1731                                         if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
1732                                             SoundData.echo_ptr = 0;
1733
1734                                         I = (MixBuffer [J] * 
1735                                              SoundData.master_volume [J & 1] +
1736                                              E * SoundData.echo_volume [J & 1]) / VOL_DIV8;
1737                                         CLIP8(I);
1738                                         buffer [J + O] = I + 128;
1739                                     }
1740                             }
1741                             else
1742                             {
1743                                     // ... with filter
1744                                     for (J = 0; J < sample_count; J++)
1745                                     {
1746                                         int E = Echo [SoundData.echo_ptr];
1747
1748                                         Loop [(Z - 0) & 15] = E;
1749                                         E =  E                    * FilterTaps [0];
1750                                         E += Loop [(Z -  2) & 15] * FilterTaps [1];
1751                                         E += Loop [(Z -  4) & 15] * FilterTaps [2];
1752                                         E += Loop [(Z -  6) & 15] * FilterTaps [3];
1753                                         E += Loop [(Z -  8) & 15] * FilterTaps [4];
1754                                         E += Loop [(Z - 10) & 15] * FilterTaps [5];
1755                                         E += Loop [(Z - 12) & 15] * FilterTaps [6];
1756                                         E += Loop [(Z - 14) & 15] * FilterTaps [7];
1757                                         E /= 128;
1758                                         Z++;
1759
1760                                         Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 + 
1761                                                                     EchoBuffer [J];
1762
1763                                         if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
1764                                             SoundData.echo_ptr = 0;
1765
1766                                         I = (MixBuffer [J] * 
1767                                              SoundData.master_volume [J & 1] +
1768                                              E * SoundData.echo_volume [J & 1]) / VOL_DIV8;
1769                                         CLIP8(I);
1770                                         buffer [J + O] = I + 128;
1771                                     }
1772                             }
1773                         }
1774                         else
1775                         {
1776                             // 8-bit mono sound with echo enabled...
1777                             if (SoundData.no_filter)
1778                             {
1779                                     // ... but no filter.
1780                                     for (J = 0; J < sample_count; J++)
1781                                     {
1782                                         int E = Echo [SoundData.echo_ptr];
1783
1784                                         Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 + 
1785                                                                     EchoBuffer [J];
1786
1787                                         if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
1788                                             SoundData.echo_ptr = 0;
1789
1790                                         I = (MixBuffer [J] * SoundData.master_volume [0] +
1791                                              E * SoundData.echo_volume [0]) / VOL_DIV8;
1792                                         CLIP8(I);
1793                                         buffer [J + O] = I + 128;
1794                                     }
1795                             }
1796                             else
1797                             {
1798                                     // ... with filter.
1799                                     for (J = 0; J < sample_count; J++)
1800                                     {
1801                                         int E = Echo [SoundData.echo_ptr];
1802
1803                                         Loop [(Z - 0) & 7] = E;
1804                                         E =  E                  * FilterTaps [0];
1805                                         E += Loop [(Z - 1) & 7] * FilterTaps [1];
1806                                         E += Loop [(Z - 2) & 7] * FilterTaps [2];
1807                                         E += Loop [(Z - 3) & 7] * FilterTaps [3];
1808                                         E += Loop [(Z - 4) & 7] * FilterTaps [4];
1809                                         E += Loop [(Z - 5) & 7] * FilterTaps [5];
1810                                         E += Loop [(Z - 6) & 7] * FilterTaps [6];
1811                                         E += Loop [(Z - 7) & 7] * FilterTaps [7];
1812                                         E /= 128;
1813                                         Z++;
1814
1815                                         Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 + 
1816                                                                     EchoBuffer [J];
1817
1818                                         if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
1819                                             SoundData.echo_ptr = 0;
1820
1821                                         I = (MixBuffer [J] * SoundData.master_volume [0] +
1822                                              E * SoundData.echo_volume [0]) / VOL_DIV8;
1823                                         CLIP8(I);
1824                                         buffer [J + O] = I + 128;
1825                                     }
1826                             }
1827                         }
1828                 }
1829                 else
1830                 {
1831                         // 8-bit mono or stereo sound, no echo
1832                         for (J = 0; J < sample_count; J++)
1833                         {
1834                             I = (MixBuffer [J] * 
1835                                  SoundData.master_volume [J & 1]) / VOL_DIV8;
1836                             CLIP8(I);
1837                             buffer [J + O] = I + 128;
1838                         }
1839             }
1840             }
1841     }
1842 }
1843
1844 #ifdef __DJGPP
1845 END_OF_FUNCTION(S9xMixSamplesO);
1846 #endif
1847
1848 void S9xResetSound (bool8_32 full)
1849 {
1850     for (int i = 0; i < 8; i++)
1851     {
1852         SoundData.channels[i].state = SOUND_SILENT;
1853         SoundData.channels[i].mode = MODE_NONE;
1854         SoundData.channels[i].type = SOUND_SAMPLE;
1855         SoundData.channels[i].volume_left = 0;
1856         SoundData.channels[i].volume_right = 0;
1857         SoundData.channels[i].hertz = 0;
1858         SoundData.channels[i].count = 0;
1859         SoundData.channels[i].loop = FALSE;
1860         SoundData.channels[i].envx_target = 0;
1861         SoundData.channels[i].env_error = 0;
1862         SoundData.channels[i].erate = 0;
1863         SoundData.channels[i].envx = 0;
1864         SoundData.channels[i].envxx = 0;
1865         SoundData.channels[i].left_vol_level = 0;
1866         SoundData.channels[i].right_vol_level = 0;
1867         SoundData.channels[i].direction = 0;
1868         SoundData.channels[i].attack_rate = 0;
1869         SoundData.channels[i].decay_rate = 0;
1870         SoundData.channels[i].sustain_rate = 0;
1871         SoundData.channels[i].release_rate = 0;
1872         SoundData.channels[i].sustain_level = 0;
1873         SoundData.echo_ptr = 0;
1874         SoundData.echo_feedback = 0;
1875         SoundData.echo_buffer_size = 1;
1876     }
1877     FilterTaps [0] = 127;
1878     FilterTaps [1] = 0;
1879     FilterTaps [2] = 0;
1880     FilterTaps [3] = 0;
1881     FilterTaps [4] = 0;
1882     FilterTaps [5] = 0;
1883     FilterTaps [6] = 0;
1884     FilterTaps [7] = 0;
1885     so.mute_sound = TRUE;
1886     so.noise_gen = 1;
1887     so.sound_switch = 255;
1888     so.samples_mixed_so_far = 0;
1889     so.play_position = 0;
1890     so.err_counter = 0;
1891
1892     if (full)
1893     {
1894         SoundData.master_volume_left = 0;
1895         SoundData.master_volume_right = 0;
1896         SoundData.echo_volume_left = 0;
1897         SoundData.echo_volume_right = 0;
1898         SoundData.echo_enable = 0;
1899         SoundData.echo_write_enabled = 0;
1900         SoundData.echo_channel_enable = 0;
1901         SoundData.pitch_mod = 0;
1902         SoundData.dummy[0] = 0;
1903         SoundData.dummy[1] = 0;
1904         SoundData.dummy[2] = 0;
1905         SoundData.master_volume[0] = 0;
1906         SoundData.master_volume[1] = 0;
1907         SoundData.echo_volume[0] = 0;
1908         SoundData.echo_volume[1] = 0;
1909         SoundData.noise_hertz = 0;
1910     }
1911
1912     SoundData.master_volume_left = 127;
1913     SoundData.master_volume_right = 127;
1914     SoundData.master_volume [0] = SoundData.master_volume [1] = 127;
1915     if (so.playback_rate)
1916         so.err_rate = (uint32) (FIXED_POINT * SNES_SCANLINE_TIME / (1.0 / so.playback_rate));
1917     else
1918         so.err_rate = 0;
1919     SoundData.no_filter = TRUE;
1920 }
1921
1922 void S9xSetPlaybackRate (uint32 playback_rate)
1923 {
1924     so.playback_rate = playback_rate;
1925     so.err_rate = (uint32) (SNES_SCANLINE_TIME * FIXED_POINT / (1.0 / (double) so.playback_rate));
1926     S9xSetEchoDelay (APU.DSP [APU_EDL] & 0xf);
1927     for (int i = 0; i < 8; i++)
1928         S9xSetSoundFrequency (i, SoundData.channels [i].hertz);
1929 }
1930
1931 bool8_32 S9xInitSound (int mode, bool8_32 stereo, int buffer_size)
1932 {
1933     so.sound_fd = -1;
1934     so.sound_switch = 255;
1935
1936     so.playback_rate = mode;
1937     so.buffer_size = buffer_size;
1938     so.stereo = false;//stereo;
1939     so.sixteen_bit = Settings.SixteenBitSound;
1940     so.encoded = FALSE;
1941     
1942     S9xResetSound (TRUE);
1943
1944     //if (!(mode & 7))
1945         //return (1);
1946
1947     S9xSetSoundMute (TRUE);
1948     if (!S9xOpenSoundDevice (mode, stereo, buffer_size))
1949     {
1950         S9xMessage (S9X_ERROR, S9X_SOUND_DEVICE_OPEN_FAILED,
1951                     "Sound device open failed");
1952         return (0);
1953     }
1954
1955     return (1);
1956 }
1957
1958 bool8_32 S9xSetSoundMode (int channel, int mode)
1959 {
1960     Channel *ch = &SoundData.channels[channel];
1961
1962     switch (mode)
1963     {
1964     case MODE_RELEASE:
1965         if (ch->mode != MODE_NONE)
1966         {
1967             ch->mode = MODE_RELEASE;
1968             return (TRUE);
1969         }
1970         break;
1971         
1972     case MODE_DECREASE_LINEAR:
1973     case MODE_DECREASE_EXPONENTIAL:
1974     case MODE_GAIN:
1975         if (ch->mode != MODE_RELEASE)
1976         {
1977             ch->mode = mode;
1978             if (ch->state != SOUND_SILENT)
1979                 ch->state = mode;
1980
1981             return (TRUE);
1982         }
1983         break;
1984
1985     case MODE_INCREASE_LINEAR:
1986     case MODE_INCREASE_BENT_LINE:
1987         if (ch->mode != MODE_RELEASE)
1988         {
1989             ch->mode = mode;
1990             if (ch->state != SOUND_SILENT)
1991                 ch->state = mode;
1992
1993             return (TRUE);
1994         }
1995         break;
1996
1997     case MODE_ADSR:
1998         if (ch->mode == MODE_NONE || ch->mode == MODE_ADSR)
1999         {
2000             ch->mode = mode;
2001             return (TRUE);
2002         }
2003     }
2004
2005     return (FALSE);
2006 }
2007
2008 void S9xSetSoundControl (int sound_switch)
2009 {
2010     so.sound_switch = sound_switch;
2011 }
2012
2013 void S9xPlaySample (int channel)
2014 {
2015     Channel *ch = &SoundData.channels[channel];
2016     
2017     ch->state = SOUND_SILENT;
2018     ch->mode = MODE_NONE;
2019     ch->envx = 0;
2020     ch->envxx = 0;
2021
2022     S9xFixEnvelope (channel,
2023                     APU.DSP [APU_GAIN  + (channel << 4)], 
2024                     APU.DSP [APU_ADSR1 + (channel << 4)],
2025                     APU.DSP [APU_ADSR2 + (channel << 4)]);
2026
2027     ch->sample_number = APU.DSP [APU_SRCN + channel * 0x10];
2028     if (APU.DSP [APU_NON] & (1 << channel))
2029         ch->type = SOUND_NOISE;
2030     else
2031         ch->type = SOUND_SAMPLE;
2032
2033     S9xSetSoundFrequency (channel, ch->hertz);
2034     ch->loop = FALSE;
2035     ch->needs_decode = TRUE;
2036     ch->last_block = FALSE;
2037     ch->previous [0] = ch->previous[1] = 0;
2038     uint8 *dir = S9xGetSampleAddress (ch->sample_number);
2039     ch->block_pointer = READ_WORD (dir);
2040     ch->sample_pointer = 0;
2041     ch->env_error = 0;
2042     ch->next_sample = 0;
2043     ch->interpolate = 0;
2044
2045     switch (ch->mode)
2046     {
2047     case MODE_ADSR:
2048         if (ch->attack_rate == 0)
2049         {
2050             if (ch->decay_rate == 0 || ch->sustain_level == 8)
2051             {
2052                 ch->state = SOUND_SUSTAIN;
2053                 ch->envx = (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3;
2054                 S9xSetEnvRate (ch, ch->sustain_rate, -1, 0);
2055             }
2056             else
2057             {
2058                 ch->state = SOUND_DECAY;
2059                 ch->envx = MAX_ENVELOPE_HEIGHT;
2060                 S9xSetEnvRate (ch, ch->decay_rate, -1, 
2061                                     (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3);
2062             }
2063             ch-> left_vol_level = (ch->envx * ch->volume_left) / 128;
2064             ch->right_vol_level = (ch->envx * ch->volume_right) / 128;
2065         }
2066         else
2067         {
2068             ch->state = SOUND_ATTACK;
2069             ch->envx = 0;
2070             ch->left_vol_level = 0;
2071             ch->right_vol_level = 0;
2072             S9xSetEnvRate (ch, ch->attack_rate, 1, MAX_ENVELOPE_HEIGHT);
2073         }
2074         ch->envxx = ch->envx << ENVX_SHIFT;
2075         break;
2076
2077     case MODE_GAIN:
2078         ch->state = SOUND_GAIN;
2079         break;
2080
2081     case MODE_INCREASE_LINEAR:
2082         ch->state = SOUND_INCREASE_LINEAR;
2083         break;
2084
2085     case MODE_INCREASE_BENT_LINE:
2086         ch->state = SOUND_INCREASE_BENT_LINE;
2087         break;
2088
2089     case MODE_DECREASE_LINEAR:
2090         ch->state = SOUND_DECREASE_LINEAR;
2091         break;
2092
2093     case MODE_DECREASE_EXPONENTIAL:
2094         ch->state = SOUND_DECREASE_EXPONENTIAL;
2095         break;
2096
2097     default:
2098         break;
2099     }
2100
2101     S9xFixEnvelope (channel,
2102                     APU.DSP [APU_GAIN  + (channel << 4)], 
2103                     APU.DSP [APU_ADSR1 + (channel << 4)],
2104                     APU.DSP [APU_ADSR2 + (channel << 4)]);
2105 }