random bug fixes
[drnoksnes] / soundux.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 <stdint.h>
47 #include <stdlib.h>
48 #include <stdio.h>
49 #include <string.h>
50 #include <errno.h>
51 //#include <fcntl.h>
52
53 //misc.s
54 #ifdef __cplusplus
55 extern "C" {
56 #endif
57 extern void memcpy16(unsigned short *dest, unsigned short *src, int count);
58 extern void memcpy16bswap(unsigned short *dest, void *src, int count);
59 extern void memcpy32(uint32_t *dest, int *src, int count);
60 extern void memset32(void *dest, int c, int count);
61 #ifdef __cplusplus
62 }
63 #endif
64
65 #define CLIP16(v) \
66 if ((v) < -32768) \
67     (v) = -32768; \
68 else \
69 if ((v) > 32767) \
70     (v) = 32767
71
72 #define CLIP16_latch(v,l) \
73 if ((v) < -32768) \
74 { (v) = -32768; (l)++; }\
75 else \
76 if ((v) > 32767) \
77 { (v) = 32767; (l)++; }
78
79 #define CLIP24(v) \
80 if ((v) < -8388608) \
81     (v) = -8388608; \
82 else \
83 if ((v) > 8388607) \
84     (v) = 8388607
85
86 /*
87 #define CLIP8(v) \
88 if ((v) < -128) \
89     (v) = -128; \
90 else \
91 if ((v) > 127) \
92     (v) = 127
93 */
94
95
96 #include "snes9x.h"
97 #include "soundux.h"
98 #include "apu.h"
99 #include "memmap.h"
100 #include "cpuexec.h"
101 //#include "asmmemfuncs.h"
102
103
104 static int wave[SOUND_BUFFER_SIZE];
105
106 //extern int Echo [24000];
107 extern int MixBuffer [SOUND_BUFFER_SIZE];
108 //extern int EchoBuffer [SOUND_BUFFER_SIZE];
109 //extern int FilterTaps [8];
110 extern unsigned long Z;
111 //extern int Loop [16];
112
113 extern long FilterValues[4][2];
114 //extern int NoiseFreq [32];
115
116
117 //#define FIXED_POINT 0x10000UL
118 #define FIXED_POINT_REMAINDER 0xffffUL
119 #define FIXED_POINT_SHIFT 16
120
121 #define VOL_DIV8  0x8000
122 #define VOL_DIV16 0x0080
123 #define ENVX_SHIFT 24
124
125 extern "C" void DecodeBlockAsm (int8 *, int16 *, int32 *, int32 *);
126
127 // F is channel's current frequency and M is the 16-bit modulation waveform
128 // from the previous channel multiplied by the current envelope volume level.
129 #define PITCH_MOD(F,M) ((F) * ((((unsigned long) (M)) + 0x800000) >> 16) >> 7)
130 //#define PITCH_MOD(F,M) ((F) * ((((M) & 0x7fffff) >> 14) + 1) >> 8)
131
132 #define LAST_SAMPLE 0xffffff
133 #define JUST_PLAYED_LAST_SAMPLE(c) ((c)->sample_pointer >= LAST_SAMPLE)
134
135
136 static inline void S9xAPUSetEndOfSample (int i, Channel *ch)
137 {
138     ch->state = SOUND_SILENT;
139     ch->mode = MODE_NONE;
140     APU.DSP [APU_ENDX] |= 1 << i;
141     APU.DSP [APU_KON] &= ~(1 << i);
142     APU.DSP [APU_KOFF] &= ~(1 << i);
143     APU.KeyedChannels &= ~(1 << i);
144 }
145 #ifdef __DJGPP
146 END_OF_FUNCTION (S9xAPUSetEndOfSample)
147 #endif
148
149 static inline void S9xAPUSetEndX (int ch)
150 {
151     APU.DSP [APU_ENDX] |= 1 << ch;
152 }
153 #ifdef __DJGPP
154 END_OF_FUNCTION (S9xAPUSetEndX)
155 #endif
156
157 void S9xSetEchoDelay (int delay)
158 {
159     SoundData.echo_buffer_size = (512 * delay * so.playback_rate) >> 15; // notaz / 32000;
160     if (so.stereo)
161                 SoundData.echo_buffer_size <<= 1;
162     if (SoundData.echo_buffer_size) {
163                 while(SoundData.echo_ptr >= SoundData.echo_buffer_size)
164                         SoundData.echo_ptr -= SoundData.echo_buffer_size;
165     } else
166                 SoundData.echo_ptr = 0;
167     S9xSetEchoEnable (APU.DSP [APU_EON]);
168 }
169
170 void S9xSetSoundKeyOff (int channel)
171 {
172     Channel *ch = &SoundData.channels[channel];
173
174     if (ch->state != SOUND_SILENT)
175     {
176         ch->state = SOUND_RELEASE;
177         ch->mode = MODE_RELEASE;
178         S9xSetEnvRate (ch, 8, -1, 0, 5<<28);
179     }
180 }
181
182 void S9xFixSoundAfterSnapshotLoad ()
183 {
184     SoundData.echo_write_enabled = !(APU.DSP [APU_FLG] & 0x20);
185     SoundData.echo_channel_enable = APU.DSP [APU_EON];
186     S9xSetEchoDelay (APU.DSP [APU_EDL] & 0xf);
187     S9xSetEchoFeedback ((signed char) APU.DSP [APU_EFB]);
188
189     S9xSetFilterCoefficient (0, (signed char) APU.DSP [APU_C0]);
190     S9xSetFilterCoefficient (1, (signed char) APU.DSP [APU_C1]);
191     S9xSetFilterCoefficient (2, (signed char) APU.DSP [APU_C2]);
192     S9xSetFilterCoefficient (3, (signed char) APU.DSP [APU_C3]);
193     S9xSetFilterCoefficient (4, (signed char) APU.DSP [APU_C4]);
194     S9xSetFilterCoefficient (5, (signed char) APU.DSP [APU_C5]);
195     S9xSetFilterCoefficient (6, (signed char) APU.DSP [APU_C6]);
196     S9xSetFilterCoefficient (7, (signed char) APU.DSP [APU_C7]);
197  
198         for (int i = 0; i < 8; i++)
199     {
200                 SoundData.channels[i].needs_decode = TRUE;
201                 S9xSetSoundFrequency (i, SoundData.channels[i].hertz);
202                 SoundData.channels [i].envxx = SoundData.channels [i].envx << ENVX_SHIFT;
203                 SoundData.channels [i].next_sample = 0;
204                 SoundData.channels [i].interpolate = 0;
205                 SoundData.channels [i].previous [0] = (int32) SoundData.channels [i].previous16 [0];
206                 SoundData.channels [i].previous [1] = (int32) SoundData.channels [i].previous16 [1];
207     }
208     SoundData.master_volume [0] = SoundData.master_volume_left;
209     SoundData.master_volume [1] = SoundData.master_volume_right;
210     SoundData.echo_volume [0] = SoundData.echo_volume_left;
211     SoundData.echo_volume [1] = SoundData.echo_volume_right;
212     IAPU.Scanline = 0;
213 }
214
215 void S9xSetEnvelopeHeight (int channel, int level)
216 {
217     Channel *ch = &SoundData.channels[channel];
218
219     ch->envx = level;
220     ch->envxx = level << ENVX_SHIFT;
221
222     ch->left_vol_level = (level * ch->volume_left) / 128;
223     ch->right_vol_level = (level * ch->volume_right) / 128;
224
225     if (ch->envx == 0 && ch->state != SOUND_SILENT && ch->state != SOUND_GAIN)
226     {
227         S9xAPUSetEndOfSample (channel, ch);
228     }
229 }
230
231 #if 1
232 void S9xSetSoundSample (int, uint16) 
233 {
234 }
235 #else
236 void S9xSetSoundSample (int channel, uint16 sample_number)
237 {
238     register Channel *ch = &SoundData.channels[channel];
239
240     if (ch->state != SOUND_SILENT && 
241         sample_number != ch->sample_number)
242     {
243         int keep = ch->state;
244         ch->state = SOUND_SILENT;
245         ch->sample_number = sample_number;
246         ch->loop = FALSE;
247         ch->needs_decode = TRUE;
248         ch->last_block = FALSE;
249         ch->previous [0] = ch->previous[1] = 0;
250         ch->block_pointer = *S9xGetSampleAddress(sample_number);
251         ch->sample_pointer = 0;
252         ch->state = keep;
253     }
254 }
255 #endif
256
257 static void DecodeBlock (Channel *ch)
258 {
259     if (ch->block_pointer >= 0x10000 - 9)
260     {
261         ch->last_block = TRUE;
262         ch->loop = FALSE;
263         ch->block = ch->decoded;
264                 memset32 (ch->decoded, 0, 8);
265         return;
266     }
267     signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer];
268
269     unsigned char filter = *compressed;
270     if ((ch->last_block = filter & 1))
271         ch->loop = (filter & 2) != 0;
272
273     int16 *raw = ch->block = ch->decoded;
274
275 #if 0 //def ARM
276         DecodeBlockAsm (compressed, raw, &ch->previous [0], &ch->previous [1]);
277 #else
278         int32 out;
279     unsigned char shift;
280     signed char sample1, sample2;
281     unsigned int i;
282         
283     compressed++;
284     
285     int32 prev0 = ch->previous [0];
286     int32 prev1 = ch->previous [1];
287     shift = filter >> 4;
288         
289     switch ((filter >> 2) & 3)
290     {
291     case 0:
292                 for (i = 8; i != 0; i--)
293                 {
294                         sample1 = *compressed++;
295                         sample2 = sample1 << 4;
296                         sample2 >>= 4;
297                         sample1 >>= 4;
298                         *raw++ = ((int32) sample1 << shift);
299                         *raw++ = ((int32) sample2 << shift);
300                 }
301                 prev1 = *(raw - 2);
302                 prev0 = *(raw - 1);
303                 break;
304     case 1:
305                 for (i = 8; i != 0; i--)
306                 {
307                         sample1 = *compressed++;
308                         sample2 = sample1 << 4;
309                         sample2 >>= 4;
310                         sample1 >>= 4;
311                         prev0 = (int16) prev0;
312                         *raw++ = prev1 = ((int32) sample1 << shift) + prev0 - (prev0 >> 4);
313                         prev1 = (int16) prev1;
314                         *raw++ = prev0 = ((int32) sample2 << shift) + prev1 - (prev1 >> 4);
315                 }
316                 break;
317     case 2:
318                 for (i = 8; i != 0; i--)
319                 {
320                         sample1 = *compressed++;
321                         sample2 = sample1 << 4;
322                         sample2 >>= 4;
323                         sample1 >>= 4;
324                         
325                         out = (sample1 << shift) - prev1 + (prev1 >> 4);
326                         prev1 = (int16) prev0;
327                         prev0 &= ~3;
328                         *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) - 
329                                 (prev0 >> 4);
330                         
331                         out = (sample2 << shift) - prev1 + (prev1 >> 4);
332                         prev1 = (int16) prev0;
333                         prev0 &= ~3;
334                         *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) -
335                                 (prev0 >> 4);
336                 }
337                 break;
338     case 3:
339                 for (i = 8; i != 0; i--)
340                 {
341                         sample1 = *compressed++;
342                         sample2 = sample1 << 4;
343                         sample2 >>= 4;
344                         sample1 >>= 4;
345                         out = (sample1 << shift);
346                         
347                         out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);
348                         prev1 = (int16) prev0;
349                         prev0 &= ~3;
350                         *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - 
351                                 (prev0 >> 4) - (prev1 >> 6);
352                         
353                         out = (sample2 << shift);
354                         out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);
355                         prev1 = (int16) prev0;
356                         prev0 &= ~3;
357                         *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - 
358                                 (prev0 >> 4) - (prev1 >> 6);
359                 }
360                 break;
361     }
362     ch->previous [0] = prev0;
363     ch->previous [1] = prev1;
364 #endif
365     ch->block_pointer += 9;
366 }
367
368
369 static void MixStereo (int sample_count)
370 {
371     int pitch_mod = SoundData.pitch_mod & (0xFFFFFFFF^APU.DSP[APU_NON]);//~APU.DSP[APU_NON];
372
373     for (uint32 J = 0; J < NUM_CHANNELS; J++) 
374     {
375         int32 VL, VR;
376         Channel *ch = &SoundData.channels[J];
377         unsigned long freq0 = ch->frequency;
378
379         if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J)))
380             continue;
381
382 //              freq0 = (unsigned long) ((double) freq0 * 0.985);//uncommented by jonathan gevaryahu, as it is necessary for most cards in linux
383
384         bool8 mod = pitch_mod & (1 << J);
385
386         if (ch->needs_decode) 
387         {
388             DecodeBlock(ch);
389             ch->needs_decode = FALSE;
390             ch->sample = ch->block[0];
391             ch->sample_pointer = freq0 >> FIXED_POINT_SHIFT;
392             if (ch->sample_pointer == 0)
393                 ch->sample_pointer = 1;
394             if (ch->sample_pointer > SOUND_DECODE_LENGTH)
395                 ch->sample_pointer = SOUND_DECODE_LENGTH - 1;
396
397             ch->next_sample = ch->block[ch->sample_pointer];
398             ch->interpolate = 0;
399
400             if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod)
401                 ch->interpolate = ((ch->next_sample - ch->sample) * 
402                                    (long) freq0) / (long) FIXED_POINT;
403         }
404         VL = (ch->sample * ch-> left_vol_level) / 128;
405         VR = (ch->sample * ch->right_vol_level) / 128;
406
407         for (uint32 I = 0; I < (uint32) sample_count; I += 2)
408         {
409             unsigned long freq = freq0;
410
411             if (mod)
412                 freq = PITCH_MOD(freq, wave [I / 2]);
413
414             ch->env_error += ch->erate;
415             if (ch->env_error >= FIXED_POINT) 
416             {
417                 uint32 step = ch->env_error >> FIXED_POINT_SHIFT;
418
419                 switch (ch->state)
420                 {
421                 case SOUND_ATTACK:
422                     ch->env_error &= FIXED_POINT_REMAINDER;
423                     ch->envx += step << 1;
424                     ch->envxx = ch->envx << ENVX_SHIFT;
425
426                     if (ch->envx >= 126)
427                     {
428                         ch->envx = 127;
429                         ch->envxx = 127 << ENVX_SHIFT;
430                         ch->state = SOUND_DECAY;
431                         if (ch->sustain_level != 8) 
432                         {
433                             S9xSetEnvRate (ch, ch->decay_rate, -1,
434                                                 (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3, 1<<28);
435                             break;
436                         }
437                         ch->state = SOUND_SUSTAIN;
438                         S9xSetEnvRate (ch, ch->sustain_rate, -1, 0, 2<<28);
439                     }
440                     break;
441                 
442                 case SOUND_DECAY:
443                     while (ch->env_error >= FIXED_POINT)
444                     {
445                         ch->envxx = (ch->envxx >> 8) * 255;
446                         ch->env_error -= FIXED_POINT;
447                     }
448                     ch->envx = ch->envxx >> ENVX_SHIFT;
449                     if (ch->envx <= ch->envx_target)
450                     {
451                         if (ch->envx <= 0)
452                         {
453                             S9xAPUSetEndOfSample (J, ch);
454                             goto stereo_exit;
455                         }
456                         ch->state = SOUND_SUSTAIN;
457                         S9xSetEnvRate (ch, ch->sustain_rate, -1, 0, 2<<28);
458                     }
459                     break;
460
461                 case SOUND_SUSTAIN:
462                     while (ch->env_error >= FIXED_POINT)
463                     {
464                         ch->envxx = (ch->envxx >> 8) * 255;
465                         ch->env_error -= FIXED_POINT;
466                     }
467                     ch->envx = ch->envxx >> ENVX_SHIFT;
468                     if (ch->envx <= 0)
469                     {
470                         S9xAPUSetEndOfSample (J, ch);
471                         goto stereo_exit;
472                     }
473                     break;
474                     
475                 case SOUND_RELEASE:
476                     while (ch->env_error >= FIXED_POINT)
477                     {
478                         ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
479                         ch->env_error -= FIXED_POINT;
480                     }
481                     ch->envx = ch->envxx >> ENVX_SHIFT;
482                     if (ch->envx <= 0)
483                     {
484                         S9xAPUSetEndOfSample (J, ch);
485                         goto stereo_exit;
486                     }
487                     break;
488                 
489                 case SOUND_INCREASE_LINEAR:
490                     ch->env_error &= FIXED_POINT_REMAINDER;
491                     ch->envx += step << 1;
492                     ch->envxx = ch->envx << ENVX_SHIFT;
493
494                     if (ch->envx >= 126)
495                     {
496                         ch->envx = 127;
497                         ch->envxx = 127 << ENVX_SHIFT;
498                         ch->state = SOUND_GAIN;
499                         ch->mode = MODE_GAIN;
500                         S9xSetEnvRate (ch, 0, -1, 0, 0);
501                     }
502                     break;
503
504                 case SOUND_INCREASE_BENT_LINE:
505                     if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4)
506                     {
507                         while (ch->env_error >= FIXED_POINT)
508                         {
509                             ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
510                             ch->env_error -= FIXED_POINT;
511                         }
512                         ch->envx = ch->envxx >> ENVX_SHIFT;
513                     }
514                     else
515                     {
516                         ch->env_error &= FIXED_POINT_REMAINDER;
517                         ch->envx += step << 1;
518                         ch->envxx = ch->envx << ENVX_SHIFT;
519                     }
520
521                     if (ch->envx >= 126)
522                     {
523                         ch->envx = 127;
524                         ch->envxx = 127 << ENVX_SHIFT;
525                         ch->state = SOUND_GAIN;
526                         ch->mode = MODE_GAIN;
527                         S9xSetEnvRate (ch, 0, -1, 0, 0);
528                     }
529                     break;
530
531                 case SOUND_DECREASE_LINEAR:
532                     ch->env_error &= FIXED_POINT_REMAINDER;
533                     ch->envx -= step << 1;
534                     ch->envxx = ch->envx << ENVX_SHIFT;
535                     if (ch->envx <= 0)
536                     {
537                         S9xAPUSetEndOfSample (J, ch);
538                         goto stereo_exit;
539                     }
540                     break;
541
542                 case SOUND_DECREASE_EXPONENTIAL:
543                     while (ch->env_error >= FIXED_POINT)
544                     {
545                         ch->envxx = (ch->envxx >> 8) * 255;
546                         ch->env_error -= FIXED_POINT;
547                     }
548                     ch->envx = ch->envxx >> ENVX_SHIFT;
549                     if (ch->envx <= 0)
550                     {
551                         S9xAPUSetEndOfSample (J, ch);
552                         goto stereo_exit;
553                     }
554                     break;
555                 
556                 case SOUND_GAIN:
557                     S9xSetEnvRate (ch, 0, -1, 0, 0);
558                     break;
559                 }
560                 ch-> left_vol_level = (ch->envx * ch->volume_left) / 128;
561                 ch->right_vol_level = (ch->envx * ch->volume_right) / 128;
562                 VL = (ch->sample * ch-> left_vol_level) / 128;
563                 VR = (ch->sample * ch->right_vol_level) / 128;
564             }
565
566             ch->count += freq;
567             if (ch->count >= FIXED_POINT)
568             {
569                         VL = ch->count >> FIXED_POINT_SHIFT;
570                         ch->sample_pointer += VL;
571                         ch->count &= FIXED_POINT_REMAINDER;
572
573                         ch->sample = ch->next_sample;
574                         if (ch->sample_pointer >= SOUND_DECODE_LENGTH)
575                         {
576                                 if (JUST_PLAYED_LAST_SAMPLE(ch))
577                                 {
578                                         S9xAPUSetEndOfSample (J, ch);
579                                         goto stereo_exit;
580                                 }
581                                 do
582                                 {
583                                         ch->sample_pointer -= SOUND_DECODE_LENGTH;
584                                         if (ch->last_block)
585                                         {
586                                                 if (!ch->loop)
587                                                 {
588                                                         ch->sample_pointer = LAST_SAMPLE;
589                                                         ch->next_sample = ch->sample;
590                                                         break;
591                                                 }
592                                                 else
593                                                 {
594                                                         S9xAPUSetEndX (J);
595                                                         ch->last_block = FALSE;
596                                                         uint16 *dir = S9xGetSampleAddress (ch->sample_number);
597                                                         ch->block_pointer = *(dir + 1);
598                                                 }
599                                         }
600                                         DecodeBlock (ch);
601                                 } while (ch->sample_pointer >= SOUND_DECODE_LENGTH);
602                                 if (!JUST_PLAYED_LAST_SAMPLE (ch))
603                                         ch->next_sample = ch->block [ch->sample_pointer];
604                         }
605                         else
606                                 ch->next_sample = ch->block [ch->sample_pointer];
607
608                         if (ch->type == SOUND_SAMPLE)
609                         {
610                                 if (Settings.InterpolatedSound && freq < FIXED_POINT && !mod)
611                                 {
612                                         ch->interpolate = ((ch->next_sample - ch->sample) * 
613                                                            (long) freq) / (long) FIXED_POINT;
614                                         ch->sample = (int16) (ch->sample + (((ch->next_sample - ch->sample) * 
615                                                            (long) (ch->count)) / (long) FIXED_POINT));
616                                 }                 
617                                 else
618                                         ch->interpolate = 0;
619                         }
620                         else
621                         {
622                                 for (;VL > 0; VL--)
623                                         if ((so.noise_gen <<= 1) & 0x80000000L)
624                                                 so.noise_gen ^= 0x0040001L;
625                                 ch->sample = (so.noise_gen << 17) >> 17;
626                                 ch->interpolate = 0;
627                         }
628
629                         VL = (ch->sample * ch-> left_vol_level) / 128;
630                         VR = (ch->sample * ch->right_vol_level) / 128;
631                 }
632             else
633             {
634                         if (ch->interpolate)
635                         {
636                                 int32 s = (int32) ch->sample + ch->interpolate;
637                                 
638                                 CLIP16(s);
639                                 ch->sample = (int16) s;
640                                 VL = (ch->sample * ch-> left_vol_level) / 128;
641                                 VR = (ch->sample * ch->right_vol_level) / 128;
642                         }
643             }
644
645             if (pitch_mod & (1 << (J + 1)))
646                         wave [I / 2] = ch->sample * ch->envx;
647
648                 MixBuffer [I]   += VL;
649                 MixBuffer [I+1] += VR;
650                 if (ch->echo_buf_ptr)
651                 {
652                         ch->echo_buf_ptr [I]   += VL;
653                         ch->echo_buf_ptr [I+1] += VR;
654                 }
655         }
656 stereo_exit: ;
657     }
658 }
659
660 static void MixMono (int sample_count)
661 {
662     int pitch_mod = SoundData.pitch_mod & (0xFFFFFFFF^APU.DSP[APU_NON]);
663
664     for (uint32 J = 0; J < NUM_CHANNELS; J++) 
665     {
666         Channel *ch = &SoundData.channels[J];
667         unsigned long freq0 = ch->frequency;
668
669         if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J)))
670             continue;
671
672 //      freq0 = (unsigned long) ((double) freq0 * 0.985);
673
674         bool8 mod = pitch_mod & (1 << J);
675
676         if (ch->needs_decode) 
677         {
678             DecodeBlock(ch);
679             ch->needs_decode = FALSE;
680             ch->sample = ch->block[0];
681             ch->sample_pointer = freq0 >> FIXED_POINT_SHIFT;
682             if (ch->sample_pointer == 0)
683                 ch->sample_pointer = 1;
684             if (ch->sample_pointer > SOUND_DECODE_LENGTH)
685                 ch->sample_pointer = SOUND_DECODE_LENGTH - 1;
686             ch->next_sample = ch->block[ch->sample_pointer];
687             ch->interpolate = 0;
688
689             if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod)
690                 ch->interpolate = ((ch->next_sample - ch->sample) * 
691                                    (long) freq0) / (long) FIXED_POINT;
692         }
693         int32 V = (ch->sample * ch->left_vol_level) / 128;
694
695         for (uint32 I = 0; I < (uint32) sample_count; I++)
696         {
697             unsigned long freq = freq0;
698
699             if (mod)
700                 freq = PITCH_MOD(freq, wave [I]);
701
702             ch->env_error += ch->erate;
703             if (ch->env_error >= FIXED_POINT) 
704             {
705                 uint32 step = ch->env_error >> FIXED_POINT_SHIFT;
706
707                 switch (ch->state)
708                 {
709                 case SOUND_ATTACK:
710                     ch->env_error &= FIXED_POINT_REMAINDER;
711                     ch->envx += step << 1;
712                     ch->envxx = ch->envx << ENVX_SHIFT;
713
714                     if (ch->envx >= 126)
715                     {
716                         ch->envx = 127;
717                         ch->envxx = 127 << ENVX_SHIFT;
718                         ch->state = SOUND_DECAY;
719                         if (ch->sustain_level != 8) 
720                         {
721                             S9xSetEnvRate (ch, ch->decay_rate, -1,
722                                                 (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3, 1<<28);
723                             break;
724                         }
725                         ch->state = SOUND_SUSTAIN;
726                         S9xSetEnvRate (ch, ch->sustain_rate, -1, 0, 2<<28);
727                     }
728                     break;
729                 
730                 case SOUND_DECAY:
731                     while (ch->env_error >= FIXED_POINT)
732                     {
733                         ch->envxx = (ch->envxx >> 8) * 255;
734                         ch->env_error -= FIXED_POINT;
735                     }
736                     ch->envx = ch->envxx >> ENVX_SHIFT;
737                     if (ch->envx <= ch->envx_target)
738                     {
739                         if (ch->envx <= 0)
740                         {
741                             S9xAPUSetEndOfSample (J, ch);
742                             goto mono_exit;
743                         }
744                         ch->state = SOUND_SUSTAIN;
745                         S9xSetEnvRate (ch, ch->sustain_rate, -1, 0, 2<<28);
746                     }
747                     break;
748
749                 case SOUND_SUSTAIN:
750                     while (ch->env_error >= FIXED_POINT)
751                     {
752                         ch->envxx = (ch->envxx >> 8) * 255;
753                         ch->env_error -= FIXED_POINT;
754                     }
755                     ch->envx = ch->envxx >> ENVX_SHIFT;
756                     if (ch->envx <= 0)
757                     {
758                         S9xAPUSetEndOfSample (J, ch);
759                         goto mono_exit;
760                     }
761                     break;
762                     
763                 case SOUND_RELEASE:
764                     while (ch->env_error >= FIXED_POINT)
765                     {
766                         ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
767                         ch->env_error -= FIXED_POINT;
768                     }
769                     ch->envx = ch->envxx >> ENVX_SHIFT;
770                     if (ch->envx <= 0)
771                     {
772                         S9xAPUSetEndOfSample (J, ch);
773                         goto mono_exit;
774                     }
775                     break;
776                 
777                 case SOUND_INCREASE_LINEAR:
778                     ch->env_error &= FIXED_POINT_REMAINDER;
779                     ch->envx += step << 1;
780                     ch->envxx = ch->envx << ENVX_SHIFT;
781
782                     if (ch->envx >= 126)
783                     {
784                         ch->envx = 127;
785                         ch->envxx = 127 << ENVX_SHIFT;
786                         ch->state = SOUND_GAIN;
787                         ch->mode = MODE_GAIN;
788                         S9xSetEnvRate (ch, 0, -1, 0, 0);
789                     }
790                     break;
791
792                 case SOUND_INCREASE_BENT_LINE:
793                     if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4)
794                     {
795                         while (ch->env_error >= FIXED_POINT)
796                         {
797                             ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
798                             ch->env_error -= FIXED_POINT;
799                         }
800                         ch->envx = ch->envxx >> ENVX_SHIFT;
801                     }
802                     else
803                     {
804                         ch->env_error &= FIXED_POINT_REMAINDER;
805                         ch->envx += step << 1;
806                         ch->envxx = ch->envx << ENVX_SHIFT;
807                     }
808
809                     if (ch->envx >= 126)
810                     {
811                         ch->envx = 127;
812                         ch->envxx = 127 << ENVX_SHIFT;
813                         ch->state = SOUND_GAIN;
814                         ch->mode = MODE_GAIN;
815                         S9xSetEnvRate (ch, 0, -1, 0, 0);
816                     }
817                     break;
818
819                 case SOUND_DECREASE_LINEAR:
820                     ch->env_error &= FIXED_POINT_REMAINDER;
821                     ch->envx -= step << 1;
822                     ch->envxx = ch->envx << ENVX_SHIFT;
823                     if (ch->envx <= 0)
824                     {
825                         S9xAPUSetEndOfSample (J, ch);
826                         goto mono_exit;
827                     }
828                     break;
829
830                 case SOUND_DECREASE_EXPONENTIAL:
831                     while (ch->env_error >= FIXED_POINT)
832                     {
833                         ch->envxx = (ch->envxx >> 8) * 255;
834                         ch->env_error -= FIXED_POINT;
835                     }
836                     ch->envx = ch->envxx >> ENVX_SHIFT;
837                     if (ch->envx <= 0)
838                     {
839                         S9xAPUSetEndOfSample (J, ch);
840                         goto mono_exit;
841                     }
842                     break;
843                 
844                 case SOUND_GAIN:
845                     S9xSetEnvRate (ch, 0, -1, 0, 0);
846                     break;
847                 }
848                 ch->left_vol_level = (ch->envx * ch->volume_left) / 128;
849                 V = (ch->sample * ch->left_vol_level) / 128;
850             }
851
852             ch->count += freq;
853             if (ch->count >= FIXED_POINT)
854             {
855                 V = ch->count >> FIXED_POINT_SHIFT;
856                 ch->sample_pointer += V;
857                 ch->count &= FIXED_POINT_REMAINDER;
858
859                 ch->sample = ch->next_sample;
860                 if (ch->sample_pointer >= SOUND_DECODE_LENGTH)
861                 {
862                     if (JUST_PLAYED_LAST_SAMPLE(ch))
863                     {
864                         S9xAPUSetEndOfSample (J, ch);
865                         goto mono_exit;
866                     }
867                     do
868                     {
869                         ch->sample_pointer -= SOUND_DECODE_LENGTH;
870                         if (ch->last_block)
871                         {
872                             if (!ch->loop)
873                             {
874                                 ch->sample_pointer = LAST_SAMPLE;
875                                 ch->next_sample = ch->sample;
876                                 break;
877                             }
878                             else
879                             {
880                                 ch->last_block = FALSE;
881                                 uint16 *dir = S9xGetSampleAddress (ch->sample_number);
882                                 ch->block_pointer = *(dir + 1);
883                                 S9xAPUSetEndX (J);
884                             }
885                         }
886                         DecodeBlock (ch);
887                     } while (ch->sample_pointer >= SOUND_DECODE_LENGTH);
888                     if (!JUST_PLAYED_LAST_SAMPLE (ch))
889                         ch->next_sample = ch->block [ch->sample_pointer];
890                 }
891                 else
892                     ch->next_sample = ch->block [ch->sample_pointer];
893
894                 if (ch->type == SOUND_SAMPLE)
895                 {
896                     if (Settings.InterpolatedSound && freq < FIXED_POINT && !mod)
897                     {
898                         ch->interpolate = ((ch->next_sample - ch->sample) * 
899                                            (long) freq) / (long) FIXED_POINT;
900                         ch->sample = (int16) (ch->sample + (((ch->next_sample - ch->sample) * 
901                                            (long) (ch->count)) / (long) FIXED_POINT));
902                     }             
903                     else
904                         ch->interpolate = 0;
905                 }
906                 else
907                 {
908                     for (;V > 0; V--)
909                         if ((so.noise_gen <<= 1) & 0x80000000L)
910                             so.noise_gen ^= 0x0040001L;
911                     ch->sample = (so.noise_gen << 17) >> 17;
912                     ch->interpolate = 0;
913                 }
914                 V = (ch->sample * ch-> left_vol_level) / 128;
915             }
916             else
917             {
918                 if (ch->interpolate)
919                 {
920                     int32 s = (int32) ch->sample + ch->interpolate;
921
922                     CLIP16(s);
923                     ch->sample = (int16) s;
924                     V = (ch->sample * ch-> left_vol_level) / 128;
925                 }
926             }
927
928             MixBuffer [I] += V;
929                 if (ch->echo_buf_ptr)
930                     ch->echo_buf_ptr [I] += V;
931
932             if (pitch_mod & (1 << (J + 1)))
933                 wave [I] = ch->sample * ch->envx;
934         }
935 mono_exit: ;
936     }
937 }
938
939
940 // For backwards compatibility with older port specific code
941 void S9xMixSamples (signed short *buffer, int sample_count)
942 {
943     S9xMixSamplesO (buffer, sample_count, 0);
944 }
945
946
947 void S9xMixSamplesO (signed short *buffer, int sample_count, int sample_offset)
948 {
949         // 16-bit sound only
950         int J;
951
952         buffer += sample_offset;
953
954         if (so.mute_sound)
955         {
956                 memset32(buffer, 0, sample_count>>1);
957                 return;
958         }
959
960         memset32 (MixBuffer, 0, sample_count);
961         if (SoundData.echo_enable)
962                 memset32 (EchoBuffer, 0, sample_count);
963
964         if (so.stereo)
965                 MixStereo (sample_count);
966         else
967                 MixMono (sample_count);
968
969     /* Mix and convert waveforms */
970         if (SoundData.echo_enable && SoundData.echo_buffer_size)
971         {
972                 if (so.stereo)
973                 {
974                         int l, r;
975                         int master_vol_l = SoundData.master_volume[0];
976                         int master_vol_r = SoundData.master_volume[1];
977                         int echo_vol_l = SoundData.echo_volume[0];
978                         int echo_vol_r = SoundData.echo_volume[1];
979
980                         // 16-bit stereo sound with echo enabled ...
981                         if (SoundData.no_filter)
982                         {
983                                 // ... but no filter defined.
984                                 for (J = 0; J < sample_count; J+=2)
985                                 {
986                                         int E = Echo [SoundData.echo_ptr];
987
988                                         Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J];
989                                         Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J+1];
990
991                                         if (SoundData.echo_ptr >= SoundData.echo_buffer_size)
992                                                 SoundData.echo_ptr = 0;
993
994                                         l = (MixBuffer[J]   * master_vol_l + E * echo_vol_l) / VOL_DIV16;
995                                         r = (MixBuffer[J+1] * master_vol_r + E * echo_vol_r) / VOL_DIV16;
996
997                                         CLIP16(l);
998                                         CLIP16(r);
999                                         buffer[J]   = l;
1000                                         buffer[J+1] = r;
1001                                 }
1002                         }
1003                         else
1004                         {
1005                                 // ... with filter defined.
1006                                 for (J = 0; J < sample_count; J+=2)
1007                                 {
1008                                         register int E = Echo [SoundData.echo_ptr];
1009
1010                                         Loop [(Z - 0) & 15] = E;
1011                                         E =  E                    * FilterTaps [0];
1012                                         E += Loop [(Z -  2) & 15] * FilterTaps [1];
1013                                         E += Loop [(Z -  4) & 15] * FilterTaps [2];
1014                                         E += Loop [(Z -  6) & 15] * FilterTaps [3];
1015                                         E += Loop [(Z -  8) & 15] * FilterTaps [4];
1016                                         E += Loop [(Z - 10) & 15] * FilterTaps [5];
1017                                         E += Loop [(Z - 12) & 15] * FilterTaps [6];
1018                                         E += Loop [(Z - 14) & 15] * FilterTaps [7];
1019                                         E /= 128;
1020                                         Z++;
1021
1022                                         Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J];
1023                                         Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J+1];
1024
1025                                         if (SoundData.echo_ptr >= SoundData.echo_buffer_size)
1026                                                 SoundData.echo_ptr = 0;
1027
1028                                         l = (MixBuffer[J]   * master_vol_l + E * echo_vol_l) / VOL_DIV16;
1029                                         r = (MixBuffer[J+1] * master_vol_r + E * echo_vol_r) / VOL_DIV16;
1030
1031                                         CLIP16(l);
1032                                         CLIP16(r);
1033                                         buffer[J]   = l;
1034                                         buffer[J+1] = r;
1035                                 }
1036                         }
1037                 }
1038                 else
1039                 {
1040                         int I;
1041                         int master_vol_l = SoundData.master_volume[0];
1042                         int echo_vol_l = SoundData.echo_volume[0];
1043
1044                         // 16-bit mono sound with echo enabled...
1045                         if (SoundData.no_filter)
1046                         {
1047                                 // ... no filter defined
1048                                 for (J = 0; J < sample_count; J++)
1049                                 {
1050                                         int E = Echo [SoundData.echo_ptr];
1051
1052                                         Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J];
1053
1054                                         if (SoundData.echo_ptr >= SoundData.echo_buffer_size)
1055                                                 SoundData.echo_ptr = 0;
1056
1057                                         I = (MixBuffer[J] * master_vol_l + E * echo_vol_l) / VOL_DIV16;
1058                                         CLIP16(I);
1059                                         buffer[J] = I;
1060                                 }
1061                         }
1062                         else
1063                         {
1064                                 // ... with filter defined
1065                                 for (J = 0; J < sample_count; J++)
1066                                 {
1067                                         register int E = Echo [SoundData.echo_ptr];
1068
1069                                         Loop [(Z - 0) & 7] = E;
1070                                         E =  E                  * FilterTaps [0];
1071                                         E += Loop [(Z - 1) & 7] * FilterTaps [1];
1072                                         E += Loop [(Z - 2) & 7] * FilterTaps [2];
1073                                         E += Loop [(Z - 3) & 7] * FilterTaps [3];
1074                                         E += Loop [(Z - 4) & 7] * FilterTaps [4];
1075                                         E += Loop [(Z - 5) & 7] * FilterTaps [5];
1076                                         E += Loop [(Z - 6) & 7] * FilterTaps [6];
1077                                         E += Loop [(Z - 7) & 7] * FilterTaps [7];
1078                                         E /= 128;
1079                                         Z++;
1080
1081                                         Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J];
1082
1083                                         if (SoundData.echo_ptr >= SoundData.echo_buffer_size)
1084                                                 SoundData.echo_ptr = 0;
1085
1086                                         I = (MixBuffer[J] * master_vol_l + E * echo_vol_l) / VOL_DIV16;
1087                                         CLIP16(I);
1088                                         buffer[J] = I;
1089                                 }
1090                         }
1091                 }
1092         }
1093         else
1094         {
1095                 int l, master_vol_l = SoundData.master_volume[0];
1096
1097                 if (so.stereo)
1098                 {
1099                         int r, master_vol_r = SoundData.master_volume[1];
1100
1101                         // 16-bit stereo sound, no echo
1102                         for (J = 0; J < sample_count; J+=2)
1103                         {
1104                                 l = (MixBuffer[J]   * master_vol_l) / VOL_DIV16;
1105                                 r = (MixBuffer[J+1] * master_vol_r) / VOL_DIV16;
1106
1107                                 CLIP16(l);
1108                                 CLIP16(r);
1109                                 buffer[J]   = l;
1110                                 buffer[J+1] = r;
1111                         }
1112                 }
1113                 else
1114                 {
1115                         // 16-bit mono sound, no echo
1116                         for (J = 0; J < sample_count; J++)
1117                         {
1118                                 l = (MixBuffer[J] * master_vol_l) / VOL_DIV16;
1119
1120                                 CLIP16(l);
1121                                 buffer[J] = l;
1122                         }
1123                 }
1124         }
1125 }
1126
1127 #ifdef __DJGPP
1128 END_OF_FUNCTION(S9xMixSamplesO);
1129 #endif
1130
1131 void S9xResetSound (bool8 full)
1132 {
1133     for (int i = 0; i < 8; i++)
1134     {
1135         SoundData.channels[i].state = SOUND_SILENT;
1136         SoundData.channels[i].mode = MODE_NONE;
1137         SoundData.channels[i].type = SOUND_SAMPLE;
1138         SoundData.channels[i].volume_left = 0;
1139         SoundData.channels[i].volume_right = 0;
1140         SoundData.channels[i].hertz = 0;
1141         SoundData.channels[i].count = 0;
1142         SoundData.channels[i].loop = FALSE;
1143         SoundData.channels[i].envx_target = 0;
1144         SoundData.channels[i].env_error = 0;
1145         SoundData.channels[i].erate = 0;
1146         SoundData.channels[i].envx = 0;
1147         SoundData.channels[i].envxx = 0;
1148         SoundData.channels[i].left_vol_level = 0;
1149         SoundData.channels[i].right_vol_level = 0;
1150         SoundData.channels[i].direction = 0;
1151         SoundData.channels[i].attack_rate = 0;
1152         SoundData.channels[i].decay_rate = 0;
1153         SoundData.channels[i].sustain_rate = 0;
1154         SoundData.channels[i].release_rate = 0;
1155         SoundData.channels[i].sustain_level = 0;
1156         // notaz
1157         SoundData.channels[i].env_ind_attack = 0;
1158         SoundData.channels[i].env_ind_decay = 0;
1159         SoundData.channels[i].env_ind_sustain = 0;
1160         SoundData.echo_ptr = 0;
1161         SoundData.echo_feedback = 0;
1162         SoundData.echo_buffer_size = 1;
1163     }
1164     FilterTaps [0] = 127;
1165     FilterTaps [1] = 0;
1166     FilterTaps [2] = 0;
1167     FilterTaps [3] = 0;
1168     FilterTaps [4] = 0;
1169     FilterTaps [5] = 0;
1170     FilterTaps [6] = 0;
1171     FilterTaps [7] = 0;
1172     so.mute_sound = TRUE;
1173     so.noise_gen = 1;
1174     so.sound_switch = 255;
1175
1176     if (full)
1177     {
1178                 SoundData.master_volume_left = 0;
1179                 SoundData.master_volume_right = 0;
1180                 SoundData.echo_volume_left = 0;
1181                 SoundData.echo_volume_right = 0;
1182                 SoundData.echo_enable = 0;
1183                 SoundData.echo_write_enabled = 0;
1184                 SoundData.echo_channel_enable = 0;
1185                 SoundData.pitch_mod = 0;
1186                 SoundData.dummy[0] = 0;
1187                 SoundData.dummy[1] = 0;
1188                 SoundData.dummy[2] = 0;
1189                 SoundData.master_volume[0] = 0;
1190                 SoundData.master_volume[1] = 0;
1191                 SoundData.echo_volume[0] = 0;
1192                 SoundData.echo_volume[1] = 0;
1193                 SoundData.noise_hertz = 0;
1194     }
1195
1196     SoundData.master_volume_left = 127;
1197     SoundData.master_volume_right = 127;
1198     SoundData.master_volume [0] = SoundData.master_volume [1] = 127;
1199     SoundData.no_filter = TRUE;
1200 }
1201
1202
1203
1204 extern unsigned long AttackRate [16];
1205 extern unsigned long DecayRate [8];
1206 extern unsigned long SustainRate [32];
1207 extern unsigned long IncreaseRate [32];
1208 extern unsigned long DecreaseRateExp [32];      
1209
1210
1211 void S9xSetPlaybackRate (uint32 playback_rate)
1212 {
1213     so.playback_rate = playback_rate;
1214
1215         if(playback_rate) {
1216                 // notaz: calclulate a value (let's call it freqbase) to simplify channel freq calculations later.
1217                 so.freqbase = (FIXED_POINT<<11) / playback_rate;
1218                 // now precalculate env rates for S9xSetEnvRate
1219                 static int steps [] =
1220                 {
1221                         //0, 64, 1238, 1238, 256, 1, 64, 109, 64, 1238
1222                         0, 64, 619, 619, 128, 1, 64, 55, 64, 619
1223                 };
1224                 int i, u;
1225                 for(i=0; i < 16; i++)
1226                         for(u=0; u < 10; u++)
1227                                 AttackERate[i][u] = (unsigned long) (((int64) FIXED_POINT * 1000 * steps[u]) /
1228                                                                                                         (AttackRate[i] * playback_rate));
1229                 for(i=0; i < 8; i++)
1230                         for(u=0; u < 10; u++)
1231                                 DecayERate[i][u]  = (unsigned long) (((int64) FIXED_POINT * 1000 * steps[u]) /
1232                                                                                                         (DecayRate[i]  * playback_rate));
1233
1234                 for(i=0; i < 32; i++)
1235                         for(u=0; u < 10; u++)
1236                                 SustainERate[i][u]= (unsigned long) (((int64) FIXED_POINT * 1000 * steps[u]) /
1237                                                                                                         (SustainRate[i]  * playback_rate));
1238
1239                 for(i=0; i < 32; i++)
1240                         for(u=0; u < 10; u++)
1241                                 IncreaseERate[i][u]=(unsigned long) (((int64) FIXED_POINT * 1000 * steps[u]) /
1242                                                                                                         (IncreaseRate[i] * playback_rate));
1243
1244                 for(i=0; i < 32; i++)
1245                         for(u=0; u < 10; u++)
1246                                 DecreaseERateExp[i][u] = (unsigned long) (((int64) FIXED_POINT * 1000 * steps[u]) /
1247                                                                                                         (DecreaseRateExp[i] / 2 * playback_rate));
1248
1249                 for(u=0; u < 10; u++)
1250                         KeyOffERate[u] = (unsigned long) (((int64) FIXED_POINT * 1000 * steps[u]) /
1251                                                                                                 (8 * playback_rate));
1252         }
1253
1254     S9xSetEchoDelay (APU.DSP [APU_EDL] & 0xf);
1255     for (int i = 0; i < 8; i++)
1256         S9xSetSoundFrequency (i, SoundData.channels [i].hertz);
1257 }
1258
1259 bool8 S9xInitSound (void)
1260 {
1261     so.playback_rate = 0;
1262     so.stereo = 0;
1263         so.sound_switch = 255;
1264
1265     S9xResetSound (TRUE);
1266     S9xSetSoundMute (TRUE);
1267
1268     return (1);
1269 }
1270