Added a latency setting to the audio settings.
Removed the Sample Rate setting. It is now hardcoded to 48000hz (accurate audio timing). Fixes issue 5672.
This commit is contained in:
parent
73140c7da7
commit
1c462a1eca
|
@ -42,7 +42,6 @@ void AudioCommonConfig::Load()
|
|||
#else
|
||||
file.Get("Config", "Backend", &sBackend, BACKEND_NULLSOUND);
|
||||
#endif
|
||||
file.Get("Config", "Frequency", &iFrequency, 48000);
|
||||
file.Get("Config", "Volume", &m_Volume, 100);
|
||||
}
|
||||
|
||||
|
@ -55,7 +54,6 @@ void AudioCommonConfig::SaveSettings()
|
|||
file.Set("Config", "EnableJIT", m_EnableJIT);
|
||||
file.Set("Config", "DumpAudio", m_DumpAudio);
|
||||
file.Set("Config", "Backend", sBackend);
|
||||
file.Set("Config", "Frequency", iFrequency);
|
||||
file.Set("Config", "Volume", m_Volume);
|
||||
|
||||
file.Save(File::GetUserPath(F_DSPCONFIG_IDX));
|
||||
|
|
|
@ -37,7 +37,6 @@ struct AudioCommonConfig
|
|||
bool m_DumpAudio;
|
||||
int m_Volume;
|
||||
std::string sBackend;
|
||||
int iFrequency;
|
||||
|
||||
// Load from given file
|
||||
void Load();
|
||||
|
|
|
@ -46,6 +46,11 @@ bool OpenALStream::Start()
|
|||
pContext = alcCreateContext(pDevice, NULL);
|
||||
if (pContext)
|
||||
{
|
||||
// Used to determine an appropriate period size (2x period = total buffer size)
|
||||
//ALCint refresh;
|
||||
//alcGetIntegerv(pDevice, ALC_REFRESH, 1, &refresh);
|
||||
//period_size_in_millisec = 1000 / refresh;
|
||||
|
||||
alcMakeContextCurrent(pContext);
|
||||
thread = std::thread(std::mem_fun(&OpenALStream::SoundLoop), this);
|
||||
bReturn = true;
|
||||
|
@ -90,7 +95,7 @@ void OpenALStream::Stop()
|
|||
// Clean up buffers and sources
|
||||
alDeleteSources(1, &uiSource);
|
||||
uiSource = 0;
|
||||
alDeleteBuffers(OAL_NUM_BUFFERS, uiBuffers);
|
||||
alDeleteBuffers(numBuffers, uiBuffers);
|
||||
|
||||
ALCcontext *pContext = alcGetCurrentContext();
|
||||
ALCdevice *pDevice = alcGetContextsDevice(pContext);
|
||||
|
@ -133,19 +138,20 @@ void OpenALStream::SoundLoop()
|
|||
Common::SetCurrentThreadName("Audio thread - openal");
|
||||
|
||||
u32 ulFrequency = m_mixer->GetSampleRate();
|
||||
numBuffers = Core::g_CoreStartupParameter.iLatency + 2; // OpenAL requires a minimum of two buffers
|
||||
|
||||
memset(uiBuffers, 0, OAL_NUM_BUFFERS * sizeof(ALuint));
|
||||
memset(uiBuffers, 0, numBuffers * sizeof(ALuint));
|
||||
uiSource = 0;
|
||||
|
||||
// Generate some AL Buffers for streaming
|
||||
alGenBuffers(OAL_NUM_BUFFERS, (ALuint *)uiBuffers);
|
||||
alGenBuffers(numBuffers, (ALuint *)uiBuffers);
|
||||
// Generate a Source to playback the Buffers
|
||||
alGenSources(1, &uiSource);
|
||||
|
||||
// Short Silence
|
||||
memset(sampleBuffer, 0, OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * OAL_NUM_BUFFERS);
|
||||
memset(sampleBuffer, 0, OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * numBuffers);
|
||||
memset(realtimeBuffer, 0, OAL_MAX_SAMPLES * 4);
|
||||
for (int i = 0; i < OAL_NUM_BUFFERS; i++)
|
||||
for (int i = 0; i < numBuffers; i++)
|
||||
{
|
||||
#if !defined(__APPLE__)
|
||||
if (Core::g_CoreStartupParameter.bDPL2Decoder)
|
||||
|
@ -154,7 +160,7 @@ void OpenALStream::SoundLoop()
|
|||
#endif
|
||||
alBufferData(uiBuffers[i], AL_FORMAT_STEREO16, realtimeBuffer, 4 * 2 * 2, ulFrequency);
|
||||
}
|
||||
alSourceQueueBuffers(uiSource, OAL_NUM_BUFFERS, uiBuffers);
|
||||
alSourceQueueBuffers(uiSource, numBuffers, uiBuffers);
|
||||
alSourcePlay(uiSource);
|
||||
|
||||
// Set the default sound volume as saved in the config file.
|
||||
|
@ -166,7 +172,7 @@ void OpenALStream::SoundLoop()
|
|||
ALint iBuffersFilled = 0;
|
||||
ALint iBuffersProcessed = 0;
|
||||
ALint iState = 0;
|
||||
ALuint uiBufferTemp[OAL_NUM_BUFFERS] = {0};
|
||||
ALuint uiBufferTemp[OAL_MAX_BUFFERS] = {0};
|
||||
|
||||
soundTouch.setChannels(2);
|
||||
soundTouch.setSampleRate(ulFrequency);
|
||||
|
@ -216,7 +222,7 @@ void OpenALStream::SoundLoop()
|
|||
soundTouch.setSetting(SETTING_SEQUENCE_MS, (int)(1 / (rate * rate)));
|
||||
soundTouch.setTempo(rate);
|
||||
}
|
||||
unsigned int nSamples = soundTouch.receiveSamples(sampleBuffer, OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * OAL_NUM_BUFFERS);
|
||||
unsigned int nSamples = soundTouch.receiveSamples(sampleBuffer, OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * OAL_MAX_BUFFERS);
|
||||
if (nSamples > 0)
|
||||
{
|
||||
// Remove the Buffer from the Queue. (uiBuffer contains the Buffer ID for the unqueued Buffer)
|
||||
|
@ -236,14 +242,14 @@ void OpenALStream::SoundLoop()
|
|||
if (surround_capable)
|
||||
{
|
||||
// Convert the samples from short to float for the dpl2 decoder
|
||||
float dest[OAL_MAX_SAMPLES * 2 * 2 * OAL_NUM_BUFFERS];
|
||||
float dest[OAL_MAX_SAMPLES * 2 * 2 * OAL_MAX_BUFFERS];
|
||||
for (u32 i = 0; i < nSamples; ++i)
|
||||
{
|
||||
dest[i * 2 + 0] = (float)sampleBuffer[i * 2 + 0] / (1<<16);
|
||||
dest[i * 2 + 1] = (float)sampleBuffer[i * 2 + 1] / (1<<16);
|
||||
}
|
||||
|
||||
float dpl2[OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * OAL_NUM_BUFFERS];
|
||||
float dpl2[OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * OAL_MAX_BUFFERS];
|
||||
dpl2decode(dest, nSamples, dpl2);
|
||||
|
||||
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_51CHN32, dpl2, nSamples * SIZE_FLOAT * SURROUND_CHANNELS, ulFrequency);
|
||||
|
@ -273,7 +279,7 @@ void OpenALStream::SoundLoop()
|
|||
}
|
||||
iBuffersFilled++;
|
||||
|
||||
if (iBuffersFilled == OAL_NUM_BUFFERS)
|
||||
if (iBuffersFilled == numBuffers)
|
||||
{
|
||||
alSourcePlay(uiSource);
|
||||
ALenum err = alGetError();
|
||||
|
|
|
@ -44,8 +44,8 @@
|
|||
|
||||
// 16 bit Stereo
|
||||
#define SFX_MAX_SOURCE 1
|
||||
#define OAL_NUM_BUFFERS 16
|
||||
#define OAL_MAX_SAMPLES 512
|
||||
#define OAL_MAX_BUFFERS 32
|
||||
#define OAL_MAX_SAMPLES 256
|
||||
#define SURROUND_CHANNELS 6 // number of channels in surround mode
|
||||
#define SIZE_FLOAT 4 // size of a float in bytes
|
||||
#endif
|
||||
|
@ -75,10 +75,12 @@ private:
|
|||
Common::Event soundSyncEvent;
|
||||
|
||||
short realtimeBuffer[OAL_MAX_SAMPLES * 2];
|
||||
soundtouch::SAMPLETYPE sampleBuffer[OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * OAL_NUM_BUFFERS];
|
||||
ALuint uiBuffers[OAL_NUM_BUFFERS];
|
||||
soundtouch::SAMPLETYPE sampleBuffer[OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * OAL_MAX_BUFFERS];
|
||||
ALuint uiBuffers[OAL_MAX_BUFFERS];
|
||||
ALuint uiSource;
|
||||
ALfloat fVolume;
|
||||
|
||||
u8 numBuffers;
|
||||
#else
|
||||
public:
|
||||
OpenALStream(CMixer *mixer, void *hWnd = NULL): SoundStream(mixer) {}
|
||||
|
|
|
@ -228,6 +228,7 @@ void SConfig::SaveSettings()
|
|||
ini.Set("Core", "EnableCheats", m_LocalCoreStartupParameter.bEnableCheats);
|
||||
ini.Set("Core", "SelectedLanguage", m_LocalCoreStartupParameter.SelectedLanguage);
|
||||
ini.Set("Core", "DPL2Decoder", m_LocalCoreStartupParameter.bDPL2Decoder);
|
||||
ini.Set("Core", "Latency", m_LocalCoreStartupParameter.iLatency);
|
||||
ini.Set("Core", "MemcardA", m_strMemoryCardA);
|
||||
ini.Set("Core", "MemcardB", m_strMemoryCardB);
|
||||
ini.Set("Core", "SlotA", m_EXIDevice[0]);
|
||||
|
@ -369,6 +370,7 @@ void SConfig::LoadSettings()
|
|||
ini.Get("Core", "EnableCheats", &m_LocalCoreStartupParameter.bEnableCheats, false);
|
||||
ini.Get("Core", "SelectedLanguage", &m_LocalCoreStartupParameter.SelectedLanguage, 0);
|
||||
ini.Get("Core", "DPL2Decoder", &m_LocalCoreStartupParameter.bDPL2Decoder, true);
|
||||
ini.Get("Core", "Latency", &m_LocalCoreStartupParameter.iLatency, 14);
|
||||
ini.Get("Core", "MemcardA", &m_strMemoryCardA);
|
||||
ini.Get("Core", "MemcardB", &m_strMemoryCardB);
|
||||
ini.Get("Core", "SlotA", (int*)&m_EXIDevice[0], EXIDEVICE_MEMORYCARD);
|
||||
|
|
|
@ -49,7 +49,7 @@ SCoreStartupParameter::SCoreStartupParameter()
|
|||
bEnableCheats(false),
|
||||
bMergeBlocks(false),
|
||||
bRunCompareServer(false), bRunCompareClient(false),
|
||||
bDPL2Decoder(true),
|
||||
bDPL2Decoder(true), iLatency(14),
|
||||
bMMU(false), bMMUBAT(false), iTLBHack(0), bVBeam(false),
|
||||
bFastDiscSpeed(false),
|
||||
SelectedLanguage(0), bWii(false), bDisableWiimoteSpeaker(false),
|
||||
|
@ -86,6 +86,7 @@ void SCoreStartupParameter::LoadDefaults()
|
|||
SelectedLanguage = 0;
|
||||
bWii = false;
|
||||
bDPL2Decoder = true;
|
||||
iLatency = 14;
|
||||
|
||||
iPosX = 100;
|
||||
iPosY = 100;
|
||||
|
|
|
@ -108,6 +108,7 @@ struct SCoreStartupParameter
|
|||
bool bMergeBlocks;
|
||||
|
||||
bool bDPL2Decoder;
|
||||
int iLatency;
|
||||
|
||||
bool bRunCompareServer;
|
||||
bool bRunCompareClient;
|
||||
|
|
|
@ -251,7 +251,7 @@ void DSPHLE::InitMixer()
|
|||
unsigned int AISampleRate, DACSampleRate;
|
||||
AudioInterface::Callback_GetSampleRate(AISampleRate, DACSampleRate);
|
||||
delete soundStream;
|
||||
soundStream = AudioCommon::InitSoundStream(new HLEMixer(this, AISampleRate, DACSampleRate, ac_Config.iFrequency), m_hWnd);
|
||||
soundStream = AudioCommon::InitSoundStream(new HLEMixer(this, AISampleRate, DACSampleRate, 48000), m_hWnd);
|
||||
if(!soundStream) PanicAlert("Error starting up sound stream");
|
||||
// Mixer is initialized
|
||||
m_InitMixer = true;
|
||||
|
|
|
@ -204,7 +204,7 @@ void DSPLLE::InitMixer()
|
|||
unsigned int AISampleRate, DACSampleRate;
|
||||
AudioInterface::Callback_GetSampleRate(AISampleRate, DACSampleRate);
|
||||
delete soundStream;
|
||||
soundStream = AudioCommon::InitSoundStream(new CMixer(AISampleRate, DACSampleRate, ac_Config.iFrequency), m_hWnd);
|
||||
soundStream = AudioCommon::InitSoundStream(new CMixer(AISampleRate, DACSampleRate, 48000), m_hWnd);
|
||||
if(!soundStream) PanicAlert("Error starting up sound stream");
|
||||
// Mixer is initialized
|
||||
m_InitMixer = true;
|
||||
|
|
|
@ -121,7 +121,7 @@ EVT_CHECKBOX(ID_DSPTHREAD, CConfigMain::AudioSettingsChanged)
|
|||
EVT_CHECKBOX(ID_ENABLE_THROTTLE, CConfigMain::AudioSettingsChanged)
|
||||
EVT_CHECKBOX(ID_DUMP_AUDIO, CConfigMain::AudioSettingsChanged)
|
||||
EVT_CHECKBOX(ID_DPL2DECODER, CConfigMain::AudioSettingsChanged)
|
||||
EVT_CHOICE(ID_FREQUENCY, CConfigMain::AudioSettingsChanged)
|
||||
EVT_SLIDER(ID_LATENCY, CConfigMain::AudioSettingsChanged)
|
||||
EVT_CHOICE(ID_BACKEND, CConfigMain::AudioSettingsChanged)
|
||||
EVT_SLIDER(ID_VOLUME, CConfigMain::AudioSettingsChanged)
|
||||
|
||||
|
@ -218,6 +218,8 @@ void CConfigMain::UpdateGUI()
|
|||
// Disable stuff on AudioPage
|
||||
DSPEngine->Disable();
|
||||
DSPThread->Disable();
|
||||
DPL2Decoder->Disable();
|
||||
LatencySlider->Disable();
|
||||
|
||||
// Disable stuff on GamecubePage
|
||||
GCSystemLang->Disable();
|
||||
|
@ -365,8 +367,9 @@ void CConfigMain::InitializeGUIValues()
|
|||
DSPThread->SetValue(startup_params.bDSPThread);
|
||||
DumpAudio->SetValue(ac_Config.m_DumpAudio ? true : false);
|
||||
DPL2Decoder->SetValue(startup_params.bDPL2Decoder);
|
||||
FrequencySelection->SetSelection(
|
||||
FrequencySelection->FindString(wxString::Format(_("%d Hz"), ac_Config.iFrequency)));
|
||||
LatencySlider->Enable(std::string(ac_Config.sBackend) == BACKEND_OPENAL);
|
||||
LatencySlider->SetValue(startup_params.iLatency);
|
||||
LatencyText->SetLabel(wxString::Format(wxT("%d"), startup_params.iLatency));
|
||||
// add backends to the list
|
||||
AddAudioBackends();
|
||||
|
||||
|
@ -511,7 +514,6 @@ void CConfigMain::InitializeGUITooltips()
|
|||
|
||||
// Audio tooltips
|
||||
DSPThread->SetToolTip(_("Run DSP LLE on a dedicated thread (not recommended)."));
|
||||
FrequencySelection->SetToolTip(_("Changing this will have no effect while the emulator is running!"));
|
||||
BackendSelection->SetToolTip(_("Changing this will have no effect while the emulator is running!"));
|
||||
|
||||
// Gamecube - Devices
|
||||
|
@ -527,6 +529,8 @@ void CConfigMain::InitializeGUITooltips()
|
|||
#elif defined(_WIN32)
|
||||
DPL2Decoder->SetToolTip(_("Enables Dolby Pro Logic II emulation using 5.1 surround. OpenAL backend only. May need to rename soft_oal.dll to OpenAL32.dll to make it work."));
|
||||
#endif
|
||||
|
||||
LatencySlider->SetToolTip(_("Sets the latency (in ms). Higher values may reduce audio crackling. OpenAL backend only."));
|
||||
}
|
||||
|
||||
void CConfigMain::CreateGUIControls()
|
||||
|
@ -630,13 +634,14 @@ void CConfigMain::CreateGUIControls()
|
|||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
BackendSelection = new wxChoice(AudioPage, ID_BACKEND, wxDefaultPosition,
|
||||
wxDefaultSize, wxArrayBackends, 0, wxDefaultValidator, wxEmptyString);
|
||||
FrequencySelection = new wxChoice(AudioPage, ID_FREQUENCY);
|
||||
FrequencySelection->Append(wxString::Format(_("%d Hz"), 48000));
|
||||
FrequencySelection->Append(wxString::Format(_("%d Hz"), 32000));
|
||||
LatencySlider = new wxSlider(AudioPage, ID_LATENCY, 0, 0, 30,
|
||||
wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL);
|
||||
LatencyText = new wxStaticText(AudioPage, wxID_ANY, wxT(""),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
|
||||
if (Core::GetState() != Core::CORE_UNINITIALIZED)
|
||||
{
|
||||
FrequencySelection->Disable();
|
||||
LatencySlider->Disable();
|
||||
BackendSelection->Disable();
|
||||
DPL2Decoder->Disable();
|
||||
}
|
||||
|
@ -655,8 +660,9 @@ void CConfigMain::CreateGUIControls()
|
|||
wxGridBagSizer *sBackend = new wxGridBagSizer();
|
||||
sBackend->Add(TEXT_BOX(AudioPage, _("Audio Backend:")), wxGBPosition(0, 0), wxDefaultSpan, wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||
sBackend->Add(BackendSelection, wxGBPosition(0, 1), wxDefaultSpan, wxALL, 5);
|
||||
sBackend->Add(TEXT_BOX(AudioPage, _("Sample Rate:")), wxGBPosition(1, 0), wxDefaultSpan, wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||
sBackend->Add(FrequencySelection, wxGBPosition(1, 1), wxDefaultSpan, wxALL, 5);
|
||||
sBackend->Add(TEXT_BOX(AudioPage, _("Latency:")), wxGBPosition(1, 0), wxDefaultSpan, wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||
sBackend->Add(LatencySlider, wxGBPosition(1, 1), wxDefaultSpan, wxALL, 5);
|
||||
sBackend->Add(LatencyText, wxGBPosition(1, 2), wxDefaultSpan, wxALL, 5);
|
||||
wxStaticBoxSizer *sbBackend = new wxStaticBoxSizer(wxHORIZONTAL, AudioPage, _("Backend Settings"));
|
||||
sbBackend->Add(sBackend, 0, wxEXPAND);
|
||||
|
||||
|
@ -946,17 +952,19 @@ void CConfigMain::AudioSettingsChanged(wxCommandEvent& event)
|
|||
|
||||
case ID_BACKEND:
|
||||
VolumeSlider->Enable(SupportsVolumeChanges(std::string(BackendSelection->GetStringSelection().mb_str())));
|
||||
LatencySlider->Enable(std::string(BackendSelection->GetStringSelection().mb_str()) == BACKEND_OPENAL);
|
||||
DPL2Decoder->Enable(std::string(BackendSelection->GetStringSelection().mb_str()) == BACKEND_OPENAL);
|
||||
ac_Config.sBackend = BackendSelection->GetStringSelection().mb_str();
|
||||
ac_Config.Update();
|
||||
break;
|
||||
|
||||
case ID_LATENCY:
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.iLatency = LatencySlider->GetValue();
|
||||
LatencyText->SetLabel(wxString::Format(wxT("%d"), LatencySlider->GetValue()));
|
||||
break;
|
||||
|
||||
default:
|
||||
ac_Config.m_DumpAudio = DumpAudio->GetValue();
|
||||
|
||||
long int frequency;
|
||||
FrequencySelection->GetStringSelection().ToLong(&frequency);
|
||||
ac_Config.iFrequency = frequency;
|
||||
ac_Config.Update();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ private:
|
|||
ID_ENABLE_THROTTLE,
|
||||
ID_DUMP_AUDIO,
|
||||
ID_DPL2DECODER,
|
||||
ID_FREQUENCY,
|
||||
ID_LATENCY,
|
||||
ID_BACKEND,
|
||||
ID_VOLUME,
|
||||
|
||||
|
@ -156,12 +156,13 @@ private:
|
|||
wxBoxSizer* sAudioPage; // GC settings
|
||||
wxRadioBox* DSPEngine;
|
||||
wxSlider* VolumeSlider;
|
||||
wxStaticText* VolumeText;
|
||||
wxStaticText* VolumeText;
|
||||
wxCheckBox* DumpAudio;
|
||||
wxCheckBox* DPL2Decoder;
|
||||
wxArrayString wxArrayBackends;
|
||||
wxChoice* BackendSelection;
|
||||
wxChoice* FrequencySelection;
|
||||
wxSlider* LatencySlider;
|
||||
wxStaticText* LatencyText;
|
||||
|
||||
// Interface
|
||||
wxCheckBox* ConfirmStop;
|
||||
|
|
Loading…
Reference in New Issue