aboutsummaryrefslogtreecommitdiff
path: root/source/soundux.cpp
diff options
context:
space:
mode:
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