win32: add dynamic rate control setting, implement for xaudio2

This commit is contained in:
OV2 2017-11-28 20:48:12 +01:00
parent 91f0caa516
commit 32e87fab07
6 changed files with 48 additions and 18 deletions

View File

@ -396,23 +396,41 @@ void CXAudio2::StopPlayback()
/* CXAudio2::ProcessSound /* CXAudio2::ProcessSound
The mixing function called by the sound core when new samples are available. 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 block is filled and queued to the source voice. bufferCount is increased by pushbuffer and decreased by
the OnBufferComplete callback. the OnBufferComplete callback.
*/ */
void CXAudio2::ProcessSound() void CXAudio2::ProcessSound()
{ {
int freeBytes = (blockCount - bufferCount) * singleBufferBytes;
if (Settings.DynamicRateControl)
{
S9xUpdateDynamicRate(freeBytes, sum_bufferSize);
}
S9xFinalizeSamples(); 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) if(!initDone)
return; return;
BYTE * curBuffer; BYTE * curBuffer;
UINT32 availableSamples;
availableSamples = S9xGetSampleCount();
while(availableSamples > singleBufferSamples && bufferCount < blockCount) { while(availableSamples > singleBufferSamples && bufferCount < blockCount) {
curBuffer = soundBuffer + writeOffset; curBuffer = soundBuffer + writeOffset;
S9xMixSamples(curBuffer,singleBufferSamples); S9xMixSamples(curBuffer,singleBufferSamples);

View File

@ -2,7 +2,7 @@
// Microsoft Visual C++ generated include file. // Microsoft Visual C++ generated include file.
// Used by snes9x.rc // Used by snes9x.rc
// //
#include "windows.h"
#define IDC_STATIC (-1) #define IDC_STATIC (-1)
#define IDR_RT_MANIFEST2 1 #define IDR_RT_MANIFEST2 1
@ -44,7 +44,7 @@
#define IDC_BUFLEN 1002 #define IDC_BUFLEN 1002
#define IDC_RATE 1003 #define IDC_RATE 1003
#define IDC_MIX 1004 #define IDC_MIX 1004
#define IDC_16BIT 1005 #define IDC_DYNRATECONTROL 1005
#define IDC_STEREO 1006 #define IDC_STEREO 1006
#define IDC_REV_STEREO 1007 #define IDC_REV_STEREO 1007
#define IDC_LINEAR_INTER 1008 #define IDC_LINEAR_INTER 1008

View File

@ -7,7 +7,9 @@
// //
// Generated from the TEXTINCLUDE 2 resource. // Generated from the TEXTINCLUDE 2 resource.
// //
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS #undef APSTUDIO_READONLY_SYMBOLS
@ -68,14 +70,14 @@ BEGIN
LTEXT "Buffer Length:",IDC_STATIC,125,58,49,11 LTEXT "Buffer Length:",IDC_STATIC,125,58,49,11
COMBOBOX IDC_RATE,177,40,106,171,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_RATE,177,40,106,171,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Playback Rate:",IDC_STATIC,125,41,49,11 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 "&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,38,93,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,53,94,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, 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 PUSHBUTTON "&Cancel",IDCANCEL,350,122,56,16
CONTROL "&Mute sound",IDC_MUTE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,295,83,93,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,98,90,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 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 EDITTEXT IDC_INRATEEDIT,177,74,105,12,ES_AUTOHSCROLL | ES_NUMBER
LTEXT "Input Rate:",IDC_INRATETEXT,126,74,46,11 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 "DN RIGHT",IDC_LABEL_DOWNRIGHT,122,120,36,8
RTEXT "UP RIGHT",IDC_LABEL_UPRIGHT,122,107,36,8 RTEXT "UP RIGHT",IDC_LABEL_UPRIGHT,122,107,36,8
RTEXT "DN LEFT",IDC_LABEL_DOWNLEFT,127,132,31,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 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 "Controller",IDC_STATIC,5,1,142,28,0,WS_EX_TRANSPARENT
GROUPBOX "Buttons",IDC_STATIC,5,30,234,117,0,WS_EX_TRANSPARENT GROUPBOX "Buttons",IDC_STATIC,5,30,234,117,0,WS_EX_TRANSPARENT
@ -787,6 +789,14 @@ BEGIN
END END
2 TEXTINCLUDE 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 BEGIN
"\r\n" "\r\n"
"\0" "\0"

View File

@ -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."); 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("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)"); AddBoolC("Mute", GUI.Mute, false, "true to mute sound output (does not disable the sound CPU)");
AddBool("DynamicRateControl", Settings.DynamicRateControl, false);
#undef CATEGORY #undef CATEGORY
#define CATEGORY "Sound\\Win" #define CATEGORY "Sound\\Win"
AddUIntC("SoundDriver", GUI.SoundDriver, 4, "0=Snes9xDirectSound, 4=XAudio2 (recommended)"); AddUIntC("SoundDriver", GUI.SoundDriver, 4, "0=Snes9xDirectSound, 4=XAudio2 (recommended)");

View File

@ -244,6 +244,7 @@ bool8 S9xOpenSoundDevice ()
switch(GUI.SoundDriver) { switch(GUI.SoundDriver) {
case WIN_SNES9X_DIRECT_SOUND_DRIVER: case WIN_SNES9X_DIRECT_SOUND_DRIVER:
S9xSoundOutput = &S9xDirectSound; S9xSoundOutput = &S9xDirectSound;
Settings.DynamicRateControl = false;
break; break;
case WIN_XAUDIO2_SOUND_DRIVER: case WIN_XAUDIO2_SOUND_DRIVER:
S9xSoundOutput = &S9xXAudio2; S9xSoundOutput = &S9xXAudio2;

View File

@ -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); SendDlgItemMessage(hDlg,IDC_BUFLEN,CB_SETCURSEL,((GUI.SoundBufferSize/16)-1),0);
if(Settings.SixteenBitSound) if(Settings.DynamicRateControl)
SendDlgItemMessage(hDlg,IDC_16BIT,BM_SETCHECK,BST_CHECKED,0); SendDlgItemMessage(hDlg,IDC_DYNRATECONTROL,BM_SETCHECK,BST_CHECKED,0);
if(Settings.Stereo) if(Settings.Stereo)
SendDlgItemMessage(hDlg,IDC_STEREO,BM_SETCHECK,BST_CHECKED,0); SendDlgItemMessage(hDlg,IDC_STEREO,BM_SETCHECK,BST_CHECKED,0);
else EnableWindow(GetDlgItem(hDlg, IDC_REV_STEREO), FALSE); 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, GUI.SoundDriver=SendDlgItemMessage(hDlg, IDC_DRIVER, CB_GETITEMDATA,
SendDlgItemMessage(hDlg, IDC_DRIVER, CB_GETCURSEL, 0,0),0); 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.SoundSync=IsDlgButtonChecked(hDlg, IDC_SYNC_TO_SOUND_CPU);
Settings.Stereo=IsDlgButtonChecked(hDlg, IDC_STEREO); Settings.Stereo=IsDlgButtonChecked(hDlg, IDC_STEREO);
Settings.ReverseStereo=IsDlgButtonChecked(hDlg, IDC_REV_STEREO); Settings.ReverseStereo=IsDlgButtonChecked(hDlg, IDC_REV_STEREO);