diff --git a/apu/apu.cpp b/apu/apu.cpp
index dd67838a..4c54f2b8 100644
--- a/apu/apu.cpp
+++ b/apu/apu.cpp
@@ -14,12 +14,12 @@
#include "bapu/snes/snes.hpp"
-static const int APU_DEFAULT_INPUT_RATE = 31920; // ~59.94Hz
+static const int APU_DEFAULT_INPUT_RATE = 31950; // ~59.94Hz
static const int APU_SAMPLE_BLOCK = 48;
-static const int APU_NUMERATOR_NTSC = 5632;
-static const int APU_DENOMINATOR_NTSC = 118125;
-static const int APU_NUMERATOR_PAL = 35527;
-static const int APU_DENOMINATOR_PAL = 738343;
+static const int APU_NUMERATOR_NTSC = 15664;
+static const int APU_DENOMINATOR_NTSC = 328125;
+static const int APU_NUMERATOR_PAL = 34176;
+static const int APU_DENOMINATOR_PAL = 709379;
// Max number of samples we'll ever generate before call to port API and
// moving the samples to the resampler.
@@ -184,7 +184,7 @@ static void UpdatePlaybackRate(void)
if (Settings.MSU1)
{
- time_ratio = (44100.0 / Settings.SoundPlaybackRate) * (Settings.SoundInputRate / 32000.0);
+ time_ratio = (44100.0 / Settings.SoundPlaybackRate) * (Settings.SoundInputRate / 32040.0);
msu::resampler->time_ratio(time_ratio);
}
}
diff --git a/docs/porting.html b/docs/porting.html
index db4537e7..cde540dd 100644
--- a/docs/porting.html
+++ b/docs/porting.html
@@ -347,7 +347,7 @@
Settings.MultiPlayer5Master = true;
Settings.FrameTimePAL = 20000;
Settings.FrameTimeNTSC = 16667;
- Settings.SoundPlaybackRate = 32000;
+ Settings.SoundPlaybackRate = 32040;
Settings.SoundInputRate = 31947;
Settings.SupportHiRes = true;
Settings.Transparency = true;
@@ -361,10 +361,10 @@
Adjusts the sound rate through resampling. For every Settings.SoundInputRate
samples generated by the SNES, Settings.SoundPlaybackRate
samples will be produced.
- On a NTSC SNES, the video refresh rate is usually 60.09881Hz, while the audio output is 32000Hz. This means for every video frame displayed, 532.4565 sound frames are produced. A modern computer display or television will usually provide one of two video rates, 60.00Hz exactly or 59.94Hz to support broadcast television. The sound output, however, is usually fixed at exact values like 32000Hz, 44100Hz, or 48000Hz. This means that the closest video-to-sound ratio we can achieve, with 60.00Hz and 32000Hz, is 1.0/533.3333. This discrepancy means if we wait for vertical sync and update once per refresh, we will experience a sound deficit of 0.87 samples every frame, eventually causing a sound underrun and producing audio problems.
+ On a NTSC SNES, the video refresh rate is usually 60.09881Hz, while the audio output is 32040Hz. This means for every video frame displayed, 532.4565 sound frames are produced. A modern computer display or television will usually provide one of two video rates, 60.00Hz exactly or 59.94Hz to support broadcast television. The sound output, however, is usually fixed at exact values like 32000Hz, 44100Hz, or 48000Hz. This means that the closest video-to-sound ratio we can achieve, with 60.00Hz and 32000Hz, is 1.0/533.3333. This discrepancy means if we wait for vertical sync and update once per refresh, we will experience a sound deficit of 0.87 samples every frame, eventually causing a sound underrun and producing audio problems.
- Settings.SoundInputRate can be set to a value such that the ratio with the video rate matches the SNES output. A 60.00Hz display, for example, should be set to 60.00 / 60.09881 * 32000, which is about 31947. The Snes9x resampler will then stretch the sound samples to fit this ratio. It may be beneficial to provide an option for users to configure Settings.SoundInputRate
to suit their own systems. Setting Settings.SoundInputRate
to a value that matches the actual output rate (i.e. 31915hz for 59.94Hz) or lower will allow the users to eliminate crackling. A range of 31000hz to 33000hz should be inclusive enough for all displays. Use of this setting paired with the S9xSyncSound
function can eliminate sound discontinuity. However, this concept is difficult for most users to understand. If possible, read the display's refresh rate and automatically calculate the appropriate input rate by default. In practice, few displays exceed a target of 60.00Hz, so a good default would be no greater than 31947Hz, but probably lower.
+ Settings.SoundInputRate can be set to a value such that the ratio with the video rate matches the SNES output. A 60.00Hz display, for example, should be set to 60.00 / 60.09881 * 32040, which is about 31987. The Snes9x resampler will then stretch the sound samples to fit this ratio. It may be beneficial to provide an option for users to configure Settings.SoundInputRate
to suit their own systems. Setting Settings.SoundInputRate
to a value that matches the actual output rate (i.e. 31915hz for 59.94Hz) or lower will allow the users to eliminate crackling. A range of 31000hz to 33000hz should be inclusive enough for all displays. Use of this setting paired with the S9xSyncSound
function can eliminate sound discontinuity. However, this concept is difficult for most users to understand. If possible, read the display's refresh rate and automatically calculate the appropriate input rate by default. In practice, few displays exceed a target of 60.00Hz, so a good default would be no greater than 31950Hz, but probably lower.
Settings.DynamicRateControl
and S9xUpdateDynamicRate(int numerator, int denominator)
diff --git a/gtk/src/gtk_preferences.cpp b/gtk/src/gtk_preferences.cpp index 73588606..41b1b3b1 100644 --- a/gtk/src/gtk_preferences.cpp +++ b/gtk/src/gtk_preferences.cpp @@ -427,7 +427,7 @@ event_input_rate_changed (GtkRange *range, gpointer data) { char text[256]; GtkLabel *label = GTK_LABEL (data); - double value = gtk_range_get_value (range) / 32000.0 * 60.09881389744051; + double value = gtk_range_get_value (range) / 32040.0 * 60.09881389744051; snprintf (text, 256, "%.4f hz", value); diff --git a/gtk/src/gtk_s9xwindow.cpp b/gtk/src/gtk_s9xwindow.cpp index d036170e..0a79ca12 100644 --- a/gtk/src/gtk_s9xwindow.cpp +++ b/gtk/src/gtk_s9xwindow.cpp @@ -1579,9 +1579,9 @@ Snes9xWindow::get_auto_input_rate () if (refresh_rate > 239.0 && refresh_rate < 241.0) refresh_rate /= 4.0; - double new_input_rate = refresh_rate * 32000.0 / 60.09881389744051 + 0.5; + double new_input_rate = refresh_rate * 32040.0 / 60.09881389744051 + 0.5; - if (new_input_rate > 32000.0 * 1.05 || new_input_rate < 32000.0 * 0.95) + if (new_input_rate > 32040.0 * 1.05 || new_input_rate < 32040.0 * 0.95) new_input_rate = 0.0; return new_input_rate; diff --git a/gtk/src/gtk_sound.cpp b/gtk/src/gtk_sound.cpp index 9a24a3f3..28d46a9e 100644 --- a/gtk/src/gtk_sound.cpp +++ b/gtk/src/gtk_sound.cpp @@ -133,7 +133,7 @@ S9xPortSoundInit () Settings.SoundInputRate = top_level->get_auto_input_rate (); if (Settings.SoundInputRate == 0.0) { - Settings.SoundInputRate = 31920; + Settings.SoundInputRate = 31950; gui_config->auto_input_rate = 0; } } diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 855fb40d..1c933487 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -749,7 +749,7 @@ void retro_get_system_av_info(struct retro_system_av_info *info) info->geometry.max_width = MAX_SNES_WIDTH_NTSC; info->geometry.max_height = MAX_SNES_HEIGHT; info->geometry.aspect_ratio = get_aspect_ratio(width, height); - info->timing.sample_rate = 32000; + info->timing.sample_rate = 32040; info->timing.fps = retro_get_region() == RETRO_REGION_NTSC ? 21477272.0 / 357366.0 : 21281370.0 / 425568.0; g_screen_gun_width = width; @@ -1254,8 +1254,8 @@ void retro_init(void) Settings.FrameTimeNTSC = 16667; Settings.SixteenBitSound = TRUE; Settings.Stereo = TRUE; - Settings.SoundPlaybackRate = 32000; - Settings.SoundInputRate = 32000; + Settings.SoundPlaybackRate = 32040; + Settings.SoundInputRate = 32040; Settings.SupportHiRes = TRUE; Settings.Transparency = TRUE; Settings.AutoDisplayMessages = TRUE; diff --git a/macosx/English.lproj/Snes9x Help/pgs/14.html b/macosx/English.lproj/Snes9x Help/pgs/14.html index e157ce9e..a1c3d064 100644 --- a/macosx/English.lproj/Snes9x Help/pgs/14.html +++ b/macosx/English.lproj/Snes9x Help/pgs/14.html @@ -56,7 +56,7 @@