diff --git a/3rdparty/cubeb/include/cubeb_export.h b/3rdparty/cubeb/include/cubeb_export.h
index a049dacf71..dda45aca22 100644
--- a/3rdparty/cubeb/include/cubeb_export.h
+++ b/3rdparty/cubeb/include/cubeb_export.h
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
- * Copyright (C) 2002-2020 PCSX2 Dev Team
+ * Copyright (C) 2002-2021 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
diff --git a/cmake/BuildParameters.cmake b/cmake/BuildParameters.cmake
index a1ca1e10bd..519dee37d4 100644
--- a/cmake/BuildParameters.cmake
+++ b/cmake/BuildParameters.cmake
@@ -46,9 +46,8 @@ option(PACKAGE_MODE "Use this option to ease packaging of PCSX2 (developer/distr
option(DISABLE_PCSX2_WRAPPER "Disable including the PCSX2-linux.sh file")
option(DISABLE_SETCAP "Do not set files capabilities")
option(XDG_STD "Use XDG standard path instead of the standard PCSX2 path")
-option(PORTAUDIO_API "Build portaudio support on SPU2" ON)
option(CUBEB_API "Build Cubeb support on SPU2" ON)
-option(SDL2_API "Use SDL2 on SPU2 and PAD Linux (wxWidget mustn't be built with SDL1.2 support" ON)
+option(SDL2_API "Use SDL2 on PAD Linux (wxWidget mustn't be built with SDL1.2 support" ON)
option(GTK2_API "Use GTK2 api (legacy)")
if(UNIX AND NOT APPLE)
diff --git a/cmake/SearchForStuff.cmake b/cmake/SearchForStuff.cmake
index cbe8670db3..850c92575c 100644
--- a/cmake/SearchForStuff.cmake
+++ b/cmake/SearchForStuff.cmake
@@ -12,7 +12,6 @@ if (WIN32)
add_subdirectory(3rdparty/libsamplerate EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/baseclasses EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/freetype EXCLUDE_FROM_ALL)
- add_subdirectory(3rdparty/portaudio EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/pthreads4w EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/soundtouch EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/wil EXCLUDE_FROM_ALL)
@@ -144,9 +143,6 @@ else()
endif()
endif()
- if(PORTAUDIO_API)
- check_lib(PORTAUDIO portaudio portaudio.h pa_linux_alsa.h)
- endif()
check_lib(SOUNDTOUCH SoundTouch SoundTouch.h PATH_SUFFIXES soundtouch)
check_lib(SAMPLERATE samplerate samplerate.h)
diff --git a/pcsx2/CMakeLists.txt b/pcsx2/CMakeLists.txt
index 2d52c4bcb0..337f0cf11f 100644
--- a/pcsx2/CMakeLists.txt
+++ b/pcsx2/CMakeLists.txt
@@ -51,11 +51,6 @@ elseif("${PGO}" STREQUAL "use")
target_compile_options(PCSX2_FLAGS INTERFACE -fprofile-use)
endif()
-if(TARGET PkgConfig::PORTAUDIO)
- target_compile_definitions(PCSX2_FLAGS INTERFACE SPU2X_PORTAUDIO)
- target_link_libraries(PCSX2_FLAGS INTERFACE PkgConfig::PORTAUDIO)
-endif()
-
if(TARGET PulseAudio::PulseAudio)
target_compile_definitions(PCSX2_FLAGS INTERFACE SPU2X_PULSEAUDIO)
target_link_libraries(PCSX2_FLAGS INTERFACE PulseAudio::PulseAudio)
@@ -293,17 +288,12 @@ set(pcsx2SPU2Sources
SPU2/RegTable.cpp
SPU2/Reverb.cpp
SPU2/SndOut.cpp
- SPU2/SndOut_SDL.cpp
SPU2/spu2freeze.cpp
SPU2/spu2sys.cpp
SPU2/Timestretcher.cpp
SPU2/Wavedump_wav.cpp
)
-if(TARGET PkgConfig::PORTAUDIO)
- list(APPEND pcsx2SPU2Sources SPU2/SndOut_Portaudio.cpp)
-endif()
-
if(CUBEB_API)
list(APPEND pcsx2SPU2Sources SPU2/SndOut_Cubeb.cpp)
target_compile_definitions(PCSX2_FLAGS INTERFACE "SPU2X_CUBEB")
diff --git a/pcsx2/SPU2/Linux/Config.cpp b/pcsx2/SPU2/Linux/Config.cpp
index 9b149e9492..4784d059a8 100644
--- a/pcsx2/SPU2/Linux/Config.cpp
+++ b/pcsx2/SPU2/Linux/Config.cpp
@@ -64,10 +64,6 @@ bool _visual_debug_enabled = false; // Windows-only feature
u32 OutputModule = 0;
int SndOutLatencyMS = 100;
int SynchMode = 0; // Time Stretch, Async or Disabled.
-#ifdef SPU2X_PORTAUDIO
-u32 OutputAPI = 0;
-#endif
-u32 SdlOutputAPI = 0;
int numSpeakers = 0;
int dplLevel = 0;
@@ -105,54 +101,20 @@ void ReadSettings()
VolumeAdjustSR = powf(10, VolumeAdjustSRdb / 10);
VolumeAdjustLFE = powf(10, VolumeAdjustLFEdb / 10);
+#ifdef SPU2X_CUBEB
+ const SndOutModule* const defaultModule = CubebOut;
+#else
+ const SndOutModule* const defaultModule = NullOut;
+#endif
+
wxString temp;
-
-#if SDL_MAJOR_VERSION >= 2 || !defined(SPU2X_PORTAUDIO)
- CfgReadStr(L"OUTPUT", L"Output_Module", temp, SDLOut->GetIdent());
-#else
- CfgReadStr(L"OUTPUT", L"Output_Module", temp, PortaudioOut->GetIdent());
-#endif
+ CfgReadStr(L"OUTPUT", L"Output_Module", temp, defaultModule->GetIdent());
OutputModule = FindOutputModuleById(temp.c_str()); // Find the driver index of this module...
-// Find current API.
-#ifdef SPU2X_PORTAUDIO
-#ifdef __linux__
- CfgReadStr(L"PORTAUDIO", L"HostApi", temp, L"ALSA");
- if (temp == L"OSS")
- OutputAPI = 1;
- else if (temp == L"JACK")
- OutputAPI = 2;
- else // L"ALSA"
- OutputAPI = 0;
-#else
- CfgReadStr(L"PORTAUDIO", L"HostApi", temp, L"OSS");
- OutputAPI = 0; // L"OSS"
-#endif
-#endif
-
-#if defined(__unix__) || defined(__APPLE__)
- CfgReadStr(L"SDL", L"HostApi", temp, L"pulseaudio");
- SdlOutputAPI = 0;
-#if SDL_MAJOR_VERSION >= 2
- // Yes, it sucks ...
- for (int i = 0; i < SDL_GetNumAudioDrivers(); ++i)
- {
- if (!temp.Cmp(wxString(SDL_GetAudioDriver(i), wxConvUTF8)))
- SdlOutputAPI = i;
- }
-#endif
-#endif
-
SndOutLatencyMS = CfgReadInt(L"OUTPUT", L"Latency", 100);
SynchMode = CfgReadInt(L"OUTPUT", L"Synch_Mode", 0);
numSpeakers = CfgReadInt(L"OUTPUT", L"SpeakerConfiguration", 0);
-#ifdef SPU2X_PORTAUDIO
- PortaudioOut->ReadSettings();
-#endif
-#if defined(__unix__) || defined(__APPLE__)
- SDLOut->ReadSettings();
-#endif
SoundtouchCfg::ReadSettings();
DebugConfig::ReadSettings();
@@ -164,8 +126,8 @@ void ReadSettings()
if (mods[OutputModule] == nullptr)
{
Console.Warning("* SPU2: Unknown output module '%s' specified in configuration file.", temp.wc_str());
- Console.Warning("* SPU2: Defaulting to SDL (%s).", SDLOut->GetIdent());
- OutputModule = FindOutputModuleById(SDLOut->GetIdent());
+ Console.Warning("* SPU2: Defaulting to %s (%s).", defaultModule->GetLongName(), defaultModule->GetIdent());
+ OutputModule = FindOutputModuleById(defaultModule->GetIdent());
}
WriteSettings();
@@ -200,12 +162,6 @@ void WriteSettings()
CfgWriteInt(L"OUTPUT", L"Synch_Mode", SynchMode);
CfgWriteInt(L"OUTPUT", L"SpeakerConfiguration", numSpeakers);
-#ifdef SPU2X_PORTAUDIO
- PortaudioOut->WriteSettings();
-#endif
-#if defined(__unix__) || defined(__APPLE__)
- SDLOut->WriteSettings();
-#endif
SoundtouchCfg::WriteSettings();
DebugConfig::WriteSettings();
}
diff --git a/pcsx2/SPU2/Linux/Config.h b/pcsx2/SPU2/Linux/Config.h
index aa080fc9cd..3bac2dcd7d 100644
--- a/pcsx2/SPU2/Linux/Config.h
+++ b/pcsx2/SPU2/Linux/Config.h
@@ -78,11 +78,6 @@ extern int dspPluginModule;
extern bool dspPluginEnabled;
extern int SynchMode;
-#ifdef SPU2X_PORTAUDIO
-extern u32 OutputAPI;
-#endif
-extern u32 SdlOutputAPI;
-
#ifdef PCSX2_DEVBUILD
const int LATENCY_MAX = 3000;
#else
diff --git a/pcsx2/SPU2/SndOut.cpp b/pcsx2/SPU2/SndOut.cpp
index e92615d68b..de76481c86 100644
--- a/pcsx2/SPU2/SndOut.cpp
+++ b/pcsx2/SPU2/SndOut.cpp
@@ -49,50 +49,47 @@ StereoOut32 StereoOut16::UpSample() const
class NullOutModule : public SndOutModule
{
public:
- s32 Init() { return 0; }
- void Close() {}
- s32 Test() const { return 0; }
- void Configure(uptr parent) {}
- int GetEmptySampleCount() { return 0; }
+ s32 Init() override { return 0; }
+ void Close() override {}
+ s32 Test() const override { return 0; }
+ void Configure(uptr parent) override {}
+ int GetEmptySampleCount() override { return 0; }
- const wchar_t* GetIdent() const
+ const wchar_t* GetIdent() const override
{
return L"nullout";
}
- const wchar_t* GetLongName() const
+ const wchar_t* GetLongName() const override
{
return L"No Sound (Emulate SPU2 only)";
}
- void ReadSettings()
+ void ReadSettings() override
{
}
- void SetApiSettings(wxString api)
+ void SetApiSettings(wxString api) override
{
}
- void WriteSettings() const
+ void WriteSettings() const override
{
}
-} NullOut;
+};
+
+static NullOutModule s_NullOut;
+SndOutModule* NullOut = &s_NullOut;
SndOutModule* mods[] =
{
- &NullOut,
-#ifdef _MSC_VER
+ NullOut,
+#ifdef _WIN32
XAudio2Out,
#endif
-#if defined(SPU2X_PORTAUDIO)
- PortaudioOut,
-#endif
#if defined(SPU2X_CUBEB)
CubebOut,
-#endif
-#if defined(__linux__) || defined(__APPLE__)
- SDLOut,
#endif
nullptr // signals the end of our list
};
@@ -169,7 +166,7 @@ void SndBuffer::_InitFail()
{
// If a failure occurs, just initialize the NoSound driver. This'll allow
// the game to emulate properly (hopefully), albeit without sound.
- OutputModule = FindOutputModuleById(NullOut.GetIdent());
+ OutputModule = FindOutputModuleById(NullOut->GetIdent());
mods[OutputModule]->Init();
}
@@ -447,7 +444,7 @@ void SndBuffer::Write(const StereoOut32& Sample)
if (WavRecordEnabled)
RecordWrite(Sample.DownSample());
- if (mods[OutputModule] == &NullOut) // null output doesn't need buffering or stretching! :p
+ if (mods[OutputModule] == NullOut) // null output doesn't need buffering or stretching! :p
return;
sndTempBuffer[sndTempProgress++] = Sample;
@@ -464,7 +461,7 @@ void SndBuffer::Write(const StereoOut32& Sample)
// Play silence
std::fill_n(sndTempBuffer, SndOutPacketSize, StereoOut32{});
}
-#ifndef __POSIX__
+#if defined(_WIN32) && !defined(PCSX2_CORE)
if (dspPluginEnabled)
{
// Convert in, send to winamp DSP, and convert out.
diff --git a/pcsx2/SPU2/SndOut.h b/pcsx2/SPU2/SndOut.h
index 66066b0e14..09377b765e 100644
--- a/pcsx2/SPU2/SndOut.h
+++ b/pcsx2/SPU2/SndOut.h
@@ -663,17 +663,13 @@ public:
virtual int GetEmptySampleCount() = 0;
};
-#ifdef _MSC_VER
-//internal
+extern SndOutModule* NullOut;
+#ifdef _WIN32
extern SndOutModule* XAudio2Out;
#endif
-#if defined(SPU2X_PORTAUDIO)
-extern SndOutModule* PortaudioOut;
-#endif
#if defined(SPU2X_CUBEB)
extern SndOutModule* CubebOut;
#endif
-extern SndOutModule* const SDLOut;
extern SndOutModule* mods[];
// =====================================================================================================
diff --git a/pcsx2/SPU2/SndOut_Portaudio.cpp b/pcsx2/SPU2/SndOut_Portaudio.cpp
deleted file mode 100644
index fb4ef75e61..0000000000
--- a/pcsx2/SPU2/SndOut_Portaudio.cpp
+++ /dev/null
@@ -1,757 +0,0 @@
-/* PCSX2 - PS2 Emulator for PCs
- * Copyright (C) 2002-2021 PCSX2 Dev Team
- *
- * PCSX2 is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Lesser General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with PCSX2.
- * If not, see .
- */
-
-#include "PrecompiledHeader.h"
-//#include "Mixer.h"
-#include "Global.h"
-#include "SndOut.h"
-
-#define _WIN32_DCOM
-#ifdef _WIN32
-#include
-#include "Windows/Dialogs.h"
-#elif defined(__linux__) || defined(__APPLE__)
-#include "portaudio.h"
-#include "Linux/Dialogs.h"
-#endif
-
-
-
-#include "wchar.h"
-
-#include
-
-#ifdef _WIN32
-#include
-#endif
-#include "Debug.h"
-
-int PaCallback(const void* inputBuffer, void* outputBuffer,
- unsigned long framesPerBuffer,
- const PaStreamCallbackTimeInfo* timeInfo,
- PaStreamCallbackFlags statusFlags,
- void* userData);
-
-class Portaudio : public SndOutModule
-{
-private:
- //////////////////////////////////////////////////////////////////////////////////////////
- // Configuration Vars (unused still)
-
- int m_ApiId;
- wxString m_Device;
-
- bool m_UseHardware;
-
- bool m_WasapiExclusiveMode;
-
- bool m_SuggestedLatencyMinimal;
- int m_SuggestedLatencyMS;
-
- //////////////////////////////////////////////////////////////////////////////////////////
- // Instance vars
-
- int writtenSoFar;
- int writtenLastTime;
- int availableLastTime;
-
- int actualUsedChannels;
-
- bool started;
- PaStream* stream;
-
- //////////////////////////////////////////////////////////////////////////////////////////
- // Stuff necessary for speaker expansion
- class SampleReader
- {
- public:
- virtual int ReadSamples(const void* inputBuffer, void* outputBuffer,
- unsigned long framesPerBuffer,
- const PaStreamCallbackTimeInfo* timeInfo,
- PaStreamCallbackFlags statusFlags,
- void* userData) = 0;
- };
-
- template
- class ConvertedSampleReader : public SampleReader
- {
- int* written;
-
- public:
- ConvertedSampleReader(int* pWritten)
- {
- written = pWritten;
- }
-
- virtual int ReadSamples(const void* inputBuffer, void* outputBuffer,
- unsigned long framesPerBuffer,
- const PaStreamCallbackTimeInfo* timeInfo,
- PaStreamCallbackFlags statusFlags,
- void* userData)
- {
- T* p1 = (T*)outputBuffer;
-
- int packets = framesPerBuffer / SndOutPacketSize;
-
- for (int p = 0; p < packets; p++, p1 += SndOutPacketSize)
- SndBuffer::ReadSamples(p1);
-
- (*written) += packets * SndOutPacketSize;
-
- return 0;
- }
- };
-
-public:
- SampleReader* ActualPaCallback;
-
- Portaudio()
- {
- m_SuggestedLatencyMinimal = true;
- m_UseHardware = false;
- m_WasapiExclusiveMode = false;
- started = false;
- stream = nullptr;
- ActualPaCallback = nullptr;
- m_ApiId = -1;
- m_SuggestedLatencyMS = 20;
- actualUsedChannels = 0;
- writtenSoFar = 0;
- writtenLastTime = 0;
- availableLastTime = 0;
- }
-
- s32 Init()
- {
- started = false;
- stream = nullptr;
-
- ReadSettings();
-
- PaError err = Pa_Initialize();
- if (err != paNoError)
- {
- fprintf(stderr, "* SPU2: PortAudio error: %s\n", Pa_GetErrorText(err));
- return -1;
- }
- started = true;
-
- int deviceIndex = -1;
-
- fprintf(stderr, "* SPU2: Enumerating PortAudio devices:\n");
- for (int i = 0, j = 0; i < Pa_GetDeviceCount(); i++)
- {
- const PaDeviceInfo* info = Pa_GetDeviceInfo(i);
-
- if (info->maxOutputChannels > 0)
- {
- const PaHostApiInfo* apiinfo = Pa_GetHostApiInfo(info->hostApi);
-
- fprintf(stderr, " *** Device %d: '%s' (%s)", j, info->name, apiinfo->name);
-
- if (apiinfo->type == m_ApiId)
- {
- if (m_Device == wxString::FromUTF8(info->name))
- {
- deviceIndex = i;
- fprintf(stderr, " (selected)");
- }
- }
- fprintf(stderr, "\n");
-
- j++;
- }
- }
- fflush(stderr);
-
- if (deviceIndex < 0 && m_ApiId >= 0)
- {
- for (int i = 0; i < Pa_GetHostApiCount(); i++)
- {
- const PaHostApiInfo* apiinfo = Pa_GetHostApiInfo(i);
- if (apiinfo->type == m_ApiId)
- {
- deviceIndex = apiinfo->defaultOutputDevice;
- }
- }
- }
-
- if (deviceIndex >= 0)
- {
- void* infoPtr = nullptr;
-
- const PaDeviceInfo* devinfo = Pa_GetDeviceInfo(deviceIndex);
-
- int speakers;
- switch (numSpeakers) // speakers = (numSpeakers + 1) *2; ?
- {
- case 0:
- speakers = 2;
- break; // Stereo
- case 1:
- speakers = 4;
- break; // Quadrafonic
- case 2:
- speakers = 6;
- break; // Surround 5.1
- case 3:
- speakers = 8;
- break; // Surround 7.1
- default:
- speakers = 2;
- }
- actualUsedChannels = std::min(speakers, devinfo->maxOutputChannels);
-
- switch (actualUsedChannels)
- {
- case 2:
- ConLog("* SPU2 > Using normal 2 speaker stereo output.\n");
- ActualPaCallback = new ConvertedSampleReader(&writtenSoFar);
- break;
-
- case 3:
- ConLog("* SPU2 > 2.1 speaker expansion enabled.\n");
- ActualPaCallback = new ConvertedSampleReader(&writtenSoFar);
- break;
-
- case 4:
- ConLog("* SPU2 > 4 speaker expansion enabled [quadraphenia]\n");
- ActualPaCallback = new ConvertedSampleReader(&writtenSoFar);
- break;
-
- case 5:
- ConLog("* SPU2 > 4.1 speaker expansion enabled.\n");
- ActualPaCallback = new ConvertedSampleReader(&writtenSoFar);
- break;
-
- case 6:
- case 7:
- switch (dplLevel)
- {
- case 0:
- ConLog("* SPU2 > 5.1 speaker expansion enabled.\n");
- ActualPaCallback = new ConvertedSampleReader(&writtenSoFar); //"normal" stereo upmix
- break;
- case 1:
- ConLog("* SPU2 > 5.1 speaker expansion with basic ProLogic dematrixing enabled.\n");
- ActualPaCallback = new ConvertedSampleReader(&writtenSoFar); // basic Dpl decoder without rear stereo balancing
- break;
- case 2:
- ConLog("* SPU2 > 5.1 speaker expansion with experimental ProLogicII dematrixing enabled.\n");
- ActualPaCallback = new ConvertedSampleReader(&writtenSoFar); //gigas PLII
- break;
- }
- actualUsedChannels = 6; // we do not support 7.0 or 6.2 configurations, downgrade to 5.1
- break;
-
- default: // anything 8 or more gets the 7.1 treatment!
- ConLog("* SPU2 > 7.1 speaker expansion enabled.\n");
- ActualPaCallback = new ConvertedSampleReader(&writtenSoFar);
- actualUsedChannels = 8; // we do not support 7.2 or more, downgrade to 7.1
- break;
- }
-
-#ifdef _WIN32
- PaWasapiStreamInfo info = {
- sizeof(PaWasapiStreamInfo),
- paWASAPI,
- 1,
- paWinWasapiExclusive};
-
- if ((m_ApiId == paWASAPI) && m_WasapiExclusiveMode)
- {
- // Pass it the Exclusive mode enable flag
- infoPtr = &info;
- }
-#endif
-
- PaStreamParameters outParams = {
-
- // PaDeviceIndex device;
- // int channelCount;
- // PaSampleFormat sampleFormat;
- // PaTime suggestedLatency;
- // void *hostApiSpecificStreamInfo;
- deviceIndex,
- actualUsedChannels,
- paInt32,
- m_SuggestedLatencyMinimal ? (SndOutPacketSize / (float)SampleRate) : (m_SuggestedLatencyMS / 1000.0f),
- infoPtr};
-
- err = Pa_OpenStream(&stream,
- nullptr, &outParams, SampleRate,
- SndOutPacketSize,
- paNoFlag,
- PaCallback,
-
- nullptr);
-
- if (err == paInvalidSampleRate && SampleRate == 48000)
- {
- DevCon.Warning("Failed to create device at 48khz, trying 96khz");
- SampleRate = 96000;
- err = Pa_OpenStream(&stream,
- nullptr, &outParams, SampleRate,
- SndOutPacketSize,
- paNoFlag,
- PaCallback,
-
- nullptr);
- }
-
- if (err == paInvalidSampleRate && SampleRate == 96000) // It didn't work, so lets just put the samplerate back
- SampleRate = 48000;
- }
- else
- {
- err = Pa_OpenDefaultStream(&stream,
- 0, actualUsedChannels, paInt32, 48000,
- SndOutPacketSize,
- PaCallback,
- nullptr);
- }
- if (err != paNoError)
- {
- if (err == paInvalidSampleRate)
- Console.Warning("Failed to create Port Audio Device %dkhz, Please use Exclusive Mode", SampleRate / 1000);
- fprintf(stderr, "* SPU2: PortAudio error: %s\n", Pa_GetErrorText(err));
- Pa_Terminate();
- return -1;
- }
-
- err = Pa_StartStream(stream);
- if (err != paNoError)
- {
- fprintf(stderr, "* SPU2: PortAudio error: %s\n", Pa_GetErrorText(err));
- Pa_CloseStream(stream);
- stream = nullptr;
- Pa_Terminate();
- return -1;
- }
-
- return 0;
- }
-
- void Close()
- {
- PaError err;
- if (started)
- {
- if (stream)
- {
- if (Pa_IsStreamActive(stream))
- {
- err = Pa_StopStream(stream);
- if (err != paNoError)
- fprintf(stderr, "* SPU2: PortAudio error: %s\n", Pa_GetErrorText(err));
- }
-
- err = Pa_CloseStream(stream);
- if (err != paNoError)
- fprintf(stderr, "* SPU2: PortAudio error: %s\n", Pa_GetErrorText(err));
-
- stream = nullptr;
- }
-
- PaError err = Pa_Terminate();
- if( err != paNoError )
- fprintf(stderr,"* SPU2: PortAudio error: %s\n", Pa_GetErrorText( err ) );
-
- started = false;
- }
- }
-
-////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////
-#ifdef _WIN32
-private:
- bool _ConfigProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- int wmId, wmEvent;
- int tSel = 0;
-
- switch (uMsg)
- {
- case WM_INITDIALOG:
- {
- wchar_t temp[128];
-
- SendMessage(GetDlgItem(hWnd, IDC_PA_DEVICE), CB_RESETCONTENT, 0, 0);
- SendMessageA(GetDlgItem(hWnd, IDC_PA_DEVICE), CB_ADDSTRING, 0, (LPARAM) "Default Device");
- SendMessage(GetDlgItem(hWnd, IDC_PA_DEVICE), CB_SETCURSEL, 0, 0);
-
- SendMessage(GetDlgItem(hWnd, IDC_PA_HOSTAPI), CB_RESETCONTENT, 0, 0);
- SendMessageA(GetDlgItem(hWnd, IDC_PA_HOSTAPI), CB_ADDSTRING, 0, (LPARAM) "Unspecified");
- int idx = 0;
- for (int i = 0; i < Pa_GetHostApiCount(); i++)
- {
- const PaHostApiInfo* apiinfo = Pa_GetHostApiInfo(i);
- if (apiinfo->deviceCount > 0)
- {
- SendMessageA(GetDlgItem(hWnd, IDC_PA_HOSTAPI), CB_ADDSTRING, 0, (LPARAM)apiinfo->name);
- SendMessageA(GetDlgItem(hWnd, IDC_PA_HOSTAPI), CB_SETITEMDATA, i + 1, apiinfo->type);
- }
- if (apiinfo->type == m_ApiId)
- {
- idx = i + 1;
- }
- }
- SendMessage(GetDlgItem(hWnd, IDC_PA_HOSTAPI), CB_SETCURSEL, idx, 0);
-
- if (idx > 0)
- {
- int api_idx = idx - 1;
- SendMessage(GetDlgItem(hWnd, IDC_PA_DEVICE), CB_RESETCONTENT, 0, 0);
- SendMessageA(GetDlgItem(hWnd, IDC_PA_DEVICE), CB_ADDSTRING, 0, (LPARAM) "Default Device");
- SendMessage(GetDlgItem(hWnd, IDC_PA_DEVICE), CB_SETITEMDATA, 0, 0);
- int _idx = 0;
- int i = 1;
- for (int j = 0; j < Pa_GetDeviceCount(); j++)
- {
- const PaDeviceInfo* info = Pa_GetDeviceInfo(j);
- if (info->hostApi == api_idx && info->maxOutputChannels > 0)
- {
- SendMessage(GetDlgItem(hWnd, IDC_PA_DEVICE), CB_ADDSTRING, 0, (LPARAM)wxString::FromUTF8(info->name).wc_str());
- SendMessage(GetDlgItem(hWnd, IDC_PA_DEVICE), CB_SETITEMDATA, i, (LPARAM)info);
- if (wxString::FromUTF8(info->name) == m_Device)
- {
- _idx = i;
- }
- i++;
- }
- }
- SendMessage(GetDlgItem(hWnd, IDC_PA_DEVICE), CB_SETCURSEL, _idx, 0);
- }
-
- INIT_SLIDER(IDC_LATENCY, 10, 200, 10, 1, 1);
- SendMessage(GetDlgItem(hWnd, IDC_LATENCY), TBM_SETPOS, TRUE, m_SuggestedLatencyMS);
- swprintf_s(temp, L"%d ms", m_SuggestedLatencyMS);
- SetWindowText(GetDlgItem(hWnd, IDC_LATENCY_LABEL), temp);
-
- if (m_SuggestedLatencyMinimal)
- SET_CHECK(IDC_MINIMIZE, true);
- else
- SET_CHECK(IDC_MANUAL, true);
-
- SET_CHECK(IDC_EXCLUSIVE, m_WasapiExclusiveMode);
- }
- break;
-
- case WM_COMMAND:
- {
- //wchar_t temp[128];
-
- wmId = LOWORD(wParam);
- wmEvent = HIWORD(wParam);
- // Parse the menu selections:
- switch (wmId)
- {
- case IDOK:
- {
- int idx = (int)SendMessage(GetDlgItem(hWnd, IDC_PA_HOSTAPI), CB_GETCURSEL, 0, 0);
- m_ApiId = SendMessage(GetDlgItem(hWnd, IDC_PA_HOSTAPI), CB_GETITEMDATA, idx, 0);
-
- idx = (int)SendMessage(GetDlgItem(hWnd, IDC_PA_DEVICE), CB_GETCURSEL, 0, 0);
- const PaDeviceInfo* info = (const PaDeviceInfo*)SendMessage(GetDlgItem(hWnd, IDC_PA_DEVICE), CB_GETITEMDATA, idx, 0);
- if (info)
- m_Device = wxString::FromUTF8(info->name);
- else
- m_Device = L"default";
-
- m_SuggestedLatencyMS = (int)SendMessage(GetDlgItem(hWnd, IDC_LATENCY), TBM_GETPOS, 0, 0);
-
- if (m_SuggestedLatencyMS < 10)
- m_SuggestedLatencyMS = 10;
- if (m_SuggestedLatencyMS > 200)
- m_SuggestedLatencyMS = 200;
-
- m_SuggestedLatencyMinimal = SendMessage(GetDlgItem(hWnd, IDC_MINIMIZE), BM_GETCHECK, 0, 0) == BST_CHECKED;
-
- m_WasapiExclusiveMode = SendMessage(GetDlgItem(hWnd, IDC_EXCLUSIVE), BM_GETCHECK, 0, 0) == BST_CHECKED;
-
- EndDialog(hWnd, 0);
- }
- break;
-
- case IDCANCEL:
- EndDialog(hWnd, 0);
- break;
-
- case IDC_PA_HOSTAPI:
- {
- if (wmEvent == CBN_SELCHANGE)
- {
- int api_idx = (int)SendMessage(GetDlgItem(hWnd, IDC_PA_HOSTAPI), CB_GETCURSEL, 0, 0) - 1;
- int apiId = SendMessageA(GetDlgItem(hWnd, IDC_PA_HOSTAPI), CB_GETITEMDATA, api_idx, 0);
- SendMessage(GetDlgItem(hWnd, IDC_PA_DEVICE), CB_RESETCONTENT, 0, 0);
- SendMessageA(GetDlgItem(hWnd, IDC_PA_DEVICE), CB_ADDSTRING, 0, (LPARAM) "Default Device");
- SendMessage(GetDlgItem(hWnd, IDC_PA_DEVICE), CB_SETITEMDATA, 0, 0);
- int idx = 0;
- int i = 1;
- for (int j = 0; j < Pa_GetDeviceCount(); j++)
- {
- const PaDeviceInfo* info = Pa_GetDeviceInfo(j);
- if (info->hostApi == api_idx && info->maxOutputChannels > 0)
- {
- SendMessage(GetDlgItem(hWnd, IDC_PA_DEVICE), CB_ADDSTRING, 0, (LPARAM)wxString::FromUTF8(info->name).wc_str());
- SendMessage(GetDlgItem(hWnd, IDC_PA_DEVICE), CB_SETITEMDATA, i, (LPARAM)info);
- i++;
- }
- }
- SendMessage(GetDlgItem(hWnd, IDC_PA_DEVICE), CB_SETCURSEL, idx, 0);
- }
- }
- break;
-
- default:
- return FALSE;
- }
- }
- break;
-
- case WM_HSCROLL:
- {
- wmId = LOWORD(wParam);
- wmEvent = HIWORD(wParam);
- switch (wmId)
- {
- case TB_LINEUP:
- case TB_LINEDOWN:
- case TB_PAGEUP:
- case TB_PAGEDOWN:
- case TB_TOP:
- case TB_BOTTOM:
- wmEvent = (int)SendMessage((HWND)lParam, TBM_GETPOS, 0, 0);
- case TB_THUMBPOSITION:
- case TB_THUMBTRACK:
- {
- wchar_t temp[128];
- if (wmEvent < 10)
- wmEvent = 10;
- if (wmEvent > 200)
- wmEvent = 200;
- SendMessage((HWND)lParam, TBM_SETPOS, TRUE, wmEvent);
- swprintf_s(temp, L"%d ms", wmEvent);
- SetWindowText(GetDlgItem(hWnd, IDC_LATENCY_LABEL), temp);
- break;
- }
- default:
- return FALSE;
- }
- }
- break;
-
- default:
- return FALSE;
- }
- return TRUE;
- }
-
- static BOOL CALLBACK ConfigProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- static BOOL CALLBACK DSEnumCallback(LPGUID lpGuid, LPCTSTR lpcstrDescription, LPCTSTR lpcstrModule, LPVOID lpContext);
-
-public:
- virtual void Configure(uptr parent)
- {
- PaError err = Pa_Initialize(); // Initialization can be done multiple times, PA keeps a counter
- if (err != paNoError)
- {
- fprintf(stderr, "* SPU2: PortAudio error: %s\n", Pa_GetErrorText(err));
- return;
- }
- // keep portaudio initialized until the dialog closes
-
- INT_PTR ret;
- ret = DialogBoxParam(nullptr, MAKEINTRESOURCE(IDD_PORTAUDIO), (HWND)parent, (DLGPROC)ConfigProc, 1);
- if (ret == -1)
- {
- MessageBox((HWND)parent, L"Error Opening the config dialog.", L"OMG ERROR!", MB_OK | MB_SETFOREGROUND);
- return;
- }
-
- Pa_Terminate();
- }
-#else
- virtual void Configure(uptr parent)
- {
- }
-#endif
-
- s32 Test() const
- {
- return 0;
- }
-
- int GetEmptySampleCount()
- {
- long availableNow = Pa_GetStreamWriteAvailable(stream);
-
- int playedSinceLastTime = (writtenSoFar - writtenLastTime) + (availableNow - availableLastTime);
- writtenLastTime = writtenSoFar;
- availableLastTime = availableNow;
-
- // Lowest resolution here is the SndOutPacketSize we use.
- return playedSinceLastTime;
- }
-
- const wchar_t* GetIdent() const
- {
- return L"portaudio";
- }
-
- const wchar_t* GetLongName() const
- {
- return L"PortAudio (Cross-platform)";
- }
-
- void ReadSettings()
- {
- wxString api(L"EMPTYEMPTYEMPTY");
- m_Device = L"EMPTYEMPTYEMPTY";
-#ifdef __linux__
- // By default on linux use the ALSA API (+99% users) -- Gregory
- CfgReadStr(L"PORTAUDIO", L"HostApi", api, L"ALSA");
-#elif defined(__APPLE__)
- // Suppose OSX only has CoreAudio...
- CfgReadStr(L"PORTAUDIO", L"HostApi", api, L"CoreAudio");
-#else
- CfgReadStr(L"PORTAUDIO", L"HostApi", api, L"WASAPI");
-#endif
- CfgReadStr(L"PORTAUDIO", L"Device", m_Device, L"default");
-
- SetApiSettings(api);
-
- m_WasapiExclusiveMode = CfgReadBool(L"PORTAUDIO", L"Wasapi_Exclusive_Mode", false);
- m_SuggestedLatencyMinimal = CfgReadBool(L"PORTAUDIO", L"Minimal_Suggested_Latency", true);
- m_SuggestedLatencyMS = CfgReadInt(L"PORTAUDIO", L"Manual_Suggested_Latency_MS", 20);
-
- if (m_SuggestedLatencyMS < 10)
- m_SuggestedLatencyMS = 10;
- if (m_SuggestedLatencyMS > 200)
- m_SuggestedLatencyMS = 200;
- }
-
- void SetApiSettings(wxString api)
- {
- m_ApiId = -1;
- if (api == L"InDevelopment")
- m_ApiId = paInDevelopment; /* use while developing support for a new host API */
- if (api == L"DirectSound")
- m_ApiId = paDirectSound;
- if (api == L"MME")
- m_ApiId = paMME;
- if (api == L"ASIO")
- m_ApiId = paASIO;
- if (api == L"SoundManager")
- m_ApiId = paSoundManager;
- if (api == L"CoreAudio")
- m_ApiId = paCoreAudio;
- if (api == L"OSS")
- m_ApiId = paOSS;
- if (api == L"ALSA")
- m_ApiId = paALSA;
- if (api == L"AL")
- m_ApiId = paAL;
- if (api == L"BeOS")
- m_ApiId = paBeOS;
- if (api == L"WDMKS")
- m_ApiId = paWDMKS;
- if (api == L"JACK")
- m_ApiId = paJACK;
- if (api == L"WASAPI")
- m_ApiId = paWASAPI;
- if (api == L"AudioScienceHPI")
- m_ApiId = paAudioScienceHPI;
- }
-
- void WriteSettings() const
- {
- wxString api;
- switch (m_ApiId)
- {
- case paInDevelopment:
- api = L"InDevelopment";
- break; /* use while developing support for a new host API */
- case paDirectSound:
- api = L"DirectSound";
- break;
- case paMME:
- api = L"MME";
- break;
- case paASIO:
- api = L"ASIO";
- break;
- case paSoundManager:
- api = L"SoundManager";
- break;
- case paCoreAudio:
- api = L"CoreAudio";
- break;
- case paOSS:
- api = L"OSS";
- break;
- case paALSA:
- api = L"ALSA";
- break;
- case paAL:
- api = L"AL";
- break;
- case paBeOS:
- api = L"BeOS";
- break;
- case paWDMKS:
- api = L"WDMKS";
- break;
- case paJACK:
- api = L"JACK";
- break;
- case paWASAPI:
- api = L"WASAPI";
- break;
- case paAudioScienceHPI:
- api = L"AudioScienceHPI";
- break;
- default:
- api = L"Unknown";
- }
-
- CfgWriteStr(L"PORTAUDIO", L"HostApi", api);
- CfgWriteStr(L"PORTAUDIO", L"Device", m_Device);
-
- CfgWriteBool(L"PORTAUDIO", L"Wasapi_Exclusive_Mode", m_WasapiExclusiveMode);
- CfgWriteBool(L"PORTAUDIO", L"Minimal_Suggested_Latency", m_SuggestedLatencyMinimal);
- CfgWriteInt(L"PORTAUDIO", L"Manual_Suggested_Latency_MS", m_SuggestedLatencyMS);
- }
-
-} static PA;
-
-int PaCallback(const void* inputBuffer, void* outputBuffer,
- unsigned long framesPerBuffer,
- const PaStreamCallbackTimeInfo* timeInfo,
- PaStreamCallbackFlags statusFlags,
- void* userData)
-{
- return PA.ActualPaCallback->ReadSamples(inputBuffer, outputBuffer, framesPerBuffer, timeInfo, statusFlags, userData);
-}
-
-#ifdef _WIN32
-BOOL CALLBACK Portaudio::ConfigProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- return PA._ConfigProc(hWnd, uMsg, wParam, lParam);
-}
-#endif
-
-SndOutModule* PortaudioOut = &PA;
diff --git a/pcsx2/SPU2/SndOut_SDL.cpp b/pcsx2/SPU2/SndOut_SDL.cpp
deleted file mode 100644
index 36f1970751..0000000000
--- a/pcsx2/SPU2/SndOut_SDL.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-/* PCSX2 - PS2 Emulator for PCs
- * Copyright (C) 2002-2021 PCSX2 Dev Team
- *
- * PCSX2 is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Lesser General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with PCSX2.
- * If not, see .
- */
-
-#include "PrecompiledHeader.h"
-
-#ifdef SDL_BUILD
-
-#include
-#include
-
-#include "Global.h"
-#include "SndOut.h"
-
-#if defined(_WIN32)
-#include "Windows/Dialogs.h"
-#else // BSD, Macos
-#include "Linux/Dialogs.h"
-#endif
-
-#include
-
-/* Using SDL2 requires other SDL dependencies in pcsx2 get upgraded as well, or the
- * symbol tables would conflict. Other dependencies in Linux are wxwidgets (you can
- * build wx without sdl support, though) and onepad at the time of writing this. */
-#include
-#include
-typedef StereoOut16 StereoOut_SDL;
-
-namespace
-{
- /* Since spu2 only ever outputs stereo, we don't worry about emitting surround sound
- * even though SDL2 supports it */
- const Uint8 channels = 2;
- /* SDL2 supports s32 audio */
- /* Samples should vary from [512,8192] according to SDL spec. Take note this is the desired
- * sample count and SDL may provide otherwise. Pulseaudio will cut this value in half if
- * PA_STREAM_ADJUST_LATENCY is set in the backened, for example. */
- const Uint16 desiredSamples = 2048;
- const Uint16 format = AUDIO_S16SYS;
-
- Uint16 samples = desiredSamples;
-
- void callback_fillBuffer(void* userdata, Uint8* stream, int len)
- {
- StereoOut16* out = (StereoOut16*)stream;
-
- // Length should always be samples in bytes.
- assert(len / sizeof(StereoOut_SDL) == samples);
-
- for (Uint16 i = 0; i < samples; i += SndOutPacketSize)
- SndBuffer::ReadSamples(&out[i]);
- }
-} // namespace
-
-struct SDLAudioMod : public SndOutModule
-{
- static SDLAudioMod mod;
- std::string m_api;
-
- s32 Init()
- {
- ReadSettings();
-
-#if SDL_MAJOR_VERSION >= 2
- std::cerr << "Request SDL audio driver: " << m_api.c_str() << std::endl;
-#endif
-
- /* SDL backends will mangle the AudioSpec and change the sample count. If we reopen
- * the audio backend, we need to make sure we keep our desired samples in the spec */
- spec.samples = desiredSamples;
-
- // Mandatory otherwise, init will be redone in SDL_OpenAudio
- if (SDL_Init(SDL_INIT_AUDIO) < 0)
- {
- std::cerr << "SPU2: SDL INIT audio error: " << SDL_GetError() << std::endl;
- return -1;
- }
-
-#if SDL_MAJOR_VERSION >= 2
- if (m_api.compare("pulseaudio"))
- {
- // Close the audio, but keep the subsystem open
- SDL_AudioQuit();
- // Reopen the audio
- if (SDL_AudioInit(m_api.c_str()) < 0)
- {
- std::cerr << "SPU2: SDL audio init error: " << SDL_GetError() << std::endl;
- return -1;
- }
- }
-#endif
-
- if (SDL_OpenAudio(&spec, nullptr) < 0)
- {
- std::cerr << "SPU2: SDL audio error: " << SDL_GetError() << std::endl;
- return -1;
- }
-
-#if SDL_MAJOR_VERSION >= 2
- std::cerr << "Opened SDL audio driver: " << SDL_GetCurrentAudioDriver() << std::endl;
-#endif
-
- if (samples != spec.samples)
- {
- fprintf(stderr, "SPU2: SDL failed to get desired samples (%d) got %d samples instead\n", samples, spec.samples);
-
- // Samples must always be a multiple of packet size.
- assert(spec.samples % SndOutPacketSize == 0);
- samples = spec.samples;
- }
- SDL_PauseAudio(0);
- return 0;
- }
-
- const wchar_t* GetIdent() const { return L"SDLAudio"; }
- const wchar_t* GetLongName() const { return L"SDL Audio"; }
-
- void Close()
- {
- // Related to SDL_Init(SDL_INIT_AUDIO)
- SDL_QuitSubSystem(SDL_INIT_AUDIO);
- }
-
- ~SDLAudioMod() { Close(); }
-
- s32 Test() const { return 0; }
- int GetEmptySampleCount() { return 0; }
-
- void Configure(uptr parent) {}
-
- void ReadSettings()
- {
- wxString api(L"EMPTYEMPTYEMPTY");
- CfgReadStr(L"SDL", L"HostApi", api, L"pulseaudio");
- SetApiSettings(api);
- }
-
- void WriteSettings() const
- {
- CfgWriteStr(L"SDL", L"HostApi", wxString(m_api.c_str(), wxConvUTF8));
- };
-
- void SetApiSettings(wxString api)
- {
-#if SDL_MAJOR_VERSION >= 2
- // Validate the api name
- bool valid = false;
- std::string api_name = std::string(api.utf8_str());
- for (int i = 0; i < SDL_GetNumAudioDrivers(); ++i)
- {
- valid |= (api_name.compare(SDL_GetAudioDriver(i)) == 0);
- }
- if (valid)
- {
- m_api = api.utf8_str();
- }
- else
- {
- std::cerr << "SDL audio driver configuration is invalid!" << std::endl
- << "It will be replaced by pulseaudio!" << std::endl;
- m_api = "pulseaudio";
- }
-#endif
- }
-
-
-private:
- SDL_AudioSpec spec;
-
- SDLAudioMod()
- : m_api("pulseaudio")
- , spec({SampleRate, format, channels, 0,
- desiredSamples, 0, 0, &callback_fillBuffer, nullptr})
- {
- // Number of samples must be a multiple of packet size.
- assert(samples % SndOutPacketSize == 0);
- }
-};
-
-SDLAudioMod SDLAudioMod::mod;
-
-SndOutModule* const SDLOut = &SDLAudioMod::mod;
-
-#endif // SDL_BUILD
diff --git a/pcsx2/SPU2/Windows/Config.cpp b/pcsx2/SPU2/Windows/Config.cpp
index bf46cb3855..7d4e8bff3e 100644
--- a/pcsx2/SPU2/Windows/Config.cpp
+++ b/pcsx2/SPU2/Windows/Config.cpp
@@ -126,8 +126,6 @@ void ReadSettings()
dspPluginModule = CfgReadInt(L"DSP PLUGIN", L"ModuleNum", 0);
dspPluginEnabled = CfgReadBool(L"DSP PLUGIN", L"Enabled", false);
- PortaudioOut->ReadSettings();
-
SoundtouchCfg::ReadSettings();
DebugConfig::ReadSettings();
@@ -173,7 +171,6 @@ void WriteSettings()
CfgWriteInt(L"DSP PLUGIN", L"ModuleNum", dspPluginModule);
CfgWriteBool(L"DSP PLUGIN", L"Enabled", dspPluginEnabled);
- PortaudioOut->WriteSettings();
SoundtouchCfg::WriteSettings();
DebugConfig::WriteSettings();
}
@@ -181,16 +178,131 @@ void WriteSettings()
void CheckOutputModule(HWND window)
{
OutputModule = SendMessage(GetDlgItem(window, IDC_OUTPUT), CB_GETCURSEL, 0, 0);
- const bool IsConfigurable = mods[OutputModule] == PortaudioOut;
+ const bool IsConfigurable = mods[OutputModule] == CubebOut;
const bool AudioExpansion =
mods[OutputModule] == XAudio2Out ||
- mods[OutputModule] == PortaudioOut;
+ mods[OutputModule] == CubebOut;
EnableWindow(GetDlgItem(window, IDC_OUTCONF), IsConfigurable);
EnableWindow(GetDlgItem(window, IDC_SPEAKERS), AudioExpansion);
EnableWindow(GetDlgItem(window, IDC_SPEAKERS_TEXT), AudioExpansion);
}
+static BOOL CALLBACK CubebConfigProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ static constexpr wchar_t* cubeb_backend_names[][2] = {
+ {L"Unspecified", L""},
+ {L"WASAPI", L"wasapi"},
+ {L"WinMM", L"winmm"}};
+
+ const bool minimalLatency = CfgReadBool(L"Cubeb", L"MinimalSuggestedLatency", false);
+ const int suggestedLatencyMS = CfgReadInt(L"Cubeb", L"ManualSuggestedLatencyMS", 20);
+ wxString backend;
+ CfgReadStr(L"Cubeb", L"BackendName", backend, L"");
+
+ SendMessage(GetDlgItem(hWnd, IDC_BACKEND), CB_RESETCONTENT, 0, 0);
+
+ for (size_t i = 0; i < std::size(cubeb_backend_names); i++)
+ {
+ SendMessageW(GetDlgItem(hWnd, IDC_BACKEND), CB_ADDSTRING, (WPARAM)i, (LPARAM)cubeb_backend_names[i][0]);
+ SendMessageW(GetDlgItem(hWnd, IDC_BACKEND), CB_SETITEMDATA, (WPARAM)i, (LPARAM)cubeb_backend_names[i][1]);
+ if (backend == cubeb_backend_names[i][1])
+ SendMessage(GetDlgItem(hWnd, IDC_BACKEND), CB_SETCURSEL, (WPARAM)i, 0);
+ }
+
+ INIT_SLIDER(IDC_LATENCY, 10, 200, 10, 1, 1);
+ SendMessage(GetDlgItem(hWnd, IDC_LATENCY), TBM_SETPOS, TRUE, suggestedLatencyMS);
+
+ wchar_t temp[128];
+ swprintf_s(temp, L"%d ms", suggestedLatencyMS);
+ SetWindowText(GetDlgItem(hWnd, IDC_LATENCY_LABEL), temp);
+
+ if (minimalLatency)
+ SET_CHECK(IDC_MINIMIZE, true);
+ else
+ SET_CHECK(IDC_MANUAL, true);
+
+ return TRUE;
+ }
+ break;
+
+ case WM_COMMAND:
+ {
+ const DWORD wmId = LOWORD(wParam);
+ const DWORD wmEvent = HIWORD(wParam);
+ // Parse the menu selections:
+ switch (wmId)
+ {
+ case IDOK:
+ {
+ int idx = (int)SendMessage(GetDlgItem(hWnd, IDC_BACKEND), CB_GETCURSEL, 0, 0);
+ const wchar_t* backend = (const wchar_t*)SendMessage(GetDlgItem(hWnd, IDC_BACKEND), CB_GETITEMDATA, idx, 0);
+ CfgWriteStr(L"Cubeb", L"BackendName", backend);
+
+ const int suggestedLatencyMS = (int)SendMessage(GetDlgItem(hWnd, IDC_LATENCY), TBM_GETPOS, 0, 0);
+ const bool minimalLatency = SendMessage(GetDlgItem(hWnd, IDC_MINIMIZE), BM_GETCHECK, 0, 0) == BST_CHECKED;
+ CfgWriteBool(L"Cubeb", L"MinimalSuggestedLatency", minimalLatency);
+ CfgWriteInt(L"Cubeb", L"ManualSuggestedLatencyMS", suggestedLatencyMS);
+
+ EndDialog(hWnd, 0);
+ return TRUE;
+ }
+ break;
+
+ case IDCANCEL:
+ EndDialog(hWnd, 0);
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+ }
+ break;
+
+ case WM_HSCROLL:
+ {
+ const DWORD wmId = LOWORD(wParam);
+ DWORD wmEvent = HIWORD(wParam);
+ switch (wmId)
+ {
+ case TB_LINEUP:
+ case TB_LINEDOWN:
+ case TB_PAGEUP:
+ case TB_PAGEDOWN:
+ case TB_TOP:
+ case TB_BOTTOM:
+ wmEvent = (int)SendMessage((HWND)lParam, TBM_GETPOS, 0, 0);
+ case TB_THUMBPOSITION:
+ case TB_THUMBTRACK:
+ {
+ wchar_t temp[128];
+ if (wmEvent < 10)
+ wmEvent = 10;
+ if (wmEvent > 200)
+ wmEvent = 200;
+ SendMessage((HWND)lParam, TBM_SETPOS, TRUE, wmEvent);
+ swprintf_s(temp, L"%d ms", wmEvent);
+ SetWindowText(GetDlgItem(hWnd, IDC_LATENCY_LABEL), temp);
+ break;
+ }
+ default:
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+ break;
+
+ default:
+ return FALSE;
+ }
+ return FALSE;
+}
+
BOOL CALLBACK ConfigProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
@@ -298,9 +410,11 @@ BOOL CALLBACK ConfigProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case IDC_OUTCONF:
{
const int module = (int)SendMessage(GetDlgItem(hWnd, IDC_OUTPUT), CB_GETCURSEL, 0, 0);
- if (mods[module] == nullptr)
+ if (mods[module] != CubebOut)
break;
- mods[module]->Configure((uptr)hWnd);
+
+ if (DialogBoxParam(nullptr, MAKEINTRESOURCE(IDD_CUBEB), hWnd, (DLGPROC)CubebConfigProc, 1) == -1)
+ MessageBox(hWnd, L"Error Opening the config dialog.", L"Error", MB_OK | MB_SETFOREGROUND);
}
break;
diff --git a/pcsx2/SPU2/Windows/SPU2.rc b/pcsx2/SPU2/Windows/SPU2.rc
index 00e1d2f62f..7354bb94c5 100644
--- a/pcsx2/SPU2/Windows/SPU2.rc
+++ b/pcsx2/SPU2/Windows/SPU2.rc
@@ -7,7 +7,6 @@
//
// Generated from the TEXTINCLUDE 2 resource.
//
-#include "svnrev.h"
#include "common/afxresmw.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
@@ -175,25 +174,22 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
// Dialog
//
-IDD_PORTAUDIO DIALOGEX 0, 0, 316, 166
+IDD_CUBEB DIALOGEX 0, 0, 316, 166
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Portaudio Output Module Settings"
+CAPTION "Cubeb Output Module Settings"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,105,144,50,14
PUSHBUTTON "Cancel",IDCANCEL,161,144,50,14
- COMBOBOX IDC_PA_HOSTAPI,7,17,95,62,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- LTEXT "Host API:",IDC_STATIC,7,7,32,8
- COMBOBOX IDC_PA_DEVICE,108,17,201,62,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- LTEXT "Device Name:",IDC_STATIC,107,7,45,8
+ COMBOBOX IDC_BACKEND,7,17,95,62,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Backend:",IDC_STATIC,7,7,32,8
CONTROL "",IDC_LATENCY,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,96,93,155,10
- LTEXT "NOTE: Depending on the hardware and drivers, the suggested manual latency might not be used, and portaudio will choose the closest possible value.",IDC_STATIC,12,111,286,19
+ LTEXT "NOTE: Depending on the hardware and drivers, the suggested manual latency might not be used, and Cubeb will choose the closest possible value.",IDC_STATIC,12,111,286,19
CTEXT "20ms",IDC_LATENCY_LABEL,264,93,35,11
GROUPBOX "Output Latency",IDC_STATIC,7,57,302,79
CONTROL "Use smallest possible (may cause issues if the actual value is too small)",IDC_MINIMIZE,
"Button",BS_AUTORADIOBUTTON | WS_GROUP,12,75,258,10
CONTROL "Use this latency:",IDC_MANUAL,"Button",BS_AUTORADIOBUTTON,12,93,69,10
- CONTROL "WASAPI Exclusive Mode",IDC_EXCLUSIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,39,93,10
END
@@ -205,7 +201,7 @@ END
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
- IDD_PORTAUDIO, DIALOG
+ IDD_CUBEB, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 309
diff --git a/pcsx2/SPU2/Windows/resource.h b/pcsx2/SPU2/Windows/resource.h
index 8dfb7f66a6..32c75f3c5e 100644
--- a/pcsx2/SPU2/Windows/resource.h
+++ b/pcsx2/SPU2/Windows/resource.h
@@ -5,7 +5,7 @@
#define IDD_DEBUG 105
#define IDD_CONFIG_SOUNDTOUCH 117
#define IDD_CONFIG_DEBUG 118
-#define IDD_PORTAUDIO 119
+#define IDD_CUBEB 119
#define IDC_DUMPREGS 1003
#define IDC_DUMPMEM 1004
#define IDC_DUMPCORE 1005
@@ -27,7 +27,6 @@
#define IDC_OUTCONF 1028
#define IDC_DSP_ENABLE 1029
#define IDC_DS_DEVICE 1032
-#define IDC_PA_DEVICE 1033
#define IDC_DBG_OVERRUNS 1038
#define IDC_DBG_CACHE 1039
#define IDC_LATENCY_SLIDER 1040
@@ -50,9 +49,8 @@
#define IDC_VOLUME_SLIDER 1068
#define IDC_MINIMIZE 1069
#define IDC_MANUAL 1070
-#define IDC_PA_HOSTAPI 1071
+#define IDC_BACKEND 1071
#define IDC_LATENCY 1072
-#define IDC_EXCLUSIVE 1073
// Next default values for new objects
//
diff --git a/pcsx2/SPU2/wx/wxConfig.cpp b/pcsx2/SPU2/wx/wxConfig.cpp
index cedae625ac..6b956ba6d4 100644
--- a/pcsx2/SPU2/wx/wxConfig.cpp
+++ b/pcsx2/SPU2/wx/wxConfig.cpp
@@ -17,10 +17,22 @@
#include "SPU2/Config.h"
#if !defined(_WIN32) // BSD, Macos
#include "SPU2/Linux/Config.h"
+#include "SPU2/Linux/Dialogs.h"
#endif
#include "SPU2/Global.h"
#include "wxConfig.h"
+static const wchar_t* s_backend_names[][2] = {
+ {L"Automatic", L""},
+#ifdef __linux__
+ {L"ALSA", L"alsa"},
+ {L"JACK", L"jack"},
+ {L"PulseAudio", L"pulseaudio"},
+#elif defined(__APPLE__)
+ {L"AudioUnit", L"audiounit"},
+#endif
+};
+
MixerTab::MixerTab(wxWindow* parent)
: wxPanel(parent, wxID_ANY)
{
@@ -352,49 +364,27 @@ Dialog::Dialog()
wxArrayString module_entries;
module_entries.Add("No Sound (Emulate SPU2 only)");
-#ifdef SPU2X_PORTAUDIO
- module_entries.Add("PortAudio (Cross-platform)");
+#ifdef SPU2X_CUBEB
+ module_entries.Add("Cubeb (Cross-platform)");
#endif
- module_entries.Add("SDL Audio (Recommended for PulseAudio)");
m_module_select = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, module_entries);
module_box->Add(m_module_select, wxSizerFlags().Centre());
-#ifdef SPU2X_PORTAUDIO
+#ifdef SPU2X_CUBEB
// Portaudio
- m_portaudio_box = new wxBoxSizer(wxVERTICAL);
- m_portaudio_text = new wxStaticText(this, wxID_ANY, "Portaudio API");
- m_portaudio_box->Add(m_portaudio_text, wxSizerFlags().Centre());
+ m_cubeb_box = new wxBoxSizer(wxVERTICAL);
+ m_cubeb_text = new wxStaticText(this, wxID_ANY, "Backend");
+ m_cubeb_box->Add(m_cubeb_text, wxSizerFlags().Centre());
- wxArrayString portaudio_entries;
-#ifdef __linux__
- portaudio_entries.Add("ALSA (recommended)");
- portaudio_entries.Add("OSS (legacy)");
- portaudio_entries.Add("JACK");
-#elif defined(__APPLE__)
- portaudio_entries.Add("CoreAudio");
-#else
- portaudio_entries.Add("OSS");
-#endif
- m_portaudio_select = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, portaudio_entries);
- m_portaudio_box->Add(m_portaudio_select, wxSizerFlags().Centre());
+ m_cubeb_select = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
+ for (size_t i = 0; i < std::size(s_backend_names); i++)
+ m_cubeb_select->Append(s_backend_names[i][0]);
+ m_cubeb_box->Add(m_cubeb_select, wxSizerFlags().Centre());
#endif
- // SDL
- m_sdl_box = new wxBoxSizer(wxVERTICAL);
- m_sdl_text = new wxStaticText(this, wxID_ANY, "SDL API");
- m_sdl_box->Add(m_sdl_text, wxSizerFlags().Centre());
-
- wxArrayString sdl_entries;
- for (int i = 0; i < SDL_GetNumAudioDrivers(); ++i)
- sdl_entries.Add(SDL_GetAudioDriver(i));
-
- m_sdl_select = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, sdl_entries);
- m_sdl_box->Add(m_sdl_select, wxSizerFlags().Centre());
-
-#ifdef SPU2X_PORTAUDIO
- module_box->Add(m_portaudio_box, wxSizerFlags().Expand());
+#ifdef SPU2X_CUBEB
+ module_box->Add(m_cubeb_box, wxSizerFlags().Expand());
#endif
- module_box->Add(m_sdl_box, wxSizerFlags().Expand());
m_top_box->Add(module_box, wxSizerFlags().Centre().Border(wxALL, 5));
@@ -423,34 +413,25 @@ Dialog::~Dialog()
void Dialog::Reconfigure()
{
const int mod = m_module_select->GetCurrentSelection();
- bool show_portaudio = false, show_sdl = false;
+ bool show_cubeb = false;
switch (mod)
{
case 0:
- show_portaudio = false;
- show_sdl = false;
+ show_cubeb = false;
break;
case 1:
- show_portaudio = true;
- show_sdl = false;
- break;
-
- case 2:
- show_portaudio = false;
- show_sdl = true;
+ show_cubeb = true;
break;
default:
- show_portaudio = false;
- show_sdl = false;
+ show_cubeb = false;
break;
}
-#ifdef SPU2X_PORTAUDIO
- m_top_box->Show(m_portaudio_box, show_portaudio, true);
+#ifdef SPU2X_CUBEB
+ m_top_box->Show(m_cubeb_box, show_cubeb, true);
#endif
- m_top_box->Show(m_sdl_box, show_sdl, true);
// Recalculating both of these accounts for if neither was showing initially.
m_top_box->Layout();
@@ -465,10 +446,18 @@ void Dialog::CallReconfigure(wxCommandEvent& event)
void Dialog::Load()
{
m_module_select->SetSelection(OutputModule);
-#ifdef SPU2X_PORTAUDIO
- m_portaudio_select->SetSelection(OutputAPI);
+#ifdef SPU2X_CUBEB
+ wxString backend;
+ CfgReadStr(L"Cubeb", L"BackendName", backend, L"");
+ for (size_t i = 0; i < std::size(s_backend_names); i++)
+ {
+ if (backend == s_backend_names[i][1])
+ {
+ m_cubeb_select->SetSelection(static_cast(i));
+ break;
+ }
+ }
#endif
- m_sdl_select->SetSelection(SdlOutputAPI);
m_mixer_panel->Load();
m_sync_panel->Load();
@@ -481,19 +470,12 @@ void Dialog::Save()
{
OutputModule = m_module_select->GetSelection();
-#ifdef SPU2X_PORTAUDIO
- OutputAPI = m_portaudio_select->GetSelection();
- wxString p_api(m_portaudio_select->GetStringSelection());
- if (p_api.Find("ALSA") != wxNOT_FOUND)
- p_api = "ALSA";
- if (p_api.Find("OSS") != wxNOT_FOUND)
- p_api = "OSS";
- PortaudioOut->SetApiSettings(p_api);
+#ifdef SPU2X_CUBEB
+ const int backend_selection = m_cubeb_select->GetSelection();
+ if (backend_selection >= 0)
+ CfgWriteStr(L"Cubeb", L"BackendName", s_backend_names[backend_selection][1]);
#endif
- SdlOutputAPI = m_sdl_select->GetSelection();
- SDLOut->SetApiSettings(m_sdl_select->GetStringSelection());
-
m_mixer_panel->Save();
m_sync_panel->Save();
m_debug_panel->Save();
diff --git a/pcsx2/SPU2/wx/wxConfig.h b/pcsx2/SPU2/wx/wxConfig.h
index 5ef3395854..8f25ee02f7 100644
--- a/pcsx2/SPU2/wx/wxConfig.h
+++ b/pcsx2/SPU2/wx/wxConfig.h
@@ -78,9 +78,9 @@ public:
class Dialog : public wxDialog
{
- wxBoxSizer *m_top_box, *m_portaudio_box, *m_sdl_box;
- wxChoice *m_module_select, *m_portaudio_select, *m_sdl_select;
- wxStaticText *m_portaudio_text, *m_sdl_text;
+ wxBoxSizer *m_top_box, *m_cubeb_box;
+ wxChoice *m_module_select, *m_cubeb_select;
+ wxStaticText *m_cubeb_text;
MixerTab* m_mixer_panel;
SyncTab* m_sync_panel;
diff --git a/pcsx2/pcsx2.vcxproj b/pcsx2/pcsx2.vcxproj
index d23f26c5fe..15ac94b0bf 100644
--- a/pcsx2/pcsx2.vcxproj
+++ b/pcsx2/pcsx2.vcxproj
@@ -48,7 +48,7 @@
PrecompiledHeader.h;%(ForcedIncludeFiles)
NoExtensions
/Zc:externConstexpr %(AdditionalOptions)
- WIN32_LEAN_AND_MEAN;LZMA_API_STATIC;BUILD_DX=1;SPU2X_CUBEB;SPU2X_PORTAUDIO;DIRECTINPUT_VERSION=0x0800;%(PreprocessorDefinitions)
+ WIN32_LEAN_AND_MEAN;LZMA_API_STATIC;BUILD_DX=1;SPU2X_CUBEB;DIRECTINPUT_VERSION=0x0800;%(PreprocessorDefinitions)
PCSX2_DEBUG;PCSX2_DEVBUILD;_SECURE_SCL_=1;%(PreprocessorDefinitions)
PCSX2_DEVEL;PCSX2_DEVBUILD;NDEBUG;_SECURE_SCL_=1;%(PreprocessorDefinitions)
NDEBUG;_SECURE_SCL_=0;%(PreprocessorDefinitions)
@@ -359,7 +359,6 @@
-
@@ -1120,9 +1119,6 @@
{47afdbef-f15f-4bc0-b436-5be443c3f80f}
-
- {0a18a071-125e-442f-aff7-a3f68abecf99}
-
{0fae817d-9a32-4830-857e-81da57246e16}
false
diff --git a/pcsx2/pcsx2.vcxproj.filters b/pcsx2/pcsx2.vcxproj.filters
index 96f31e9a9c..b243c92bce 100644
--- a/pcsx2/pcsx2.vcxproj.filters
+++ b/pcsx2/pcsx2.vcxproj.filters
@@ -1133,9 +1133,6 @@
System\Ps2\SPU2
-
- System\Ps2\SPU2
-
System\Ps2\DEV9\ATA\Commands