2 * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
4 * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and
5 * Jerremy Koot (jkoot@snes9x.com)
7 * Super FX C emulator code
8 * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and
10 * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
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).
16 * DOS port code contains the works of other authors. See headers in
19 * Snes9x homepage: http://www.snes9x.com
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.
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.
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.
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
38 * Super NES and Super Nintendo Entertainment System are trademarks of
39 * Nintendo Co., Limited and its subsidiary companies.
42 //#include <allegro.h>
61 #define CLIP16_latch(v,l) \
63 { (v) = -32768; (l)++; }\
66 { (v) = 32767; (l)++; }
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;
97 extern long FilterValues[4][2];
98 extern int NoiseFreq [32];
101 #define ABS(a) ((a) < 0 ? -(a) : (a))
103 #define FIXED_POINT 0x10000UL
104 #define FIXED_POINT_REMAINDER 0xffffUL
105 #define FIXED_POINT_SHIFT 16
107 #define VOL_DIV8 0x8000
108 #define VOL_DIV16 0x0080
109 #define ENVX_SHIFT 24
111 extern "C" void DecodeBlockAsm (int8 *, int16 *, int32 *, int32 *);
112 extern "C" void DecodeBlockAsm2 (int8 *, int16 *, int32 *, int32 *);
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)
119 #define LAST_SAMPLE 0xffffff
120 #define JUST_PLAYED_LAST_SAMPLE(c) ((c)->sample_pointer >= LAST_SAMPLE)
122 STATIC INLINE uint8 *S9xGetSampleAddress (int sample_number)
124 uint32 addr = (((APU.DSP[APU_DIR] << 8) + (sample_number << 2)) & 0xffff);
125 return (IAPU.RAM + addr);
128 void S9xAPUSetEndOfSample (int i, Channel *ch)
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);
138 END_OF_FUNCTION (S9xAPUSetEndOfSample)
141 void S9xAPUSetEndX (int ch)
143 APU.DSP [APU_ENDX] |= 1 << ch;
146 END_OF_FUNCTION (S9xAPUSetEndX)
149 void S9xSetEnvRate (Channel *ch, unsigned long rate, int direction, int target)
151 ch->envx_target = target;
159 ch->direction = direction;
161 static int steps [] =
163 // 0, 64, 1238, 1238, 256, 1, 64, 109, 64, 1238
164 0, 64, 619, 619, 128, 1, 64, 55, 64, 619
167 if (rate == 0 || so.playback_rate == 0)
171 ch->erate = (unsigned long)
172 (((int64) FIXED_POINT * 1000 * steps [ch->state]) /
173 (rate * so.playback_rate));
178 END_OF_FUNCTION(S9xSetEnvRate);
181 void S9xSetEnvelopeRate (int channel, unsigned long rate, int direction,
184 S9xSetEnvRate (&SoundData.channels [channel], rate, direction, target);
188 END_OF_FUNCTION(S9xSetEnvelopeRate);
191 void S9xSetSoundVolume (int channel, short volume_left, short volume_right)
193 Channel *ch = &SoundData.channels[channel];
195 volume_left = (ABS(volume_right) + ABS(volume_left)) / 2;
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;
203 void S9xSetMasterVolume (short volume_left, short volume_right)
205 if (Settings.DisableMasterVolume)
207 SoundData.master_volume_left = 127;
208 SoundData.master_volume_right = 127;
209 SoundData.master_volume [0] = SoundData.master_volume [1] = 127;
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;
222 void S9xSetEchoVolume (short volume_left, short volume_right)
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;
232 void S9xSetEchoEnable (uint8 byte)
234 SoundData.echo_channel_enable = byte;
235 if (!SoundData.echo_write_enabled || Settings.DisableSoundEcho)
237 if (byte && !SoundData.echo_enable)
239 memset (Echo, 0, sizeof (Echo));
240 memset (Loop, 0, sizeof (Loop));
243 SoundData.echo_enable = byte;
244 for (int i = 0; i < 8; i++)
247 SoundData.channels [i].echo_buf_ptr = EchoBuffer;
249 SoundData.channels [i].echo_buf_ptr = DummyEchoBuffer;
253 void S9xSetEchoFeedback (int feedback)
256 SoundData.echo_feedback = feedback;
259 void S9xSetEchoDelay (int delay)
261 SoundData.echo_buffer_size = (512 * delay * so.playback_rate) / 32000;
263 SoundData.echo_buffer_size <<= 1;
264 if (SoundData.echo_buffer_size)
265 SoundData.echo_ptr %= SoundData.echo_buffer_size;
267 SoundData.echo_ptr = 0;
268 S9xSetEchoEnable (APU.DSP [APU_EON]);
271 void S9xSetEchoWriteEnable (uint8 byte)
273 SoundData.echo_write_enabled = byte;
274 S9xSetEchoDelay (APU.DSP [APU_EDL] & 15);
277 void S9xSetFrequencyModulationEnable (uint8 byte)
279 SoundData.pitch_mod = byte & ~1;
282 void S9xSetSoundKeyOff (int channel)
284 Channel *ch = &SoundData.channels[channel];
286 if (ch->state != SOUND_SILENT)
288 ch->state = SOUND_RELEASE;
289 ch->mode = MODE_RELEASE;
290 S9xSetEnvRate (ch, 8, -1, 0);
294 void S9xFixSoundAfterSnapshotLoad ()
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]);
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++)
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];
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;
326 void S9xSetFilterCoefficient (int tap, int value)
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 &&
339 void S9xSetSoundADSR (int channel, int attack_rate, int decay_rate,
340 int sustain_rate, int sustain_level, int release_rate)
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;
348 switch (SoundData.channels[channel].state)
351 S9xSetEnvelopeRate (channel, attack_rate, 1, 127);
355 S9xSetEnvelopeRate (channel, decay_rate, -1,
356 (MAX_ENVELOPE_HEIGHT * (sustain_level + 1)) >> 3);
359 S9xSetEnvelopeRate (channel, sustain_rate, -1, 0);
364 void S9xSetEnvelopeHeight (int channel, int level)
366 Channel *ch = &SoundData.channels[channel];
369 ch->envxx = level << ENVX_SHIFT;
371 ch->left_vol_level = (level * ch->volume_left) / 128;
372 ch->right_vol_level = (level * ch->volume_right) / 128;
374 if (ch->envx == 0 && ch->state != SOUND_SILENT && ch->state != SOUND_GAIN)
376 S9xAPUSetEndOfSample (channel, ch);
380 int S9xGetEnvelopeHeight (int channel)
382 if ((Settings.SoundEnvelopeHeightReading ||
383 SNESGameFixes.SoundEnvelopeHeightReading2) &&
384 SoundData.channels[channel].state != SOUND_SILENT &&
385 SoundData.channels[channel].state != SOUND_GAIN)
387 return (SoundData.channels[channel].envx);
391 if (SNESGameFixes.SoundEnvelopeHeightReading2 &&
392 SoundData.channels[channel].state != SOUND_SILENT)
394 return (SoundData.channels[channel].envx);
401 void S9xSetSoundSample (int, uint16)
405 void S9xSetSoundSample (int channel, uint16 sample_number)
407 register Channel *ch = &SoundData.channels[channel];
409 if (ch->state != SOUND_SILENT &&
410 sample_number != ch->sample_number)
412 int keep = ch->state;
413 ch->state = SOUND_SILENT;
414 ch->sample_number = sample_number;
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;
427 void S9xSetSoundFrequency (int channel, int hertz)
429 if (so.playback_rate)
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)
437 SoundData.channels[channel].frequency =
438 (unsigned long) ((double) SoundData.channels[channel].frequency * 0.980);
443 void S9xSetSoundHertz (int channel, int hertz)
445 SoundData.channels[channel].hertz = hertz;
446 S9xSetSoundFrequency (channel, hertz);
449 void S9xSetSoundType (int channel, int type_of_sound)
451 SoundData.channels[channel].type = type_of_sound;
454 bool8_32 S9xSetSoundMute (bool8_32 mute)
456 bool8_32 old = so.mute_sound;
457 so.mute_sound = mute;
461 void AltDecodeBlock_PPC (Channel *ch, struct SIAPU * iapu)
463 if (ch->block_pointer >= 0x10000 - 9)
465 ch->last_block = TRUE;
467 ch->block = ch->decoded;
468 memset ((void *) ch->decoded, 0, sizeof (int16) * 16);
471 signed char *compressed = (signed char *) &iapu->RAM [ch->block_pointer];
473 unsigned char filter = *compressed;
474 if ((ch->last_block = filter & 1))
475 ch->loop = (filter & 2) != 0;
477 #if (defined (__i386__) || defined (__i486__) ||\
478 defined (__i586__) || defined (__WIN32__) || defined (__DJGPP))
479 int16 *raw = ch->block = ch->decoded;
481 if (Settings.AltSampleDecode == 1)
482 DecodeBlockAsm (compressed, raw, &ch->previous [0], &ch->previous [1]);
484 DecodeBlockAsm2 (compressed, raw, &ch->previous [0], &ch->previous [1]);
488 signed char sample1, sample2;
492 signed short *raw = ch->block = ch->decoded;
494 int32 prev0 = ch->previous [0];
495 int32 prev1 = ch->previous [1];
498 switch ((filter >> 2) & 3)
501 for (i = 8; i != 0; i--)
503 sample1 = *compressed++;
504 sample2 = sample1 << 4;
507 *raw++ = ((int32) sample1 << shift);
508 *raw++ = ((int32) sample2 << shift);
514 for (i = 8; i != 0; i--)
516 sample1 = *compressed++;
517 sample2 = 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);
527 for (i = 8; i != 0; i--)
529 sample1 = *compressed++;
530 sample2 = sample1 << 4;
534 out = (sample1 << shift) - prev1 + (prev1 >> 4);
535 prev1 = (int16) prev0;
537 *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) -
540 out = (sample2 << shift) - prev1 + (prev1 >> 4);
541 prev1 = (int16) prev0;
543 *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) -
548 for (i = 8; i != 0; i--)
550 sample1 = *compressed++;
551 sample2 = sample1 << 4;
554 out = (sample1 << shift);
556 out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);
557 prev1 = (int16) prev0;
559 *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) -
560 (prev0 >> 4) - (prev1 >> 6);
562 out = (sample2 << shift);
563 out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);
564 prev1 = (int16) prev0;
566 *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) -
567 (prev0 >> 4) - (prev1 >> 6);
571 ch->previous [0] = prev0;
572 ch->previous [1] = prev1;
575 ch->block_pointer += 9;
578 void AltDecodeBlock (Channel *ch, struct SIAPU * iapu)
580 if (ch->block_pointer >= 0x10000 - 9)
582 ch->last_block = TRUE;
584 ch->block = ch->decoded;
585 memset ((void *) ch->decoded, 0, sizeof (int16) * 16);
588 signed char *compressed = (signed char *) &iapu->RAM [ch->block_pointer];
590 unsigned char filter = *compressed;
591 if ((ch->last_block = filter & 1))
592 ch->loop = (filter & 2) != 0;
594 #if (defined (__i386__) || defined (__i486__) ||\
595 defined (__i586__) || defined (__WIN32__) || defined (__DJGPP))
596 int16 *raw = ch->block = ch->decoded;
598 if (Settings.AltSampleDecode == 1)
599 DecodeBlockAsm (compressed, raw, &ch->previous [0], &ch->previous [1]);
601 DecodeBlockAsm2 (compressed, raw, &ch->previous [0], &ch->previous [1]);
605 signed char sample1, sample2;
609 signed short *raw = ch->block = ch->decoded;
611 int32 prev0 = ch->previous [0];
612 int32 prev1 = ch->previous [1];
615 switch ((filter >> 2) & 3)
618 for (i = 8; i != 0; i--)
620 sample1 = *compressed++;
621 sample2 = sample1 << 4;
624 *raw++ = ((int32) sample1 << shift);
625 *raw++ = ((int32) sample2 << shift);
631 for (i = 8; i != 0; i--)
633 sample1 = *compressed++;
634 sample2 = 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);
644 for (i = 8; i != 0; i--)
646 sample1 = *compressed++;
647 sample2 = sample1 << 4;
651 out = (sample1 << shift) - prev1 + (prev1 >> 4);
652 prev1 = (int16) prev0;
654 *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) -
657 out = (sample2 << shift) - prev1 + (prev1 >> 4);
658 prev1 = (int16) prev0;
660 *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) -
665 for (i = 8; i != 0; i--)
667 sample1 = *compressed++;
668 sample2 = sample1 << 4;
671 out = (sample1 << shift);
673 out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);
674 prev1 = (int16) prev0;
676 *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) -
677 (prev0 >> 4) - (prev1 >> 6);
679 out = (sample2 << shift);
680 out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);
681 prev1 = (int16) prev0;
683 *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) -
684 (prev0 >> 4) - (prev1 >> 6);
688 ch->previous [0] = prev0;
689 ch->previous [1] = prev1;
692 ch->block_pointer += 9;
695 void AltDecodeBlock2 (Channel *ch)
698 unsigned char filter;
700 signed char sample1, sample2;
703 if (ch->block_pointer > 0x10000 - 9)
705 ch->last_block = TRUE;
707 ch->block = ch->decoded;
708 memset ((void *) ch->decoded, 0, sizeof (int16) * 16);
712 signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer];
714 filter = *compressed;
715 if ((ch->last_block = filter & 1))
716 ch->loop = (filter & 2) != 0;
719 signed short *raw = ch->block = ch->decoded;
722 int32 prev0 = ch->previous [0];
723 int32 prev1 = ch->previous [1];
728 switch ((filter >> 2) & 3)
731 for (i = 8; i != 0; i--)
733 sample1 = *compressed++;
734 sample2 = sample1 << 4;
735 //Sample 2 = Bottom Nibble, Sign Extended.
737 //Sample 1 = Top Nibble, shifted down and Sign Extended.
740 out = (int32)(sample1 << shift);
747 out = (int32)(sample2 << shift);
756 for (i = 8; i != 0; i--)
758 sample1 = *compressed++;
759 sample2 = sample1 << 4;
760 //Sample 2 = Bottom Nibble, Sign Extended.
762 //Sample 1 = Top Nibble, shifted down and Sign Extended.
764 out = (int32)(sample1 << shift);
765 out += (int32)((double)prev0 * 15/16);
772 out = (int32)(sample2 << shift);
773 out += (int32)((double)prev0 * 15/16);
782 for (i = 8; i != 0; i--)
784 sample1 = *compressed++;
785 sample2 = sample1 << 4;
786 //Sample 2 = Bottom Nibble, Sign Extended.
788 //Sample 1 = Top Nibble, shifted down and Sign Extended.
791 out = ((sample1 << shift) * 256 + (prev0 & ~0x2) * 488 - prev1 * 240) >> 8;
797 out = ((sample2 << shift) * 256 + (prev0 & ~0x2) * 488 - prev1 * 240) >> 8;
806 for (i = 8; i != 0; i--)
808 sample1 = *compressed++;
809 sample2 = sample1 << 4;
810 //Sample 2 = Bottom Nibble, Sign Extended.
812 //Sample 1 = Top Nibble, shifted down and Sign Extended.
814 out = (int32)(sample1 << shift);
815 out += (int32)((double)prev0 * 115/64 - (double)prev1 * 13/16);
823 out = (int32)(sample2 << shift);
824 out += (int32)((double)prev0 * 115/64 - (double)prev1 * 13/16);
834 ch->previous [0] = prev0;
835 ch->previous [1] = prev1;
836 ch->block_pointer += 9;
839 void DecodeBlock (Channel *ch)
842 unsigned char filter;
844 signed char sample1, sample2;
847 if (Settings.AltSampleDecode)
849 if (Settings.AltSampleDecode < 3)
850 AltDecodeBlock (ch, &IAPU);
852 AltDecodeBlock2 (ch);
855 if (ch->block_pointer > 0x10000 - 9)
857 ch->last_block = TRUE;
859 ch->block = ch->decoded;
862 signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer];
864 filter = *compressed;
865 if ((ch->last_block = filter & 1))
866 ch->loop = (filter & 2) != 0;
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
871 if (!Settings.DisableSampleCaching &&
872 memcmp ((uint8 *) compressed, &IAPU.ShadowRAM [ch->block_pointer], 9) == 0)
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];
880 if (!Settings.DisableSampleCaching)
881 memcpy (&IAPU.ShadowRAM [ch->block_pointer], (uint8 *) compressed, 9);
883 signed short *raw = ch->block = ch->decoded;
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];
892 for (i = 8; i != 0; i--)
894 sample1 = *compressed++;
895 sample2 = sample1 << 4;
896 //Sample 2 = Bottom Nibble, Sign Extended.
898 //Sample 1 = Top Nibble, shifted down and Sign Extended.
900 out = (sample1 << shift);
901 out += (prev0 * f0 + prev1 * f1) / 256;
906 *raw++ = (signed short) out;
908 out = (sample2 << shift);
909 out += (prev0 * f0 + prev1 * f1) / 256;
914 *raw++ = (signed short) out;
916 ch->previous [0] = prev0;
917 ch->previous [1] = prev1;
919 if (!Settings.DisableSampleCaching)
921 memcpy (IAPU.CachedSamples + (ch->block_pointer << 2),
922 (uint8 *) ch->decoded, 32);
925 ch->block_pointer += 9;
928 void MixStereo (int sample_count)
930 struct SIAPU * iapu = &IAPU;
931 #if defined(TARGET_OS_MAC) && TARGET_OS_MAC
932 static int wave[SOUND_BUFFER_SIZE];
934 int wave[SOUND_BUFFER_SIZE];
936 int pitch_mod = SoundData.pitch_mod & ~APU.DSP[APU_NON];
938 for (uint32 J = 0; J < NUM_CHANNELS; J++)
941 Channel *ch = &SoundData.channels[J];
942 unsigned long freq0 = ch->frequency;
944 if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J)))
947 // freq0 = (unsigned long) ((double) freq0 * 0.985);
949 bool8_32 mod = pitch_mod & (1 << J);
951 if (ch->needs_decode)
953 AltDecodeBlock(ch, iapu);
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;
963 ch->next_sample = ch->block[ch->sample_pointer];
966 if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod)
967 ch->interpolate = ((ch->next_sample - ch->sample) *
968 (long) freq0) / (long) FIXED_POINT;
970 VL = (ch->sample * ch-> left_vol_level) / 128;
971 VR = (ch->sample * ch->right_vol_level) / 128;
973 for (uint32 I = 0; I < (uint32) sample_count; I += 2)
975 unsigned long freq = freq0;
978 freq = PITCH_MOD(freq, wave [I / 2]);
980 ch->env_error += ch->erate;
981 if (ch->env_error >= FIXED_POINT)
983 uint32 step = ch->env_error >> FIXED_POINT_SHIFT;
988 ch->env_error &= FIXED_POINT_REMAINDER;
989 ch->envx += step << 1;
990 ch->envxx = ch->envx << ENVX_SHIFT;
995 ch->envxx = 127 << ENVX_SHIFT;
996 ch->state = SOUND_DECAY;
997 if (ch->sustain_level != 8)
999 S9xSetEnvRate (ch, ch->decay_rate, -1,
1000 (MAX_ENVELOPE_HEIGHT * ch->sustain_level)
1004 ch->state = SOUND_SUSTAIN;
1005 S9xSetEnvRate (ch, ch->sustain_rate, -1, 0);
1010 while (ch->env_error >= FIXED_POINT)
1012 ch->envxx = (ch->envxx >> 8) * 255;
1013 ch->env_error -= FIXED_POINT;
1015 ch->envx = ch->envxx >> ENVX_SHIFT;
1016 if (ch->envx <= ch->envx_target)
1020 S9xAPUSetEndOfSample (J, ch);
1023 ch->state = SOUND_SUSTAIN;
1024 S9xSetEnvRate (ch, ch->sustain_rate, -1, 0);
1029 while (ch->env_error >= FIXED_POINT)
1031 ch->envxx = (ch->envxx >> 8) * 255;
1032 ch->env_error -= FIXED_POINT;
1034 ch->envx = ch->envxx >> ENVX_SHIFT;
1037 S9xAPUSetEndOfSample (J, ch);
1043 while (ch->env_error >= FIXED_POINT)
1045 ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
1046 ch->env_error -= FIXED_POINT;
1048 ch->envx = ch->envxx >> ENVX_SHIFT;
1051 S9xAPUSetEndOfSample (J, ch);
1056 case SOUND_INCREASE_LINEAR:
1057 ch->env_error &= FIXED_POINT_REMAINDER;
1058 ch->envx += step << 1;
1059 ch->envxx = ch->envx << ENVX_SHIFT;
1061 if (ch->envx >= 126)
1064 ch->envxx = 127 << ENVX_SHIFT;
1065 ch->state = SOUND_GAIN;
1066 ch->mode = MODE_GAIN;
1067 S9xSetEnvRate (ch, 0, -1, 0);
1071 case SOUND_INCREASE_BENT_LINE:
1072 if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4)
1074 while (ch->env_error >= FIXED_POINT)
1076 ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
1077 ch->env_error -= FIXED_POINT;
1079 ch->envx = ch->envxx >> ENVX_SHIFT;
1083 ch->env_error &= FIXED_POINT_REMAINDER;
1084 ch->envx += step << 1;
1085 ch->envxx = ch->envx << ENVX_SHIFT;
1088 if (ch->envx >= 126)
1091 ch->envxx = 127 << ENVX_SHIFT;
1092 ch->state = SOUND_GAIN;
1093 ch->mode = MODE_GAIN;
1094 S9xSetEnvRate (ch, 0, -1, 0);
1098 case SOUND_DECREASE_LINEAR:
1099 ch->env_error &= FIXED_POINT_REMAINDER;
1100 ch->envx -= step << 1;
1101 ch->envxx = ch->envx << ENVX_SHIFT;
1104 S9xAPUSetEndOfSample (J, ch);
1109 case SOUND_DECREASE_EXPONENTIAL:
1110 while (ch->env_error >= FIXED_POINT)
1112 ch->envxx = (ch->envxx >> 8) * 255;
1113 ch->env_error -= FIXED_POINT;
1115 ch->envx = ch->envxx >> ENVX_SHIFT;
1118 S9xAPUSetEndOfSample (J, ch);
1124 S9xSetEnvRate (ch, 0, -1, 0);
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;
1134 if (ch->count >= FIXED_POINT)
1136 VL = ch->count >> FIXED_POINT_SHIFT;
1137 ch->sample_pointer += VL;
1138 ch->count &= FIXED_POINT_REMAINDER;
1140 ch->sample = ch->next_sample;
1141 if (ch->sample_pointer >= SOUND_DECODE_LENGTH)
1143 if (JUST_PLAYED_LAST_SAMPLE(ch))
1145 S9xAPUSetEndOfSample (J, ch);
1150 ch->sample_pointer -= SOUND_DECODE_LENGTH;
1155 ch->sample_pointer = LAST_SAMPLE;
1156 ch->next_sample = ch->sample;
1162 ch->last_block = FALSE;
1163 uint8 *dir = S9xGetSampleAddress (ch->sample_number);
1164 ch->block_pointer = READ_WORD(dir + 2);
1167 AltDecodeBlock(ch, iapu);
1169 } while (ch->sample_pointer >= SOUND_DECODE_LENGTH);
1170 if (!JUST_PLAYED_LAST_SAMPLE (ch))
1171 ch->next_sample = ch->block [ch->sample_pointer];
1174 ch->next_sample = ch->block [ch->sample_pointer];
1176 if (ch->type == SOUND_SAMPLE)
1178 if (Settings.InterpolatedSound && freq < FIXED_POINT && !mod)
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));
1186 ch->interpolate = 0;
1191 if ((so.noise_gen <<= 1) & 0x80000000L)
1192 so.noise_gen ^= 0x0040001L;
1193 ch->sample = (so.noise_gen << 17) >> 17;
1194 ch->interpolate = 0;
1197 VL = (ch->sample * ch-> left_vol_level) / 128;
1198 VR = (ch->sample * ch->right_vol_level) / 128;
1202 if (ch->interpolate)
1204 int32 s = (int32) ch->sample + ch->interpolate;
1207 ch->sample = (int16) s;
1208 VL = (ch->sample * ch-> left_vol_level) / 128;
1209 VR = (ch->sample * ch->right_vol_level) / 128;
1213 if (pitch_mod & (1 << (J + 1)))
1214 wave [I / 2] = ch->sample * ch->envx;
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;
1226 END_OF_FUNCTION(MixStereo);
1229 void MixMono (int sample_count)
1231 struct SIAPU * iapu = &IAPU;
1232 #if defined(TARGET_OS_MAC) && TARGET_OS_MAC
1233 static int wave[SOUND_BUFFER_SIZE];
1236 static int wave[SOUND_BUFFER_SIZE];
1238 int wave[SOUND_BUFFER_SIZE];
1241 int pitch_mod = SoundData.pitch_mod & (~APU.DSP[APU_NON]);
1243 for (uint32 J = 0; J < NUM_CHANNELS; J++)
1245 Channel *ch = &SoundData.channels[J];
1246 unsigned long freq0 = ch->frequency;
1248 if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J)))
1251 // freq0 = (unsigned long) ((double) freq0 * 0.985);
1253 bool8_32 mod = pitch_mod & (1 << J);
1255 if (ch->needs_decode)
1257 AltDecodeBlock(ch, iapu);
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;
1269 if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod)
1270 ch->interpolate = ((ch->next_sample - ch->sample) *
1271 (long) freq0) / (long) FIXED_POINT;
1273 int32 V = (ch->sample * ch->left_vol_level) / 128;
1275 for (uint32 I = 0; I < (uint32) sample_count; I++)
1277 unsigned long freq = freq0;
1280 freq = PITCH_MOD(freq, wave [I]);
1282 ch->env_error += ch->erate;
1283 if (ch->env_error >= FIXED_POINT)
1285 uint32 step = ch->env_error >> FIXED_POINT_SHIFT;
1290 ch->env_error &= FIXED_POINT_REMAINDER;
1291 ch->envx += step << 1;
1292 ch->envxx = ch->envx << ENVX_SHIFT;
1294 if (ch->envx >= 126)
1297 ch->envxx = 127 << ENVX_SHIFT;
1298 ch->state = SOUND_DECAY;
1299 if (ch->sustain_level != 8)
1301 S9xSetEnvRate (ch, ch->decay_rate, -1,
1302 (MAX_ENVELOPE_HEIGHT * ch->sustain_level)
1306 ch->state = SOUND_SUSTAIN;
1307 S9xSetEnvRate (ch, ch->sustain_rate, -1, 0);
1312 while (ch->env_error >= FIXED_POINT)
1314 ch->envxx = (ch->envxx >> 8) * 255;
1315 ch->env_error -= FIXED_POINT;
1317 ch->envx = ch->envxx >> ENVX_SHIFT;
1318 if (ch->envx <= ch->envx_target)
1322 S9xAPUSetEndOfSample (J, ch);
1325 ch->state = SOUND_SUSTAIN;
1326 S9xSetEnvRate (ch, ch->sustain_rate, -1, 0);
1331 while (ch->env_error >= FIXED_POINT)
1333 ch->envxx = (ch->envxx >> 8) * 255;
1334 ch->env_error -= FIXED_POINT;
1336 ch->envx = ch->envxx >> ENVX_SHIFT;
1339 S9xAPUSetEndOfSample (J, ch);
1345 while (ch->env_error >= FIXED_POINT)
1347 ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
1348 ch->env_error -= FIXED_POINT;
1350 ch->envx = ch->envxx >> ENVX_SHIFT;
1353 S9xAPUSetEndOfSample (J, ch);
1358 case SOUND_INCREASE_LINEAR:
1359 ch->env_error &= FIXED_POINT_REMAINDER;
1360 ch->envx += step << 1;
1361 ch->envxx = ch->envx << ENVX_SHIFT;
1363 if (ch->envx >= 126)
1366 ch->envxx = 127 << ENVX_SHIFT;
1367 ch->state = SOUND_GAIN;
1368 ch->mode = MODE_GAIN;
1369 S9xSetEnvRate (ch, 0, -1, 0);
1373 case SOUND_INCREASE_BENT_LINE:
1374 if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4)
1376 while (ch->env_error >= FIXED_POINT)
1378 ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
1379 ch->env_error -= FIXED_POINT;
1381 ch->envx = ch->envxx >> ENVX_SHIFT;
1385 ch->env_error &= FIXED_POINT_REMAINDER;
1386 ch->envx += step << 1;
1387 ch->envxx = ch->envx << ENVX_SHIFT;
1390 if (ch->envx >= 126)
1393 ch->envxx = 127 << ENVX_SHIFT;
1394 ch->state = SOUND_GAIN;
1395 ch->mode = MODE_GAIN;
1396 S9xSetEnvRate (ch, 0, -1, 0);
1400 case SOUND_DECREASE_LINEAR:
1401 ch->env_error &= FIXED_POINT_REMAINDER;
1402 ch->envx -= step << 1;
1403 ch->envxx = ch->envx << ENVX_SHIFT;
1406 S9xAPUSetEndOfSample (J, ch);
1411 case SOUND_DECREASE_EXPONENTIAL:
1412 while (ch->env_error >= FIXED_POINT)
1414 ch->envxx = (ch->envxx >> 8) * 255;
1415 ch->env_error -= FIXED_POINT;
1417 ch->envx = ch->envxx >> ENVX_SHIFT;
1420 S9xAPUSetEndOfSample (J, ch);
1426 S9xSetEnvRate (ch, 0, -1, 0);
1429 ch->left_vol_level = (ch->envx * ch->volume_left) / 128;
1430 V = (ch->sample * ch->left_vol_level) / 128;
1434 if (ch->count >= FIXED_POINT)
1436 V = ch->count >> FIXED_POINT_SHIFT;
1437 ch->sample_pointer += V;
1438 ch->count &= FIXED_POINT_REMAINDER;
1440 ch->sample = ch->next_sample;
1441 if (ch->sample_pointer >= SOUND_DECODE_LENGTH)
1443 if (JUST_PLAYED_LAST_SAMPLE(ch))
1445 S9xAPUSetEndOfSample (J, ch);
1450 ch->sample_pointer -= SOUND_DECODE_LENGTH;
1455 ch->sample_pointer = LAST_SAMPLE;
1456 ch->next_sample = ch->sample;
1461 ch->last_block = FALSE;
1462 uint8 *dir = S9xGetSampleAddress (ch->sample_number);
1463 ch->block_pointer = READ_WORD(dir + 2);
1467 AltDecodeBlock(ch, iapu);
1469 } while (ch->sample_pointer >= SOUND_DECODE_LENGTH);
1470 if (!JUST_PLAYED_LAST_SAMPLE (ch))
1471 ch->next_sample = ch->block [ch->sample_pointer];
1474 ch->next_sample = ch->block [ch->sample_pointer];
1476 if (ch->type == SOUND_SAMPLE)
1478 if (Settings.InterpolatedSound && freq < FIXED_POINT && !mod)
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));
1486 ch->interpolate = 0;
1491 if ((so.noise_gen <<= 1) & 0x80000000L)
1492 so.noise_gen ^= 0x0040001L;
1493 ch->sample = (so.noise_gen << 17) >> 17;
1494 ch->interpolate = 0;
1496 V = (ch->sample * ch-> left_vol_level) / 128;
1500 if (ch->interpolate)
1502 int32 s = (int32) ch->sample + ch->interpolate;
1505 ch->sample = (int16) s;
1506 V = (ch->sample * ch-> left_vol_level) / 128;
1511 ch->echo_buf_ptr [I] += V;
1513 if (pitch_mod & (1 << (J + 1)))
1514 wave [I] = ch->sample * ch->envx;
1520 END_OF_FUNCTION(MixMono);
1524 extern uint8 int2ulaw (int);
1527 // For backwards compatibility with older port specific code
1528 void S9xMixSamples (uint8 *buffer, int sample_count)
1530 S9xMixSamplesO (buffer, sample_count, 0);
1533 END_OF_FUNCTION(S9xMixSamples);
1536 void S9xMixSamplesO (uint8 *buffer, int sample_count, int byte_offset)
1543 memset (MixBuffer, 0, sample_count * sizeof (MixBuffer [0]));
1544 if (SoundData.echo_enable)
1545 memset (EchoBuffer, 0, sample_count * sizeof (EchoBuffer [0]));
1548 MixStereo (sample_count);
1550 MixMono (sample_count);
1553 /* Mix and convert waveforms */
1556 int byte_count = sample_count << 1;
1561 memset (buffer + byte_offset, 0, byte_count);
1565 int O = byte_offset >> 1;
1566 if (SoundData.echo_enable && SoundData.echo_buffer_size)
1570 // 16-bit stereo sound with echo enabled ...
1571 if (SoundData.no_filter)
1573 // ... but no filter defined.
1574 for (J = 0; J < sample_count; J++)
1576 int E = Echo [SoundData.echo_ptr];
1578 Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 + EchoBuffer [J];
1580 if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
1581 SoundData.echo_ptr = 0;
1583 I = (MixBuffer [J] * SoundData.master_volume [J & 1] + E * SoundData.echo_volume [J & 1]) / VOL_DIV16;
1586 ((signed short *) buffer)[J + O] = I;
1591 // ... with filter defined.
1592 for (J = 0; J < sample_count; J++)
1594 int E = Echo [SoundData.echo_ptr];
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];
1608 Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
1611 if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
1612 SoundData.echo_ptr = 0;
1614 I = (MixBuffer [J] *
1615 SoundData.master_volume [J & 1] +
1616 E * SoundData.echo_volume [J & 1]) / VOL_DIV16;
1619 ((signed short *) buffer)[J + O] = I;
1625 // 16-bit mono sound with echo enabled...
1626 if (SoundData.no_filter)
1628 // ... no filter defined
1629 for (J = 0; J < sample_count; J++)
1631 int E = Echo [SoundData.echo_ptr];
1633 Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
1636 if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
1637 SoundData.echo_ptr = 0;
1639 I = (MixBuffer [J] *
1640 SoundData.master_volume [0] +
1641 E * SoundData.echo_volume [0]) / VOL_DIV16;
1643 ((signed short *) buffer)[J + O] = I;
1648 // ... with filter defined
1649 for (J = 0; J < sample_count; J++)
1651 int E = Echo [SoundData.echo_ptr];
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];
1665 Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
1668 if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
1669 SoundData.echo_ptr = 0;
1671 I = (MixBuffer [J] * SoundData.master_volume [0] +
1672 E * SoundData.echo_volume [0]) / VOL_DIV16;
1674 ((signed short *) buffer)[J + O] = I;
1681 // 16-bit mono or stereo sound, no echo
1682 for (J = 0; J < sample_count; J++)
1684 I = (MixBuffer [J] *
1685 SoundData.master_volume [J & 1]) / VOL_DIV16;
1688 ((signed short *) buffer)[J + O] = I;
1695 int O = byte_offset;
1700 memset (buffer + O, 128, sample_count);
1706 for (J = 0; J < sample_count; J++)
1708 I = (MixBuffer [J] * SoundData.master_volume_left) / VOL_DIV16;
1710 buffer[J + O] = int2ulaw (I);
1716 if (SoundData.echo_enable && SoundData.echo_buffer_size)
1720 // 8-bit stereo sound with echo enabled...
1721 if (SoundData.no_filter)
1723 // ... but no filter
1724 for (J = 0; J < sample_count; J++)
1726 int E = Echo [SoundData.echo_ptr];
1728 Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
1731 if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
1732 SoundData.echo_ptr = 0;
1734 I = (MixBuffer [J] *
1735 SoundData.master_volume [J & 1] +
1736 E * SoundData.echo_volume [J & 1]) / VOL_DIV8;
1738 buffer [J + O] = I + 128;
1744 for (J = 0; J < sample_count; J++)
1746 int E = Echo [SoundData.echo_ptr];
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];
1760 Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
1763 if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
1764 SoundData.echo_ptr = 0;
1766 I = (MixBuffer [J] *
1767 SoundData.master_volume [J & 1] +
1768 E * SoundData.echo_volume [J & 1]) / VOL_DIV8;
1770 buffer [J + O] = I + 128;
1776 // 8-bit mono sound with echo enabled...
1777 if (SoundData.no_filter)
1779 // ... but no filter.
1780 for (J = 0; J < sample_count; J++)
1782 int E = Echo [SoundData.echo_ptr];
1784 Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
1787 if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
1788 SoundData.echo_ptr = 0;
1790 I = (MixBuffer [J] * SoundData.master_volume [0] +
1791 E * SoundData.echo_volume [0]) / VOL_DIV8;
1793 buffer [J + O] = I + 128;
1799 for (J = 0; J < sample_count; J++)
1801 int E = Echo [SoundData.echo_ptr];
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];
1815 Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
1818 if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
1819 SoundData.echo_ptr = 0;
1821 I = (MixBuffer [J] * SoundData.master_volume [0] +
1822 E * SoundData.echo_volume [0]) / VOL_DIV8;
1824 buffer [J + O] = I + 128;
1831 // 8-bit mono or stereo sound, no echo
1832 for (J = 0; J < sample_count; J++)
1834 I = (MixBuffer [J] *
1835 SoundData.master_volume [J & 1]) / VOL_DIV8;
1837 buffer [J + O] = I + 128;
1845 END_OF_FUNCTION(S9xMixSamplesO);
1848 void S9xResetSound (bool8_32 full)
1850 for (int i = 0; i < 8; i++)
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;
1877 FilterTaps [0] = 127;
1885 so.mute_sound = TRUE;
1887 so.sound_switch = 255;
1888 so.samples_mixed_so_far = 0;
1889 so.play_position = 0;
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;
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));
1919 SoundData.no_filter = TRUE;
1922 void S9xSetPlaybackRate (uint32 playback_rate)
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);
1931 bool8_32 S9xInitSound (int mode, bool8_32 stereo, int buffer_size)
1934 so.sound_switch = 255;
1936 so.playback_rate = mode;
1937 so.buffer_size = buffer_size;
1938 so.stereo = false;//stereo;
1939 so.sixteen_bit = Settings.SixteenBitSound;
1942 S9xResetSound (TRUE);
1947 S9xSetSoundMute (TRUE);
1948 if (!S9xOpenSoundDevice (mode, stereo, buffer_size))
1950 S9xMessage (S9X_ERROR, S9X_SOUND_DEVICE_OPEN_FAILED,
1951 "Sound device open failed");
1958 bool8_32 S9xSetSoundMode (int channel, int mode)
1960 Channel *ch = &SoundData.channels[channel];
1965 if (ch->mode != MODE_NONE)
1967 ch->mode = MODE_RELEASE;
1972 case MODE_DECREASE_LINEAR:
1973 case MODE_DECREASE_EXPONENTIAL:
1975 if (ch->mode != MODE_RELEASE)
1978 if (ch->state != SOUND_SILENT)
1985 case MODE_INCREASE_LINEAR:
1986 case MODE_INCREASE_BENT_LINE:
1987 if (ch->mode != MODE_RELEASE)
1990 if (ch->state != SOUND_SILENT)
1998 if (ch->mode == MODE_NONE || ch->mode == MODE_ADSR)
2008 void S9xSetSoundControl (int sound_switch)
2010 so.sound_switch = sound_switch;
2013 void S9xPlaySample (int channel)
2015 Channel *ch = &SoundData.channels[channel];
2017 ch->state = SOUND_SILENT;
2018 ch->mode = MODE_NONE;
2022 S9xFixEnvelope (channel,
2023 APU.DSP [APU_GAIN + (channel << 4)],
2024 APU.DSP [APU_ADSR1 + (channel << 4)],
2025 APU.DSP [APU_ADSR2 + (channel << 4)]);
2027 ch->sample_number = APU.DSP [APU_SRCN + channel * 0x10];
2028 if (APU.DSP [APU_NON] & (1 << channel))
2029 ch->type = SOUND_NOISE;
2031 ch->type = SOUND_SAMPLE;
2033 S9xSetSoundFrequency (channel, ch->hertz);
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;
2042 ch->next_sample = 0;
2043 ch->interpolate = 0;
2048 if (ch->attack_rate == 0)
2050 if (ch->decay_rate == 0 || ch->sustain_level == 8)
2052 ch->state = SOUND_SUSTAIN;
2053 ch->envx = (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3;
2054 S9xSetEnvRate (ch, ch->sustain_rate, -1, 0);
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);
2063 ch-> left_vol_level = (ch->envx * ch->volume_left) / 128;
2064 ch->right_vol_level = (ch->envx * ch->volume_right) / 128;
2068 ch->state = SOUND_ATTACK;
2070 ch->left_vol_level = 0;
2071 ch->right_vol_level = 0;
2072 S9xSetEnvRate (ch, ch->attack_rate, 1, MAX_ENVELOPE_HEIGHT);
2074 ch->envxx = ch->envx << ENVX_SHIFT;
2078 ch->state = SOUND_GAIN;
2081 case MODE_INCREASE_LINEAR:
2082 ch->state = SOUND_INCREASE_LINEAR;
2085 case MODE_INCREASE_BENT_LINE:
2086 ch->state = SOUND_INCREASE_BENT_LINE;
2089 case MODE_DECREASE_LINEAR:
2090 ch->state = SOUND_DECREASE_LINEAR;
2093 case MODE_DECREASE_EXPONENTIAL:
2094 ch->state = SOUND_DECREASE_EXPONENTIAL;
2101 S9xFixEnvelope (channel,
2102 APU.DSP [APU_GAIN + (channel << 4)],
2103 APU.DSP [APU_ADSR1 + (channel << 4)],
2104 APU.DSP [APU_ADSR2 + (channel << 4)]);