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.
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);
72 #define CLIP16_latch(v,l) \
74 { (v) = -32768; (l)++; }\
77 { (v) = 32767; (l)++; }
101 //#include "asmmemfuncs.h"
104 static int wave[SOUND_BUFFER_SIZE];
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];
113 extern long FilterValues[4][2];
114 //extern int NoiseFreq [32];
117 //#define FIXED_POINT 0x10000UL
118 #define FIXED_POINT_REMAINDER 0xffffUL
119 #define FIXED_POINT_SHIFT 16
121 #define VOL_DIV8 0x8000
122 #define VOL_DIV16 0x0080
123 #define ENVX_SHIFT 24
125 extern "C" void DecodeBlockAsm (int8 *, int16 *, int32 *, int32 *);
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)
132 #define LAST_SAMPLE 0xffffff
133 #define JUST_PLAYED_LAST_SAMPLE(c) ((c)->sample_pointer >= LAST_SAMPLE)
136 static inline void S9xAPUSetEndOfSample (int i, Channel *ch)
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);
146 END_OF_FUNCTION (S9xAPUSetEndOfSample)
149 static inline void S9xAPUSetEndX (int ch)
151 APU.DSP [APU_ENDX] |= 1 << ch;
154 END_OF_FUNCTION (S9xAPUSetEndX)
157 void S9xSetEchoDelay (int delay)
159 SoundData.echo_buffer_size = (512 * delay * so.playback_rate) >> 15; // notaz / 32000;
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;
166 SoundData.echo_ptr = 0;
167 S9xSetEchoEnable (APU.DSP [APU_EON]);
170 void S9xSetSoundKeyOff (int channel)
172 Channel *ch = &SoundData.channels[channel];
174 if (ch->state != SOUND_SILENT)
176 ch->state = SOUND_RELEASE;
177 ch->mode = MODE_RELEASE;
178 S9xSetEnvRate (ch, 8, -1, 0, 5<<28);
182 void S9xFixSoundAfterSnapshotLoad ()
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]);
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]);
198 for (int i = 0; i < 8; i++)
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];
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;
215 void S9xSetEnvelopeHeight (int channel, int level)
217 Channel *ch = &SoundData.channels[channel];
220 ch->envxx = level << ENVX_SHIFT;
222 ch->left_vol_level = (level * ch->volume_left) / 128;
223 ch->right_vol_level = (level * ch->volume_right) / 128;
225 if (ch->envx == 0 && ch->state != SOUND_SILENT && ch->state != SOUND_GAIN)
227 S9xAPUSetEndOfSample (channel, ch);
232 void S9xSetSoundSample (int, uint16)
236 void S9xSetSoundSample (int channel, uint16 sample_number)
238 register Channel *ch = &SoundData.channels[channel];
240 if (ch->state != SOUND_SILENT &&
241 sample_number != ch->sample_number)
243 int keep = ch->state;
244 ch->state = SOUND_SILENT;
245 ch->sample_number = sample_number;
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;
257 static void DecodeBlock (Channel *ch)
259 if (ch->block_pointer >= 0x10000 - 9)
261 ch->last_block = TRUE;
263 ch->block = ch->decoded;
264 memset32 (ch->decoded, 0, 8);
267 signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer];
269 unsigned char filter = *compressed;
270 if ((ch->last_block = filter & 1))
271 ch->loop = (filter & 2) != 0;
273 int16 *raw = ch->block = ch->decoded;
276 DecodeBlockAsm (compressed, raw, &ch->previous [0], &ch->previous [1]);
280 signed char sample1, sample2;
285 int32 prev0 = ch->previous [0];
286 int32 prev1 = ch->previous [1];
289 switch ((filter >> 2) & 3)
292 for (i = 8; i != 0; i--)
294 sample1 = *compressed++;
295 sample2 = sample1 << 4;
298 *raw++ = ((int32) sample1 << shift);
299 *raw++ = ((int32) sample2 << shift);
305 for (i = 8; i != 0; i--)
307 sample1 = *compressed++;
308 sample2 = 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);
318 for (i = 8; i != 0; i--)
320 sample1 = *compressed++;
321 sample2 = sample1 << 4;
325 out = (sample1 << shift) - prev1 + (prev1 >> 4);
326 prev1 = (int16) prev0;
328 *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) -
331 out = (sample2 << shift) - prev1 + (prev1 >> 4);
332 prev1 = (int16) prev0;
334 *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) -
339 for (i = 8; i != 0; i--)
341 sample1 = *compressed++;
342 sample2 = sample1 << 4;
345 out = (sample1 << shift);
347 out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);
348 prev1 = (int16) prev0;
350 *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) -
351 (prev0 >> 4) - (prev1 >> 6);
353 out = (sample2 << shift);
354 out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);
355 prev1 = (int16) prev0;
357 *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) -
358 (prev0 >> 4) - (prev1 >> 6);
362 ch->previous [0] = prev0;
363 ch->previous [1] = prev1;
365 ch->block_pointer += 9;
369 static void MixStereo (int sample_count)
371 int pitch_mod = SoundData.pitch_mod & (0xFFFFFFFF^APU.DSP[APU_NON]);//~APU.DSP[APU_NON];
373 for (uint32 J = 0; J < NUM_CHANNELS; J++)
376 Channel *ch = &SoundData.channels[J];
377 unsigned long freq0 = ch->frequency;
379 if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J)))
382 // freq0 = (unsigned long) ((double) freq0 * 0.985);//uncommented by jonathan gevaryahu, as it is necessary for most cards in linux
384 bool8 mod = pitch_mod & (1 << J);
386 if (ch->needs_decode)
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;
397 ch->next_sample = ch->block[ch->sample_pointer];
400 if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod)
401 ch->interpolate = ((ch->next_sample - ch->sample) *
402 (long) freq0) / (long) FIXED_POINT;
404 VL = (ch->sample * ch-> left_vol_level) / 128;
405 VR = (ch->sample * ch->right_vol_level) / 128;
407 for (uint32 I = 0; I < (uint32) sample_count; I += 2)
409 unsigned long freq = freq0;
412 freq = PITCH_MOD(freq, wave [I / 2]);
414 ch->env_error += ch->erate;
415 if (ch->env_error >= FIXED_POINT)
417 uint32 step = ch->env_error >> FIXED_POINT_SHIFT;
422 ch->env_error &= FIXED_POINT_REMAINDER;
423 ch->envx += step << 1;
424 ch->envxx = ch->envx << ENVX_SHIFT;
429 ch->envxx = 127 << ENVX_SHIFT;
430 ch->state = SOUND_DECAY;
431 if (ch->sustain_level != 8)
433 S9xSetEnvRate (ch, ch->decay_rate, -1,
434 (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3, 1<<28);
437 ch->state = SOUND_SUSTAIN;
438 S9xSetEnvRate (ch, ch->sustain_rate, -1, 0, 2<<28);
443 while (ch->env_error >= FIXED_POINT)
445 ch->envxx = (ch->envxx >> 8) * 255;
446 ch->env_error -= FIXED_POINT;
448 ch->envx = ch->envxx >> ENVX_SHIFT;
449 if (ch->envx <= ch->envx_target)
453 S9xAPUSetEndOfSample (J, ch);
456 ch->state = SOUND_SUSTAIN;
457 S9xSetEnvRate (ch, ch->sustain_rate, -1, 0, 2<<28);
462 while (ch->env_error >= FIXED_POINT)
464 ch->envxx = (ch->envxx >> 8) * 255;
465 ch->env_error -= FIXED_POINT;
467 ch->envx = ch->envxx >> ENVX_SHIFT;
470 S9xAPUSetEndOfSample (J, ch);
476 while (ch->env_error >= FIXED_POINT)
478 ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
479 ch->env_error -= FIXED_POINT;
481 ch->envx = ch->envxx >> ENVX_SHIFT;
484 S9xAPUSetEndOfSample (J, ch);
489 case SOUND_INCREASE_LINEAR:
490 ch->env_error &= FIXED_POINT_REMAINDER;
491 ch->envx += step << 1;
492 ch->envxx = ch->envx << ENVX_SHIFT;
497 ch->envxx = 127 << ENVX_SHIFT;
498 ch->state = SOUND_GAIN;
499 ch->mode = MODE_GAIN;
500 S9xSetEnvRate (ch, 0, -1, 0, 0);
504 case SOUND_INCREASE_BENT_LINE:
505 if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4)
507 while (ch->env_error >= FIXED_POINT)
509 ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
510 ch->env_error -= FIXED_POINT;
512 ch->envx = ch->envxx >> ENVX_SHIFT;
516 ch->env_error &= FIXED_POINT_REMAINDER;
517 ch->envx += step << 1;
518 ch->envxx = ch->envx << ENVX_SHIFT;
524 ch->envxx = 127 << ENVX_SHIFT;
525 ch->state = SOUND_GAIN;
526 ch->mode = MODE_GAIN;
527 S9xSetEnvRate (ch, 0, -1, 0, 0);
531 case SOUND_DECREASE_LINEAR:
532 ch->env_error &= FIXED_POINT_REMAINDER;
533 ch->envx -= step << 1;
534 ch->envxx = ch->envx << ENVX_SHIFT;
537 S9xAPUSetEndOfSample (J, ch);
542 case SOUND_DECREASE_EXPONENTIAL:
543 while (ch->env_error >= FIXED_POINT)
545 ch->envxx = (ch->envxx >> 8) * 255;
546 ch->env_error -= FIXED_POINT;
548 ch->envx = ch->envxx >> ENVX_SHIFT;
551 S9xAPUSetEndOfSample (J, ch);
557 S9xSetEnvRate (ch, 0, -1, 0, 0);
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;
567 if (ch->count >= FIXED_POINT)
569 VL = ch->count >> FIXED_POINT_SHIFT;
570 ch->sample_pointer += VL;
571 ch->count &= FIXED_POINT_REMAINDER;
573 ch->sample = ch->next_sample;
574 if (ch->sample_pointer >= SOUND_DECODE_LENGTH)
576 if (JUST_PLAYED_LAST_SAMPLE(ch))
578 S9xAPUSetEndOfSample (J, ch);
583 ch->sample_pointer -= SOUND_DECODE_LENGTH;
588 ch->sample_pointer = LAST_SAMPLE;
589 ch->next_sample = ch->sample;
595 ch->last_block = FALSE;
596 uint16 *dir = S9xGetSampleAddress (ch->sample_number);
597 ch->block_pointer = *(dir + 1);
601 } while (ch->sample_pointer >= SOUND_DECODE_LENGTH);
602 if (!JUST_PLAYED_LAST_SAMPLE (ch))
603 ch->next_sample = ch->block [ch->sample_pointer];
606 ch->next_sample = ch->block [ch->sample_pointer];
608 if (ch->type == SOUND_SAMPLE)
610 if (Settings.InterpolatedSound && freq < FIXED_POINT && !mod)
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));
623 if ((so.noise_gen <<= 1) & 0x80000000L)
624 so.noise_gen ^= 0x0040001L;
625 ch->sample = (so.noise_gen << 17) >> 17;
629 VL = (ch->sample * ch-> left_vol_level) / 128;
630 VR = (ch->sample * ch->right_vol_level) / 128;
636 int32 s = (int32) ch->sample + ch->interpolate;
639 ch->sample = (int16) s;
640 VL = (ch->sample * ch-> left_vol_level) / 128;
641 VR = (ch->sample * ch->right_vol_level) / 128;
645 if (pitch_mod & (1 << (J + 1)))
646 wave [I / 2] = ch->sample * ch->envx;
649 MixBuffer [I+1] += VR;
650 if (ch->echo_buf_ptr)
652 ch->echo_buf_ptr [I] += VL;
653 ch->echo_buf_ptr [I+1] += VR;
660 static void MixMono (int sample_count)
662 int pitch_mod = SoundData.pitch_mod & (0xFFFFFFFF^APU.DSP[APU_NON]);
664 for (uint32 J = 0; J < NUM_CHANNELS; J++)
666 Channel *ch = &SoundData.channels[J];
667 unsigned long freq0 = ch->frequency;
669 if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J)))
672 // freq0 = (unsigned long) ((double) freq0 * 0.985);
674 bool8 mod = pitch_mod & (1 << J);
676 if (ch->needs_decode)
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];
689 if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod)
690 ch->interpolate = ((ch->next_sample - ch->sample) *
691 (long) freq0) / (long) FIXED_POINT;
693 int32 V = (ch->sample * ch->left_vol_level) / 128;
695 for (uint32 I = 0; I < (uint32) sample_count; I++)
697 unsigned long freq = freq0;
700 freq = PITCH_MOD(freq, wave [I]);
702 ch->env_error += ch->erate;
703 if (ch->env_error >= FIXED_POINT)
705 uint32 step = ch->env_error >> FIXED_POINT_SHIFT;
710 ch->env_error &= FIXED_POINT_REMAINDER;
711 ch->envx += step << 1;
712 ch->envxx = ch->envx << ENVX_SHIFT;
717 ch->envxx = 127 << ENVX_SHIFT;
718 ch->state = SOUND_DECAY;
719 if (ch->sustain_level != 8)
721 S9xSetEnvRate (ch, ch->decay_rate, -1,
722 (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3, 1<<28);
725 ch->state = SOUND_SUSTAIN;
726 S9xSetEnvRate (ch, ch->sustain_rate, -1, 0, 2<<28);
731 while (ch->env_error >= FIXED_POINT)
733 ch->envxx = (ch->envxx >> 8) * 255;
734 ch->env_error -= FIXED_POINT;
736 ch->envx = ch->envxx >> ENVX_SHIFT;
737 if (ch->envx <= ch->envx_target)
741 S9xAPUSetEndOfSample (J, ch);
744 ch->state = SOUND_SUSTAIN;
745 S9xSetEnvRate (ch, ch->sustain_rate, -1, 0, 2<<28);
750 while (ch->env_error >= FIXED_POINT)
752 ch->envxx = (ch->envxx >> 8) * 255;
753 ch->env_error -= FIXED_POINT;
755 ch->envx = ch->envxx >> ENVX_SHIFT;
758 S9xAPUSetEndOfSample (J, ch);
764 while (ch->env_error >= FIXED_POINT)
766 ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
767 ch->env_error -= FIXED_POINT;
769 ch->envx = ch->envxx >> ENVX_SHIFT;
772 S9xAPUSetEndOfSample (J, ch);
777 case SOUND_INCREASE_LINEAR:
778 ch->env_error &= FIXED_POINT_REMAINDER;
779 ch->envx += step << 1;
780 ch->envxx = ch->envx << ENVX_SHIFT;
785 ch->envxx = 127 << ENVX_SHIFT;
786 ch->state = SOUND_GAIN;
787 ch->mode = MODE_GAIN;
788 S9xSetEnvRate (ch, 0, -1, 0, 0);
792 case SOUND_INCREASE_BENT_LINE:
793 if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4)
795 while (ch->env_error >= FIXED_POINT)
797 ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
798 ch->env_error -= FIXED_POINT;
800 ch->envx = ch->envxx >> ENVX_SHIFT;
804 ch->env_error &= FIXED_POINT_REMAINDER;
805 ch->envx += step << 1;
806 ch->envxx = ch->envx << ENVX_SHIFT;
812 ch->envxx = 127 << ENVX_SHIFT;
813 ch->state = SOUND_GAIN;
814 ch->mode = MODE_GAIN;
815 S9xSetEnvRate (ch, 0, -1, 0, 0);
819 case SOUND_DECREASE_LINEAR:
820 ch->env_error &= FIXED_POINT_REMAINDER;
821 ch->envx -= step << 1;
822 ch->envxx = ch->envx << ENVX_SHIFT;
825 S9xAPUSetEndOfSample (J, ch);
830 case SOUND_DECREASE_EXPONENTIAL:
831 while (ch->env_error >= FIXED_POINT)
833 ch->envxx = (ch->envxx >> 8) * 255;
834 ch->env_error -= FIXED_POINT;
836 ch->envx = ch->envxx >> ENVX_SHIFT;
839 S9xAPUSetEndOfSample (J, ch);
845 S9xSetEnvRate (ch, 0, -1, 0, 0);
848 ch->left_vol_level = (ch->envx * ch->volume_left) / 128;
849 V = (ch->sample * ch->left_vol_level) / 128;
853 if (ch->count >= FIXED_POINT)
855 V = ch->count >> FIXED_POINT_SHIFT;
856 ch->sample_pointer += V;
857 ch->count &= FIXED_POINT_REMAINDER;
859 ch->sample = ch->next_sample;
860 if (ch->sample_pointer >= SOUND_DECODE_LENGTH)
862 if (JUST_PLAYED_LAST_SAMPLE(ch))
864 S9xAPUSetEndOfSample (J, ch);
869 ch->sample_pointer -= SOUND_DECODE_LENGTH;
874 ch->sample_pointer = LAST_SAMPLE;
875 ch->next_sample = ch->sample;
880 ch->last_block = FALSE;
881 uint16 *dir = S9xGetSampleAddress (ch->sample_number);
882 ch->block_pointer = *(dir + 1);
887 } while (ch->sample_pointer >= SOUND_DECODE_LENGTH);
888 if (!JUST_PLAYED_LAST_SAMPLE (ch))
889 ch->next_sample = ch->block [ch->sample_pointer];
892 ch->next_sample = ch->block [ch->sample_pointer];
894 if (ch->type == SOUND_SAMPLE)
896 if (Settings.InterpolatedSound && freq < FIXED_POINT && !mod)
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));
909 if ((so.noise_gen <<= 1) & 0x80000000L)
910 so.noise_gen ^= 0x0040001L;
911 ch->sample = (so.noise_gen << 17) >> 17;
914 V = (ch->sample * ch-> left_vol_level) / 128;
920 int32 s = (int32) ch->sample + ch->interpolate;
923 ch->sample = (int16) s;
924 V = (ch->sample * ch-> left_vol_level) / 128;
929 if (ch->echo_buf_ptr)
930 ch->echo_buf_ptr [I] += V;
932 if (pitch_mod & (1 << (J + 1)))
933 wave [I] = ch->sample * ch->envx;
940 // For backwards compatibility with older port specific code
941 void S9xMixSamples (signed short *buffer, int sample_count)
943 S9xMixSamplesO (buffer, sample_count, 0);
947 void S9xMixSamplesO (signed short *buffer, int sample_count, int sample_offset)
952 buffer += sample_offset;
956 memset32(buffer, 0, sample_count>>1);
960 memset32 (MixBuffer, 0, sample_count);
961 if (SoundData.echo_enable)
962 memset32 (EchoBuffer, 0, sample_count);
965 MixStereo (sample_count);
967 MixMono (sample_count);
969 /* Mix and convert waveforms */
970 if (SoundData.echo_enable && SoundData.echo_buffer_size)
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];
980 // 16-bit stereo sound with echo enabled ...
981 if (SoundData.no_filter)
983 // ... but no filter defined.
984 for (J = 0; J < sample_count; J+=2)
986 int E = Echo [SoundData.echo_ptr];
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];
991 if (SoundData.echo_ptr >= SoundData.echo_buffer_size)
992 SoundData.echo_ptr = 0;
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;
1005 // ... with filter defined.
1006 for (J = 0; J < sample_count; J+=2)
1008 register int E = Echo [SoundData.echo_ptr];
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];
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];
1025 if (SoundData.echo_ptr >= SoundData.echo_buffer_size)
1026 SoundData.echo_ptr = 0;
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;
1041 int master_vol_l = SoundData.master_volume[0];
1042 int echo_vol_l = SoundData.echo_volume[0];
1044 // 16-bit mono sound with echo enabled...
1045 if (SoundData.no_filter)
1047 // ... no filter defined
1048 for (J = 0; J < sample_count; J++)
1050 int E = Echo [SoundData.echo_ptr];
1052 Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J];
1054 if (SoundData.echo_ptr >= SoundData.echo_buffer_size)
1055 SoundData.echo_ptr = 0;
1057 I = (MixBuffer[J] * master_vol_l + E * echo_vol_l) / VOL_DIV16;
1064 // ... with filter defined
1065 for (J = 0; J < sample_count; J++)
1067 register int E = Echo [SoundData.echo_ptr];
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];
1081 Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J];
1083 if (SoundData.echo_ptr >= SoundData.echo_buffer_size)
1084 SoundData.echo_ptr = 0;
1086 I = (MixBuffer[J] * master_vol_l + E * echo_vol_l) / VOL_DIV16;
1095 int l, master_vol_l = SoundData.master_volume[0];
1099 int r, master_vol_r = SoundData.master_volume[1];
1101 // 16-bit stereo sound, no echo
1102 for (J = 0; J < sample_count; J+=2)
1104 l = (MixBuffer[J] * master_vol_l) / VOL_DIV16;
1105 r = (MixBuffer[J+1] * master_vol_r) / VOL_DIV16;
1115 // 16-bit mono sound, no echo
1116 for (J = 0; J < sample_count; J++)
1118 l = (MixBuffer[J] * master_vol_l) / VOL_DIV16;
1128 END_OF_FUNCTION(S9xMixSamplesO);
1131 void S9xResetSound (bool8 full)
1133 for (int i = 0; i < 8; i++)
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;
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;
1164 FilterTaps [0] = 127;
1172 so.mute_sound = TRUE;
1174 so.sound_switch = 255;
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;
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;
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];
1211 void S9xSetPlaybackRate (uint32 playback_rate)
1213 so.playback_rate = 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 [] =
1221 //0, 64, 1238, 1238, 256, 1, 64, 109, 64, 1238
1222 0, 64, 619, 619, 128, 1, 64, 55, 64, 619
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));
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));
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));
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));
1249 for(u=0; u < 10; u++)
1250 KeyOffERate[u] = (unsigned long) (((int64) FIXED_POINT * 1000 * steps[u]) /
1251 (8 * playback_rate));
1254 S9xSetEchoDelay (APU.DSP [APU_EDL] & 0xf);
1255 for (int i = 0; i < 8; i++)
1256 S9xSetSoundFrequency (i, SoundData.channels [i].hertz);
1259 bool8 S9xInitSound (void)
1261 so.playback_rate = 0;
1263 so.sound_switch = 255;
1265 S9xResetSound (TRUE);
1266 S9xSetSoundMute (TRUE);