From 0028091d0f98f92a709dd2caa951e61ae28e5e34 Mon Sep 17 00:00:00 2001 From: Nebuleon Fumika Date: Fri, 11 Jan 2013 03:31:03 -0500 Subject: Fix the interrupts glitching sound. Put the sound back at 22050 Hz. --- source/nds/ds2sound.h | 20 +++---- source/nds/entry.cpp | 143 ++++++++++---------------------------------------- 2 files changed, 39 insertions(+), 124 deletions(-) diff --git a/source/nds/ds2sound.h b/source/nds/ds2sound.h index 4bb715b..544a670 100644 --- a/source/nds/ds2sound.h +++ b/source/nds/ds2sound.h @@ -1,15 +1,15 @@ // The sound buffer sizes used on the DS2's side, for each value of // Settings.SoundPlaybackRate. #define DS2_BUFFER_SIZE_4 512 /* tested working */ -#define DS2_BUFFER_SIZE_5 1024 /* like the SNES! tested working */ -#define DS2_BUFFER_SIZE_6 1024 /* tested working */ -#define DS2_BUFFER_SIZE_7 1024 /* tested working */ +#define DS2_BUFFER_SIZE_5 1024 /* like the SNES! tested working, but slow */ +#define DS2_BUFFER_SIZE_6 1024 /* tested working, slow because of upsampling */ +#define DS2_BUFFER_SIZE_7 1024 /* tested working, slow because of upsampling */ // In microseconds. #define INTERRUPT_TIME_4 4000 /* tested working */ -#define INTERRUPT_TIME_5 5000 /* like the SNES! underflows at 4000 */ -#define INTERRUPT_TIME_6 4000 /* tested working */ -#define INTERRUPT_TIME_7 4000 /* tested working */ +#define INTERRUPT_TIME_5 8000 /* like the SNES! tested working, but slow */ +#define INTERRUPT_TIME_6 4000 /* tested working, slow because of upsampling */ +#define INTERRUPT_TIME_7 4000 /* tested working, slow because of upsampling */ // The sampling rate for the sound, in Hz, for each value of // Settings.SoundPlaybackRate. @@ -22,7 +22,7 @@ #define SND_SAMPLE_RATE_7 48000 // Settings in use. The number should match in all three settings. -#define INTERRUPT_TIME INTERRUPT_TIME_7 -#define DS2_BUFFER_SIZE DS2_BUFFER_SIZE_7 -#define SND_SAMPLE_RATE SND_SAMPLE_RATE_7 -#define SNES9X_SRATE_ID 7 +#define INTERRUPT_TIME INTERRUPT_TIME_4 +#define DS2_BUFFER_SIZE DS2_BUFFER_SIZE_4 +#define SND_SAMPLE_RATE SND_SAMPLE_RATE_4 +#define SNES9X_SRATE_ID 4 diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp index 77716da..f157f1c 100644 --- a/source/nds/entry.cpp +++ b/source/nds/entry.cpp @@ -883,17 +883,21 @@ bool8 S9xOpenSoundDevice (int mode, bool8 stereo, int buffer_size) * glitches and/or crashes (!) from occurring while sound is not being * generated. */ -bool8 IsSoundGenerated = FALSE; +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; + int bytes_so_far = so.sixteen_bit ? (so.samples_mixed_so_far << 1) : so.samples_mixed_so_far; if (bytes_so_far >= so.buffer_size) - return; - - block_signal = TRUE; + goto end; so.err_counter += so.err_rate; if (so.err_counter >= FIXED_POINT) @@ -941,135 +945,49 @@ void S9xGenerateSound () } while (sample_count > 0); } - block_signal = FALSE; IsSoundGenerated = TRUE; +end: + if (pending_signal) { + block_signal = FALSE; + pending_signal = FALSE; // S9xProcessSound (0); NDSSFCProduceSound (0); - pending_signal = FALSE; } + else + block_signal = FALSE; } void S9xProcessSound (unsigned int) { -#if 0 - unsigned short *audiobuff; - - if (so.mute_sound || !game_enable_audio) - return; + // Nothing here! See the interrupt handling code below. +} - if(ds2_checkAudiobuff() > 4) +void NDSSFCProduceSound (unsigned int unused) +{ + if (InInterrupt) return; - /* Number of samples to generate now */ - int sample_count = so.buffer_size; - - if (so.sixteen_bit) - { - /* to prevent running out of buffer space, - * create less samples - */ - sample_count >>= 1; - } - + InInterrupt = TRUE; if (block_signal) { pending_signal = TRUE; - return; - } - -// block_generate_sound = TRUE; - - audiobuff = (unsigned short*)ds2_getAudiobuff(); - if(NULL == audiobuff) //There are audio queue in sending or wait to send - { - return; - } - - /* If we need more audio samples */ - if (so.samples_mixed_so_far < sample_count) - { - /* Where to put the samples to */ - unsigned byte_offset = so.play_position + - (so.sixteen_bit ? (so.samples_mixed_so_far << 1) : so.samples_mixed_so_far); - - //printf ("%d:", sample_count - so.samples_mixed_so_far); fflush (stdout); - if (Settings.SoundSync == 2) - { - /*memset (Buf + (byte_offset & SOUND_BUFFER_SIZE_MASK), 0, - sample_count - so.samples_mixed_so_far);*/ - } - else - { - /* Mix the missing samples */ - S9xMixSamplesO (Buf, sample_count - so.samples_mixed_so_far, - byte_offset & SOUND_BUFFER_SIZE_MASK); - } - so.samples_mixed_so_far = sample_count; + goto end; } -// if (!so.mute_sound) - { - unsigned bytes_to_write = sample_count; - if(so.sixteen_bit) bytes_to_write <<= 1; - - unsigned byte_offset = so.play_position; - so.play_position += bytes_to_write; - so.play_position &= SOUND_BUFFER_SIZE_MASK; /* wrap to beginning */ - -// block_generate_sound = FALSE; - - unsigned short *dst_pt = audiobuff; - unsigned short *dst_pt1 = dst_pt + DS2_BUFFER_SIZE; - - /* Feed the samples to the soundcard 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(dst_pt, (char *) Buf + byte_offset, I); -// dst_pt += I; - - unsigned short *src_pt= (unsigned short*)(Buf + byte_offset); - for(int m= 0; m < I/4; m++) - { - *dst_pt++= *src_pt++;//(*src_pt++) <<1; - *dst_pt1++= *src_pt++;//(*src_pt++) <<1; - } - - bytes_to_write -= I; - byte_offset += I; - byte_offset &= SOUND_BUFFER_SIZE_MASK; /* wrap */ - } - - ds2_updateAudio(); - - /* All data sent. */ - } - - so.samples_mixed_so_far -= sample_count; -#endif -} - -void NDSSFCProduceSound (unsigned int unused) -{ unsigned short *audiobuff; if (Settings.Paused || !IsSoundGenerated || so.mute_sound || !game_enable_audio) - return; + goto end; if(ds2_checkAudiobuff() > 4) - return; + goto end; /* Number of samples to generate now */ - int sample_count = so.buffer_size; + int sample_count; + sample_count = so.buffer_size; if (so.sixteen_bit) { /* to prevent running out of buffer space, @@ -1078,18 +996,12 @@ void NDSSFCProduceSound (unsigned int unused) sample_count >>= 1; } - if (block_signal) - { - pending_signal = TRUE; - return; - } - // block_generate_sound = TRUE; 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 */ @@ -1161,6 +1073,9 @@ void NDSSFCProduceSound (unsigned int unused) IsSoundGenerated = FALSE; so.samples_mixed_so_far -= sample_count; + +end: + InInterrupt = FALSE; } void Init_Timer (void) -- cgit v1.2.3