Hi,
here is a deterministic sound proposal for all architectures:
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/cpuexec.cpp snes9x-1.43-dev-src/snes9x/cpuexec.cpp
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/cpuexec.cpp 2005-01-22 02:19:03.000000000 +0100
+++ snes9x-1.43-dev-src/snes9x/cpuexec.cpp 2005-01-23 03:25:15.000000000 +0100
@@ -95,6 +95,7 @@
#include "debug.h"
#include "snapshot.h"
#include "gfx.h"
+#include "soundux.h"
#include "missing.h"
#include "apu.h"
#include "dma.h"
@@ -301,6 +302,8 @@
{
// Start of V-blank
S9xEndScreenRefresh ();
+ if (Settings.SoundDeterministic)
+ S9xMixSamplesPrepare ();
IPPU.HDMA = 0;
// Bits 7 and 6 of $4212 are computed when read in S9xGetPPU.
missing.dma_this_frame = 0;
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/i386/cpuexec.S snes9x-1.43-dev-src/snes9x/i386/cpuexec.S
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/i386/cpuexec.S 2005-01-21 14:55:18.000000000 +0100
+++ snes9x-1.43-dev-src/snes9x/i386/cpuexec.S 2005-01-23 03:19:25.000000000 +0100
@@ -391,6 +391,10 @@
cmpl %eax,%edx
jne .L165
ccall S9xEndScreenRefresh
+ testb $0xff, SoundDeterministic
+ jz .nosounddet
+ ccall S9xMixSamplesPrepare
+.nosounddet:
movb Brightness,%al
xorl %ecx,%ecx
movb %al,MaxBrightness
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/i386/offsets.h snes9x-1.43-dev-src/snes9x/i386/offsets.h
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/i386/offsets.h 2005-01-22 02:13:34.000000000 +0100
+++ snes9x-1.43-dev-src/snes9x/i386/offsets.h 2005-01-23 03:55:07.000000000 +0100
@@ -108,6 +108,7 @@
#define Paused Settings + 17
#define PAL Settings + 29
#define SoundSync Settings + 108
+#define SoundDeterministic Settings + 109
#define SA1Enabled Settings + 82
#define SuperFXEnabled Settings + 80
#define ApuP APURegisters + 0
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/offsets.cpp snes9x-1.43-dev-src/snes9x/offsets.cpp
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/offsets.cpp 2004-07-11 23:50:59.000000000 +0200
+++ snes9x-1.43-dev-src/snes9x/offsets.cpp 2005-01-23 03:55:06.000000000 +0100
@@ -243,6 +243,7 @@
OFFSET7(Paused,Paused)
OFFSET7(PAL,PAL)
OFFSET7(SoundSync,SoundSync)
+ OFFSET7(SoundDeterministic,SoundDeterministic)
OFFSET7(SA1Enabled,SA1)
OFFSET7(SuperFXEnabled,SuperFX)
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/snes9x.cpp snes9x-1.43-dev-src/snes9x/snes9x.cpp
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/snes9x.cpp 2005-01-21 17:01:42.000000000 +0100
+++ snes9x-1.43-dev-src/snes9x/snes9x.cpp 2005-01-22 02:32:50.000000000 +0100
@@ -254,6 +254,12 @@
{
Settings.NextAPUEnabled = FALSE;
}
+ else if (strcasecmp (argv [i], "-ds") == 0 ||
+ strcasecmp (argv [i], "-detsound") == 0)
+ {
+ Settings.SoundDeterministic = TRUE;
+ }
+
else if (strcasecmp (argv [i], "-soundskip") == 0 ||
strcasecmp (argv [i], "-sk") == 0)
{
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/snes9x.h snes9x-1.43-dev-src/snes9x/snes9x.h
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/snes9x.h 2005-01-22 02:20:10.000000000 +0100
+++ snes9x-1.43-dev-src/snes9x/snes9x.h 2005-01-22 02:13:32.000000000 +0100
@@ -330,6 +330,7 @@
bool8 DisableSampleCaching;
bool8 DisableMasterVolume;
bool8 SoundSync;
+ bool8 SoundDeterministic;
bool8 InterpolatedSound;
bool8 ThreadSound;
bool8 Mute;
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/soundux.cpp snes9x-1.43-dev-src/snes9x/soundux.cpp
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/soundux.cpp 2005-01-22 01:48:29.000000000 +0100
+++ snes9x-1.43-dev-src/snes9x/soundux.cpp 2005-01-23 14:57:59.000000000 +0100
@@ -1442,6 +1442,102 @@
extern uint8 int2ulaw (int);
#endif
+
+uint8 SoundBuffer[SOUND_BUFFER_SIZE];
+int32 play_position=0;
+int32 samples_mixed_so_far=0;
+int32 turbo_on=0;
+
+void S9xMixSamplesPrepare ()
+{
+ static int carry=0;
+ if (!Settings.SoundDeterministic)
+ return;
+
+ // Go back to "sync with soundcard" after turbo mode
+ if (!Settings.TurboMode && turbo_on)
+ {
+ play_position=0;
+ samples_mixed_so_far=0;
+ turbo_on=0;
+ }
+
+ if (Settings.TurboMode)
+ turbo_on=1;
+ /* Where to put the samples to */
+ unsigned byte_offset = play_position +
+ (so.sixteen_bit ? (samples_mixed_so_far << 1)
+ : samples_mixed_so_far);
+ byte_offset &= SOUND_BUFFER_SIZE_MASK; /* wrap */
+
+ /* Number of samples to generate now */
+ carry += so.playback_rate * Settings.FrameTime;
+ int sample_count = carry / 1000000, sample16=1;
+ carry -= sample_count * 1000000;
+ if(so.stereo) sample_count *= 2;
+
+ if (so.sixteen_bit)
+ sample16=2;
+
+ /* Mix the samples */
+ samples_mixed_so_far += sample_count;
+ for(;;)
+ {
+
+ int I = sample_count;
+ if (byte_offset + I*sample16 > SOUND_BUFFER_SIZE)
+ {
+ I = (SOUND_BUFFER_SIZE - byte_offset) / sample16;
+ }
+ if(I == 0) break;
+
+ S9xMixSamplesR (SoundBuffer+byte_offset, I);
+
+ sample_count-= I;
+ byte_offset += I*sample16;
+ byte_offset &= SOUND_BUFFER_SIZE_MASK; /* wrap */
+ }
+}
+
+void S9xMixSamples (uint8 *buffer, int sample_count)
+{
+ if (samples_mixed_so_far<sample_count)
+ return;
+
+ if (!Settings.SoundDeterministic)
+ {
+ S9xMixSamplesR (buffer, sample_count);
+ return;
+ }
+ unsigned bytes_to_write = sample_count;
+ if(so.sixteen_bit) bytes_to_write <<= 1;
+
+ unsigned byte_offset = play_position, byte_offset_w=0;
+ play_position += bytes_to_write;
+ play_position &= SOUND_BUFFER_SIZE_MASK; /* wrap to beginning */
+
+ /* Copy the samples to the buffer until nothing is left */
+ for(;;)
+ {
+
+ int I = bytes_to_write;
+ if (byte_offset + I > SOUND_BUFFER_SIZE)
+ {
+ I = SOUND_BUFFER_SIZE - byte_offset;
+ }
+ if(I == 0) break;
+
+ memcpy ((char *) buffer + byte_offset_w, (char *) SoundBuffer + byte_offset, I);
+
+ bytes_to_write -= I;
+ byte_offset_w += I;
+ byte_offset += I;
+ byte_offset &= SOUND_BUFFER_SIZE_MASK; /* wrap */
+ }
+ /* All data copied. */
+ samples_mixed_so_far -= sample_count;
+}
+
// For backwards compatibility with older port specific code
void S9xMixSamplesO (uint8 *buffer, int sample_count, int byte_offset)
{
@@ -1451,7 +1547,7 @@
END_OF_FUNCTION(S9xMixSamplesO);
#endif
-void S9xMixSamples (uint8 *buffer, int sample_count)
+void S9xMixSamplesR (uint8 *buffer, int sample_count)
{
int J;
int I;
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/soundux.h snes9x-1.43-dev-src/snes9x/soundux.h
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/soundux.h 2004-07-11 23:51:00.000000000 +0200
+++ snes9x-1.43-dev-src/snes9x/soundux.h 2005-01-23 03:36:37.000000000 +0100
@@ -239,7 +239,9 @@
void S9xFixEnvelope (int channel, uint8 gain, uint8 adsr1, uint8 adsr2);
void S9xStartSample (int channel);
+EXTERN_C void S9xMixSamplesPrepare (void);
EXTERN_C void S9xMixSamples (uint8 *buffer, int sample_count);
+EXTERN_C void S9xMixSamplesR (uint8 *buffer, int sample_count);
EXTERN_C void S9xMixSamplesO (uint8 *buffer, int sample_count, int byte_offset);
bool8 S9xOpenSoundDevice (int, bool8, int);
void S9xSetPlaybackRate (uint32 rate);
Tell me what you think of it.
cu
Fabian
PS: And yes this was mostly copied from the unix ringbuffer-version.
PPS: Revision 3