summaryrefslogtreecommitdiff
path: root/src/soundux.c
diff options
context:
space:
mode:
authoraliaspider2015-11-09 20:42:25 +0100
committeraliaspider2015-11-09 20:42:25 +0100
commite144a0acc4854ad80f9e6945f4d94223ee865d78 (patch)
treeba76f908710407e43ca31ec51eca73a60d525eb2 /src/soundux.c
parent8d4780b83a112579e729a6f163ccd0ff30fc829f (diff)
downloadsnes9x2002-e144a0acc4854ad80f9e6945f4d94223ee865d78.tar.gz
snes9x2002-e144a0acc4854ad80f9e6945f4d94223ee865d78.tar.bz2
snes9x2002-e144a0acc4854ad80f9e6945f4d94223ee865d78.zip
reindent all files.
Diffstat (limited to 'src/soundux.c')
-rw-r--r--src/soundux.c2015
1 files changed, 1010 insertions, 1005 deletions
diff --git a/src/soundux.c b/src/soundux.c
index aed71f3..60d5540 100644
--- a/src/soundux.c
+++ b/src/soundux.c
@@ -4,7 +4,7 @@
* (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and
* Jerremy Koot (jkoot@snes9x.com)
*
- * Super FX C emulator code
+ * Super FX C emulator code
* (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and
* Gary Henderson.
* Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
@@ -105,7 +105,7 @@ extern long FilterValues[4][2];
#define VOL_DIV16 0x0080
#define ENVX_SHIFT 24
-void DecodeBlockAsm (int8 *, int16 *, int32 *, int32 *);
+void DecodeBlockAsm(int8*, int16*, int32*, int32*);
// F is channel's current frequency and M is the 16-bit modulation waveform
// from the previous channel multiplied by the current envelope volume level.
@@ -116,1020 +116,1024 @@ void DecodeBlockAsm (int8 *, int16 *, int32 *, int32 *);
#define JUST_PLAYED_LAST_SAMPLE(c) ((c)->sample_pointer >= LAST_SAMPLE)
-static inline void S9xAPUSetEndOfSample (int i, Channel *ch)
+static inline void S9xAPUSetEndOfSample(int i, Channel* ch)
{
- ch->state = SOUND_SILENT;
- ch->mode = MODE_NONE;
- APU.DSP [APU_ENDX] |= 1 << i;
- APU.DSP [APU_KON] &= ~(1 << i);
- APU.DSP [APU_KOFF] &= ~(1 << i);
- APU.KeyedChannels &= ~(1 << i);
+ ch->state = SOUND_SILENT;
+ ch->mode = MODE_NONE;
+ APU.DSP [APU_ENDX] |= 1 << i;
+ APU.DSP [APU_KON] &= ~(1 << i);
+ APU.DSP [APU_KOFF] &= ~(1 << i);
+ APU.KeyedChannels &= ~(1 << i);
}
#ifdef __DJGPP
-END_OF_FUNCTION (S9xAPUSetEndOfSample)
+END_OF_FUNCTION(S9xAPUSetEndOfSample)
#endif
-static inline void S9xAPUSetEndX (int ch)
+static inline void S9xAPUSetEndX(int ch)
{
- APU.DSP [APU_ENDX] |= 1 << ch;
+ APU.DSP [APU_ENDX] |= 1 << ch;
}
#ifdef __DJGPP
-END_OF_FUNCTION (S9xAPUSetEndX)
+END_OF_FUNCTION(S9xAPUSetEndX)
#endif
-void S9xSetEchoDelay (int delay)
+void S9xSetEchoDelay(int delay)
{
- SoundData.echo_buffer_size = (512 * delay * so.playback_rate) >> 15; // notaz / 32000;
- if (so.stereo)
- SoundData.echo_buffer_size <<= 1;
- if (SoundData.echo_buffer_size) {
- while(SoundData.echo_ptr >= SoundData.echo_buffer_size)
- SoundData.echo_ptr -= SoundData.echo_buffer_size;
- } else
- SoundData.echo_ptr = 0;
- S9xSetEchoEnable (APU.DSP [APU_EON]);
+ SoundData.echo_buffer_size = (512 * delay * so.playback_rate) >> 15; // notaz / 32000;
+ if (so.stereo)
+ SoundData.echo_buffer_size <<= 1;
+ if (SoundData.echo_buffer_size)
+ {
+ while (SoundData.echo_ptr >= SoundData.echo_buffer_size)
+ SoundData.echo_ptr -= SoundData.echo_buffer_size;
+ }
+ else
+ SoundData.echo_ptr = 0;
+ S9xSetEchoEnable(APU.DSP [APU_EON]);
}
-void S9xSetSoundKeyOff (int channel)
+void S9xSetSoundKeyOff(int channel)
{
- Channel *ch = &SoundData.channels[channel];
-
- if (ch->state != SOUND_SILENT)
- {
- ch->state = SOUND_RELEASE;
- ch->mode = MODE_RELEASE;
- S9xSetEnvRate (ch, 8, -1, 0, 5<<28);
- }
+ Channel* ch = &SoundData.channels[channel];
+
+ if (ch->state != SOUND_SILENT)
+ {
+ ch->state = SOUND_RELEASE;
+ ch->mode = MODE_RELEASE;
+ S9xSetEnvRate(ch, 8, -1, 0, 5 << 28);
+ }
}
-void S9xFixSoundAfterSnapshotLoad ()
+void S9xFixSoundAfterSnapshotLoad()
{
- SoundData.echo_write_enabled = !(APU.DSP [APU_FLG] & 0x20);
- SoundData.echo_channel_enable = APU.DSP [APU_EON];
- S9xSetEchoDelay (APU.DSP [APU_EDL] & 0xf);
- S9xSetEchoFeedback ((signed char) APU.DSP [APU_EFB]);
-
- S9xSetFilterCoefficient (0, (signed char) APU.DSP [APU_C0]);
- S9xSetFilterCoefficient (1, (signed char) APU.DSP [APU_C1]);
- S9xSetFilterCoefficient (2, (signed char) APU.DSP [APU_C2]);
- S9xSetFilterCoefficient (3, (signed char) APU.DSP [APU_C3]);
- S9xSetFilterCoefficient (4, (signed char) APU.DSP [APU_C4]);
- S9xSetFilterCoefficient (5, (signed char) APU.DSP [APU_C5]);
- S9xSetFilterCoefficient (6, (signed char) APU.DSP [APU_C6]);
- S9xSetFilterCoefficient (7, (signed char) APU.DSP [APU_C7]);
-
- int i;
- for (i = 0; i < 8; i++)
- {
- SoundData.channels[i].needs_decode = TRUE;
- S9xSetSoundFrequency (i, SoundData.channels[i].hertz);
- SoundData.channels [i].envxx = SoundData.channels [i].envx << ENVX_SHIFT;
- SoundData.channels [i].next_sample = 0;
- SoundData.channels [i].previous [0] = (int32) SoundData.channels [i].previous16 [0];
- SoundData.channels [i].previous [1] = (int32) SoundData.channels [i].previous16 [1];
- }
- SoundData.master_volume [0] = SoundData.master_volume_left;
- SoundData.master_volume [1] = SoundData.master_volume_right;
- SoundData.echo_volume [0] = SoundData.echo_volume_left;
- SoundData.echo_volume [1] = SoundData.echo_volume_right;
- IAPU.Scanline = 0;
+ SoundData.echo_write_enabled = !(APU.DSP [APU_FLG] & 0x20);
+ SoundData.echo_channel_enable = APU.DSP [APU_EON];
+ S9xSetEchoDelay(APU.DSP [APU_EDL] & 0xf);
+ S9xSetEchoFeedback((signed char) APU.DSP [APU_EFB]);
+
+ S9xSetFilterCoefficient(0, (signed char) APU.DSP [APU_C0]);
+ S9xSetFilterCoefficient(1, (signed char) APU.DSP [APU_C1]);
+ S9xSetFilterCoefficient(2, (signed char) APU.DSP [APU_C2]);
+ S9xSetFilterCoefficient(3, (signed char) APU.DSP [APU_C3]);
+ S9xSetFilterCoefficient(4, (signed char) APU.DSP [APU_C4]);
+ S9xSetFilterCoefficient(5, (signed char) APU.DSP [APU_C5]);
+ S9xSetFilterCoefficient(6, (signed char) APU.DSP [APU_C6]);
+ S9xSetFilterCoefficient(7, (signed char) APU.DSP [APU_C7]);
+
+ int i;
+ for (i = 0; i < 8; i++)
+ {
+ SoundData.channels[i].needs_decode = TRUE;
+ S9xSetSoundFrequency(i, SoundData.channels[i].hertz);
+ SoundData.channels [i].envxx = SoundData.channels [i].envx << ENVX_SHIFT;
+ SoundData.channels [i].next_sample = 0;
+ SoundData.channels [i].previous [0] = (int32) SoundData.channels [i].previous16 [0];
+ SoundData.channels [i].previous [1] = (int32) SoundData.channels [i].previous16 [1];
+ }
+ SoundData.master_volume [0] = SoundData.master_volume_left;
+ SoundData.master_volume [1] = SoundData.master_volume_right;
+ SoundData.echo_volume [0] = SoundData.echo_volume_left;
+ SoundData.echo_volume [1] = SoundData.echo_volume_right;
+ IAPU.Scanline = 0;
}
-void S9xSetEnvelopeHeight (int channel, int level)
+void S9xSetEnvelopeHeight(int channel, int level)
{
- Channel *ch = &SoundData.channels[channel];
+ Channel* ch = &SoundData.channels[channel];
- ch->envx = level;
- ch->envxx = level << ENVX_SHIFT;
+ ch->envx = level;
+ ch->envxx = level << ENVX_SHIFT;
- ch->left_vol_level = (level * ch->volume_left) / 128;
- ch->right_vol_level = (level * ch->volume_right) / 128;
+ ch->left_vol_level = (level * ch->volume_left) / 128;
+ ch->right_vol_level = (level * ch->volume_right) / 128;
- if (ch->envx == 0 && ch->state != SOUND_SILENT && ch->state != SOUND_GAIN)
- {
- S9xAPUSetEndOfSample (channel, ch);
- }
+ if (ch->envx == 0 && ch->state != SOUND_SILENT && ch->state != SOUND_GAIN)
+ S9xAPUSetEndOfSample(channel, ch);
}
#if 1
-void S9xSetSoundSample (int channel, uint16 sample_number)
+void S9xSetSoundSample(int channel, uint16 sample_number)
{
}
#else
-void S9xSetSoundSample (int channel, uint16 sample_number)
+void S9xSetSoundSample(int channel, uint16 sample_number)
{
- register Channel *ch = &SoundData.channels[channel];
-
- if (ch->state != SOUND_SILENT &&
- sample_number != ch->sample_number)
- {
- int keep = ch->state;
- ch->state = SOUND_SILENT;
- ch->sample_number = sample_number;
- ch->loop = FALSE;
- ch->needs_decode = TRUE;
- ch->last_block = FALSE;
- ch->previous [0] = ch->previous[1] = 0;
- ch->block_pointer = *S9xGetSampleAddress(sample_number);
- ch->sample_pointer = 0;
- ch->state = keep;
- }
+ register Channel* ch = &SoundData.channels[channel];
+
+ if (ch->state != SOUND_SILENT &&
+ sample_number != ch->sample_number)
+ {
+ int keep = ch->state;
+ ch->state = SOUND_SILENT;
+ ch->sample_number = sample_number;
+ ch->loop = FALSE;
+ ch->needs_decode = TRUE;
+ ch->last_block = FALSE;
+ ch->previous [0] = ch->previous[1] = 0;
+ ch->block_pointer = *S9xGetSampleAddress(sample_number);
+ ch->sample_pointer = 0;
+ ch->state = keep;
+ }
}
#endif
-static void DecodeBlock (Channel *ch)
+static void DecodeBlock(Channel* ch)
{
- if (ch->block_pointer >= 0x10000 - 9)
- {
- ch->last_block = TRUE;
- ch->loop = FALSE;
- ch->block = ch->decoded;
- memset32 ((uint32_t *) ch->decoded, 0, 8);
- return;
- }
- signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer];
-
- unsigned char filter = *compressed;
- if ((ch->last_block = filter & 1))
- ch->loop = (filter & 2) != 0;
-
- int16 *raw = ch->block = ch->decoded;
+ if (ch->block_pointer >= 0x10000 - 9)
+ {
+ ch->last_block = TRUE;
+ ch->loop = FALSE;
+ ch->block = ch->decoded;
+ memset32((uint32_t*) ch->decoded, 0, 8);
+ return;
+ }
+ signed char* compressed = (signed char*) &IAPU.RAM [ch->block_pointer];
+
+ unsigned char filter = *compressed;
+ if ((ch->last_block = filter & 1))
+ ch->loop = (filter & 2) != 0;
+
+ int16* raw = ch->block = ch->decoded;
#ifdef ARM
- DecodeBlockAsm (compressed, raw, &ch->previous [0], &ch->previous [1]);
+ DecodeBlockAsm(compressed, raw, &ch->previous [0], &ch->previous [1]);
#else
- int32 out;
- unsigned char shift;
- signed char sample1, sample2;
- unsigned int i;
-
- compressed++;
-
- int32 prev0 = ch->previous [0];
- int32 prev1 = ch->previous [1];
- shift = filter >> 4;
-
- switch ((filter >> 2) & 3)
- {
- case 0:
- for (i = 8; i != 0; i--)
- {
- sample1 = *compressed++;
- sample2 = sample1 << 4;
- sample2 >>= 4;
- sample1 >>= 4;
- *raw++ = ((int32) sample1 << shift);
- *raw++ = ((int32) sample2 << shift);
- }
- prev1 = *(raw - 2);
- prev0 = *(raw - 1);
- break;
- case 1:
- for (i = 8; i != 0; i--)
- {
- sample1 = *compressed++;
- sample2 = sample1 << 4;
- sample2 >>= 4;
- sample1 >>= 4;
- prev0 = (int16) prev0;
- *raw++ = prev1 = ((int32) sample1 << shift) + prev0 - (prev0 >> 4);
- prev1 = (int16) prev1;
- *raw++ = prev0 = ((int32) sample2 << shift) + prev1 - (prev1 >> 4);
- }
- break;
- case 2:
- for (i = 8; i != 0; i--)
- {
- sample1 = *compressed++;
- sample2 = sample1 << 4;
- sample2 >>= 4;
- sample1 >>= 4;
-
- out = (sample1 << shift) - prev1 + (prev1 >> 4);
- prev1 = (int16) prev0;
- prev0 &= ~3;
- *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) -
- (prev0 >> 4);
-
- out = (sample2 << shift) - prev1 + (prev1 >> 4);
- prev1 = (int16) prev0;
- prev0 &= ~3;
- *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) -
- (prev0 >> 4);
- }
- break;
- case 3:
- for (i = 8; i != 0; i--)
- {
- sample1 = *compressed++;
- sample2 = sample1 << 4;
- sample2 >>= 4;
- sample1 >>= 4;
- out = (sample1 << shift);
-
- out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);
- prev1 = (int16) prev0;
- prev0 &= ~3;
- *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) -
- (prev0 >> 4) - (prev1 >> 6);
-
- out = (sample2 << shift);
- out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);
- prev1 = (int16) prev0;
- prev0 &= ~3;
- *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) -
- (prev0 >> 4) - (prev1 >> 6);
- }
- break;
- }
- ch->previous [0] = prev0;
- ch->previous [1] = prev1;
+ int32 out;
+ unsigned char shift;
+ signed char sample1, sample2;
+ unsigned int i;
+
+ compressed++;
+
+ int32 prev0 = ch->previous [0];
+ int32 prev1 = ch->previous [1];
+ shift = filter >> 4;
+
+ switch ((filter >> 2) & 3)
+ {
+ case 0:
+ for (i = 8; i != 0; i--)
+ {
+ sample1 = *compressed++;
+ sample2 = sample1 << 4;
+ sample2 >>= 4;
+ sample1 >>= 4;
+ *raw++ = ((int32) sample1 << shift);
+ *raw++ = ((int32) sample2 << shift);
+ }
+ prev1 = *(raw - 2);
+ prev0 = *(raw - 1);
+ break;
+ case 1:
+ for (i = 8; i != 0; i--)
+ {
+ sample1 = *compressed++;
+ sample2 = sample1 << 4;
+ sample2 >>= 4;
+ sample1 >>= 4;
+ prev0 = (int16) prev0;
+ *raw++ = prev1 = ((int32) sample1 << shift) + prev0 - (prev0 >> 4);
+ prev1 = (int16) prev1;
+ *raw++ = prev0 = ((int32) sample2 << shift) + prev1 - (prev1 >> 4);
+ }
+ break;
+ case 2:
+ for (i = 8; i != 0; i--)
+ {
+ sample1 = *compressed++;
+ sample2 = sample1 << 4;
+ sample2 >>= 4;
+ sample1 >>= 4;
+
+ out = (sample1 << shift) - prev1 + (prev1 >> 4);
+ prev1 = (int16) prev0;
+ prev0 &= ~3;
+ *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) -
+ (prev0 >> 4);
+
+ out = (sample2 << shift) - prev1 + (prev1 >> 4);
+ prev1 = (int16) prev0;
+ prev0 &= ~3;
+ *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) -
+ (prev0 >> 4);
+ }
+ break;
+ case 3:
+ for (i = 8; i != 0; i--)
+ {
+ sample1 = *compressed++;
+ sample2 = sample1 << 4;
+ sample2 >>= 4;
+ sample1 >>= 4;
+ out = (sample1 << shift);
+
+ out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);
+ prev1 = (int16) prev0;
+ prev0 &= ~3;
+ *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) -
+ (prev0 >> 4) - (prev1 >> 6);
+
+ out = (sample2 << shift);
+ out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);
+ prev1 = (int16) prev0;
+ prev0 &= ~3;
+ *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) -
+ (prev0 >> 4) - (prev1 >> 6);
+ }
+ break;
+ }
+ ch->previous [0] = prev0;
+ ch->previous [1] = prev1;
#endif
- ch->block_pointer += 9;
+ ch->block_pointer += 9;
}
-static void MixStereo (int sample_count)
+static void MixStereo(int sample_count)
{
- int pitch_mod = SoundData.pitch_mod & (0xFFFFFFFF^APU.DSP[APU_NON]);//~APU.DSP[APU_NON];
-
- uint32 J;
- for (J = 0; J < NUM_CHANNELS; J++)
- {
- int32 VL, VR;
- Channel *ch = &SoundData.channels[J];
- unsigned long freq0 = ch->frequency;
-
- if (ch->state == SOUND_SILENT)
- continue;
-
-// freq0 = (unsigned long) ((double) freq0 * 0.985);//uncommented by jonathan gevaryahu, as it is necessary for most cards in linux
-
- bool8 mod = pitch_mod & (1 << J);
-
- if (ch->needs_decode)
- {
- DecodeBlock(ch);
- ch->needs_decode = FALSE;
- ch->sample = ch->block[0];
- ch->sample_pointer = freq0 >> FIXED_POINT_SHIFT;
- if (ch->sample_pointer == 0)
- ch->sample_pointer = 1;
- if (ch->sample_pointer > SOUND_DECODE_LENGTH)
- ch->sample_pointer = SOUND_DECODE_LENGTH - 1;
-
- ch->next_sample = ch->block[ch->sample_pointer];
- }
- VL = (ch->sample * ch-> left_vol_level) / 128;
- VR = (ch->sample * ch->right_vol_level) / 128;
-
- uint32 I;
- for (I = 0; I < (uint32) sample_count; I += 2)
- {
- unsigned long freq = freq0;
-
- if (mod)
- freq = PITCH_MOD(freq, wave [I / 2]);
-
- ch->env_error += ch->erate;
- if (ch->env_error >= FIXED_POINT)
- {
- uint32 step = ch->env_error >> FIXED_POINT_SHIFT;
-
- switch (ch->state)
- {
- case SOUND_ATTACK:
- ch->env_error &= FIXED_POINT_REMAINDER;
- ch->envx += step << 1;
- ch->envxx = ch->envx << ENVX_SHIFT;
-
- if (ch->envx >= 126)
- {
- ch->envx = 127;
- ch->envxx = 127 << ENVX_SHIFT;
- ch->state = SOUND_DECAY;
- if (ch->sustain_level != 8)
- {
- S9xSetEnvRate (ch, ch->decay_rate, -1,
- (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3, 1<<28);
- break;
- }
- ch->state = SOUND_SUSTAIN;
- S9xSetEnvRate (ch, ch->sustain_rate, -1, 0, 2<<28);
- }
- break;
-
- case SOUND_DECAY:
- while (ch->env_error >= FIXED_POINT)
- {
- ch->envxx = (ch->envxx >> 8) * 255;
- ch->env_error -= FIXED_POINT;
- }
- ch->envx = ch->envxx >> ENVX_SHIFT;
- if (ch->envx <= ch->envx_target)
- {
- if (ch->envx <= 0)
- {
- S9xAPUSetEndOfSample (J, ch);
- goto stereo_exit;
- }
- ch->state = SOUND_SUSTAIN;
- S9xSetEnvRate (ch, ch->sustain_rate, -1, 0, 2<<28);
- }
- break;
-
- case SOUND_SUSTAIN:
- while (ch->env_error >= FIXED_POINT)
- {
- ch->envxx = (ch->envxx >> 8) * 255;
- ch->env_error -= FIXED_POINT;
- }
- ch->envx = ch->envxx >> ENVX_SHIFT;
- if (ch->envx <= 0)
- {
- S9xAPUSetEndOfSample (J, ch);
- goto stereo_exit;
- }
- break;
-
- case SOUND_RELEASE:
- while (ch->env_error >= FIXED_POINT)
- {
- ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
- ch->env_error -= FIXED_POINT;
- }
- ch->envx = ch->envxx >> ENVX_SHIFT;
- if (ch->envx <= 0)
- {
- S9xAPUSetEndOfSample (J, ch);
- goto stereo_exit;
- }
- break;
-
- case SOUND_INCREASE_LINEAR:
- ch->env_error &= FIXED_POINT_REMAINDER;
- ch->envx += step << 1;
- ch->envxx = ch->envx << ENVX_SHIFT;
-
- if (ch->envx >= 126)
- {
- ch->envx = 127;
- ch->envxx = 127 << ENVX_SHIFT;
- ch->state = SOUND_GAIN;
- ch->mode = MODE_GAIN;
- S9xSetEnvRate (ch, 0, -1, 0, 0);
- }
- break;
-
- case SOUND_INCREASE_BENT_LINE:
- if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4)
- {
- while (ch->env_error >= FIXED_POINT)
- {
- ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
- ch->env_error -= FIXED_POINT;
- }
- ch->envx = ch->envxx >> ENVX_SHIFT;
- }
- else
- {
- ch->env_error &= FIXED_POINT_REMAINDER;
- ch->envx += step << 1;
- ch->envxx = ch->envx << ENVX_SHIFT;
- }
-
- if (ch->envx >= 126)
- {
- ch->envx = 127;
- ch->envxx = 127 << ENVX_SHIFT;
- ch->state = SOUND_GAIN;
- ch->mode = MODE_GAIN;
- S9xSetEnvRate (ch, 0, -1, 0, 0);
- }
- break;
-
- case SOUND_DECREASE_LINEAR:
- ch->env_error &= FIXED_POINT_REMAINDER;
- ch->envx -= step << 1;
- ch->envxx = ch->envx << ENVX_SHIFT;
- if (ch->envx <= 0)
- {
- S9xAPUSetEndOfSample (J, ch);
- goto stereo_exit;
- }
- break;
-
- case SOUND_DECREASE_EXPONENTIAL:
- while (ch->env_error >= FIXED_POINT)
- {
- ch->envxx = (ch->envxx >> 8) * 255;
- ch->env_error -= FIXED_POINT;
- }
- ch->envx = ch->envxx >> ENVX_SHIFT;
- if (ch->envx <= 0)
- {
- S9xAPUSetEndOfSample (J, ch);
- goto stereo_exit;
- }
- break;
-
- case SOUND_GAIN:
- S9xSetEnvRate (ch, 0, -1, 0, 0);
- break;
- }
- ch-> left_vol_level = (ch->envx * ch->volume_left) / 128;
- ch->right_vol_level = (ch->envx * ch->volume_right) / 128;
- VL = (ch->sample * ch-> left_vol_level) / 128;
- VR = (ch->sample * ch->right_vol_level) / 128;
- }
-
- ch->count += freq;
- if (ch->count >= FIXED_POINT)
- {
- VL = ch->count >> FIXED_POINT_SHIFT;
- ch->sample_pointer += VL;
- ch->count &= FIXED_POINT_REMAINDER;
-
- ch->sample = ch->next_sample;
- if (ch->sample_pointer >= SOUND_DECODE_LENGTH)
- {
- if (JUST_PLAYED_LAST_SAMPLE(ch))
- {
- S9xAPUSetEndOfSample (J, ch);
- goto stereo_exit;
- }
- do
- {
- ch->sample_pointer -= SOUND_DECODE_LENGTH;
- if (ch->last_block)
- {
- if (!ch->loop)
- {
- ch->sample_pointer = LAST_SAMPLE;
- ch->next_sample = ch->sample;
- break;
- }
- else
- {
- S9xAPUSetEndX (J);
- ch->last_block = FALSE;
- uint16 *dir = S9xGetSampleAddress (ch->sample_number);
- ch->block_pointer = *(dir + 1);
- }
- }
- DecodeBlock (ch);
- } while (ch->sample_pointer >= SOUND_DECODE_LENGTH);
- if (!JUST_PLAYED_LAST_SAMPLE (ch))
- ch->next_sample = ch->block [ch->sample_pointer];
- }
- else
- ch->next_sample = ch->block [ch->sample_pointer];
-
- if (ch->type != SOUND_SAMPLE)
- {
- for (;VL > 0; VL--)
- if ((so.noise_gen <<= 1) & 0x80000000L)
- so.noise_gen ^= 0x0040001L;
- ch->sample = (so.noise_gen << 17) >> 17;
- }
-
- VL = (ch->sample * ch-> left_vol_level) / 128;
- VR = (ch->sample * ch->right_vol_level) / 128;
- }
-
- if (pitch_mod & (1 << (J + 1)))
- wave [I / 2] = ch->sample * ch->envx;
-
- MixBuffer [I] += VL;
- MixBuffer [I+1] += VR;
- if (ch->echo_buf_ptr)
- {
- ch->echo_buf_ptr [I] += VL;
- ch->echo_buf_ptr [I+1] += VR;
- }
- }
-stereo_exit: ;
- }
+ int pitch_mod = SoundData.pitch_mod & (0xFFFFFFFF ^ APU.DSP[APU_NON]); //~APU.DSP[APU_NON];
+
+ uint32 J;
+ for (J = 0; J < NUM_CHANNELS; J++)
+ {
+ int32 VL, VR;
+ Channel* ch = &SoundData.channels[J];
+ unsigned long freq0 = ch->frequency;
+
+ if (ch->state == SOUND_SILENT)
+ continue;
+
+ // freq0 = (unsigned long) ((double) freq0 * 0.985);//uncommented by jonathan gevaryahu, as it is necessary for most cards in linux
+
+ bool8 mod = pitch_mod & (1 << J);
+
+ if (ch->needs_decode)
+ {
+ DecodeBlock(ch);
+ ch->needs_decode = FALSE;
+ ch->sample = ch->block[0];
+ ch->sample_pointer = freq0 >> FIXED_POINT_SHIFT;
+ if (ch->sample_pointer == 0)
+ ch->sample_pointer = 1;
+ if (ch->sample_pointer > SOUND_DECODE_LENGTH)
+ ch->sample_pointer = SOUND_DECODE_LENGTH - 1;
+
+ ch->next_sample = ch->block[ch->sample_pointer];
+ }
+ VL = (ch->sample * ch-> left_vol_level) / 128;
+ VR = (ch->sample * ch->right_vol_level) / 128;
+
+ uint32 I;
+ for (I = 0; I < (uint32) sample_count; I += 2)
+ {
+ unsigned long freq = freq0;
+
+ if (mod)
+ freq = PITCH_MOD(freq, wave [I / 2]);
+
+ ch->env_error += ch->erate;
+ if (ch->env_error >= FIXED_POINT)
+ {
+ uint32 step = ch->env_error >> FIXED_POINT_SHIFT;
+
+ switch (ch->state)
+ {
+ case SOUND_ATTACK:
+ ch->env_error &= FIXED_POINT_REMAINDER;
+ ch->envx += step << 1;
+ ch->envxx = ch->envx << ENVX_SHIFT;
+
+ if (ch->envx >= 126)
+ {
+ ch->envx = 127;
+ ch->envxx = 127 << ENVX_SHIFT;
+ ch->state = SOUND_DECAY;
+ if (ch->sustain_level != 8)
+ {
+ S9xSetEnvRate(ch, ch->decay_rate, -1,
+ (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3, 1 << 28);
+ break;
+ }
+ ch->state = SOUND_SUSTAIN;
+ S9xSetEnvRate(ch, ch->sustain_rate, -1, 0, 2 << 28);
+ }
+ break;
+
+ case SOUND_DECAY:
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx = (ch->envxx >> 8) * 255;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ if (ch->envx <= ch->envx_target)
+ {
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample(J, ch);
+ goto stereo_exit;
+ }
+ ch->state = SOUND_SUSTAIN;
+ S9xSetEnvRate(ch, ch->sustain_rate, -1, 0, 2 << 28);
+ }
+ break;
+
+ case SOUND_SUSTAIN:
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx = (ch->envxx >> 8) * 255;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample(J, ch);
+ goto stereo_exit;
+ }
+ break;
+
+ case SOUND_RELEASE:
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample(J, ch);
+ goto stereo_exit;
+ }
+ break;
+
+ case SOUND_INCREASE_LINEAR:
+ ch->env_error &= FIXED_POINT_REMAINDER;
+ ch->envx += step << 1;
+ ch->envxx = ch->envx << ENVX_SHIFT;
+
+ if (ch->envx >= 126)
+ {
+ ch->envx = 127;
+ ch->envxx = 127 << ENVX_SHIFT;
+ ch->state = SOUND_GAIN;
+ ch->mode = MODE_GAIN;
+ S9xSetEnvRate(ch, 0, -1, 0, 0);
+ }
+ break;
+
+ case SOUND_INCREASE_BENT_LINE:
+ if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4)
+ {
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ }
+ else
+ {
+ ch->env_error &= FIXED_POINT_REMAINDER;
+ ch->envx += step << 1;
+ ch->envxx = ch->envx << ENVX_SHIFT;
+ }
+
+ if (ch->envx >= 126)
+ {
+ ch->envx = 127;
+ ch->envxx = 127 << ENVX_SHIFT;
+ ch->state = SOUND_GAIN;
+ ch->mode = MODE_GAIN;
+ S9xSetEnvRate(ch, 0, -1, 0, 0);
+ }
+ break;
+
+ case SOUND_DECREASE_LINEAR:
+ ch->env_error &= FIXED_POINT_REMAINDER;
+ ch->envx -= step << 1;
+ ch->envxx = ch->envx << ENVX_SHIFT;
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample(J, ch);
+ goto stereo_exit;
+ }
+ break;
+
+ case SOUND_DECREASE_EXPONENTIAL:
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx = (ch->envxx >> 8) * 255;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample(J, ch);
+ goto stereo_exit;
+ }
+ break;
+
+ case SOUND_GAIN:
+ S9xSetEnvRate(ch, 0, -1, 0, 0);
+ break;
+ }
+ ch-> left_vol_level = (ch->envx * ch->volume_left) / 128;
+ ch->right_vol_level = (ch->envx * ch->volume_right) / 128;
+ VL = (ch->sample * ch-> left_vol_level) / 128;
+ VR = (ch->sample * ch->right_vol_level) / 128;
+ }
+
+ ch->count += freq;
+ if (ch->count >= FIXED_POINT)
+ {
+ VL = ch->count >> FIXED_POINT_SHIFT;
+ ch->sample_pointer += VL;
+ ch->count &= FIXED_POINT_REMAINDER;
+
+ ch->sample = ch->next_sample;
+ if (ch->sample_pointer >= SOUND_DECODE_LENGTH)
+ {
+ if (JUST_PLAYED_LAST_SAMPLE(ch))
+ {
+ S9xAPUSetEndOfSample(J, ch);
+ goto stereo_exit;
+ }
+ do
+ {
+ ch->sample_pointer -= SOUND_DECODE_LENGTH;
+ if (ch->last_block)
+ {
+ if (!ch->loop)
+ {
+ ch->sample_pointer = LAST_SAMPLE;
+ ch->next_sample = ch->sample;
+ break;
+ }
+ else
+ {
+ S9xAPUSetEndX(J);
+ ch->last_block = FALSE;
+ uint16* dir = S9xGetSampleAddress(ch->sample_number);
+ ch->block_pointer = *(dir + 1);
+ }
+ }
+ DecodeBlock(ch);
+ }
+ while (ch->sample_pointer >= SOUND_DECODE_LENGTH);
+ if (!JUST_PLAYED_LAST_SAMPLE(ch))
+ ch->next_sample = ch->block [ch->sample_pointer];
+ }
+ else
+ ch->next_sample = ch->block [ch->sample_pointer];
+
+ if (ch->type != SOUND_SAMPLE)
+ {
+ for (; VL > 0; VL--)
+ if ((so.noise_gen <<= 1) & 0x80000000L)
+ so.noise_gen ^= 0x0040001L;
+ ch->sample = (so.noise_gen << 17) >> 17;
+ }
+
+ VL = (ch->sample * ch-> left_vol_level) / 128;
+ VR = (ch->sample * ch->right_vol_level) / 128;
+ }
+
+ if (pitch_mod & (1 << (J + 1)))
+ wave [I / 2] = ch->sample * ch->envx;
+
+ MixBuffer [I] += VL;
+ MixBuffer [I + 1] += VR;
+ if (ch->echo_buf_ptr)
+ {
+ ch->echo_buf_ptr [I] += VL;
+ ch->echo_buf_ptr [I + 1] += VR;
+ }
+ }
+stereo_exit:
+ ;
+ }
}
-static void MixMono (int sample_count)
+static void MixMono(int sample_count)
{
- int pitch_mod = SoundData.pitch_mod & (0xFFFFFFFF^APU.DSP[APU_NON]);
-
- uint32 J;
- for (J = 0; J < NUM_CHANNELS; J++)
- {
- Channel *ch = &SoundData.channels[J];
- unsigned long freq0 = ch->frequency;
-
- if (ch->state == SOUND_SILENT)
- continue;
-
-// freq0 = (unsigned long) ((double) freq0 * 0.985);
-
- bool8 mod = pitch_mod & (1 << J);
-
- if (ch->needs_decode)
- {
- DecodeBlock(ch);
- ch->needs_decode = FALSE;
- ch->sample = ch->block[0];
- ch->sample_pointer = freq0 >> FIXED_POINT_SHIFT;
- if (ch->sample_pointer == 0)
- ch->sample_pointer = 1;
- if (ch->sample_pointer > SOUND_DECODE_LENGTH)
- ch->sample_pointer = SOUND_DECODE_LENGTH - 1;
- ch->next_sample = ch->block[ch->sample_pointer];
-
- }
- int32 V = (ch->sample * ch->left_vol_level) / 128;
-
- uint32 I;
- for (I = 0; I < (uint32) sample_count; I++)
- {
- unsigned long freq = freq0;
-
- if (mod)
- freq = PITCH_MOD(freq, wave [I]);
-
- ch->env_error += ch->erate;
- if (ch->env_error >= FIXED_POINT)
- {
- uint32 step = ch->env_error >> FIXED_POINT_SHIFT;
-
- switch (ch->state)
- {
- case SOUND_ATTACK:
- ch->env_error &= FIXED_POINT_REMAINDER;
- ch->envx += step << 1;
- ch->envxx = ch->envx << ENVX_SHIFT;
-
- if (ch->envx >= 126)
- {
- ch->envx = 127;
- ch->envxx = 127 << ENVX_SHIFT;
- ch->state = SOUND_DECAY;
- if (ch->sustain_level != 8)
- {
- S9xSetEnvRate (ch, ch->decay_rate, -1,
- (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3, 1<<28);
- break;
- }
- ch->state = SOUND_SUSTAIN;
- S9xSetEnvRate (ch, ch->sustain_rate, -1, 0, 2<<28);
- }
- break;
-
- case SOUND_DECAY:
- while (ch->env_error >= FIXED_POINT)
- {
- ch->envxx = (ch->envxx >> 8) * 255;
- ch->env_error -= FIXED_POINT;
- }
- ch->envx = ch->envxx >> ENVX_SHIFT;
- if (ch->envx <= ch->envx_target)
- {
- if (ch->envx <= 0)
- {
- S9xAPUSetEndOfSample (J, ch);
- goto mono_exit;
- }
- ch->state = SOUND_SUSTAIN;
- S9xSetEnvRate (ch, ch->sustain_rate, -1, 0, 2<<28);
- }
- break;
-
- case SOUND_SUSTAIN:
- while (ch->env_error >= FIXED_POINT)
- {
- ch->envxx = (ch->envxx >> 8) * 255;
- ch->env_error -= FIXED_POINT;
- }
- ch->envx = ch->envxx >> ENVX_SHIFT;
- if (ch->envx <= 0)
- {
- S9xAPUSetEndOfSample (J, ch);
- goto mono_exit;
- }
- break;
-
- case SOUND_RELEASE:
- while (ch->env_error >= FIXED_POINT)
- {
- ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
- ch->env_error -= FIXED_POINT;
- }
- ch->envx = ch->envxx >> ENVX_SHIFT;
- if (ch->envx <= 0)
- {
- S9xAPUSetEndOfSample (J, ch);
- goto mono_exit;
- }
- break;
-
- case SOUND_INCREASE_LINEAR:
- ch->env_error &= FIXED_POINT_REMAINDER;
- ch->envx += step << 1;
- ch->envxx = ch->envx << ENVX_SHIFT;
-
- if (ch->envx >= 126)
- {
- ch->envx = 127;
- ch->envxx = 127 << ENVX_SHIFT;
- ch->state = SOUND_GAIN;
- ch->mode = MODE_GAIN;
- S9xSetEnvRate (ch, 0, -1, 0, 0);
- }
- break;
-
- case SOUND_INCREASE_BENT_LINE:
- if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4)
- {
- while (ch->env_error >= FIXED_POINT)
- {
- ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
- ch->env_error -= FIXED_POINT;
- }
- ch->envx = ch->envxx >> ENVX_SHIFT;
- }
- else
- {
- ch->env_error &= FIXED_POINT_REMAINDER;
- ch->envx += step << 1;
- ch->envxx = ch->envx << ENVX_SHIFT;
- }
-
- if (ch->envx >= 126)
- {
- ch->envx = 127;
- ch->envxx = 127 << ENVX_SHIFT;
- ch->state = SOUND_GAIN;
- ch->mode = MODE_GAIN;
- S9xSetEnvRate (ch, 0, -1, 0, 0);
- }
- break;
-
- case SOUND_DECREASE_LINEAR:
- ch->env_error &= FIXED_POINT_REMAINDER;
- ch->envx -= step << 1;
- ch->envxx = ch->envx << ENVX_SHIFT;
- if (ch->envx <= 0)
- {
- S9xAPUSetEndOfSample (J, ch);
- goto mono_exit;
- }
- break;
-
- case SOUND_DECREASE_EXPONENTIAL:
- while (ch->env_error >= FIXED_POINT)
- {
- ch->envxx = (ch->envxx >> 8) * 255;
- ch->env_error -= FIXED_POINT;
- }
- ch->envx = ch->envxx >> ENVX_SHIFT;
- if (ch->envx <= 0)
- {
- S9xAPUSetEndOfSample (J, ch);
- goto mono_exit;
- }
- break;
-
- case SOUND_GAIN:
- S9xSetEnvRate (ch, 0, -1, 0, 0);
- break;
- }
- ch->left_vol_level = (ch->envx * ch->volume_left) / 128;
- V = (ch->sample * ch->left_vol_level) / 128;
- }
-
- ch->count += freq;
- if (ch->count >= FIXED_POINT)
- {
- V = ch->count >> FIXED_POINT_SHIFT;
- ch->sample_pointer += V;
- ch->count &= FIXED_POINT_REMAINDER;
-
- ch->sample = ch->next_sample;
- if (ch->sample_pointer >= SOUND_DECODE_LENGTH)
- {
- if (JUST_PLAYED_LAST_SAMPLE(ch))
- {
- S9xAPUSetEndOfSample (J, ch);
- goto mono_exit;
- }
- do
- {
- ch->sample_pointer -= SOUND_DECODE_LENGTH;
- if (ch->last_block)
- {
- if (!ch->loop)
- {
- ch->sample_pointer = LAST_SAMPLE;
- ch->next_sample = ch->sample;
- break;
- }
- else
- {
- ch->last_block = FALSE;
- uint16 *dir = S9xGetSampleAddress (ch->sample_number);
- ch->block_pointer = *(dir + 1);
- S9xAPUSetEndX (J);
- }
- }
- DecodeBlock (ch);
- } while (ch->sample_pointer >= SOUND_DECODE_LENGTH);
- if (!JUST_PLAYED_LAST_SAMPLE (ch))
- ch->next_sample = ch->block [ch->sample_pointer];
- }
- else
- ch->next_sample = ch->block [ch->sample_pointer];
-
- if (ch->type != SOUND_SAMPLE)
- {
- for (;V > 0; V--)
- if ((so.noise_gen <<= 1) & 0x80000000L)
- so.noise_gen ^= 0x0040001L;
- ch->sample = (so.noise_gen << 17) >> 17;
- }
- V = (ch->sample * ch-> left_vol_level) / 128;
+ int pitch_mod = SoundData.pitch_mod & (0xFFFFFFFF ^ APU.DSP[APU_NON]);
+
+ uint32 J;
+ for (J = 0; J < NUM_CHANNELS; J++)
+ {
+ Channel* ch = &SoundData.channels[J];
+ unsigned long freq0 = ch->frequency;
+
+ if (ch->state == SOUND_SILENT)
+ continue;
+
+ // freq0 = (unsigned long) ((double) freq0 * 0.985);
+
+ bool8 mod = pitch_mod & (1 << J);
+
+ if (ch->needs_decode)
+ {
+ DecodeBlock(ch);
+ ch->needs_decode = FALSE;
+ ch->sample = ch->block[0];
+ ch->sample_pointer = freq0 >> FIXED_POINT_SHIFT;
+ if (ch->sample_pointer == 0)
+ ch->sample_pointer = 1;
+ if (ch->sample_pointer > SOUND_DECODE_LENGTH)
+ ch->sample_pointer = SOUND_DECODE_LENGTH - 1;
+ ch->next_sample = ch->block[ch->sample_pointer];
+
+ }
+ int32 V = (ch->sample * ch->left_vol_level) / 128;
+
+ uint32 I;
+ for (I = 0; I < (uint32) sample_count; I++)
+ {
+ unsigned long freq = freq0;
+
+ if (mod)
+ freq = PITCH_MOD(freq, wave [I]);
+
+ ch->env_error += ch->erate;
+ if (ch->env_error >= FIXED_POINT)
+ {
+ uint32 step = ch->env_error >> FIXED_POINT_SHIFT;
+
+ switch (ch->state)
+ {
+ case SOUND_ATTACK:
+ ch->env_error &= FIXED_POINT_REMAINDER;
+ ch->envx += step << 1;
+ ch->envxx = ch->envx << ENVX_SHIFT;
+
+ if (ch->envx >= 126)
+ {
+ ch->envx = 127;
+ ch->envxx = 127 << ENVX_SHIFT;
+ ch->state = SOUND_DECAY;
+ if (ch->sustain_level != 8)
+ {
+ S9xSetEnvRate(ch, ch->decay_rate, -1,
+ (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3, 1 << 28);
+ break;
+ }
+ ch->state = SOUND_SUSTAIN;
+ S9xSetEnvRate(ch, ch->sustain_rate, -1, 0, 2 << 28);
+ }
+ break;
+
+ case SOUND_DECAY:
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx = (ch->envxx >> 8) * 255;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ if (ch->envx <= ch->envx_target)
+ {
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample(J, ch);
+ goto mono_exit;
+ }
+ ch->state = SOUND_SUSTAIN;
+ S9xSetEnvRate(ch, ch->sustain_rate, -1, 0, 2 << 28);
+ }
+ break;
+
+ case SOUND_SUSTAIN:
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx = (ch->envxx >> 8) * 255;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample(J, ch);
+ goto mono_exit;
+ }
+ break;
+
+ case SOUND_RELEASE:
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample(J, ch);
+ goto mono_exit;
+ }
+ break;
+
+ case SOUND_INCREASE_LINEAR:
+ ch->env_error &= FIXED_POINT_REMAINDER;
+ ch->envx += step << 1;
+ ch->envxx = ch->envx << ENVX_SHIFT;
+
+ if (ch->envx >= 126)
+ {
+ ch->envx = 127;
+ ch->envxx = 127 << ENVX_SHIFT;
+ ch->state = SOUND_GAIN;
+ ch->mode = MODE_GAIN;
+ S9xSetEnvRate(ch, 0, -1, 0, 0);
+ }
+ break;
+
+ case SOUND_INCREASE_BENT_LINE:
+ if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4)
+ {
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ }
+ else
+ {
+ ch->env_error &= FIXED_POINT_REMAINDER;
+ ch->envx += step << 1;
+ ch->envxx = ch->envx << ENVX_SHIFT;
+ }
+
+ if (ch->envx >= 126)
+ {
+ ch->envx = 127;
+ ch->envxx = 127 << ENVX_SHIFT;
+ ch->state = SOUND_GAIN;
+ ch->mode = MODE_GAIN;
+ S9xSetEnvRate(ch, 0, -1, 0, 0);
+ }
+ break;
+
+ case SOUND_DECREASE_LINEAR:
+ ch->env_error &= FIXED_POINT_REMAINDER;
+ ch->envx -= step << 1;
+ ch->envxx = ch->envx << ENVX_SHIFT;
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample(J, ch);
+ goto mono_exit;
+ }
+ break;
+
+ case SOUND_DECREASE_EXPONENTIAL:
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx = (ch->envxx >> 8) * 255;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample(J, ch);
+ goto mono_exit;
+ }
+ break;
+
+ case SOUND_GAIN:
+ S9xSetEnvRate(ch, 0, -1, 0, 0);
+ break;
}
-
- MixBuffer [I] += V;
- if (ch->echo_buf_ptr)
- ch->echo_buf_ptr [I] += V;
-
- if (pitch_mod & (1 << (J + 1)))
- wave [I] = ch->sample * ch->envx;
- }
-mono_exit: ;
- }
+ ch->left_vol_level = (ch->envx * ch->volume_left) / 128;
+ V = (ch->sample * ch->left_vol_level) / 128;
+ }
+
+ ch->count += freq;
+ if (ch->count >= FIXED_POINT)
+ {
+ V = ch->count >> FIXED_POINT_SHIFT;
+ ch->sample_pointer += V;
+ ch->count &= FIXED_POINT_REMAINDER;
+
+ ch->sample = ch->next_sample;
+ if (ch->sample_pointer >= SOUND_DECODE_LENGTH)
+ {
+ if (JUST_PLAYED_LAST_SAMPLE(ch))
+ {
+ S9xAPUSetEndOfSample(J, ch);
+ goto mono_exit;
+ }
+ do
+ {
+ ch->sample_pointer -= SOUND_DECODE_LENGTH;
+ if (ch->last_block)
+ {
+ if (!ch->loop)
+ {
+ ch->sample_pointer = LAST_SAMPLE;
+ ch->next_sample = ch->sample;
+ break;
+ }
+ else
+ {
+ ch->last_block = FALSE;
+ uint16* dir = S9xGetSampleAddress(ch->sample_number);
+ ch->block_pointer = *(dir + 1);
+ S9xAPUSetEndX(J);
+ }
+ }
+ DecodeBlock(ch);
+ }
+ while (ch->sample_pointer >= SOUND_DECODE_LENGTH);
+ if (!JUST_PLAYED_LAST_SAMPLE(ch))
+ ch->next_sample = ch->block [ch->sample_pointer];
+ }
+ else
+ ch->next_sample = ch->block [ch->sample_pointer];
+
+ if (ch->type != SOUND_SAMPLE)
+ {
+ for (; V > 0; V--)
+ if ((so.noise_gen <<= 1) & 0x80000000L)
+ so.noise_gen ^= 0x0040001L;
+ ch->sample = (so.noise_gen << 17) >> 17;
+ }
+ V = (ch->sample * ch-> left_vol_level) / 128;
+ }
+
+ MixBuffer [I] += V;
+ if (ch->echo_buf_ptr)
+ ch->echo_buf_ptr [I] += V;
+
+ if (pitch_mod & (1 << (J + 1)))
+ wave [I] = ch->sample * ch->envx;
+ }
+mono_exit:
+ ;
+ }
}
// For backwards compatibility with older port specific code
-void S9xMixSamples (signed short *buffer, int sample_count)
+void S9xMixSamples(signed short* buffer, int sample_count)
{
- S9xMixSamplesO (buffer, sample_count, 0);
+ S9xMixSamplesO(buffer, sample_count, 0);
}
-void S9xMixSamplesO (signed short *buffer, int sample_count, int sample_offset)
+void S9xMixSamplesO(signed short* buffer, int sample_count, int sample_offset)
{
- // 16-bit sound only
- int J;
-
- buffer += sample_offset;
-
- if (so.mute_sound)
- {
- memset16((uint16_t*)buffer, 0, sample_count);
- return;
- }
-
- memset32 ((uint32_t*)MixBuffer, 0, sample_count);
- if (SoundData.echo_enable)
- memset32 ((uint32_t*)EchoBuffer, 0, sample_count);
-
- if (so.stereo)
- MixStereo (sample_count);
- else
- MixMono (sample_count);
-
- /* Mix and convert waveforms */
- if (SoundData.echo_enable && SoundData.echo_buffer_size)
- {
- if (so.stereo)
- {
- int l, r;
- int master_vol_l = SoundData.master_volume[0];
- int master_vol_r = SoundData.master_volume[1];
- int echo_vol_l = SoundData.echo_volume[0];
- int echo_vol_r = SoundData.echo_volume[1];
-
- // 16-bit stereo sound with echo enabled ...
- if (SoundData.no_filter)
- {
- // ... but no filter defined.
- for (J = 0; J < sample_count; J+=2)
- {
- int E = Echo [SoundData.echo_ptr];
-
- Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J];
- Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J+1];
-
- if (SoundData.echo_ptr >= SoundData.echo_buffer_size)
- SoundData.echo_ptr = 0;
-
- l = (MixBuffer[J] * master_vol_l + E * echo_vol_l) / VOL_DIV16;
- r = (MixBuffer[J+1] * master_vol_r + E * echo_vol_r) / VOL_DIV16;
-
- CLIP16(l);
- CLIP16(r);
- buffer[J] = l;
- buffer[J+1] = r;
- }
- }
- else
- {
- // ... with filter defined.
- for (J = 0; J < sample_count; J+=2)
- {
- register int E = Echo [SoundData.echo_ptr];
-
- Loop [(Z - 0) & 15] = E;
-
-
-
- E = E * FilterTaps [0];
- E += Loop [(Z - 2) & 15] * FilterTaps [1];
- E += Loop [(Z - 4) & 15] * FilterTaps [2];
- E += Loop [(Z - 6) & 15] * FilterTaps [3];
- E += Loop [(Z - 8) & 15] * FilterTaps [4];
- E += Loop [(Z - 10) & 15] * FilterTaps [5];
- E += Loop [(Z - 12) & 15] * FilterTaps [6];
- E += Loop [(Z - 14) & 15] * FilterTaps [7];
- E /= 128;
- Z++;
-
- Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J];
- Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J+1];
-
- if (SoundData.echo_ptr >= SoundData.echo_buffer_size)
- SoundData.echo_ptr = 0;
-
- l = (MixBuffer[J] * master_vol_l + E * echo_vol_l) / VOL_DIV16;
- r = (MixBuffer[J+1] * master_vol_r + E * echo_vol_r) / VOL_DIV16;
-
- CLIP16(l);
- CLIP16(r);
- buffer[J] = l;
- buffer[J+1] = r;
- }
- }
- }
- else
- {
- int I;
- int master_vol_l = SoundData.master_volume[0];
- int echo_vol_l = SoundData.echo_volume[0];
-
- // 16-bit mono sound with echo enabled...
- if (SoundData.no_filter)
- {
- // ... no filter defined
- for (J = 0; J < sample_count; J++)
- {
- int E = Echo [SoundData.echo_ptr];
-
- Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J];
-
- if (SoundData.echo_ptr >= SoundData.echo_buffer_size)
- SoundData.echo_ptr = 0;
-
- I = (MixBuffer[J] * master_vol_l + E * echo_vol_l) / VOL_DIV16;
- CLIP16(I);
- buffer[J] = I;
- }
- }
- else
- {
- // ... with filter defined
- for (J = 0; J < sample_count; J++)
- {
- register int E = Echo [SoundData.echo_ptr];
-
- Loop [(Z - 0) & 7] = E;
- E = E * FilterTaps [0];
- E += Loop [(Z - 1) & 7] * FilterTaps [1];
- E += Loop [(Z - 2) & 7] * FilterTaps [2];
- E += Loop [(Z - 3) & 7] * FilterTaps [3];
- E += Loop [(Z - 4) & 7] * FilterTaps [4];
- E += Loop [(Z - 5) & 7] * FilterTaps [5];
- E += Loop [(Z - 6) & 7] * FilterTaps [6];
- E += Loop [(Z - 7) & 7] * FilterTaps [7];
- E /= 128;
- Z++;
-
- Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J];
-
- if (SoundData.echo_ptr >= SoundData.echo_buffer_size)
- SoundData.echo_ptr = 0;
-
- I = (MixBuffer[J] * master_vol_l + E * echo_vol_l) / VOL_DIV16;
- CLIP16(I);
- buffer[J] = I;
- }
- }
- }
- }
- else
- {
- int l, master_vol_l = SoundData.master_volume[0];
-
- if (so.stereo)
- {
- int r, master_vol_r = SoundData.master_volume[1];
-
- // 16-bit stereo sound, no echo
- for (J = 0; J < sample_count; J+=2)
- {
- l = (MixBuffer[J] * master_vol_l) / VOL_DIV16;
- r = (MixBuffer[J+1] * master_vol_r) / VOL_DIV16;
-
- CLIP16(l);
- CLIP16(r);
- buffer[J] = l;
- buffer[J+1] = r;
- }
- }
- else
- {
- // 16-bit mono sound, no echo
- for (J = 0; J < sample_count; J++)
- {
- l = (MixBuffer[J] * master_vol_l) / VOL_DIV16;
-
- CLIP16(l);
- buffer[J] = l;
- }
- }
- }
+ // 16-bit sound only
+ int J;
+
+ buffer += sample_offset;
+
+ if (so.mute_sound)
+ {
+ memset16((uint16_t*)buffer, 0, sample_count);
+ return;
+ }
+
+ memset32((uint32_t*)MixBuffer, 0, sample_count);
+ if (SoundData.echo_enable)
+ memset32((uint32_t*)EchoBuffer, 0, sample_count);
+
+ if (so.stereo)
+ MixStereo(sample_count);
+ else
+ MixMono(sample_count);
+
+ /* Mix and convert waveforms */
+ if (SoundData.echo_enable && SoundData.echo_buffer_size)
+ {
+ if (so.stereo)
+ {
+ int l, r;
+ int master_vol_l = SoundData.master_volume[0];
+ int master_vol_r = SoundData.master_volume[1];
+ int echo_vol_l = SoundData.echo_volume[0];
+ int echo_vol_r = SoundData.echo_volume[1];
+
+ // 16-bit stereo sound with echo enabled ...
+ if (SoundData.no_filter)
+ {
+ // ... but no filter defined.
+ for (J = 0; J < sample_count; J += 2)
+ {
+ int E = Echo [SoundData.echo_ptr];
+
+ Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J];
+ Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J + 1];
+
+ if (SoundData.echo_ptr >= SoundData.echo_buffer_size)
+ SoundData.echo_ptr = 0;
+
+ l = (MixBuffer[J] * master_vol_l + E * echo_vol_l) / VOL_DIV16;
+ r = (MixBuffer[J + 1] * master_vol_r + E * echo_vol_r) / VOL_DIV16;
+
+ CLIP16(l);
+ CLIP16(r);
+ buffer[J] = l;
+ buffer[J + 1] = r;
+ }
+ }
+ else
+ {
+ // ... with filter defined.
+ for (J = 0; J < sample_count; J += 2)
+ {
+ register int E = Echo [SoundData.echo_ptr];
+
+ Loop [(Z - 0) & 15] = E;
+
+
+
+ E = E * FilterTaps [0];
+ E += Loop [(Z - 2) & 15] * FilterTaps [1];
+ E += Loop [(Z - 4) & 15] * FilterTaps [2];
+ E += Loop [(Z - 6) & 15] * FilterTaps [3];
+ E += Loop [(Z - 8) & 15] * FilterTaps [4];
+ E += Loop [(Z - 10) & 15] * FilterTaps [5];
+ E += Loop [(Z - 12) & 15] * FilterTaps [6];
+ E += Loop [(Z - 14) & 15] * FilterTaps [7];
+ E /= 128;
+ Z++;
+
+ Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J];
+ Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J + 1];
+
+ if (SoundData.echo_ptr >= SoundData.echo_buffer_size)
+ SoundData.echo_ptr = 0;
+
+ l = (MixBuffer[J] * master_vol_l + E * echo_vol_l) / VOL_DIV16;
+ r = (MixBuffer[J + 1] * master_vol_r + E * echo_vol_r) / VOL_DIV16;
+
+ CLIP16(l);
+ CLIP16(r);
+ buffer[J] = l;
+ buffer[J + 1] = r;
+ }
+ }
+ }
+ else
+ {
+ int I;
+ int master_vol_l = SoundData.master_volume[0];
+ int echo_vol_l = SoundData.echo_volume[0];
+
+ // 16-bit mono sound with echo enabled...
+ if (SoundData.no_filter)
+ {
+ // ... no filter defined
+ for (J = 0; J < sample_count; J++)
+ {
+ int E = Echo [SoundData.echo_ptr];
+
+ Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J];
+
+ if (SoundData.echo_ptr >= SoundData.echo_buffer_size)
+ SoundData.echo_ptr = 0;
+
+ I = (MixBuffer[J] * master_vol_l + E * echo_vol_l) / VOL_DIV16;
+ CLIP16(I);
+ buffer[J] = I;
+ }
+ }
+ else
+ {
+ // ... with filter defined
+ for (J = 0; J < sample_count; J++)
+ {
+ register int E = Echo [SoundData.echo_ptr];
+
+ Loop [(Z - 0) & 7] = E;
+ E = E * FilterTaps [0];
+ E += Loop [(Z - 1) & 7] * FilterTaps [1];
+ E += Loop [(Z - 2) & 7] * FilterTaps [2];
+ E += Loop [(Z - 3) & 7] * FilterTaps [3];
+ E += Loop [(Z - 4) & 7] * FilterTaps [4];
+ E += Loop [(Z - 5) & 7] * FilterTaps [5];
+ E += Loop [(Z - 6) & 7] * FilterTaps [6];
+ E += Loop [(Z - 7) & 7] * FilterTaps [7];
+ E /= 128;
+ Z++;
+
+ Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J];
+
+ if (SoundData.echo_ptr >= SoundData.echo_buffer_size)
+ SoundData.echo_ptr = 0;
+
+ I = (MixBuffer[J] * master_vol_l + E * echo_vol_l) / VOL_DIV16;
+ CLIP16(I);
+ buffer[J] = I;
+ }
+ }
+ }
+ }
+ else
+ {
+ int l, master_vol_l = SoundData.master_volume[0];
+
+ if (so.stereo)
+ {
+ int r, master_vol_r = SoundData.master_volume[1];
+
+ // 16-bit stereo sound, no echo
+ for (J = 0; J < sample_count; J += 2)
+ {
+ l = (MixBuffer[J] * master_vol_l) / VOL_DIV16;
+ r = (MixBuffer[J + 1] * master_vol_r) / VOL_DIV16;
+
+ CLIP16(l);
+ CLIP16(r);
+ buffer[J] = l;
+ buffer[J + 1] = r;
+ }
+ }
+ else
+ {
+ // 16-bit mono sound, no echo
+ for (J = 0; J < sample_count; J++)
+ {
+ l = (MixBuffer[J] * master_vol_l) / VOL_DIV16;
+
+ CLIP16(l);
+ buffer[J] = l;
+ }
+ }
+ }
}
#ifdef __DJGPP
END_OF_FUNCTION(S9xMixSamplesO);
#endif
-void S9xResetSound (bool8 full)
+void S9xResetSound(bool8 full)
{
int i;
- for (i = 0; i < 8; i++)
- {
- SoundData.channels[i].state = SOUND_SILENT;
- SoundData.channels[i].mode = MODE_NONE;
- SoundData.channels[i].type = SOUND_SAMPLE;
- SoundData.channels[i].volume_left = 0;
- SoundData.channels[i].volume_right = 0;
- SoundData.channels[i].hertz = 0;
- SoundData.channels[i].count = 0;
- SoundData.channels[i].loop = FALSE;
- SoundData.channels[i].envx_target = 0;
- SoundData.channels[i].env_error = 0;
- SoundData.channels[i].erate = 0;
- SoundData.channels[i].envx = 0;
- SoundData.channels[i].envxx = 0;
- SoundData.channels[i].left_vol_level = 0;
- SoundData.channels[i].right_vol_level = 0;
- SoundData.channels[i].direction = 0;
- SoundData.channels[i].attack_rate = 0;
- SoundData.channels[i].decay_rate = 0;
- SoundData.channels[i].sustain_rate = 0;
- SoundData.channels[i].release_rate = 0;
- SoundData.channels[i].sustain_level = 0;
- // notaz
- SoundData.channels[i].env_ind_attack = 0;
- SoundData.channels[i].env_ind_decay = 0;
- SoundData.channels[i].env_ind_sustain = 0;
- SoundData.echo_ptr = 0;
- SoundData.echo_feedback = 0;
- SoundData.echo_buffer_size = 1;
- }
- FilterTaps [0] = 127;
- FilterTaps [1] = 0;
- FilterTaps [2] = 0;
- FilterTaps [3] = 0;
- FilterTaps [4] = 0;
- FilterTaps [5] = 0;
- FilterTaps [6] = 0;
- FilterTaps [7] = 0;
- so.mute_sound = TRUE;
- so.noise_gen = 1;
-
- if (full)
- {
- SoundData.master_volume_left = 0;
- SoundData.master_volume_right = 0;
- SoundData.echo_volume_left = 0;
- SoundData.echo_volume_right = 0;
- SoundData.echo_enable = 0;
- SoundData.echo_write_enabled = 0;
- SoundData.echo_channel_enable = 0;
- SoundData.pitch_mod = 0;
- SoundData.dummy[0] = 0;
- SoundData.dummy[1] = 0;
- SoundData.dummy[2] = 0;
- SoundData.master_volume[0] = 0;
- SoundData.master_volume[1] = 0;
- SoundData.echo_volume[0] = 0;
- SoundData.echo_volume[1] = 0;
- SoundData.noise_hertz = 0;
- }
-
- SoundData.master_volume_left = 127;
- SoundData.master_volume_right = 127;
- SoundData.master_volume [0] = SoundData.master_volume [1] = 127;
- SoundData.no_filter = TRUE;
+ for (i = 0; i < 8; i++)
+ {
+ SoundData.channels[i].state = SOUND_SILENT;
+ SoundData.channels[i].mode = MODE_NONE;
+ SoundData.channels[i].type = SOUND_SAMPLE;
+ SoundData.channels[i].volume_left = 0;
+ SoundData.channels[i].volume_right = 0;
+ SoundData.channels[i].hertz = 0;
+ SoundData.channels[i].count = 0;
+ SoundData.channels[i].loop = FALSE;
+ SoundData.channels[i].envx_target = 0;
+ SoundData.channels[i].env_error = 0;
+ SoundData.channels[i].erate = 0;
+ SoundData.channels[i].envx = 0;
+ SoundData.channels[i].envxx = 0;
+ SoundData.channels[i].left_vol_level = 0;
+ SoundData.channels[i].right_vol_level = 0;
+ SoundData.channels[i].direction = 0;
+ SoundData.channels[i].attack_rate = 0;
+ SoundData.channels[i].decay_rate = 0;
+ SoundData.channels[i].sustain_rate = 0;
+ SoundData.channels[i].release_rate = 0;
+ SoundData.channels[i].sustain_level = 0;
+ // notaz
+ SoundData.channels[i].env_ind_attack = 0;
+ SoundData.channels[i].env_ind_decay = 0;
+ SoundData.channels[i].env_ind_sustain = 0;
+ SoundData.echo_ptr = 0;
+ SoundData.echo_feedback = 0;
+ SoundData.echo_buffer_size = 1;
+ }
+ FilterTaps [0] = 127;
+ FilterTaps [1] = 0;
+ FilterTaps [2] = 0;
+ FilterTaps [3] = 0;
+ FilterTaps [4] = 0;
+ FilterTaps [5] = 0;
+ FilterTaps [6] = 0;
+ FilterTaps [7] = 0;
+ so.mute_sound = TRUE;
+ so.noise_gen = 1;
+
+ if (full)
+ {
+ SoundData.master_volume_left = 0;
+ SoundData.master_volume_right = 0;
+ SoundData.echo_volume_left = 0;
+ SoundData.echo_volume_right = 0;
+ SoundData.echo_enable = 0;
+ SoundData.echo_write_enabled = 0;
+ SoundData.echo_channel_enable = 0;
+ SoundData.pitch_mod = 0;
+ SoundData.dummy[0] = 0;
+ SoundData.dummy[1] = 0;
+ SoundData.dummy[2] = 0;
+ SoundData.master_volume[0] = 0;
+ SoundData.master_volume[1] = 0;
+ SoundData.echo_volume[0] = 0;
+ SoundData.echo_volume[1] = 0;
+ SoundData.noise_hertz = 0;
+ }
+
+ SoundData.master_volume_left = 127;
+ SoundData.master_volume_right = 127;
+ SoundData.master_volume [0] = SoundData.master_volume [1] = 127;
+ SoundData.no_filter = TRUE;
}
@@ -1138,66 +1142,67 @@ extern unsigned long AttackRate [16];
extern unsigned long DecayRate [8];
extern unsigned long SustainRate [32];
extern unsigned long IncreaseRate [32];
-extern unsigned long DecreaseRateExp [32];
+extern unsigned long DecreaseRateExp [32];
-void S9xSetPlaybackRate (uint32 playback_rate)
+void S9xSetPlaybackRate(uint32 playback_rate)
{
- so.playback_rate = playback_rate;
-
- if(playback_rate) {
- // notaz: calclulate a value (let's call it freqbase) to simplify channel freq calculations later.
- so.freqbase = (FIXED_POINT<<11) / (playback_rate * 33 / 32);
- // now precalculate env rates for S9xSetEnvRate
- static int steps [] =
- {
- //0, 64, 1238, 1238, 256, 1, 64, 109, 64, 1238
- 0, 64, 619, 619, 128, 1, 64, 55, 64, 619
- };
- int i, u;
- for(i=0; i < 16; i++)
- for(u=0; u < 10; u++)
- AttackERate[i][u] = (unsigned long) (((int64) FIXED_POINT * 1000 * steps[u]) /
- (AttackRate[i] * playback_rate));
- for(i=0; i < 8; i++)
- for(u=0; u < 10; u++)
- DecayERate[i][u] = (unsigned long) (((int64) FIXED_POINT * 1000 * steps[u]) /
- (DecayRate[i] * playback_rate));
-
- for(i=0; i < 32; i++)
- for(u=0; u < 10; u++)
- SustainERate[i][u]= (unsigned long) (((int64) FIXED_POINT * 1000 * steps[u]) /
- (SustainRate[i] * playback_rate));
-
- for(i=0; i < 32; i++)
- for(u=0; u < 10; u++)
- IncreaseERate[i][u]=(unsigned long) (((int64) FIXED_POINT * 1000 * steps[u]) /
- (IncreaseRate[i] * playback_rate));
-
- for(i=0; i < 32; i++)
- for(u=0; u < 10; u++)
- DecreaseERateExp[i][u] = (unsigned long) (((int64) FIXED_POINT * 1000 * steps[u]) /
- (DecreaseRateExp[i] / 2 * playback_rate));
-
- for(u=0; u < 10; u++)
- KeyOffERate[u] = (unsigned long) (((int64) FIXED_POINT * 1000 * steps[u]) /
- (8 * playback_rate));
- }
-
- S9xSetEchoDelay (APU.DSP [APU_EDL] & 0xf);
- int i;
- for (i = 0; i < 8; i++)
- S9xSetSoundFrequency (i, SoundData.channels [i].hertz);
+ so.playback_rate = playback_rate;
+
+ if (playback_rate)
+ {
+ // notaz: calclulate a value (let's call it freqbase) to simplify channel freq calculations later.
+ so.freqbase = (FIXED_POINT << 11) / (playback_rate * 33 / 32);
+ // now precalculate env rates for S9xSetEnvRate
+ static int steps [] =
+ {
+ //0, 64, 1238, 1238, 256, 1, 64, 109, 64, 1238
+ 0, 64, 619, 619, 128, 1, 64, 55, 64, 619
+ };
+ int i, u;
+ for (i = 0; i < 16; i++)
+ for (u = 0; u < 10; u++)
+ AttackERate[i][u] = (unsigned long)(((int64) FIXED_POINT * 1000 * steps[u]) /
+ (AttackRate[i] * playback_rate));
+ for (i = 0; i < 8; i++)
+ for (u = 0; u < 10; u++)
+ DecayERate[i][u] = (unsigned long)(((int64) FIXED_POINT * 1000 * steps[u]) /
+ (DecayRate[i] * playback_rate));
+
+ for (i = 0; i < 32; i++)
+ for (u = 0; u < 10; u++)
+ SustainERate[i][u] = (unsigned long)(((int64) FIXED_POINT * 1000 * steps[u]) /
+ (SustainRate[i] * playback_rate));
+
+ for (i = 0; i < 32; i++)
+ for (u = 0; u < 10; u++)
+ IncreaseERate[i][u] = (unsigned long)(((int64) FIXED_POINT * 1000 * steps[u]) /
+ (IncreaseRate[i] * playback_rate));
+
+ for (i = 0; i < 32; i++)
+ for (u = 0; u < 10; u++)
+ DecreaseERateExp[i][u] = (unsigned long)(((int64) FIXED_POINT * 1000 * steps[u]) /
+ (DecreaseRateExp[i] / 2 * playback_rate));
+
+ for (u = 0; u < 10; u++)
+ KeyOffERate[u] = (unsigned long)(((int64) FIXED_POINT * 1000 * steps[u]) /
+ (8 * playback_rate));
+ }
+
+ S9xSetEchoDelay(APU.DSP [APU_EDL] & 0xf);
+ int i;
+ for (i = 0; i < 8; i++)
+ S9xSetSoundFrequency(i, SoundData.channels [i].hertz);
}
-bool8 S9xInitSound (void)
+bool8 S9xInitSound(void)
{
- so.playback_rate = 0;
- so.stereo = 0;
+ so.playback_rate = 0;
+ so.stereo = 0;
- S9xResetSound (TRUE);
- S9xSetSoundMute (TRUE);
+ S9xResetSound(TRUE);
+ S9xSetSoundMute(TRUE);
- return (1);
+ return (1);
}