aboutsummaryrefslogtreecommitdiff
path: root/source/soundux.cpp
diff options
context:
space:
mode:
authorNebuleon Fumika2013-02-01 19:02:38 -0500
committerNebuleon Fumika2013-02-01 19:02:38 -0500
commite61731a524028f8286f83a82686b2f4e236c1a9d (patch)
tree72d124e9c854a8a0cc7985e03dc298c43029cc49 /source/soundux.cpp
parent30fe9eaf6ab8b0701419949a4415736675d15377 (diff)
downloadsnesemu-e61731a524028f8286f83a82686b2f4e236c1a9d.tar.gz
snesemu-e61731a524028f8286f83a82686b2f4e236c1a9d.tar.bz2
snesemu-e61731a524028f8286f83a82686b2f4e236c1a9d.zip
Revert the reversed stereo mixing loop. This makes it more consistent with mainline Snes9x, in case of merges from 1.53. It also didn't help much, given that the problem was trying to push 92 milliseconds of audio inside 20 milliseconds of time.
This reverts commit 2b715684087675747df7cb8995695936f20c782b.
Diffstat (limited to 'source/soundux.cpp')
-rw-r--r--source/soundux.cpp339
1 files changed, 2 insertions, 337 deletions
diff --git a/source/soundux.cpp b/source/soundux.cpp
index 124ce6d..dde8a14 100644
--- a/source/soundux.cpp
+++ b/source/soundux.cpp
@@ -889,334 +889,6 @@ void DecodeBlock (Channel *ch)
ch->block_pointer += 9;
}
-/*
- * The layout of loops in this function is optimised for outputting a few
- * samples, reducing the number of memory accesses per sample-channel pair.
- * For each SAMPLE, each channel is mixed into CPU registers and
- * assigned to the mix buffer.
- */
-static inline void MixStereo_ReversedLoop (int sample_count)
-{
- int pitch_mod = SoundData.pitch_mod & ~APU.DSP[APU_NON];
- int32 VL[NUM_CHANNELS], VR[NUM_CHANNELS];
- int32 PreviousChannelSample = 0;
-
- for (uint32 I = 0; I < (uint32) sample_count; I += 2)
- {
- int32 OutputLeft = 0, OutputRight = 0;
-
- for (uint32 J = 0; J < NUM_CHANNELS; J++)
- {
- Channel *ch = &SoundData.channels[J];
-
- if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J)))
- continue;
-
- unsigned long freq0 = ch->frequency;
-
- // freq0 = (unsigned long) ((double) freq0 * 0.985);//uncommented by jonathan gevaryahu, as it is necessary for most cards in linux
- freq0 = freq0 * 985/1000;
-
- bool8 mod = pitch_mod & (1 << J);
-
- if (I == 0)
- {
- 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];
- ch->interpolate = 0;
-
- if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod)
- ch->interpolate = ((ch->next_sample - ch->sample) *
- (long) freq0) / (long) FIXED_POINT;
- }
- VL [J] = (ch->sample * ch-> left_vol_level) / 128;
- VR [J] = (ch->sample * ch->right_vol_level) / 128;
- }
-
- unsigned long freq = freq0;
-
- if (mod)
- freq = PITCH_MOD(freq, PreviousChannelSample);
-
- 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);
- break;
- }
- ch->state = SOUND_SUSTAIN;
- S9xSetEnvRate (ch, ch->sustain_rate, -1, 0);
- }
- 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);
- }
- 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);
- }
- 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);
- }
- 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);
- break;
- }
- ch-> left_vol_level = (ch->envx * ch->volume_left) / 128;
- ch->right_vol_level = (ch->envx * ch->volume_right) / 128;
- VL [J] = (ch->sample * ch-> left_vol_level) / 128;
- VR [J] = (ch->sample * ch->right_vol_level) / 128;
- }
-
- ch->count += freq;
- if (ch->count >= FIXED_POINT)
- {
- VL [J] = ch->count >> FIXED_POINT_SHIFT;
- ch->sample_pointer += VL [J];
- 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;
- uint8 *dir = S9xGetSampleAddress (ch->sample_number);
- ch->block_pointer = READ_WORD(dir + 2);
- }
- }
- 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)
- {
- if (Settings.InterpolatedSound && freq < FIXED_POINT && !mod)
- {
- ch->interpolate = ((ch->next_sample - ch->sample) *
- (long) freq) / (long) FIXED_POINT;
- ch->sample = (int16) (ch->sample + (((ch->next_sample - ch->sample) *
- (long) (ch->count)) / (long) FIXED_POINT));
- }
- else
- ch->interpolate = 0;
- }
- else
- {
- // Snes9x 1.53's SPC_DSP.cpp, by blargg
- int feedback = (noise_gen << 13) ^ (noise_gen << 14);
- noise_gen = (feedback & 0x4000) ^ (noise_gen >> 1);
- ch->sample = (noise_gen << 17) >> 17;
- ch->interpolate = 0;
- }
-
- VL [J] = (ch->sample * ch-> left_vol_level) / 128;
- VR [J] = (ch->sample * ch->right_vol_level) / 128;
- }
- else
- {
- if (ch->interpolate)
- {
- int32 s = (int32) ch->sample + ch->interpolate;
-
- CLIP16(s);
- ch->sample = (int16) s;
- VL [J] = (ch->sample * ch-> left_vol_level) / 128;
- VR [J] = (ch->sample * ch->right_vol_level) / 128;
- }
- }
-
- OutputLeft += VL [J];
- OutputRight += VR [J];
-
- if (pitch_mod & (1 << (J + 1)))
- PreviousChannelSample = ch->sample * ch->envx;
-
-#ifndef FOREVER_FORWARD_STEREO
- ch->echo_buf_ptr [I ^ Settings.ReverseStereo ] += VL [J];
- ch->echo_buf_ptr [I + (1 ^ Settings.ReverseStereo)] += VR [J];
-#else
- ch->echo_buf_ptr [I ] += VL [J];
- ch->echo_buf_ptr [I + 1] += VR [J];
-#endif
-stereo_exit:
- ;
- }
-#ifndef FOREVER_FORWARD_STEREO
- MixBuffer [I ^ Settings.ReverseStereo ] = OutputLeft;
- MixBuffer [I + (1 ^ Settings.ReverseStereo)] = OutputRight;
-#else
- MixBuffer [I ] = OutputLeft;
- MixBuffer [I + 1] = OutputRight;
-#endif
- }
-}
-
-#ifdef __DJGPP
-END_OF_FUNCTION(MixStereo_ReversedLoop);
-#endif
-
-/*
- * The layout of loops in this function is optimised for outputting a lot of
- * samples, quickly ignoring channels that are muted so that they're not
- * processed any further before the function returns.
- * For each CHANNEL, samples are mixed into the mix buffer until the channel
- * is muted or the sample count is met.
- */
static inline void MixStereo (int sample_count)
{
static int32 wave[SOUND_BUFFER_SIZE];
@@ -1829,20 +1501,13 @@ void S9xMixSamples (uint8 *buffer, int sample_count)
{
if (SoundData.echo_enable)
memset (EchoBuffer, 0, sample_count * sizeof (EchoBuffer [0]));
+ memset (MixBuffer, 0, sample_count * sizeof (MixBuffer [0]));
#ifndef FOREVER_STEREO
if (so.stereo)
- {
#endif
- if (sample_count < 12)
- MixStereo_ReversedLoop (sample_count);
- else
- {
- memset (MixBuffer, 0, sample_count * sizeof (MixBuffer [0]));
- MixStereo (sample_count);
- }
+ MixStereo (sample_count);
#ifndef FOREVER_STEREO
- }
else
MixMono (sample_count);
#endif