aboutsummaryrefslogtreecommitdiff
path: root/source/soundux.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/soundux.c')
-rw-r--r--source/soundux.c2845
1 files changed, 1429 insertions, 1416 deletions
diff --git a/source/soundux.c b/source/soundux.c
index e021381..4e7fe57 100644
--- a/source/soundux.c
+++ b/source/soundux.c
@@ -1,6 +1,6 @@
/*******************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
-
+
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
@@ -43,46 +43,46 @@
S-DD1 C emulator code
(c) Copyright 2003 Brad Jorsch with research by
Andreas Naive and John Weidman
-
+
S-RTC C emulator code
(c) Copyright 2001 John Weidman
-
+
ST010 C++ emulator code
(c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
- Super FX x86 assembler emulator code
- (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
- Super FX C emulator code
+ Super FX C emulator code
(c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
SH assembler code partly based on x86 assembler code
- (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
-
Specific ports contains the works of other authors. See headers in
individual files.
-
+
Snes9x homepage: http://www.snes9x.com
-
+
Permission to use, copy, modify and distribute Snes9x in both binary and
source form, for non-commercial purposes, is hereby granted without fee,
providing that this license information and copyright notice appear with
all copies and any derived work.
-
+
This software is provided 'as-is', without any express or implied
warranty. In no event shall the authors be held liable for any damages
arising from the use of this software.
-
+
Snes9x is freeware for PERSONAL USE only. Commercial users should
seek permission of the copyright holders first. Commercial use includes
charging money for Snes9x or software derived from Snes9x.
-
+
The copyright holders request that bug fixes and improvements to the code
should be forwarded to them so everyone can benefit from the modifications
in future versions.
-
+
Super NES and Super Nintendo Entertainment System are trademarks of
Nintendo Co., Limited and its subsidiary companies.
*******************************************************************************/
@@ -98,31 +98,31 @@
#include <fcntl.h>
#define CLIP16(v) \
- if ((v) < -32768) \
+ if ((v) < -32768) \
(v) = -32768; \
- else \
- if ((v) > 32767) \
+ else \
+ if ((v) > 32767) \
(v) = 32767
#define CLIP16_latch(v,l) \
- if ((v) < -32768) \
+ if ((v) < -32768) \
{ (v) = -32768; (l)++; }\
- else \
- if ((v) > 32767) \
+ else \
+ if ((v) > 32767) \
{ (v) = 32767; (l)++; }
#define CLIP24(v) \
- if ((v) < -8388608) \
+ if ((v) < -8388608) \
(v) = -8388608; \
- else \
- if ((v) > 8388607) \
+ else \
+ if ((v) > 8388607) \
(v) = 8388607
#define CLIP8(v) \
- if ((v) < -128) \
+ if ((v) < -128) \
(v) = -128; \
- else \
- if ((v) > 127) \
+ else \
+ if ((v) > 127) \
(v) = 127
#include "snes9x.h"
@@ -157,8 +157,8 @@ static int32 noise_gen;
#define VOL_DIV16 0x0080
#define ENVX_SHIFT 24
-void DecodeBlockAsm (int8 *, int16 *, int32 *, int32 *);
-void DecodeBlockAsm2 (int8 *, int16 *, int32 *, int32 *);
+void DecodeBlockAsm(int8*, int16*, int32*, int32*);
+void DecodeBlockAsm2(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.
@@ -168,1186 +168,1192 @@ void DecodeBlockAsm2 (int8 *, int16 *, int32 *, int32 *);
#define LAST_SAMPLE 0xffffff
#define JUST_PLAYED_LAST_SAMPLE(c) ((c)->sample_pointer >= LAST_SAMPLE)
-void S9xSetEightBitConsoleSound (bool8 Enabled)
+void S9xSetEightBitConsoleSound(bool8 Enabled)
{
- if (Settings.EightBitConsoleSound != Enabled)
- {
- Settings.EightBitConsoleSound = Enabled;
- int i;
- for (i = 0; i < 8; i++)
- {
- SoundData.channels[i].needs_decode = TRUE;
- }
- }
+ if (Settings.EightBitConsoleSound != Enabled)
+ {
+ Settings.EightBitConsoleSound = Enabled;
+ int i;
+ for (i = 0; i < 8; i++)
+ SoundData.channels[i].needs_decode = TRUE;
+ }
}
-STATIC inline uint8 *S9xGetSampleAddress (int sample_number)
+STATIC inline uint8* S9xGetSampleAddress(int sample_number)
{
- uint32 addr = (((APU.DSP[APU_DIR] << 8) + (sample_number << 2)) & 0xffff);
- return (IAPU.RAM + addr);
+ uint32 addr = (((APU.DSP[APU_DIR] << 8) + (sample_number << 2)) & 0xffff);
+ return (IAPU.RAM + addr);
}
-void S9xAPUSetEndOfSample (int i, Channel *ch)
+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
-void S9xAPUSetEndX (int ch)
+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 S9xSetEnvRate (Channel *ch, unsigned long rate, int direction, int target)
+void S9xSetEnvRate(Channel* ch, unsigned long rate, int direction, int target)
{
- ch->envx_target = target;
-
- if (rate == ~0UL)
- {
- ch->direction = 0;
- rate = 0;
- }
- else
- ch->direction = direction;
-
- static int64 steps [] =
- {
- // 0, 64, 1238, 1238, 256, 1, 64, 109, 64, 1238
- 0,
- (int64) FIXED_POINT * 1000 * 64,
- (int64) FIXED_POINT * 1000 * 619,
- (int64) FIXED_POINT * 1000 * 619,
- (int64) FIXED_POINT * 1000 * 128,
- (int64) FIXED_POINT * 1000 * 1,
- (int64) FIXED_POINT * 1000 * 64,
- (int64) FIXED_POINT * 1000 * 55,
- (int64) FIXED_POINT * 1000 * 64,
- (int64) FIXED_POINT * 1000 * 619
- };
-
- if (rate == 0 || so.playback_rate == 0)
- ch->erate = 0;
- else
- {
- ch->erate = (unsigned long)
- (steps [ch->state] / (rate * so.playback_rate));
- }
+ ch->envx_target = target;
+
+ if (rate == ~0UL)
+ {
+ ch->direction = 0;
+ rate = 0;
+ }
+ else
+ ch->direction = direction;
+
+ static int64 steps [] =
+ {
+ // 0, 64, 1238, 1238, 256, 1, 64, 109, 64, 1238
+ 0,
+ (int64) FIXED_POINT * 1000 * 64,
+ (int64) FIXED_POINT * 1000 * 619,
+ (int64) FIXED_POINT * 1000 * 619,
+ (int64) FIXED_POINT * 1000 * 128,
+ (int64) FIXED_POINT * 1000 * 1,
+ (int64) FIXED_POINT * 1000 * 64,
+ (int64) FIXED_POINT * 1000 * 55,
+ (int64) FIXED_POINT * 1000 * 64,
+ (int64) FIXED_POINT * 1000 * 619
+ };
+
+ if (rate == 0 || so.playback_rate == 0)
+ ch->erate = 0;
+ else
+ {
+ ch->erate = (unsigned long)
+ (steps [ch->state] / (rate * so.playback_rate));
+ }
}
#ifdef __DJGPP
END_OF_FUNCTION(S9xSetEnvRate);
#endif
-void S9xSetEnvelopeRate (int channel, unsigned long rate, int direction,
- int target)
+void S9xSetEnvelopeRate(int channel, unsigned long rate, int direction,
+ int target)
{
- S9xSetEnvRate (&SoundData.channels [channel], rate, direction, target);
+ S9xSetEnvRate(&SoundData.channels [channel], rate, direction, target);
}
#ifdef __DJGPP
END_OF_FUNCTION(S9xSetEnvelopeRate);
#endif
-void S9xSetSoundVolume (int channel, short volume_left, short volume_right)
+void S9xSetSoundVolume(int channel, short volume_left, short volume_right)
{
- Channel *ch = &SoundData.channels[channel];
- ch->volume_left = volume_left;
- ch->volume_right = volume_right;
- ch-> left_vol_level = (ch->envx * volume_left) / 128;
- ch->right_vol_level = (ch->envx * volume_right) / 128;
+ Channel* ch = &SoundData.channels[channel];
+ ch->volume_left = volume_left;
+ ch->volume_right = volume_right;
+ ch-> left_vol_level = (ch->envx * volume_left) / 128;
+ ch->right_vol_level = (ch->envx * volume_right) / 128;
}
-void S9xSetMasterVolume (short volume_left, short volume_right)
+void S9xSetMasterVolume(short volume_left, short volume_right)
{
- if (Settings.DisableMasterVolume || SNESGameFixes.EchoOnlyOutput)
- {
- SoundData.master_volume [0] = SoundData.master_volume [1] = 127;
- }
- else
- {
- SoundData.master_volume [0] = volume_left;
- SoundData.master_volume [1] = volume_right;
- }
+ if (Settings.DisableMasterVolume || SNESGameFixes.EchoOnlyOutput)
+ SoundData.master_volume [0] = SoundData.master_volume [1] = 127;
+ else
+ {
+ SoundData.master_volume [0] = volume_left;
+ SoundData.master_volume [1] = volume_right;
+ }
}
-void S9xSetEchoVolume (short volume_left, short volume_right)
+void S9xSetEchoVolume(short volume_left, short volume_right)
{
- SoundData.echo_volume [0] = volume_left;
- SoundData.echo_volume [1] = volume_right;
+ SoundData.echo_volume [0] = volume_left;
+ SoundData.echo_volume [1] = volume_right;
}
-void S9xSetEchoEnable (uint8 byte)
+void S9xSetEchoEnable(uint8 byte)
{
- SoundData.echo_channel_enable = byte;
- if (!SoundData.echo_write_enabled || Settings.DisableSoundEcho)
- byte = 0;
- if (byte && !SoundData.echo_enable)
- {
- memset (Echo, 0, sizeof (Echo));
- memset (Loop, 0, sizeof (Loop));
- }
-
- SoundData.echo_enable = byte;
- int i;
- for (i = 0; i < NUM_CHANNELS; i++)
- {
- if (byte & (1 << i))
- SoundData.channels [i].echo_buf_ptr = EchoBuffer;
- else
- SoundData.channels [i].echo_buf_ptr = DummyEchoBuffer;
- }
+ SoundData.echo_channel_enable = byte;
+ if (!SoundData.echo_write_enabled || Settings.DisableSoundEcho)
+ byte = 0;
+ if (byte && !SoundData.echo_enable)
+ {
+ memset(Echo, 0, sizeof(Echo));
+ memset(Loop, 0, sizeof(Loop));
+ }
+
+ SoundData.echo_enable = byte;
+ int i;
+ for (i = 0; i < NUM_CHANNELS; i++)
+ {
+ if (byte & (1 << i))
+ SoundData.channels [i].echo_buf_ptr = EchoBuffer;
+ else
+ SoundData.channels [i].echo_buf_ptr = DummyEchoBuffer;
+ }
}
-void S9xSetEchoFeedback (int feedback)
+void S9xSetEchoFeedback(int feedback)
{
- CLIP8(feedback);
- SoundData.echo_feedback = feedback;
+ CLIP8(feedback);
+ SoundData.echo_feedback = feedback;
}
-void S9xSetEchoDelay (int delay)
+void S9xSetEchoDelay(int delay)
{
- SoundData.echo_buffer_size = (512 * delay * so.playback_rate) / 32000;
- SoundData.echo_buffer_size <<= 1;
- if (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) / 32000;
+ SoundData.echo_buffer_size <<= 1;
+ if (SoundData.echo_buffer_size)
+ SoundData.echo_ptr %= SoundData.echo_buffer_size;
+ else
+ SoundData.echo_ptr = 0;
+ S9xSetEchoEnable(APU.DSP [APU_EON]);
}
-void S9xSetEchoWriteEnable (uint8 byte)
+void S9xSetEchoWriteEnable(uint8 byte)
{
- SoundData.echo_write_enabled = byte;
- S9xSetEchoDelay (APU.DSP [APU_EDL] & 15);
+ SoundData.echo_write_enabled = byte;
+ S9xSetEchoDelay(APU.DSP [APU_EDL] & 15);
}
-void S9xSetFrequencyModulationEnable (uint8 byte)
+void S9xSetFrequencyModulationEnable(uint8 byte)
{
- SoundData.pitch_mod = byte & ~1;
+ SoundData.pitch_mod = byte & ~1;
}
-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);
- }
+ Channel* ch = &SoundData.channels[channel];
+
+ if (ch->state != SOUND_SILENT)
+ {
+ ch->state = SOUND_RELEASE;
+ ch->mode = MODE_RELEASE;
+ S9xSetEnvRate(ch, 8, -1, 0);
+ }
}
-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].interpolate = 0;
- SoundData.channels [i].previous [0] = (int32) SoundData.channels [i].previous16 [0];
- SoundData.channels [i].previous [1] = (int32) SoundData.channels [i].previous16 [1];
- }
- 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].interpolate = 0;
+ SoundData.channels [i].previous [0] = (int32)
+ SoundData.channels [i].previous16 [0];
+ SoundData.channels [i].previous [1] = (int32)
+ SoundData.channels [i].previous16 [1];
+ }
+ IAPU.Scanline = 0;
}
-void S9xSetFilterCoefficient (int tap, int value)
+void S9xSetFilterCoefficient(int tap, int value)
{
- FilterTaps [tap & 7] = value;
- if (value == 0 || (tap == 0 && value == 127))
- FilterTapDefinitionBitfield &= ~(1 << (tap & 7));
- else
- FilterTapDefinitionBitfield |= 1 << (tap & 7);
+ FilterTaps [tap & 7] = value;
+ if (value == 0 || (tap == 0 && value == 127))
+ FilterTapDefinitionBitfield &= ~(1 << (tap & 7));
+ else
+ FilterTapDefinitionBitfield |= 1 << (tap & 7);
}
-void S9xSetSoundADSR (int channel, int attack_rate, int decay_rate,
- int sustain_rate, int sustain_level, int release_rate)
+void S9xSetSoundADSR(int channel, int attack_rate, int decay_rate,
+ int sustain_rate, int sustain_level, int release_rate)
{
- Channel *ch = &SoundData.channels[channel];
- ch->attack_rate = attack_rate;
- ch->decay_rate = decay_rate;
- ch->sustain_rate = sustain_rate;
- ch->release_rate = release_rate;
- ch->sustain_level = sustain_level + 1;
-
- switch (SoundData.channels[channel].state)
- {
- case SOUND_ATTACK:
- S9xSetEnvRate (ch, attack_rate, 1, 127);
- break;
-
- case SOUND_DECAY:
- S9xSetEnvRate (ch, decay_rate, -1,
- (MAX_ENVELOPE_HEIGHT * (sustain_level + 1)) >> 3);
- break;
- case SOUND_SUSTAIN:
- S9xSetEnvRate (ch, sustain_rate, -1, 0);
- break;
- }
+ Channel* ch = &SoundData.channels[channel];
+ ch->attack_rate = attack_rate;
+ ch->decay_rate = decay_rate;
+ ch->sustain_rate = sustain_rate;
+ ch->release_rate = release_rate;
+ ch->sustain_level = sustain_level + 1;
+
+ switch (SoundData.channels[channel].state)
+ {
+ case SOUND_ATTACK:
+ S9xSetEnvRate(ch, attack_rate, 1, 127);
+ break;
+
+ case SOUND_DECAY:
+ S9xSetEnvRate(ch, decay_rate, -1,
+ (MAX_ENVELOPE_HEIGHT * (sustain_level + 1)) >> 3);
+ break;
+ case SOUND_SUSTAIN:
+ S9xSetEnvRate(ch, sustain_rate, -1, 0);
+ break;
+ }
}
-void S9xSetEnvelopeHeight (int channel, int level)
+void S9xSetEnvelopeHeight(int channel, int level)
{
- Channel *ch = &SoundData.channels[channel];
-
- 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;
-
- if (ch->envx == 0 && ch->state != SOUND_SILENT && ch->state != SOUND_GAIN)
- {
- S9xAPUSetEndOfSample (channel, ch);
- }
+ Channel* ch = &SoundData.channels[channel];
+
+ 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;
+
+ if (ch->envx == 0 && ch->state != SOUND_SILENT && ch->state != SOUND_GAIN)
+ S9xAPUSetEndOfSample(channel, ch);
}
-int S9xGetEnvelopeHeight (int channel)
+int S9xGetEnvelopeHeight(int channel)
{
- if ((Settings.SoundEnvelopeHeightReading ||
- SNESGameFixes.SoundEnvelopeHeightReading2) &&
- SoundData.channels[channel].state != SOUND_SILENT &&
- SoundData.channels[channel].state != SOUND_GAIN)
- {
- return (SoundData.channels[channel].envx);
- }
-
- //siren fix from XPP
- if (SNESGameFixes.SoundEnvelopeHeightReading2 &&
- SoundData.channels[channel].state != SOUND_SILENT)
- {
- return (SoundData.channels[channel].envx);
- }
-
- return (0);
+ if ((Settings.SoundEnvelopeHeightReading ||
+ SNESGameFixes.SoundEnvelopeHeightReading2) &&
+ SoundData.channels[channel].state != SOUND_SILENT &&
+ SoundData.channels[channel].state != SOUND_GAIN)
+ return (SoundData.channels[channel].envx);
+
+ //siren fix from XPP
+ if (SNESGameFixes.SoundEnvelopeHeightReading2 &&
+ SoundData.channels[channel].state != SOUND_SILENT)
+ return (SoundData.channels[channel].envx);
+
+ return (0);
}
#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;
- uint8 *dir = S9xGetSampleAddress (sample_number);
- ch->block_pointer = READ_WORD (dir);
- 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;
+ uint8* dir = S9xGetSampleAddress(sample_number);
+ ch->block_pointer = READ_WORD(dir);
+ ch->sample_pointer = 0;
+ ch->state = keep;
+ }
}
#endif
-void S9xSetSoundFrequency (int channel, int hertz)
+void S9xSetSoundFrequency(int channel, int hertz)
{
- if (so.playback_rate)
- {
- if (SoundData.channels[channel].type == SOUND_NOISE)
- hertz = NoiseFreq [APU.DSP [APU_FLG] & 0x1f];
- SoundData.channels[channel].frequency = (int)
- (((int64) hertz * FIXED_POINT) / so.playback_rate);
- if (Settings.FixFrequency)
- {
- SoundData.channels[channel].frequency =
- (unsigned long) (SoundData.channels[channel].frequency * 49 / 50);
- }
- }
+ if (so.playback_rate)
+ {
+ if (SoundData.channels[channel].type == SOUND_NOISE)
+ hertz = NoiseFreq [APU.DSP [APU_FLG] & 0x1f];
+ SoundData.channels[channel].frequency = (int)
+ (((int64) hertz * FIXED_POINT) / so.playback_rate);
+ if (Settings.FixFrequency)
+ {
+ SoundData.channels[channel].frequency =
+ (unsigned long)(SoundData.channels[channel].frequency * 49 / 50);
+ }
+ }
}
-void S9xSetSoundHertz (int channel, int hertz)
+void S9xSetSoundHertz(int channel, int hertz)
{
- SoundData.channels[channel].hertz = hertz;
- S9xSetSoundFrequency (channel, hertz);
+ SoundData.channels[channel].hertz = hertz;
+ S9xSetSoundFrequency(channel, hertz);
}
-void S9xSetSoundType (int channel, int type_of_sound)
+void S9xSetSoundType(int channel, int type_of_sound)
{
- SoundData.channels[channel].type = type_of_sound;
+ SoundData.channels[channel].type = type_of_sound;
}
-bool8 S9xSetSoundMute (bool8 mute)
+bool8 S9xSetSoundMute(bool8 mute)
{
- bool8 old = so.mute_sound;
- so.mute_sound = mute;
- return (old);
+ bool8 old = so.mute_sound;
+ so.mute_sound = mute;
+ return (old);
}
-void AltDecodeBlock (Channel *ch)
+void AltDecodeBlock(Channel* ch)
{
- if (ch->block_pointer >= 0x10000 - 9)
- {
- ch->last_block = TRUE;
- ch->loop = FALSE;
- ch->block = ch->decoded;
- memset ((void *) ch->decoded, 0, sizeof (int16) * 16);
- 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;
-
+ if (ch->block_pointer >= 0x10000 - 9)
+ {
+ ch->last_block = TRUE;
+ ch->loop = FALSE;
+ ch->block = ch->decoded;
+ memset((void*) ch->decoded, 0, sizeof(int16) * 16);
+ 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;
+
#if (defined (USE_X86_ASM) && (defined (__i386__) || defined (__i486__) ||\
defined (__i586__) || defined (__WIN32__) || defined (__DJGPP)))
- int16 *raw = ch->block = ch->decoded;
-
- if (Settings.AltSampleDecode == 1)
- DecodeBlockAsm (compressed, raw, &ch->previous [0], &ch->previous [1]);
- else
- DecodeBlockAsm2 (compressed, raw, &ch->previous [0], &ch->previous [1]);
+ int16* raw = ch->block = ch->decoded;
+
+ if (Settings.AltSampleDecode == 1)
+ DecodeBlockAsm(compressed, raw, &ch->previous [0], &ch->previous [1]);
+ else
+ DecodeBlockAsm2(compressed, raw, &ch->previous [0], &ch->previous [1]);
#else
- int32 out;
- unsigned char shift;
- signed char sample1, sample2;
- unsigned int i;
-
- compressed++;
- signed short *raw = ch->block = ch->decoded;
-
- 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++;
+ signed short* raw = ch->block = ch->decoded;
+
+ 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;
}
-void AltDecodeBlock2 (Channel *ch)
+void AltDecodeBlock2(Channel* ch)
{
- int32 out;
- unsigned char filter;
- unsigned char shift;
- signed char sample1, sample2;
- unsigned char i;
-
- if (ch->block_pointer > 0x10000 - 9)
- {
- ch->last_block = TRUE;
- ch->loop = FALSE;
- ch->block = ch->decoded;
- memset ((void *) ch->decoded, 0, sizeof (int16) * 16);
- return;
- }
-
- signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer];
-
- filter = *compressed;
- if ((ch->last_block = filter & 1))
- ch->loop = (filter & 2) != 0;
-
- compressed++;
- signed short *raw = ch->block = ch->decoded;
-
- shift = filter >> 4;
- int32 prev0 = ch->previous [0];
- int32 prev1 = ch->previous [1];
-
- if(shift > 12)
- shift -= 4;
-
- switch ((filter >> 2) & 3)
- {
- case 0:
- for (i = 8; i != 0; i--)
- {
- sample1 = *compressed++;
- sample2 = sample1 << 4;
- //Sample 2 = Bottom Nibble, Sign Extended.
- sample2 >>= 4;
- //Sample 1 = Top Nibble, shifted down and Sign Extended.
- sample1 >>= 4;
-
- out = (int32)(sample1 << shift);
-
- prev1 = prev0;
- prev0 = out;
- CLIP16(out);
- *raw++ = (int16)out;
-
- out = (int32)(sample2 << shift);
-
- prev1 = prev0;
- prev0 = out;
- CLIP16(out);
- *raw++ = (int16)out;
- }
- break;
- case 1:
- for (i = 8; i != 0; i--)
- {
- sample1 = *compressed++;
- sample2 = sample1 << 4;
- //Sample 2 = Bottom Nibble, Sign Extended.
- sample2 >>= 4;
- //Sample 1 = Top Nibble, shifted down and Sign Extended.
- sample1 >>= 4;
- out = (int32)(sample1 << shift);
- out += (int32)((double)prev0 * 15/16);
-
- prev1 = prev0;
- prev0 = out;
- CLIP16(out);
- *raw++ = (int16)out;
-
- out = (int32)(sample2 << shift);
- out += (int32)((double)prev0 * 15/16);
-
- prev1 = prev0;
- prev0 = out;
- CLIP16(out);
- *raw++ = (int16)out;
- }
- break;
- case 2:
- for (i = 8; i != 0; i--)
- {
- sample1 = *compressed++;
- sample2 = sample1 << 4;
- //Sample 2 = Bottom Nibble, Sign Extended.
- sample2 >>= 4;
- //Sample 1 = Top Nibble, shifted down and Sign Extended.
- sample1 >>= 4;
-
- out = ((sample1 << shift) * 256 + (prev0 & ~0x2) * 488 - prev1 * 240) >> 8;
-
- prev1 = prev0;
- prev0 = (int16)out;
- *raw++ = (int16)out;
-
- out = ((sample2 << shift) * 256 + (prev0 & ~0x2) * 488 - prev1 * 240) >> 8;
-
- prev1 = prev0;
- prev0 = (int16)out;
- *raw++ = (int16)out;
- }
- break;
-
- case 3:
- for (i = 8; i != 0; i--)
- {
- sample1 = *compressed++;
- sample2 = sample1 << 4;
- //Sample 2 = Bottom Nibble, Sign Extended.
- sample2 >>= 4;
- //Sample 1 = Top Nibble, shifted down and Sign Extended.
- sample1 >>= 4;
- out = (int32)(sample1 << shift);
- out += (int32)((double)prev0 * 115/64 - (double)prev1 * 13/16);
-
- prev1 = prev0;
- prev0 = out;
-
- CLIP16(out);
- *raw++ = (int16)out;
-
- out = (int32)(sample2 << shift);
- out += (int32)((double)prev0 * 115/64 - (double)prev1 * 13/16);
-
- prev1 = prev0;
- prev0 = out;
-
- CLIP16(out);
- *raw++ = (int16)out;
- }
- break;
- }
- ch->previous [0] = prev0;
- ch->previous [1] = prev1;
- ch->block_pointer += 9;
+ int32 out;
+ unsigned char filter;
+ unsigned char shift;
+ signed char sample1, sample2;
+ unsigned char i;
+
+ if (ch->block_pointer > 0x10000 - 9)
+ {
+ ch->last_block = TRUE;
+ ch->loop = FALSE;
+ ch->block = ch->decoded;
+ memset((void*) ch->decoded, 0, sizeof(int16) * 16);
+ return;
+ }
+
+ signed char* compressed = (signed char*) &IAPU.RAM [ch->block_pointer];
+
+ filter = *compressed;
+ if ((ch->last_block = filter & 1))
+ ch->loop = (filter & 2) != 0;
+
+ compressed++;
+ signed short* raw = ch->block = ch->decoded;
+
+ shift = filter >> 4;
+ int32 prev0 = ch->previous [0];
+ int32 prev1 = ch->previous [1];
+
+ if (shift > 12)
+ shift -= 4;
+
+ switch ((filter >> 2) & 3)
+ {
+ case 0:
+ for (i = 8; i != 0; i--)
+ {
+ sample1 = *compressed++;
+ sample2 = sample1 << 4;
+ //Sample 2 = Bottom Nibble, Sign Extended.
+ sample2 >>= 4;
+ //Sample 1 = Top Nibble, shifted down and Sign Extended.
+ sample1 >>= 4;
+
+ out = (int32)(sample1 << shift);
+
+ prev1 = prev0;
+ prev0 = out;
+ CLIP16(out);
+ *raw++ = (int16)out;
+
+ out = (int32)(sample2 << shift);
+
+ prev1 = prev0;
+ prev0 = out;
+ CLIP16(out);
+ *raw++ = (int16)out;
+ }
+ break;
+ case 1:
+ for (i = 8; i != 0; i--)
+ {
+ sample1 = *compressed++;
+ sample2 = sample1 << 4;
+ //Sample 2 = Bottom Nibble, Sign Extended.
+ sample2 >>= 4;
+ //Sample 1 = Top Nibble, shifted down and Sign Extended.
+ sample1 >>= 4;
+ out = (int32)(sample1 << shift);
+ out += (int32)((double)prev0 * 15 / 16);
+
+ prev1 = prev0;
+ prev0 = out;
+ CLIP16(out);
+ *raw++ = (int16)out;
+
+ out = (int32)(sample2 << shift);
+ out += (int32)((double)prev0 * 15 / 16);
+
+ prev1 = prev0;
+ prev0 = out;
+ CLIP16(out);
+ *raw++ = (int16)out;
+ }
+ break;
+ case 2:
+ for (i = 8; i != 0; i--)
+ {
+ sample1 = *compressed++;
+ sample2 = sample1 << 4;
+ //Sample 2 = Bottom Nibble, Sign Extended.
+ sample2 >>= 4;
+ //Sample 1 = Top Nibble, shifted down and Sign Extended.
+ sample1 >>= 4;
+
+ out = ((sample1 << shift) * 256 + (prev0 & ~0x2) * 488 - prev1 * 240) >> 8;
+
+ prev1 = prev0;
+ prev0 = (int16)out;
+ *raw++ = (int16)out;
+
+ out = ((sample2 << shift) * 256 + (prev0 & ~0x2) * 488 - prev1 * 240) >> 8;
+
+ prev1 = prev0;
+ prev0 = (int16)out;
+ *raw++ = (int16)out;
+ }
+ break;
+
+ case 3:
+ for (i = 8; i != 0; i--)
+ {
+ sample1 = *compressed++;
+ sample2 = sample1 << 4;
+ //Sample 2 = Bottom Nibble, Sign Extended.
+ sample2 >>= 4;
+ //Sample 1 = Top Nibble, shifted down and Sign Extended.
+ sample1 >>= 4;
+ out = (int32)(sample1 << shift);
+ out += (int32)((double)prev0 * 115 / 64 - (double)prev1 * 13 / 16);
+
+ prev1 = prev0;
+ prev0 = out;
+
+ CLIP16(out);
+ *raw++ = (int16)out;
+
+ out = (int32)(sample2 << shift);
+ out += (int32)((double)prev0 * 115 / 64 - (double)prev1 * 13 / 16);
+
+ prev1 = prev0;
+ prev0 = out;
+
+ CLIP16(out);
+ *raw++ = (int16)out;
+ }
+ break;
+ }
+ ch->previous [0] = prev0;
+ ch->previous [1] = prev1;
+ ch->block_pointer += 9;
}
-void DecodeBlock (Channel *ch)
+void DecodeBlock(Channel* ch)
{
- int32 out;
- unsigned char filter;
- unsigned char shift;
- signed char sample1, sample2;
- unsigned char i;
- bool invalid_header;
-
- if (Settings.AltSampleDecode)
- {
- if (Settings.AltSampleDecode < 3)
- AltDecodeBlock (ch);
- else
- AltDecodeBlock2 (ch);
- return;
- }
- if (ch->block_pointer > 0x10000 - 9)
- {
- ch->last_block = TRUE;
- ch->loop = FALSE;
- ch->block = ch->decoded;
- return;
- }
-
- if (Settings.EightBitConsoleSound)
- {
- signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer];
-
- filter = *compressed;
- if ((ch->last_block = filter & 1))
- ch->loop = (filter & 2) != 0;
-
- int16 interim[16];
- uint8 interim_byte = 0;
-
- compressed++;
- signed short *raw = ch->block = ch->decoded;
-
- // Seperate out the header parts used for decoding
-
- shift = filter >> 4;
-
- // Header validity check: if range(shift) is over 12, ignore
- // all bits of the data for that block except for the sign bit of each
- invalid_header = (shift >= 0xD);
-
- filter = filter&0x0c;
-
- int32 prev0 = ch->previous [0];
- int32 prev1 = ch->previous [1];
-
- int16 amplitude = 0;
-
- for (i = 8; i != 0; i--)
- {
- sample1 = *compressed++;
- sample2 = sample1 << 4;
- //Sample 2 = Bottom Nibble, Sign Extended.
- sample2 >>= 4;
- //Sample 1 = Top Nibble, shifted down and Sign Extended.
- sample1 >>= 4;
- if (invalid_header) { sample1>>=3; sample2>>=3; }
-
- int nybblesmp;
- for (nybblesmp = 0; nybblesmp<2; nybblesmp++){
- out=(((nybblesmp) ? sample2 : sample1) << shift);
- out >>= 1;
-
- switch(filter)
- {
- case 0x00:
- // Method0 - [Smp]
- break;
-
- case 0x04:
- // Method1 - [Delta]+[Smp-1](15/16)
- out+=(prev0>>1)+((-prev0)>>5);
- break;
-
- case 0x08:
- // Method2 - [Delta]+[Smp-1](61/32)-[Smp-2](15/16)
- out+=(prev0)+((-(prev0 +(prev0>>1)))>>5)-(prev1>>1)+(prev1>>5);
- break;
-
- default:
- // Method3 - [Delta]+[Smp-1](115/64)-[Smp-2](13/16)
- out+=(prev0)+((-(prev0 + (prev0<<2) + (prev0<<3)))>>7)-(prev1>>1)+((prev1+(prev1>>1))>>4);
- break;
-
- }
- CLIP16(out);
- int16 result = (signed short)(out<<1);
- if (abs(result) > amplitude)
- amplitude = abs(result);
- interim[interim_byte++] = out;
- prev1=(signed short)prev0;
- prev0=(signed short)(out<<1);
- }
- }
- ch->previous [0] = prev0;
- ch->previous [1] = prev1;
-
- int32 total_deviation_from_previous = 0;
- for (i = 1; i < 16; i++)
- total_deviation_from_previous += abs(interim[i] - interim[i - 1]);
- if (total_deviation_from_previous >= (int32) amplitude * 4)
- {
- /* Looks like noise. Generate noise. */
- for (i = 0; i < 16; i++)
- {
- int feedback = (noise_gen << 13) ^ (noise_gen << 14);
- noise_gen = (feedback & 0x4000) ^ (noise_gen >> 1);
- ch->decoded[i] = (noise_gen << 17) >> 17;
- }
- }
- else if (interim[0] < interim[1] && interim[1] < interim[2]
- && interim[2] < interim[3]
- && interim[4] > interim[5] && interim[5] > interim[6]
- && interim[6] > interim[7] && interim[7] > interim[8]
- && interim[8] > interim[9] && interim[9] > interim[10]
- && interim[10] > interim[11]
- && interim[12] < interim[13] && interim[13] < interim[14]
- && interim[14] < interim[15])
- {
- /* Looks like a sine or triangle wave. Make it a
- * triangle wave with an amplitude equivalent to that
- * of the highest amplitude sample of the block. */
- ch->decoded[0] = ch->decoded[8] = 0;
- ch->decoded[1] = ch->decoded[7] = amplitude / 4;
- ch->decoded[2] = ch->decoded[6] = amplitude / 2;
- ch->decoded[3] = ch->decoded[5] = amplitude * 3 / 4;
- ch->decoded[4] = amplitude;
- ch->decoded[9] = ch->decoded[15] = -(amplitude / 4);
- ch->decoded[10] = ch->decoded[14] = -(amplitude / 2);
- ch->decoded[11] = ch->decoded[13] = -(amplitude * 3 / 4);
- ch->decoded[12] = -amplitude;
- }
- else if (interim[0] > interim[1] && interim[1] > interim[2]
- && interim[2] > interim[3]
- && interim[4] < interim[5] && interim[5] < interim[6]
- && interim[6] < interim[7] && interim[7] < interim[8]
- && interim[8] < interim[9] && interim[9] < interim[10]
- && interim[10] < interim[11]
- && interim[12] > interim[13] && interim[13] > interim[14]
- && interim[14] > interim[15])
- {
- /* Inverted triangle wave. */
- ch->decoded[0] = ch->decoded[8] = 0;
- ch->decoded[1] = ch->decoded[7] = -(amplitude / 4);
- ch->decoded[2] = ch->decoded[6] = -(amplitude / 2);
- ch->decoded[3] = ch->decoded[5] = -(amplitude * 3 / 4);
- ch->decoded[4] = -amplitude;
- ch->decoded[9] = ch->decoded[15] = amplitude / 4;
- ch->decoded[10] = ch->decoded[14] = amplitude / 2;
- ch->decoded[11] = ch->decoded[13] = amplitude * 3 / 4;
- ch->decoded[12] = amplitude;
- }
- else if (interim[0] < interim[1] && interim[1] < interim[2]
- && interim[2] < interim[3] && interim[3] < interim[4]
- && interim[4] < interim[5] && interim[5] < interim[6]
- && interim[6] < interim[7]
- && interim[8] > interim[9] && interim[9] > interim[10]
- && interim[10] > interim[11] && interim[11] > interim[12]
- && interim[12] > interim[13] && interim[13] > interim[14]
- && interim[14] > interim[15])
- {
- /* Looks like a V wave. Make it a half-triangle wave
- * with an amplitude equivalent to that
- * of the highest amplitude sample of the block. */
- ch->decoded[0] = 0;
- ch->decoded[1] = ch->decoded[15] = amplitude / 8;
- ch->decoded[2] = ch->decoded[14] = amplitude / 4;
- ch->decoded[3] = ch->decoded[13] = amplitude * 3 / 8;
- ch->decoded[4] = ch->decoded[12] = amplitude / 2;
- ch->decoded[5] = ch->decoded[11] = amplitude * 5 / 8;
- ch->decoded[6] = ch->decoded[10] = amplitude * 3 / 4;
- ch->decoded[7] = ch->decoded[9] = amplitude * 7 / 8;
- ch->decoded[8] = amplitude;
- }
- else if (interim[0] > interim[1] && interim[1] > interim[2]
- && interim[2] > interim[3] && interim[3] > interim[4]
- && interim[4] > interim[5] && interim[5] > interim[6]
- && interim[6] > interim[7]
- && interim[8] < interim[9] && interim[9] < interim[10]
- && interim[10] < interim[11] && interim[11] < interim[12]
- && interim[12] < interim[13] && interim[13] < interim[14]
- && interim[14] < interim[15])
- {
- /* Inverted V wave. */
- ch->decoded[0] = 0;
- ch->decoded[1] = ch->decoded[15] = -(amplitude / 8);
- ch->decoded[2] = ch->decoded[14] = -(amplitude / 4);
- ch->decoded[3] = ch->decoded[13] = -(amplitude * 3 / 8);
- ch->decoded[4] = ch->decoded[12] = -(amplitude / 2);
- ch->decoded[5] = ch->decoded[11] = -(amplitude * 5 / 8);
- ch->decoded[6] = ch->decoded[10] = -(amplitude * 3 / 4);
- ch->decoded[7] = ch->decoded[9] = -(amplitude * 7 / 8);
- ch->decoded[8] = -amplitude;
- }
- else
- {
- // Make it a square wave with an amplitude equivalent to that
- // of the highest amplitude sample of the block.
- // But actually put half of the amplitude, because
- // square waves are just loud.
- for (i = 0; i < 8; i++)
- ch->decoded[i] = amplitude / 2;
- for (i = 8; i < 16; i++)
- ch->decoded[i] = -(amplitude / 2);
- }
- }
- else
- {
- signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer];
-
- filter = *compressed;
- if ((ch->last_block = filter & 1))
- ch->loop = (filter & 2) != 0;
-
- compressed++;
- signed short *raw = ch->block = ch->decoded;
-
- // Seperate out the header parts used for decoding
-
- shift = filter >> 4;
-
- // Header validity check: if range(shift) is over 12, ignore
- // all bits of the data for that block except for the sign bit of each
- invalid_header = (shift >= 0xD);
-
- filter = filter&0x0c;
-
- int32 prev0 = ch->previous [0];
- int32 prev1 = ch->previous [1];
-
- for (i = 8; i != 0; i--)
- {
- sample1 = *compressed++;
- sample2 = sample1 << 4;
- //Sample 2 = Bottom Nibble, Sign Extended.
- sample2 >>= 4;
- //Sample 1 = Top Nibble, shifted down and Sign Extended.
- sample1 >>= 4;
- if (invalid_header) { sample1>>=3; sample2>>=3; }
-
+ int32 out;
+ unsigned char filter;
+ unsigned char shift;
+ signed char sample1, sample2;
+ unsigned char i;
+ bool invalid_header;
+
+ if (Settings.AltSampleDecode)
+ {
+ if (Settings.AltSampleDecode < 3)
+ AltDecodeBlock(ch);
+ else
+ AltDecodeBlock2(ch);
+ return;
+ }
+ if (ch->block_pointer > 0x10000 - 9)
+ {
+ ch->last_block = TRUE;
+ ch->loop = FALSE;
+ ch->block = ch->decoded;
+ return;
+ }
+
+ if (Settings.EightBitConsoleSound)
+ {
+ signed char* compressed = (signed char*) &IAPU.RAM [ch->block_pointer];
+
+ filter = *compressed;
+ if ((ch->last_block = filter & 1))
+ ch->loop = (filter & 2) != 0;
+
+ int16 interim[16];
+ uint8 interim_byte = 0;
+
+ compressed++;
+ signed short* raw = ch->block = ch->decoded;
+
+ // Seperate out the header parts used for decoding
+
+ shift = filter >> 4;
+
+ // Header validity check: if range(shift) is over 12, ignore
+ // all bits of the data for that block except for the sign bit of each
+ invalid_header = (shift >= 0xD);
+
+ filter = filter & 0x0c;
+
+ int32 prev0 = ch->previous [0];
+ int32 prev1 = ch->previous [1];
+
+ int16 amplitude = 0;
+
+ for (i = 8; i != 0; i--)
+ {
+ sample1 = *compressed++;
+ sample2 = sample1 << 4;
+ //Sample 2 = Bottom Nibble, Sign Extended.
+ sample2 >>= 4;
+ //Sample 1 = Top Nibble, shifted down and Sign Extended.
+ sample1 >>= 4;
+ if (invalid_header)
+ {
+ sample1 >>= 3;
+ sample2 >>= 3;
+ }
+
+ int nybblesmp;
+ for (nybblesmp = 0; nybblesmp < 2; nybblesmp++)
+ {
+ out = (((nybblesmp) ? sample2 : sample1) << shift);
+ out >>= 1;
+
+ switch (filter)
+ {
+ case 0x00:
+ // Method0 - [Smp]
+ break;
+
+ case 0x04:
+ // Method1 - [Delta]+[Smp-1](15/16)
+ out += (prev0 >> 1) + ((-prev0) >> 5);
+ break;
+
+ case 0x08:
+ // Method2 - [Delta]+[Smp-1](61/32)-[Smp-2](15/16)
+ out += (prev0) + ((-(prev0 + (prev0 >> 1))) >> 5) - (prev1 >> 1) + (prev1 >> 5);
+ break;
+
+ default:
+ // Method3 - [Delta]+[Smp-1](115/64)-[Smp-2](13/16)
+ out += (prev0) + ((-(prev0 + (prev0 << 2) + (prev0 << 3))) >> 7) -
+ (prev1 >> 1) + ((prev1 + (prev1 >> 1)) >> 4);
+ break;
+
+ }
+ CLIP16(out);
+ int16 result = (signed short)(out << 1);
+ if (abs(result) > amplitude)
+ amplitude = abs(result);
+ interim[interim_byte++] = out;
+ prev1 = (signed short)prev0;
+ prev0 = (signed short)(out << 1);
+ }
+ }
+ ch->previous [0] = prev0;
+ ch->previous [1] = prev1;
+
+ int32 total_deviation_from_previous = 0;
+ for (i = 1; i < 16; i++)
+ total_deviation_from_previous += abs(interim[i] - interim[i - 1]);
+ if (total_deviation_from_previous >= (int32) amplitude * 4)
+ {
+ /* Looks like noise. Generate noise. */
+ for (i = 0; i < 16; i++)
+ {
+ int feedback = (noise_gen << 13) ^ (noise_gen << 14);
+ noise_gen = (feedback & 0x4000) ^ (noise_gen >> 1);
+ ch->decoded[i] = (noise_gen << 17) >> 17;
+ }
+ }
+ else if (interim[0] < interim[1] && interim[1] < interim[2]
+ && interim[2] < interim[3]
+ && interim[4] > interim[5] && interim[5] > interim[6]
+ && interim[6] > interim[7] && interim[7] > interim[8]
+ && interim[8] > interim[9] && interim[9] > interim[10]
+ && interim[10] > interim[11]
+ && interim[12] < interim[13] && interim[13] < interim[14]
+ && interim[14] < interim[15])
+ {
+ /* Looks like a sine or triangle wave. Make it a
+ * triangle wave with an amplitude equivalent to that
+ * of the highest amplitude sample of the block. */
+ ch->decoded[0] = ch->decoded[8] = 0;
+ ch->decoded[1] = ch->decoded[7] = amplitude / 4;
+ ch->decoded[2] = ch->decoded[6] = amplitude / 2;
+ ch->decoded[3] = ch->decoded[5] = amplitude * 3 / 4;
+ ch->decoded[4] = amplitude;
+ ch->decoded[9] = ch->decoded[15] = -(amplitude / 4);
+ ch->decoded[10] = ch->decoded[14] = -(amplitude / 2);
+ ch->decoded[11] = ch->decoded[13] = -(amplitude * 3 / 4);
+ ch->decoded[12] = -amplitude;
+ }
+ else if (interim[0] > interim[1] && interim[1] > interim[2]
+ && interim[2] > interim[3]
+ && interim[4] < interim[5] && interim[5] < interim[6]
+ && interim[6] < interim[7] && interim[7] < interim[8]
+ && interim[8] < interim[9] && interim[9] < interim[10]
+ && interim[10] < interim[11]
+ && interim[12] > interim[13] && interim[13] > interim[14]
+ && interim[14] > interim[15])
+ {
+ /* Inverted triangle wave. */
+ ch->decoded[0] = ch->decoded[8] = 0;
+ ch->decoded[1] = ch->decoded[7] = -(amplitude / 4);
+ ch->decoded[2] = ch->decoded[6] = -(amplitude / 2);
+ ch->decoded[3] = ch->decoded[5] = -(amplitude * 3 / 4);
+ ch->decoded[4] = -amplitude;
+ ch->decoded[9] = ch->decoded[15] = amplitude / 4;
+ ch->decoded[10] = ch->decoded[14] = amplitude / 2;
+ ch->decoded[11] = ch->decoded[13] = amplitude * 3 / 4;
+ ch->decoded[12] = amplitude;
+ }
+ else if (interim[0] < interim[1] && interim[1] < interim[2]
+ && interim[2] < interim[3] && interim[3] < interim[4]
+ && interim[4] < interim[5] && interim[5] < interim[6]
+ && interim[6] < interim[7]
+ && interim[8] > interim[9] && interim[9] > interim[10]
+ && interim[10] > interim[11] && interim[11] > interim[12]
+ && interim[12] > interim[13] && interim[13] > interim[14]
+ && interim[14] > interim[15])
+ {
+ /* Looks like a V wave. Make it a half-triangle wave
+ * with an amplitude equivalent to that
+ * of the highest amplitude sample of the block. */
+ ch->decoded[0] = 0;
+ ch->decoded[1] = ch->decoded[15] = amplitude / 8;
+ ch->decoded[2] = ch->decoded[14] = amplitude / 4;
+ ch->decoded[3] = ch->decoded[13] = amplitude * 3 / 8;
+ ch->decoded[4] = ch->decoded[12] = amplitude / 2;
+ ch->decoded[5] = ch->decoded[11] = amplitude * 5 / 8;
+ ch->decoded[6] = ch->decoded[10] = amplitude * 3 / 4;
+ ch->decoded[7] = ch->decoded[9] = amplitude * 7 / 8;
+ ch->decoded[8] = amplitude;
+ }
+ else if (interim[0] > interim[1] && interim[1] > interim[2]
+ && interim[2] > interim[3] && interim[3] > interim[4]
+ && interim[4] > interim[5] && interim[5] > interim[6]
+ && interim[6] > interim[7]
+ && interim[8] < interim[9] && interim[9] < interim[10]
+ && interim[10] < interim[11] && interim[11] < interim[12]
+ && interim[12] < interim[13] && interim[13] < interim[14]
+ && interim[14] < interim[15])
+ {
+ /* Inverted V wave. */
+ ch->decoded[0] = 0;
+ ch->decoded[1] = ch->decoded[15] = -(amplitude / 8);
+ ch->decoded[2] = ch->decoded[14] = -(amplitude / 4);
+ ch->decoded[3] = ch->decoded[13] = -(amplitude * 3 / 8);
+ ch->decoded[4] = ch->decoded[12] = -(amplitude / 2);
+ ch->decoded[5] = ch->decoded[11] = -(amplitude * 5 / 8);
+ ch->decoded[6] = ch->decoded[10] = -(amplitude * 3 / 4);
+ ch->decoded[7] = ch->decoded[9] = -(amplitude * 7 / 8);
+ ch->decoded[8] = -amplitude;
+ }
+ else
+ {
+ // Make it a square wave with an amplitude equivalent to that
+ // of the highest amplitude sample of the block.
+ // But actually put half of the amplitude, because
+ // square waves are just loud.
+ for (i = 0; i < 8; i++)
+ ch->decoded[i] = amplitude / 2;
+ for (i = 8; i < 16; i++)
+ ch->decoded[i] = -(amplitude / 2);
+ }
+ }
+ else
+ {
+ signed char* compressed = (signed char*) &IAPU.RAM [ch->block_pointer];
+
+ filter = *compressed;
+ if ((ch->last_block = filter & 1))
+ ch->loop = (filter & 2) != 0;
+
+ compressed++;
+ signed short* raw = ch->block = ch->decoded;
+
+ // Seperate out the header parts used for decoding
+
+ shift = filter >> 4;
+
+ // Header validity check: if range(shift) is over 12, ignore
+ // all bits of the data for that block except for the sign bit of each
+ invalid_header = (shift >= 0xD);
+
+ filter = filter & 0x0c;
+
+ int32 prev0 = ch->previous [0];
+ int32 prev1 = ch->previous [1];
+
+ for (i = 8; i != 0; i--)
+ {
+ sample1 = *compressed++;
+ sample2 = sample1 << 4;
+ //Sample 2 = Bottom Nibble, Sign Extended.
+ sample2 >>= 4;
+ //Sample 1 = Top Nibble, shifted down and Sign Extended.
+ sample1 >>= 4;
+ if (invalid_header)
+ {
+ sample1 >>= 3;
+ sample2 >>= 3;
+ }
+
int nybblesmp;
- for (nybblesmp = 0; nybblesmp<2; nybblesmp++){
- out=(((nybblesmp) ? sample2 : sample1) << shift);
- out >>= 1;
-
- switch(filter)
- {
- case 0x00:
- // Method0 - [Smp]
- break;
-
- case 0x04:
- // Method1 - [Delta]+[Smp-1](15/16)
- out+=(prev0>>1)+((-prev0)>>5);
- break;
-
- case 0x08:
- // Method2 - [Delta]+[Smp-1](61/32)-[Smp-2](15/16)
- out+=(prev0)+((-(prev0 +(prev0>>1)))>>5)-(prev1>>1)+(prev1>>5);
- break;
-
- default:
- // Method3 - [Delta]+[Smp-1](115/64)-[Smp-2](13/16)
- out+=(prev0)+((-(prev0 + (prev0<<2) + (prev0<<3)))>>7)-(prev1>>1)+((prev1+(prev1>>1))>>4);
- break;
-
- }
- CLIP16(out);
- *raw++ = (signed short)(out<<1);
- prev1=(signed short)prev0;
- prev0=(signed short)(out<<1);
- }
- }
- ch->previous [0] = prev0;
- ch->previous [1] = prev1;
- }
- ch->block_pointer += 9;
+ for (nybblesmp = 0; nybblesmp < 2; nybblesmp++)
+ {
+ out = (((nybblesmp) ? sample2 : sample1) << shift);
+ out >>= 1;
+
+ switch (filter)
+ {
+ case 0x00:
+ // Method0 - [Smp]
+ break;
+
+ case 0x04:
+ // Method1 - [Delta]+[Smp-1](15/16)
+ out += (prev0 >> 1) + ((-prev0) >> 5);
+ break;
+
+ case 0x08:
+ // Method2 - [Delta]+[Smp-1](61/32)-[Smp-2](15/16)
+ out += (prev0) + ((-(prev0 + (prev0 >> 1))) >> 5) - (prev1 >> 1) + (prev1 >> 5);
+ break;
+
+ default:
+ // Method3 - [Delta]+[Smp-1](115/64)-[Smp-2](13/16)
+ out += (prev0) + ((-(prev0 + (prev0 << 2) + (prev0 << 3))) >> 7) -
+ (prev1 >> 1) + ((prev1 + (prev1 >> 1)) >> 4);
+ break;
+
+ }
+ CLIP16(out);
+ *raw++ = (signed short)(out << 1);
+ prev1 = (signed short)prev0;
+ prev0 = (signed short)(out << 1);
+ }
+ }
+ ch->previous [0] = prev0;
+ ch->previous [1] = prev1;
+ }
+ ch->block_pointer += 9;
}
-static inline void MixStereo (int sample_count)
+static inline void MixStereo(int sample_count)
{
- static int32 wave[SOUND_BUFFER_SIZE];
+ static int32 wave[SOUND_BUFFER_SIZE];
- int pitch_mod = SoundData.pitch_mod & ~APU.DSP[APU_NON];
+ int pitch_mod = SoundData.pitch_mod & ~APU.DSP[APU_NON];
uint32 J;
for (J = 0; J < NUM_CHANNELS; J++)
- {
- Channel *ch = &SoundData.channels[J];
+ {
+ Channel* ch = &SoundData.channels[J];
- if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J)))
- continue;
+ if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J)))
+ continue;
- int32 VL, VR;
- unsigned long freq0 = ch->frequency;
+ int32 VL, VR;
+ 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;
+ // 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);
+ 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;
+ 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;
+ 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 = (ch->sample * ch-> left_vol_level) / 128;
- VR = (ch->sample * ch->right_vol_level) / 128;
+ if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod)
+ ch->interpolate = ((ch->next_sample - ch->sample) *
+ (long) freq0) / (long) FIXED_POINT;
+ }
+ 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);
- 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 = (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;
- 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 = (ch->sample * ch-> left_vol_level) / 128;
- VR = (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 = (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;
- ch->echo_buf_ptr [I ] += VL;
- ch->echo_buf_ptr [I + 1] += VR;
- }
-stereo_exit: ;
- }
+ {
+ 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);
+ 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 = (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;
+ 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 = (ch->sample * ch-> left_vol_level) / 128;
+ VR = (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 = (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;
+ ch->echo_buf_ptr [I ] += VL;
+ ch->echo_buf_ptr [I + 1] += VR;
+ }
+stereo_exit:
+ ;
+ }
}
#ifdef __DJGPP
@@ -1355,368 +1361,375 @@ END_OF_FUNCTION(MixStereo);
#endif
#ifdef __sun
-extern uint8 int2ulaw (int);
+extern uint8 int2ulaw(int);
#endif
// For backwards compatibility with older port specific code
-void S9xMixSamplesO (uint8 *buffer, int sample_count, int byte_offset)
+void S9xMixSamplesO(uint8* buffer, int sample_count, int byte_offset)
{
- S9xMixSamples (buffer+byte_offset, sample_count);
+ S9xMixSamples(buffer + byte_offset, sample_count);
}
#ifdef __DJGPP
END_OF_FUNCTION(S9xMixSamplesO);
#endif
-void S9xMixSamples (uint8 *buffer, int sample_count)
+void S9xMixSamples(uint8* buffer, int sample_count)
{
- int J;
- int I;
-
- if (!so.mute_sound)
- {
- if (SoundData.echo_enable)
- memset (EchoBuffer, 0, sample_count * sizeof (EchoBuffer [0]));
- memset (MixBuffer, 0, sample_count * sizeof (MixBuffer [0]));
- MixStereo (sample_count);
- }
-
- /* Mix and convert waveforms */
- int byte_count = sample_count << 1;
-
- // 16-bit sound
- if (so.mute_sound)
- {
- memset (buffer, 0, byte_count);
- }
- else
- {
- if (SoundData.echo_enable && SoundData.echo_buffer_size)
- {
- // 16-bit stereo sound with echo enabled ...
- if (FilterTapDefinitionBitfield == 0)
- {
- // ... but 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 += 1) >= SoundData.echo_buffer_size)
- SoundData.echo_ptr = 0;
-
- I = (MixBuffer [J] *
- SoundData.master_volume [J & 1] +
- E * SoundData.echo_volume [J & 1]) / VOL_DIV16;
-
- CLIP16(I);
- ((signed short *) buffer)[J] = I;
- }
- }
- else
- {
- // ... with filter defined.
- for (J = 0; J < sample_count; J++)
- {
- int E = Echo [SoundData.echo_ptr];
-
- Loop [(Z - 0) & 15] = E;
- E = E * FilterTaps [0];
- if (FilterTapDefinitionBitfield & 0x02) E += Loop [(Z - 2) & 15] * FilterTaps [1];
- if (FilterTapDefinitionBitfield & 0x04) E += Loop [(Z - 4) & 15] * FilterTaps [2];
- if (FilterTapDefinitionBitfield & 0x08) E += Loop [(Z - 6) & 15] * FilterTaps [3];
- if (FilterTapDefinitionBitfield & 0x10) E += Loop [(Z - 8) & 15] * FilterTaps [4];
- if (FilterTapDefinitionBitfield & 0x20) E += Loop [(Z - 10) & 15] * FilterTaps [5];
- if (FilterTapDefinitionBitfield & 0x40) E += Loop [(Z - 12) & 15] * FilterTaps [6];
- if (FilterTapDefinitionBitfield & 0x80) E += Loop [(Z - 14) & 15] * FilterTaps [7];
- E /= 128;
- Z++;
-
- Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
- EchoBuffer [J];
-
- if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
- SoundData.echo_ptr = 0;
-
- I = (MixBuffer [J] *
- SoundData.master_volume [J & 1] +
- E * SoundData.echo_volume [J & 1]) / VOL_DIV16;
-
- CLIP16(I);
- ((signed short *) buffer)[J] = I;
- }
- }
- }
- else
- {
- // 16-bit mono or stereo sound, no echo
- for (J = 0; J < sample_count; J++)
- {
- I = (MixBuffer [J] *
- SoundData.master_volume [J & 1]) / VOL_DIV16;
-
- CLIP16(I);
- ((signed short *) buffer)[J] = I;
- }
- }
- }
+ int J;
+ int I;
+
+ if (!so.mute_sound)
+ {
+ if (SoundData.echo_enable)
+ memset(EchoBuffer, 0, sample_count * sizeof(EchoBuffer [0]));
+ memset(MixBuffer, 0, sample_count * sizeof(MixBuffer [0]));
+ MixStereo(sample_count);
+ }
+
+ /* Mix and convert waveforms */
+ int byte_count = sample_count << 1;
+
+ // 16-bit sound
+ if (so.mute_sound)
+ memset(buffer, 0, byte_count);
+ else
+ {
+ if (SoundData.echo_enable && SoundData.echo_buffer_size)
+ {
+ // 16-bit stereo sound with echo enabled ...
+ if (FilterTapDefinitionBitfield == 0)
+ {
+ // ... but 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 += 1) >= SoundData.echo_buffer_size)
+ SoundData.echo_ptr = 0;
+
+ I = (MixBuffer [J] *
+ SoundData.master_volume [J & 1] +
+ E * SoundData.echo_volume [J & 1]) / VOL_DIV16;
+
+ CLIP16(I);
+ ((signed short*) buffer)[J] = I;
+ }
+ }
+ else
+ {
+ // ... with filter defined.
+ for (J = 0; J < sample_count; J++)
+ {
+ int E = Echo [SoundData.echo_ptr];
+
+ Loop [(Z - 0) & 15] = E;
+ E = E * FilterTaps [0];
+ if (FilterTapDefinitionBitfield & 0x02) E += Loop [(Z - 2) & 15] *
+ FilterTaps [1];
+ if (FilterTapDefinitionBitfield & 0x04) E += Loop [(Z - 4) & 15] *
+ FilterTaps [2];
+ if (FilterTapDefinitionBitfield & 0x08) E += Loop [(Z - 6) & 15] *
+ FilterTaps [3];
+ if (FilterTapDefinitionBitfield & 0x10) E += Loop [(Z - 8) & 15] *
+ FilterTaps [4];
+ if (FilterTapDefinitionBitfield & 0x20) E += Loop [(Z - 10) & 15] *
+ FilterTaps [5];
+ if (FilterTapDefinitionBitfield & 0x40) E += Loop [(Z - 12) & 15] *
+ FilterTaps [6];
+ if (FilterTapDefinitionBitfield & 0x80) E += Loop [(Z - 14) & 15] *
+ FilterTaps [7];
+ E /= 128;
+ Z++;
+
+ Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
+ EchoBuffer [J];
+
+ if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
+ SoundData.echo_ptr = 0;
+
+ I = (MixBuffer [J] *
+ SoundData.master_volume [J & 1] +
+ E * SoundData.echo_volume [J & 1]) / VOL_DIV16;
+
+ CLIP16(I);
+ ((signed short*) buffer)[J] = I;
+ }
+ }
+ }
+ else
+ {
+ // 16-bit mono or stereo sound, no echo
+ for (J = 0; J < sample_count; J++)
+ {
+ I = (MixBuffer [J] *
+ SoundData.master_volume [J & 1]) / VOL_DIV16;
+
+ CLIP16(I);
+ ((signed short*) buffer)[J] = I;
+ }
+ }
+ }
}
#ifdef __DJGPP
END_OF_FUNCTION(S9xMixSamples);
#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;
- 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;
- FilterTapDefinitionBitfield = 0;
- so.mute_sound = TRUE;
- noise_gen = 1;
- so.sound_switch = 255;
- so.samples_mixed_so_far = 0;
- so.play_position = 0;
- so.err_counter = 0;
-
- if (full)
- {
- 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 [0] = SoundData.master_volume [1] = 127;
- if (so.playback_rate)
- so.err_rate = (uint32) (FIXED_POINT * SNES_SCANLINE_TIME / (1.0 / so.playback_rate));
- else
- so.err_rate = 0;
+ 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;
+ 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;
+ FilterTapDefinitionBitfield = 0;
+ so.mute_sound = TRUE;
+ noise_gen = 1;
+ so.sound_switch = 255;
+ so.samples_mixed_so_far = 0;
+ so.play_position = 0;
+ so.err_counter = 0;
+
+ if (full)
+ {
+ 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 [0] = SoundData.master_volume [1] = 127;
+ if (so.playback_rate)
+ so.err_rate = (uint32)(FIXED_POINT * SNES_SCANLINE_TIME /
+ (1.0 / so.playback_rate));
+ else
+ so.err_rate = 0;
}
-void S9xSetPlaybackRate (uint32 playback_rate)
+void S9xSetPlaybackRate(uint32 playback_rate)
{
- so.playback_rate = playback_rate;
- so.err_rate = (uint32) (SNES_SCANLINE_TIME * FIXED_POINT / (1.0 / (double) so.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;
+ so.err_rate = (uint32)(SNES_SCANLINE_TIME * FIXED_POINT / (1.0 /
+ (double) so.playback_rate));
+ S9xSetEchoDelay(APU.DSP [APU_EDL] & 0xf);
+ int i;
+ for (i = 0; i < 8; i++)
+ S9xSetSoundFrequency(i, SoundData.channels [i].hertz);
}
-bool8 S9xInitSound (int mode, bool8 stereo, int buffer_size)
+bool8 S9xInitSound(int mode, bool8 stereo, int buffer_size)
{
- so.sound_fd = -1;
- so.sound_switch = 255;
-
- so.playback_rate = 0;
- so.buffer_size = 0;
- so.encoded = FALSE;
-
- S9xResetSound (TRUE);
-
- if (!(mode & 7))
- return (1);
-
- S9xSetSoundMute (TRUE);
- if (!S9xOpenSoundDevice (mode, stereo, buffer_size))
- {
- S9xMessage (S9X_ERROR, S9X_SOUND_DEVICE_OPEN_FAILED,
- "Sound device open failed");
- return (0);
- }
-
- return (1);
+ so.sound_fd = -1;
+ so.sound_switch = 255;
+
+ so.playback_rate = 0;
+ so.buffer_size = 0;
+ so.encoded = FALSE;
+
+ S9xResetSound(TRUE);
+
+ if (!(mode & 7))
+ return (1);
+
+ S9xSetSoundMute(TRUE);
+ if (!S9xOpenSoundDevice(mode, stereo, buffer_size))
+ {
+ S9xMessage(S9X_ERROR, S9X_SOUND_DEVICE_OPEN_FAILED,
+ "Sound device open failed");
+ return (0);
+ }
+
+ return (1);
}
-bool8 S9xSetSoundMode (int channel, int mode)
+bool8 S9xSetSoundMode(int channel, int mode)
{
- Channel *ch = &SoundData.channels[channel];
-
- switch (mode)
- {
- case MODE_RELEASE:
- if (ch->mode != MODE_NONE)
- {
- ch->mode = MODE_RELEASE;
- return (TRUE);
- }
- break;
-
- case MODE_DECREASE_LINEAR:
- case MODE_DECREASE_EXPONENTIAL:
- case MODE_GAIN:
- if (ch->mode != MODE_RELEASE)
- {
- ch->mode = mode;
- if (ch->state != SOUND_SILENT)
- ch->state = mode;
-
- return (TRUE);
- }
- break;
-
- case MODE_INCREASE_LINEAR:
- case MODE_INCREASE_BENT_LINE:
- if (ch->mode != MODE_RELEASE)
- {
- ch->mode = mode;
- if (ch->state != SOUND_SILENT)
- ch->state = mode;
-
- return (TRUE);
- }
- break;
-
- case MODE_ADSR:
- if (ch->mode == MODE_NONE || ch->mode == MODE_ADSR)
- {
- ch->mode = mode;
- return (TRUE);
- }
- }
-
- return (FALSE);
+ Channel* ch = &SoundData.channels[channel];
+
+ switch (mode)
+ {
+ case MODE_RELEASE:
+ if (ch->mode != MODE_NONE)
+ {
+ ch->mode = MODE_RELEASE;
+ return (TRUE);
+ }
+ break;
+
+ case MODE_DECREASE_LINEAR:
+ case MODE_DECREASE_EXPONENTIAL:
+ case MODE_GAIN:
+ if (ch->mode != MODE_RELEASE)
+ {
+ ch->mode = mode;
+ if (ch->state != SOUND_SILENT)
+ ch->state = mode;
+
+ return (TRUE);
+ }
+ break;
+
+ case MODE_INCREASE_LINEAR:
+ case MODE_INCREASE_BENT_LINE:
+ if (ch->mode != MODE_RELEASE)
+ {
+ ch->mode = mode;
+ if (ch->state != SOUND_SILENT)
+ ch->state = mode;
+
+ return (TRUE);
+ }
+ break;
+
+ case MODE_ADSR:
+ if (ch->mode == MODE_NONE || ch->mode == MODE_ADSR)
+ {
+ ch->mode = mode;
+ return (TRUE);
+ }
+ }
+
+ return (FALSE);
}
-void S9xSetSoundControl (int sound_switch)
+void S9xSetSoundControl(int sound_switch)
{
- so.sound_switch = sound_switch;
+ so.sound_switch = sound_switch;
}
-void S9xPlaySample (int channel)
+void S9xPlaySample(int channel)
{
- Channel *ch = &SoundData.channels[channel];
-
- ch->state = SOUND_SILENT;
- ch->mode = MODE_NONE;
- ch->envx = 0;
- ch->envxx = 0;
-
- S9xFixEnvelope (channel,
- APU.DSP [APU_GAIN + (channel << 4)],
- APU.DSP [APU_ADSR1 + (channel << 4)],
- APU.DSP [APU_ADSR2 + (channel << 4)]);
-
- ch->sample_number = APU.DSP [APU_SRCN + channel * 0x10];
- if (APU.DSP [APU_NON] & (1 << channel))
- ch->type = SOUND_NOISE;
- else
- ch->type = SOUND_SAMPLE;
-
- S9xSetSoundFrequency (channel, ch->hertz);
- ch->loop = FALSE;
- ch->needs_decode = TRUE;
- ch->last_block = FALSE;
- ch->previous [0] = ch->previous[1] = 0;
- uint8 *dir = S9xGetSampleAddress (ch->sample_number);
- ch->block_pointer = READ_WORD (dir);
- ch->sample_pointer = 0;
- ch->env_error = 0;
- ch->next_sample = 0;
- ch->interpolate = 0;
- switch (ch->mode)
- {
- case MODE_ADSR:
- if (ch->attack_rate == 0)
- {
- if (ch->decay_rate == 0 || ch->sustain_level == 8)
- {
- ch->state = SOUND_SUSTAIN;
- ch->envx = (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3;
- S9xSetEnvRate (ch, ch->sustain_rate, -1, 0);
- }
- else
- {
- ch->state = SOUND_DECAY;
- ch->envx = MAX_ENVELOPE_HEIGHT;
- S9xSetEnvRate (ch, ch->decay_rate, -1,
- (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3);
- }
- ch-> left_vol_level = (ch->envx * ch->volume_left) / 128;
- ch->right_vol_level = (ch->envx * ch->volume_right) / 128;
- }
- else
- {
- ch->state = SOUND_ATTACK;
- ch->envx = 0;
- ch->left_vol_level = 0;
- ch->right_vol_level = 0;
- S9xSetEnvRate (ch, ch->attack_rate, 1, MAX_ENVELOPE_HEIGHT);
- }
- ch->envxx = ch->envx << ENVX_SHIFT;
- break;
-
- case MODE_GAIN:
- ch->state = SOUND_GAIN;
- break;
-
- case MODE_INCREASE_LINEAR:
- ch->state = SOUND_INCREASE_LINEAR;
- break;
-
- case MODE_INCREASE_BENT_LINE:
- ch->state = SOUND_INCREASE_BENT_LINE;
- break;
-
- case MODE_DECREASE_LINEAR:
- ch->state = SOUND_DECREASE_LINEAR;
- break;
-
- case MODE_DECREASE_EXPONENTIAL:
- ch->state = SOUND_DECREASE_EXPONENTIAL;
- break;
-
- default:
- break;
- }
-
- S9xFixEnvelope (channel,
- APU.DSP [APU_GAIN + (channel << 4)],
- APU.DSP [APU_ADSR1 + (channel << 4)],
- APU.DSP [APU_ADSR2 + (channel << 4)]);
+ Channel* ch = &SoundData.channels[channel];
+
+ ch->state = SOUND_SILENT;
+ ch->mode = MODE_NONE;
+ ch->envx = 0;
+ ch->envxx = 0;
+
+ S9xFixEnvelope(channel,
+ APU.DSP [APU_GAIN + (channel << 4)],
+ APU.DSP [APU_ADSR1 + (channel << 4)],
+ APU.DSP [APU_ADSR2 + (channel << 4)]);
+
+ ch->sample_number = APU.DSP [APU_SRCN + channel * 0x10];
+ if (APU.DSP [APU_NON] & (1 << channel))
+ ch->type = SOUND_NOISE;
+ else
+ ch->type = SOUND_SAMPLE;
+
+ S9xSetSoundFrequency(channel, ch->hertz);
+ ch->loop = FALSE;
+ ch->needs_decode = TRUE;
+ ch->last_block = FALSE;
+ ch->previous [0] = ch->previous[1] = 0;
+ uint8* dir = S9xGetSampleAddress(ch->sample_number);
+ ch->block_pointer = READ_WORD(dir);
+ ch->sample_pointer = 0;
+ ch->env_error = 0;
+ ch->next_sample = 0;
+ ch->interpolate = 0;
+ switch (ch->mode)
+ {
+ case MODE_ADSR:
+ if (ch->attack_rate == 0)
+ {
+ if (ch->decay_rate == 0 || ch->sustain_level == 8)
+ {
+ ch->state = SOUND_SUSTAIN;
+ ch->envx = (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3;
+ S9xSetEnvRate(ch, ch->sustain_rate, -1, 0);
+ }
+ else
+ {
+ ch->state = SOUND_DECAY;
+ ch->envx = MAX_ENVELOPE_HEIGHT;
+ S9xSetEnvRate(ch, ch->decay_rate, -1,
+ (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3);
+ }
+ ch-> left_vol_level = (ch->envx * ch->volume_left) / 128;
+ ch->right_vol_level = (ch->envx * ch->volume_right) / 128;
+ }
+ else
+ {
+ ch->state = SOUND_ATTACK;
+ ch->envx = 0;
+ ch->left_vol_level = 0;
+ ch->right_vol_level = 0;
+ S9xSetEnvRate(ch, ch->attack_rate, 1, MAX_ENVELOPE_HEIGHT);
+ }
+ ch->envxx = ch->envx << ENVX_SHIFT;
+ break;
+
+ case MODE_GAIN:
+ ch->state = SOUND_GAIN;
+ break;
+
+ case MODE_INCREASE_LINEAR:
+ ch->state = SOUND_INCREASE_LINEAR;
+ break;
+
+ case MODE_INCREASE_BENT_LINE:
+ ch->state = SOUND_INCREASE_BENT_LINE;
+ break;
+
+ case MODE_DECREASE_LINEAR:
+ ch->state = SOUND_DECREASE_LINEAR;
+ break;
+
+ case MODE_DECREASE_EXPONENTIAL:
+ ch->state = SOUND_DECREASE_EXPONENTIAL;
+ break;
+
+ default:
+ break;
+ }
+
+ S9xFixEnvelope(channel,
+ APU.DSP [APU_GAIN + (channel << 4)],
+ APU.DSP [APU_ADSR1 + (channel << 4)],
+ APU.DSP [APU_ADSR2 + (channel << 4)]);
}