menu_cbs_ok: re-adjust audio rates when the resolution dropdown changes refresh

Picking an entry from Settings -> Video -> Output -> Screen Resolution
runs action_cb_push_dropdown_item_resolution, which applied the new
refresh rate by calling video_monitor_set_refresh_rate() directly.

That function only writes settings->floats.video_refresh_rate and
pushes an OSD message.  The rest of the work lives in the
RARCH_DRIVER_CTL_SET_REFRESH_RATE case in retroarch.c, which also
resets audio_st->src_ratio_orig / src_ratio_curr, calls
driver_adjust_system_rates() so audio_st->input tracks the new
display rate, and recomputes the DRC threshold via
audio_driver_update_drc_threshold().

Because the dropdown skipped all of that, the resampler kept
converting for the old refresh rate after a mode change.  Menu
background music (Menu Sounds -> Enable BGM Sound) is fed through
audio_driver_menu_sample() -> audio_driver_flush(), which resamples
with the stale src_ratio_curr, so it becomes garbled the moment the
mode is switched and stays that way until something else re-adjusts
the rates.  It is loudest on a 120 Hz -> 60 Hz switch, where the
ratio is off by 2x, but the defect is not display- or
platform-specific: any refresh change made through this dropdown hits
it.

Route the change through driver_ctl() instead.  This is how every
refresh-rate case in menu_setting.c (VIDEO_REFRESH_RATE,
VIDEO_REFRESH_RATE_AUTO, VIDEO_REFRESH_RATE_POLLED) already applies a
change, so the dropdown was the odd one out.

driver.h is already included here, so no new dependency.  The
early-out in video_monitor_set_refresh_rate() for an unchanged value
still applies; only the audio re-adjustment is added, and it is
harmless when the rate did not actually move.
This commit is contained in:
libretroadmin authored and libretroadmin committed 2026-07-27 06:41:10 +02:00
1 parent 7c0aed3c7b
commit 2089f43b8d
1 file changed
+12 -1
+12 -1
View File
@@ -7514,7 +7514,18 @@ int action_cb_push_dropdown_item_resolution(const char *path,
if (refreshrate == (60.0f * refresh_mod) - 1)
refresh_exact = 59.94f * refresh_mod;
video_monitor_set_refresh_rate(refresh_exact);
/* Apply through driver_ctl rather than calling
* video_monitor_set_refresh_rate() directly. Updating the
* config float is only half the job: the driver_ctl case also
* resets the resampler ratio, re-runs
* driver_adjust_system_rates() and recomputes the DRC
* threshold. Skipping those leaves the audio resampler
* converting for the previous refresh rate until something
* else happens to re-adjust the rates - on a 120 Hz -> 60 Hz
* switch the ratio is wrong by 2x and the output is audibly
* garbled. Every refresh-rate case in menu_setting.c already
* applies changes this way. */
driver_ctl(RARCH_DRIVER_CTL_SET_REFRESH_RATE, &refresh_exact);
settings->uints.video_fullscreen_x = width;
settings->uints.video_fullscreen_y = height;