diff --git a/win32/CXAudio2.cpp b/win32/CXAudio2.cpp index 99da6190..7d740e40 100644 --- a/win32/CXAudio2.cpp +++ b/win32/CXAudio2.cpp @@ -396,23 +396,41 @@ void CXAudio2::StopPlayback() /* CXAudio2::ProcessSound The mixing function called by the sound core when new samples are available. -SoundBuffer is divided into blockCount blocks. If there are enought available samples and a free block, +SoundBuffer is divided into blockCount blocks. If there are enough available samples and a free block, the block is filled and queued to the source voice. bufferCount is increased by pushbuffer and decreased by the OnBufferComplete callback. */ void CXAudio2::ProcessSound() { + int freeBytes = (blockCount - bufferCount) * singleBufferBytes; + + if (Settings.DynamicRateControl) + { + S9xUpdateDynamicRate(freeBytes, sum_bufferSize); + } + S9xFinalizeSamples(); + UINT32 availableSamples; + + availableSamples = S9xGetSampleCount(); + + if (Settings.DynamicRateControl) + { + // Using rate control, we should always keep the emulator's sound buffers empty to + // maintain an accurate measurement. + if (availableSamples > (freeBytes >> (Settings.SixteenBitSound ? 1 : 0))) + { + S9xClearSamples(); + return; + } + } + if(!initDone) return; BYTE * curBuffer; - UINT32 availableSamples; - - availableSamples = S9xGetSampleCount(); - while(availableSamples > singleBufferSamples && bufferCount < blockCount) { curBuffer = soundBuffer + writeOffset; S9xMixSamples(curBuffer,singleBufferSamples); diff --git a/win32/rsrc/resource.h b/win32/rsrc/resource.h index 09d09853..f0d6df41 100644 --- a/win32/rsrc/resource.h +++ b/win32/rsrc/resource.h @@ -2,7 +2,7 @@ // Microsoft Visual C++ generated include file. // Used by snes9x.rc // -#include "windows.h" + #define IDC_STATIC (-1) #define IDR_RT_MANIFEST2 1 @@ -44,7 +44,7 @@ #define IDC_BUFLEN 1002 #define IDC_RATE 1003 #define IDC_MIX 1004 -#define IDC_16BIT 1005 +#define IDC_DYNRATECONTROL 1005 #define IDC_STEREO 1006 #define IDC_REV_STEREO 1007 #define IDC_LINEAR_INTER 1008 diff --git a/win32/rsrc/snes9x.rc b/win32/rsrc/snes9x.rc index db6d8c66..af36dfd8 100644 --- a/win32/rsrc/snes9x.rc +++ b/win32/rsrc/snes9x.rc @@ -7,7 +7,9 @@ // // Generated from the TEXTINCLUDE 2 resource. // - +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS @@ -68,14 +70,14 @@ BEGIN LTEXT "Buffer Length:",IDC_STATIC,125,58,49,11 COMBOBOX IDC_RATE,177,40,106,171,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Playback Rate:",IDC_STATIC,125,41,49,11 - CONTROL "&16 Bit playback",IDC_16BIT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,295,24,96,10 - CONTROL "&Stereo",IDC_STEREO,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,295,38,93,10 - CONTROL "&Reverse Stereo",IDC_REV_STEREO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,295,53,94,10 + CONTROL "&Dynamic Rate Control",IDC_DYNRATECONTROL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,295,99,96,10 + CONTROL "&Stereo",IDC_STEREO,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,295,20,93,10 + CONTROL "&Reverse Stereo",IDC_REV_STEREO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,295,35,94,10 CONTROL "&Synchronize with sound core",IDC_SYNC_TO_SOUND_CPU, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,295,68,102,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,295,84,102,10 PUSHBUTTON "&Cancel",IDCANCEL,350,122,56,16 - CONTROL "&Mute sound",IDC_MUTE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,295,83,93,12 - CONTROL "Frame Advance mu&te",IDC_FAMT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,295,98,90,12 + CONTROL "&Mute sound",IDC_MUTE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,295,50,93,12 + CONTROL "Frame Advance mu&te",IDC_FAMT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,295,67,90,12 CONTROL "",IDC_INRATE,"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | WS_TABSTOP,124,88,157,26 EDITTEXT IDC_INRATEEDIT,177,74,105,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Input Rate:",IDC_INRATETEXT,126,74,46,11 @@ -315,7 +317,7 @@ BEGIN RTEXT "DN RIGHT",IDC_LABEL_DOWNRIGHT,122,120,36,8 RTEXT "UP RIGHT",IDC_LABEL_UPRIGHT,122,107,36,8 RTEXT "DN LEFT",IDC_LABEL_DOWNLEFT,127,132,31,8 - CONTROL 133,IDC_STATIC,"Static",SS_BITMAP,243,39,80,74 + CONTROL IDB_PAD,IDC_STATIC,"Static",SS_BITMAP,243,39,80,74 CONTROL "Allow Left+Rt/Up+Dn",IDC_ALLOWLEFTRIGHT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,243,115,80,11 GROUPBOX "Controller",IDC_STATIC,5,1,142,28,0,WS_EX_TRANSPARENT GROUPBOX "Buttons",IDC_STATIC,5,30,234,117,0,WS_EX_TRANSPARENT @@ -787,6 +789,14 @@ BEGIN END 2 TEXTINCLUDE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "\0" +END + +3 TEXTINCLUDE BEGIN "\r\n" "\0" diff --git a/win32/wconfig.cpp b/win32/wconfig.cpp index e1418f98..2353e0db 100644 --- a/win32/wconfig.cpp +++ b/win32/wconfig.cpp @@ -976,6 +976,7 @@ void WinRegisterConfigItems() AddUIntC("InputRate", Settings.SoundInputRate, 31900, "for each 'Input rate' samples generated by the SNES, 'Playback rate' samples will produced. If you experience crackling you can try to lower this setting."); AddBoolC("ReverseStereo", Settings.ReverseStereo, false, "true to swap speaker outputs"); AddBoolC("Mute", GUI.Mute, false, "true to mute sound output (does not disable the sound CPU)"); + AddBool("DynamicRateControl", Settings.DynamicRateControl, false); #undef CATEGORY #define CATEGORY "Sound\\Win" AddUIntC("SoundDriver", GUI.SoundDriver, 4, "0=Snes9xDirectSound, 4=XAudio2 (recommended)"); diff --git a/win32/win32_sound.cpp b/win32/win32_sound.cpp index efc673e4..f74a55a7 100644 --- a/win32/win32_sound.cpp +++ b/win32/win32_sound.cpp @@ -244,6 +244,7 @@ bool8 S9xOpenSoundDevice () switch(GUI.SoundDriver) { case WIN_SNES9X_DIRECT_SOUND_DRIVER: S9xSoundOutput = &S9xDirectSound; + Settings.DynamicRateControl = false; break; case WIN_XAUDIO2_SOUND_DRIVER: S9xSoundOutput = &S9xXAudio2; diff --git a/win32/wsnes9x.cpp b/win32/wsnes9x.cpp index e3202c36..00a47e7d 100644 --- a/win32/wsnes9x.cpp +++ b/win32/wsnes9x.cpp @@ -4565,8 +4565,8 @@ INT_PTR CALLBACK DlgSoundConf(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) SendDlgItemMessage(hDlg,IDC_BUFLEN,CB_SETCURSEL,((GUI.SoundBufferSize/16)-1),0); - if(Settings.SixteenBitSound) - SendDlgItemMessage(hDlg,IDC_16BIT,BM_SETCHECK,BST_CHECKED,0); + if(Settings.DynamicRateControl) + SendDlgItemMessage(hDlg,IDC_DYNRATECONTROL,BM_SETCHECK,BST_CHECKED,0); if(Settings.Stereo) SendDlgItemMessage(hDlg,IDC_STEREO,BM_SETCHECK,BST_CHECKED,0); else EnableWindow(GetDlgItem(hDlg, IDC_REV_STEREO), FALSE); @@ -4625,7 +4625,7 @@ INT_PTR CALLBACK DlgSoundConf(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { GUI.SoundDriver=SendDlgItemMessage(hDlg, IDC_DRIVER, CB_GETITEMDATA, SendDlgItemMessage(hDlg, IDC_DRIVER, CB_GETCURSEL, 0,0),0); - Settings.SixteenBitSound=IsDlgButtonChecked(hDlg, IDC_16BIT); + Settings.DynamicRateControl=IsDlgButtonChecked(hDlg, IDC_DYNRATECONTROL); Settings.SoundSync=IsDlgButtonChecked(hDlg, IDC_SYNC_TO_SOUND_CPU); Settings.Stereo=IsDlgButtonChecked(hDlg, IDC_STEREO); Settings.ReverseStereo=IsDlgButtonChecked(hDlg, IDC_REV_STEREO);