aboutsummaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/nds/entry.cpp49
-rw-r--r--source/nds/gui.c3
2 files changed, 46 insertions, 6 deletions
diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp
index a389ebc..f470a43 100644
--- a/source/nds/entry.cpp
+++ b/source/nds/entry.cpp
@@ -23,6 +23,7 @@
#include "ds2sound.h"
void S9xProcessSound (unsigned int);
+void NDSSFCProduceSound (unsigned int);
char *rom_filename = NULL;
char *SDD1_pack = NULL;
@@ -544,6 +545,13 @@ int sfc_main (int argc, char **argv)
TRUE,
#endif
Settings.SoundBufferSize);
+ // Start a timer for the sound
+ initTimer(0 /* timer channel, 0 or 1 */,
+ INTERRUPT_TIME /* period in microseconds */,
+ NDSSFCProduceSound /* timer function, void (unsigned int) */,
+ 0 /* programmer-specified argument to ^ */);
+ runTimer(0 /* timer channel, 0 or 1 */);
+
#ifdef GFX_MULTI_FORMAT
// S9xSetRenderPixelFormat (RGB565);
S9xSetRenderPixelFormat (BGR555);
@@ -885,6 +893,18 @@ bool8 S9xOpenSoundDevice (int mode, bool8 stereo, int buffer_size)
return (TRUE);
}
+/*
+ * In the interrupt model, calls to NDSSFCProduceSound could happen even
+ * when the CPU or APU is being reset or reloaded from a file. Prevent
+ * glitches and/or crashes (!) from occurring while sound is not being
+ * generated.
+ */
+static volatile bool8 IsSoundGenerated = FALSE;
+/*
+ * Also prevent an interrupt from triggering on top of another one.
+ */
+static volatile bool8 InInterrupt = FALSE;
+
void S9xGenerateSound ()
{
block_signal = TRUE;
@@ -951,13 +971,16 @@ void S9xGenerateSound ()
} while (samples_to_write > 0);
}
+ IsSoundGenerated = TRUE;
+
end:
if (pending_signal)
{
block_signal = FALSE;
pending_signal = FALSE;
- S9xProcessSound (0);
+ // S9xProcessSound (0);
+ NDSSFCProduceSound (0);
}
else
block_signal = FALSE;
@@ -965,19 +988,28 @@ end:
void S9xProcessSound (unsigned int)
{
+ // Nothing here! See the interrupt handling code below.
+}
+
+void NDSSFCProduceSound (unsigned int unused)
+{
+ if (InInterrupt)
+ return;
+
+ InInterrupt = TRUE;
if (block_signal)
{
pending_signal = TRUE;
- return;
+ goto end;
}
unsigned short *audiobuff;
- if (Settings.Paused || so.mute_sound || !game_enable_audio)
- return;
+ if (Settings.Paused || !IsSoundGenerated || so.mute_sound || !game_enable_audio)
+ goto end;
if(ds2_checkAudiobuff() > 4)
- return;
+ goto end;
/* Number of samples to generate now */
int sample_count;
@@ -997,7 +1029,7 @@ void S9xProcessSound (unsigned int)
audiobuff = (unsigned short*)ds2_getAudiobuff();
if(NULL == audiobuff) //There are audio queue in sending or wait to send
{
- return;
+ goto end;
}
/* If we need more audio samples */
@@ -1112,7 +1144,12 @@ void S9xProcessSound (unsigned int)
/* All data sent. */
}
+ IsSoundGenerated = FALSE;
+
so.samples_mixed_so_far -= sample_count;
+
+end:
+ InInterrupt = FALSE;
}
void Init_Timer (void)
diff --git a/source/nds/gui.c b/source/nds/gui.c
index c3d5043..baa6f6b 100644
--- a/source/nds/gui.c
+++ b/source/nds/gui.c
@@ -1654,6 +1654,7 @@ unsigned int frame_interval;
--------------------------------------------------------*/
u32 menu(u16 *screen)
{
+ stopTimer(0 /* timer interrupt channel for sound */);
gui_action_type gui_action;
u32 i;
u32 repeat;
@@ -3867,6 +3868,8 @@ u32 menu(u16 *screen)
set_cpu_clock(clock_speed_number);
+ runTimer(0 /* timer interrupt channel for sound */);
+
return return_value;
}