mirror of https://github.com/PCSX2/pcsx2.git
SPU2: Remove Portaudio and SDL2 output modules
This commit is contained in:
parent
88ce192610
commit
f3d51a242d
|
@ -1,5 +1,5 @@
|
||||||
/* PCSX2 - PS2 Emulator for PCs
|
/* 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
|
* 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-
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||||
|
|
|
@ -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_PCSX2_WRAPPER "Disable including the PCSX2-linux.sh file")
|
||||||
option(DISABLE_SETCAP "Do not set files capabilities")
|
option(DISABLE_SETCAP "Do not set files capabilities")
|
||||||
option(XDG_STD "Use XDG standard path instead of the standard PCSX2 path")
|
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(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)")
|
option(GTK2_API "Use GTK2 api (legacy)")
|
||||||
|
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
|
|
|
@ -12,7 +12,6 @@ if (WIN32)
|
||||||
add_subdirectory(3rdparty/libsamplerate EXCLUDE_FROM_ALL)
|
add_subdirectory(3rdparty/libsamplerate EXCLUDE_FROM_ALL)
|
||||||
add_subdirectory(3rdparty/baseclasses EXCLUDE_FROM_ALL)
|
add_subdirectory(3rdparty/baseclasses EXCLUDE_FROM_ALL)
|
||||||
add_subdirectory(3rdparty/freetype 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/pthreads4w EXCLUDE_FROM_ALL)
|
||||||
add_subdirectory(3rdparty/soundtouch EXCLUDE_FROM_ALL)
|
add_subdirectory(3rdparty/soundtouch EXCLUDE_FROM_ALL)
|
||||||
add_subdirectory(3rdparty/wil EXCLUDE_FROM_ALL)
|
add_subdirectory(3rdparty/wil EXCLUDE_FROM_ALL)
|
||||||
|
@ -144,9 +143,6 @@ else()
|
||||||
endif()
|
endif()
|
||||||
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(SOUNDTOUCH SoundTouch SoundTouch.h PATH_SUFFIXES soundtouch)
|
||||||
check_lib(SAMPLERATE samplerate samplerate.h)
|
check_lib(SAMPLERATE samplerate samplerate.h)
|
||||||
|
|
||||||
|
|
|
@ -51,11 +51,6 @@ elseif("${PGO}" STREQUAL "use")
|
||||||
target_compile_options(PCSX2_FLAGS INTERFACE -fprofile-use)
|
target_compile_options(PCSX2_FLAGS INTERFACE -fprofile-use)
|
||||||
endif()
|
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)
|
if(TARGET PulseAudio::PulseAudio)
|
||||||
target_compile_definitions(PCSX2_FLAGS INTERFACE SPU2X_PULSEAUDIO)
|
target_compile_definitions(PCSX2_FLAGS INTERFACE SPU2X_PULSEAUDIO)
|
||||||
target_link_libraries(PCSX2_FLAGS INTERFACE PulseAudio::PulseAudio)
|
target_link_libraries(PCSX2_FLAGS INTERFACE PulseAudio::PulseAudio)
|
||||||
|
@ -293,17 +288,12 @@ set(pcsx2SPU2Sources
|
||||||
SPU2/RegTable.cpp
|
SPU2/RegTable.cpp
|
||||||
SPU2/Reverb.cpp
|
SPU2/Reverb.cpp
|
||||||
SPU2/SndOut.cpp
|
SPU2/SndOut.cpp
|
||||||
SPU2/SndOut_SDL.cpp
|
|
||||||
SPU2/spu2freeze.cpp
|
SPU2/spu2freeze.cpp
|
||||||
SPU2/spu2sys.cpp
|
SPU2/spu2sys.cpp
|
||||||
SPU2/Timestretcher.cpp
|
SPU2/Timestretcher.cpp
|
||||||
SPU2/Wavedump_wav.cpp
|
SPU2/Wavedump_wav.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(TARGET PkgConfig::PORTAUDIO)
|
|
||||||
list(APPEND pcsx2SPU2Sources SPU2/SndOut_Portaudio.cpp)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CUBEB_API)
|
if(CUBEB_API)
|
||||||
list(APPEND pcsx2SPU2Sources SPU2/SndOut_Cubeb.cpp)
|
list(APPEND pcsx2SPU2Sources SPU2/SndOut_Cubeb.cpp)
|
||||||
target_compile_definitions(PCSX2_FLAGS INTERFACE "SPU2X_CUBEB")
|
target_compile_definitions(PCSX2_FLAGS INTERFACE "SPU2X_CUBEB")
|
||||||
|
|
|
@ -64,10 +64,6 @@ bool _visual_debug_enabled = false; // Windows-only feature
|
||||||
u32 OutputModule = 0;
|
u32 OutputModule = 0;
|
||||||
int SndOutLatencyMS = 100;
|
int SndOutLatencyMS = 100;
|
||||||
int SynchMode = 0; // Time Stretch, Async or Disabled.
|
int SynchMode = 0; // Time Stretch, Async or Disabled.
|
||||||
#ifdef SPU2X_PORTAUDIO
|
|
||||||
u32 OutputAPI = 0;
|
|
||||||
#endif
|
|
||||||
u32 SdlOutputAPI = 0;
|
|
||||||
|
|
||||||
int numSpeakers = 0;
|
int numSpeakers = 0;
|
||||||
int dplLevel = 0;
|
int dplLevel = 0;
|
||||||
|
@ -105,54 +101,20 @@ void ReadSettings()
|
||||||
VolumeAdjustSR = powf(10, VolumeAdjustSRdb / 10);
|
VolumeAdjustSR = powf(10, VolumeAdjustSRdb / 10);
|
||||||
VolumeAdjustLFE = powf(10, VolumeAdjustLFEdb / 10);
|
VolumeAdjustLFE = powf(10, VolumeAdjustLFEdb / 10);
|
||||||
|
|
||||||
|
#ifdef SPU2X_CUBEB
|
||||||
|
const SndOutModule* const defaultModule = CubebOut;
|
||||||
|
#else
|
||||||
|
const SndOutModule* const defaultModule = NullOut;
|
||||||
|
#endif
|
||||||
|
|
||||||
wxString temp;
|
wxString temp;
|
||||||
|
CfgReadStr(L"OUTPUT", L"Output_Module", temp, defaultModule->GetIdent());
|
||||||
#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
|
|
||||||
OutputModule = FindOutputModuleById(temp.c_str()); // Find the driver index of this module...
|
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);
|
SndOutLatencyMS = CfgReadInt(L"OUTPUT", L"Latency", 100);
|
||||||
SynchMode = CfgReadInt(L"OUTPUT", L"Synch_Mode", 0);
|
SynchMode = CfgReadInt(L"OUTPUT", L"Synch_Mode", 0);
|
||||||
numSpeakers = CfgReadInt(L"OUTPUT", L"SpeakerConfiguration", 0);
|
numSpeakers = CfgReadInt(L"OUTPUT", L"SpeakerConfiguration", 0);
|
||||||
|
|
||||||
#ifdef SPU2X_PORTAUDIO
|
|
||||||
PortaudioOut->ReadSettings();
|
|
||||||
#endif
|
|
||||||
#if defined(__unix__) || defined(__APPLE__)
|
|
||||||
SDLOut->ReadSettings();
|
|
||||||
#endif
|
|
||||||
SoundtouchCfg::ReadSettings();
|
SoundtouchCfg::ReadSettings();
|
||||||
DebugConfig::ReadSettings();
|
DebugConfig::ReadSettings();
|
||||||
|
|
||||||
|
@ -164,8 +126,8 @@ void ReadSettings()
|
||||||
if (mods[OutputModule] == nullptr)
|
if (mods[OutputModule] == nullptr)
|
||||||
{
|
{
|
||||||
Console.Warning("* SPU2: Unknown output module '%s' specified in configuration file.", temp.wc_str());
|
Console.Warning("* SPU2: Unknown output module '%s' specified in configuration file.", temp.wc_str());
|
||||||
Console.Warning("* SPU2: Defaulting to SDL (%s).", SDLOut->GetIdent());
|
Console.Warning("* SPU2: Defaulting to %s (%s).", defaultModule->GetLongName(), defaultModule->GetIdent());
|
||||||
OutputModule = FindOutputModuleById(SDLOut->GetIdent());
|
OutputModule = FindOutputModuleById(defaultModule->GetIdent());
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteSettings();
|
WriteSettings();
|
||||||
|
@ -200,12 +162,6 @@ void WriteSettings()
|
||||||
CfgWriteInt(L"OUTPUT", L"Synch_Mode", SynchMode);
|
CfgWriteInt(L"OUTPUT", L"Synch_Mode", SynchMode);
|
||||||
CfgWriteInt(L"OUTPUT", L"SpeakerConfiguration", numSpeakers);
|
CfgWriteInt(L"OUTPUT", L"SpeakerConfiguration", numSpeakers);
|
||||||
|
|
||||||
#ifdef SPU2X_PORTAUDIO
|
|
||||||
PortaudioOut->WriteSettings();
|
|
||||||
#endif
|
|
||||||
#if defined(__unix__) || defined(__APPLE__)
|
|
||||||
SDLOut->WriteSettings();
|
|
||||||
#endif
|
|
||||||
SoundtouchCfg::WriteSettings();
|
SoundtouchCfg::WriteSettings();
|
||||||
DebugConfig::WriteSettings();
|
DebugConfig::WriteSettings();
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,11 +78,6 @@ extern int dspPluginModule;
|
||||||
extern bool dspPluginEnabled;
|
extern bool dspPluginEnabled;
|
||||||
extern int SynchMode;
|
extern int SynchMode;
|
||||||
|
|
||||||
#ifdef SPU2X_PORTAUDIO
|
|
||||||
extern u32 OutputAPI;
|
|
||||||
#endif
|
|
||||||
extern u32 SdlOutputAPI;
|
|
||||||
|
|
||||||
#ifdef PCSX2_DEVBUILD
|
#ifdef PCSX2_DEVBUILD
|
||||||
const int LATENCY_MAX = 3000;
|
const int LATENCY_MAX = 3000;
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -49,50 +49,47 @@ StereoOut32 StereoOut16::UpSample() const
|
||||||
class NullOutModule : public SndOutModule
|
class NullOutModule : public SndOutModule
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
s32 Init() { return 0; }
|
s32 Init() override { return 0; }
|
||||||
void Close() {}
|
void Close() override {}
|
||||||
s32 Test() const { return 0; }
|
s32 Test() const override { return 0; }
|
||||||
void Configure(uptr parent) {}
|
void Configure(uptr parent) override {}
|
||||||
int GetEmptySampleCount() { return 0; }
|
int GetEmptySampleCount() override { return 0; }
|
||||||
|
|
||||||
const wchar_t* GetIdent() const
|
const wchar_t* GetIdent() const override
|
||||||
{
|
{
|
||||||
return L"nullout";
|
return L"nullout";
|
||||||
}
|
}
|
||||||
|
|
||||||
const wchar_t* GetLongName() const
|
const wchar_t* GetLongName() const override
|
||||||
{
|
{
|
||||||
return L"No Sound (Emulate SPU2 only)";
|
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[] =
|
SndOutModule* mods[] =
|
||||||
{
|
{
|
||||||
&NullOut,
|
NullOut,
|
||||||
#ifdef _MSC_VER
|
#ifdef _WIN32
|
||||||
XAudio2Out,
|
XAudio2Out,
|
||||||
#endif
|
#endif
|
||||||
#if defined(SPU2X_PORTAUDIO)
|
|
||||||
PortaudioOut,
|
|
||||||
#endif
|
|
||||||
#if defined(SPU2X_CUBEB)
|
#if defined(SPU2X_CUBEB)
|
||||||
CubebOut,
|
CubebOut,
|
||||||
#endif
|
|
||||||
#if defined(__linux__) || defined(__APPLE__)
|
|
||||||
SDLOut,
|
|
||||||
#endif
|
#endif
|
||||||
nullptr // signals the end of our list
|
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
|
// If a failure occurs, just initialize the NoSound driver. This'll allow
|
||||||
// the game to emulate properly (hopefully), albeit without sound.
|
// the game to emulate properly (hopefully), albeit without sound.
|
||||||
OutputModule = FindOutputModuleById(NullOut.GetIdent());
|
OutputModule = FindOutputModuleById(NullOut->GetIdent());
|
||||||
mods[OutputModule]->Init();
|
mods[OutputModule]->Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,7 +444,7 @@ void SndBuffer::Write(const StereoOut32& Sample)
|
||||||
if (WavRecordEnabled)
|
if (WavRecordEnabled)
|
||||||
RecordWrite(Sample.DownSample());
|
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;
|
return;
|
||||||
|
|
||||||
sndTempBuffer[sndTempProgress++] = Sample;
|
sndTempBuffer[sndTempProgress++] = Sample;
|
||||||
|
@ -464,7 +461,7 @@ void SndBuffer::Write(const StereoOut32& Sample)
|
||||||
// Play silence
|
// Play silence
|
||||||
std::fill_n(sndTempBuffer, SndOutPacketSize, StereoOut32{});
|
std::fill_n(sndTempBuffer, SndOutPacketSize, StereoOut32{});
|
||||||
}
|
}
|
||||||
#ifndef __POSIX__
|
#if defined(_WIN32) && !defined(PCSX2_CORE)
|
||||||
if (dspPluginEnabled)
|
if (dspPluginEnabled)
|
||||||
{
|
{
|
||||||
// Convert in, send to winamp DSP, and convert out.
|
// Convert in, send to winamp DSP, and convert out.
|
||||||
|
|
|
@ -663,17 +663,13 @@ public:
|
||||||
virtual int GetEmptySampleCount() = 0;
|
virtual int GetEmptySampleCount() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
extern SndOutModule* NullOut;
|
||||||
//internal
|
#ifdef _WIN32
|
||||||
extern SndOutModule* XAudio2Out;
|
extern SndOutModule* XAudio2Out;
|
||||||
#endif
|
#endif
|
||||||
#if defined(SPU2X_PORTAUDIO)
|
|
||||||
extern SndOutModule* PortaudioOut;
|
|
||||||
#endif
|
|
||||||
#if defined(SPU2X_CUBEB)
|
#if defined(SPU2X_CUBEB)
|
||||||
extern SndOutModule* CubebOut;
|
extern SndOutModule* CubebOut;
|
||||||
#endif
|
#endif
|
||||||
extern SndOutModule* const SDLOut;
|
|
||||||
extern SndOutModule* mods[];
|
extern SndOutModule* mods[];
|
||||||
|
|
||||||
// =====================================================================================================
|
// =====================================================================================================
|
||||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "PrecompiledHeader.h"
|
|
||||||
//#include "Mixer.h"
|
|
||||||
#include "Global.h"
|
|
||||||
#include "SndOut.h"
|
|
||||||
|
|
||||||
#define _WIN32_DCOM
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <portaudio/include/portaudio.h>
|
|
||||||
#include "Windows/Dialogs.h"
|
|
||||||
#elif defined(__linux__) || defined(__APPLE__)
|
|
||||||
#include "portaudio.h"
|
|
||||||
#include "Linux/Dialogs.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "wchar.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <portaudio/include/pa_win_wasapi.h>
|
|
||||||
#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 T>
|
|
||||||
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<Stereo20Out32>(&writtenSoFar);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
ConLog("* SPU2 > 2.1 speaker expansion enabled.\n");
|
|
||||||
ActualPaCallback = new ConvertedSampleReader<Stereo21Out32>(&writtenSoFar);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
ConLog("* SPU2 > 4 speaker expansion enabled [quadraphenia]\n");
|
|
||||||
ActualPaCallback = new ConvertedSampleReader<Stereo40Out32>(&writtenSoFar);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5:
|
|
||||||
ConLog("* SPU2 > 4.1 speaker expansion enabled.\n");
|
|
||||||
ActualPaCallback = new ConvertedSampleReader<Stereo41Out32>(&writtenSoFar);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 6:
|
|
||||||
case 7:
|
|
||||||
switch (dplLevel)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
ConLog("* SPU2 > 5.1 speaker expansion enabled.\n");
|
|
||||||
ActualPaCallback = new ConvertedSampleReader<Stereo51Out32>(&writtenSoFar); //"normal" stereo upmix
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
ConLog("* SPU2 > 5.1 speaker expansion with basic ProLogic dematrixing enabled.\n");
|
|
||||||
ActualPaCallback = new ConvertedSampleReader<Stereo51Out32Dpl>(&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<Stereo51Out32DplII>(&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<Stereo71Out32>(&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;
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "PrecompiledHeader.h"
|
|
||||||
|
|
||||||
#ifdef SDL_BUILD
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "Global.h"
|
|
||||||
#include "SndOut.h"
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
#include "Windows/Dialogs.h"
|
|
||||||
#else // BSD, Macos
|
|
||||||
#include "Linux/Dialogs.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
/* 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 <SDL.h>
|
|
||||||
#include <SDL_audio.h>
|
|
||||||
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
|
|
|
@ -126,8 +126,6 @@ void ReadSettings()
|
||||||
dspPluginModule = CfgReadInt(L"DSP PLUGIN", L"ModuleNum", 0);
|
dspPluginModule = CfgReadInt(L"DSP PLUGIN", L"ModuleNum", 0);
|
||||||
dspPluginEnabled = CfgReadBool(L"DSP PLUGIN", L"Enabled", false);
|
dspPluginEnabled = CfgReadBool(L"DSP PLUGIN", L"Enabled", false);
|
||||||
|
|
||||||
PortaudioOut->ReadSettings();
|
|
||||||
|
|
||||||
SoundtouchCfg::ReadSettings();
|
SoundtouchCfg::ReadSettings();
|
||||||
DebugConfig::ReadSettings();
|
DebugConfig::ReadSettings();
|
||||||
|
|
||||||
|
@ -173,7 +171,6 @@ void WriteSettings()
|
||||||
CfgWriteInt(L"DSP PLUGIN", L"ModuleNum", dspPluginModule);
|
CfgWriteInt(L"DSP PLUGIN", L"ModuleNum", dspPluginModule);
|
||||||
CfgWriteBool(L"DSP PLUGIN", L"Enabled", dspPluginEnabled);
|
CfgWriteBool(L"DSP PLUGIN", L"Enabled", dspPluginEnabled);
|
||||||
|
|
||||||
PortaudioOut->WriteSettings();
|
|
||||||
SoundtouchCfg::WriteSettings();
|
SoundtouchCfg::WriteSettings();
|
||||||
DebugConfig::WriteSettings();
|
DebugConfig::WriteSettings();
|
||||||
}
|
}
|
||||||
|
@ -181,16 +178,131 @@ void WriteSettings()
|
||||||
void CheckOutputModule(HWND window)
|
void CheckOutputModule(HWND window)
|
||||||
{
|
{
|
||||||
OutputModule = SendMessage(GetDlgItem(window, IDC_OUTPUT), CB_GETCURSEL, 0, 0);
|
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 =
|
const bool AudioExpansion =
|
||||||
mods[OutputModule] == XAudio2Out ||
|
mods[OutputModule] == XAudio2Out ||
|
||||||
mods[OutputModule] == PortaudioOut;
|
mods[OutputModule] == CubebOut;
|
||||||
|
|
||||||
EnableWindow(GetDlgItem(window, IDC_OUTCONF), IsConfigurable);
|
EnableWindow(GetDlgItem(window, IDC_OUTCONF), IsConfigurable);
|
||||||
EnableWindow(GetDlgItem(window, IDC_SPEAKERS), AudioExpansion);
|
EnableWindow(GetDlgItem(window, IDC_SPEAKERS), AudioExpansion);
|
||||||
EnableWindow(GetDlgItem(window, IDC_SPEAKERS_TEXT), 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)
|
BOOL CALLBACK ConfigProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
int wmId, wmEvent;
|
int wmId, wmEvent;
|
||||||
|
@ -298,9 +410,11 @@ BOOL CALLBACK ConfigProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
case IDC_OUTCONF:
|
case IDC_OUTCONF:
|
||||||
{
|
{
|
||||||
const int module = (int)SendMessage(GetDlgItem(hWnd, IDC_OUTPUT), CB_GETCURSEL, 0, 0);
|
const int module = (int)SendMessage(GetDlgItem(hWnd, IDC_OUTPUT), CB_GETCURSEL, 0, 0);
|
||||||
if (mods[module] == nullptr)
|
if (mods[module] != CubebOut)
|
||||||
break;
|
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;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
//
|
//
|
||||||
// Generated from the TEXTINCLUDE 2 resource.
|
// Generated from the TEXTINCLUDE 2 resource.
|
||||||
//
|
//
|
||||||
#include "svnrev.h"
|
|
||||||
#include "common/afxresmw.h"
|
#include "common/afxresmw.h"
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
#undef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
@ -175,25 +174,22 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
|
||||||
// Dialog
|
// 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
|
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
|
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||||
BEGIN
|
BEGIN
|
||||||
DEFPUSHBUTTON "OK",IDOK,105,144,50,14
|
DEFPUSHBUTTON "OK",IDOK,105,144,50,14
|
||||||
PUSHBUTTON "Cancel",IDCANCEL,161,144,50,14
|
PUSHBUTTON "Cancel",IDCANCEL,161,144,50,14
|
||||||
COMBOBOX IDC_PA_HOSTAPI,7,17,95,62,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
COMBOBOX IDC_BACKEND,7,17,95,62,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||||
LTEXT "Host API:",IDC_STATIC,7,7,32,8
|
LTEXT "Backend:",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
|
|
||||||
CONTROL "",IDC_LATENCY,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,96,93,155,10
|
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
|
CTEXT "20ms",IDC_LATENCY_LABEL,264,93,35,11
|
||||||
GROUPBOX "Output Latency",IDC_STATIC,7,57,302,79
|
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,
|
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
|
"Button",BS_AUTORADIOBUTTON | WS_GROUP,12,75,258,10
|
||||||
CONTROL "Use this latency:",IDC_MANUAL,"Button",BS_AUTORADIOBUTTON,12,93,69,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
|
END
|
||||||
|
|
||||||
|
|
||||||
|
@ -205,7 +201,7 @@ END
|
||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
GUIDELINES DESIGNINFO
|
GUIDELINES DESIGNINFO
|
||||||
BEGIN
|
BEGIN
|
||||||
IDD_PORTAUDIO, DIALOG
|
IDD_CUBEB, DIALOG
|
||||||
BEGIN
|
BEGIN
|
||||||
LEFTMARGIN, 7
|
LEFTMARGIN, 7
|
||||||
RIGHTMARGIN, 309
|
RIGHTMARGIN, 309
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#define IDD_DEBUG 105
|
#define IDD_DEBUG 105
|
||||||
#define IDD_CONFIG_SOUNDTOUCH 117
|
#define IDD_CONFIG_SOUNDTOUCH 117
|
||||||
#define IDD_CONFIG_DEBUG 118
|
#define IDD_CONFIG_DEBUG 118
|
||||||
#define IDD_PORTAUDIO 119
|
#define IDD_CUBEB 119
|
||||||
#define IDC_DUMPREGS 1003
|
#define IDC_DUMPREGS 1003
|
||||||
#define IDC_DUMPMEM 1004
|
#define IDC_DUMPMEM 1004
|
||||||
#define IDC_DUMPCORE 1005
|
#define IDC_DUMPCORE 1005
|
||||||
|
@ -27,7 +27,6 @@
|
||||||
#define IDC_OUTCONF 1028
|
#define IDC_OUTCONF 1028
|
||||||
#define IDC_DSP_ENABLE 1029
|
#define IDC_DSP_ENABLE 1029
|
||||||
#define IDC_DS_DEVICE 1032
|
#define IDC_DS_DEVICE 1032
|
||||||
#define IDC_PA_DEVICE 1033
|
|
||||||
#define IDC_DBG_OVERRUNS 1038
|
#define IDC_DBG_OVERRUNS 1038
|
||||||
#define IDC_DBG_CACHE 1039
|
#define IDC_DBG_CACHE 1039
|
||||||
#define IDC_LATENCY_SLIDER 1040
|
#define IDC_LATENCY_SLIDER 1040
|
||||||
|
@ -50,9 +49,8 @@
|
||||||
#define IDC_VOLUME_SLIDER 1068
|
#define IDC_VOLUME_SLIDER 1068
|
||||||
#define IDC_MINIMIZE 1069
|
#define IDC_MINIMIZE 1069
|
||||||
#define IDC_MANUAL 1070
|
#define IDC_MANUAL 1070
|
||||||
#define IDC_PA_HOSTAPI 1071
|
#define IDC_BACKEND 1071
|
||||||
#define IDC_LATENCY 1072
|
#define IDC_LATENCY 1072
|
||||||
#define IDC_EXCLUSIVE 1073
|
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
|
|
|
@ -17,10 +17,22 @@
|
||||||
#include "SPU2/Config.h"
|
#include "SPU2/Config.h"
|
||||||
#if !defined(_WIN32) // BSD, Macos
|
#if !defined(_WIN32) // BSD, Macos
|
||||||
#include "SPU2/Linux/Config.h"
|
#include "SPU2/Linux/Config.h"
|
||||||
|
#include "SPU2/Linux/Dialogs.h"
|
||||||
#endif
|
#endif
|
||||||
#include "SPU2/Global.h"
|
#include "SPU2/Global.h"
|
||||||
#include "wxConfig.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)
|
MixerTab::MixerTab(wxWindow* parent)
|
||||||
: wxPanel(parent, wxID_ANY)
|
: wxPanel(parent, wxID_ANY)
|
||||||
{
|
{
|
||||||
|
@ -352,49 +364,27 @@ Dialog::Dialog()
|
||||||
|
|
||||||
wxArrayString module_entries;
|
wxArrayString module_entries;
|
||||||
module_entries.Add("No Sound (Emulate SPU2 only)");
|
module_entries.Add("No Sound (Emulate SPU2 only)");
|
||||||
#ifdef SPU2X_PORTAUDIO
|
#ifdef SPU2X_CUBEB
|
||||||
module_entries.Add("PortAudio (Cross-platform)");
|
module_entries.Add("Cubeb (Cross-platform)");
|
||||||
#endif
|
#endif
|
||||||
module_entries.Add("SDL Audio (Recommended for PulseAudio)");
|
|
||||||
m_module_select = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, module_entries);
|
m_module_select = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, module_entries);
|
||||||
module_box->Add(m_module_select, wxSizerFlags().Centre());
|
module_box->Add(m_module_select, wxSizerFlags().Centre());
|
||||||
|
|
||||||
#ifdef SPU2X_PORTAUDIO
|
#ifdef SPU2X_CUBEB
|
||||||
// Portaudio
|
// Portaudio
|
||||||
m_portaudio_box = new wxBoxSizer(wxVERTICAL);
|
m_cubeb_box = new wxBoxSizer(wxVERTICAL);
|
||||||
m_portaudio_text = new wxStaticText(this, wxID_ANY, "Portaudio API");
|
m_cubeb_text = new wxStaticText(this, wxID_ANY, "Backend");
|
||||||
m_portaudio_box->Add(m_portaudio_text, wxSizerFlags().Centre());
|
m_cubeb_box->Add(m_cubeb_text, wxSizerFlags().Centre());
|
||||||
|
|
||||||
wxArrayString portaudio_entries;
|
m_cubeb_select = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||||
#ifdef __linux__
|
for (size_t i = 0; i < std::size(s_backend_names); i++)
|
||||||
portaudio_entries.Add("ALSA (recommended)");
|
m_cubeb_select->Append(s_backend_names[i][0]);
|
||||||
portaudio_entries.Add("OSS (legacy)");
|
m_cubeb_box->Add(m_cubeb_select, wxSizerFlags().Centre());
|
||||||
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());
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// SDL
|
#ifdef SPU2X_CUBEB
|
||||||
m_sdl_box = new wxBoxSizer(wxVERTICAL);
|
module_box->Add(m_cubeb_box, wxSizerFlags().Expand());
|
||||||
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());
|
|
||||||
#endif
|
#endif
|
||||||
module_box->Add(m_sdl_box, wxSizerFlags().Expand());
|
|
||||||
|
|
||||||
m_top_box->Add(module_box, wxSizerFlags().Centre().Border(wxALL, 5));
|
m_top_box->Add(module_box, wxSizerFlags().Centre().Border(wxALL, 5));
|
||||||
|
|
||||||
|
@ -423,34 +413,25 @@ Dialog::~Dialog()
|
||||||
void Dialog::Reconfigure()
|
void Dialog::Reconfigure()
|
||||||
{
|
{
|
||||||
const int mod = m_module_select->GetCurrentSelection();
|
const int mod = m_module_select->GetCurrentSelection();
|
||||||
bool show_portaudio = false, show_sdl = false;
|
bool show_cubeb = false;
|
||||||
|
|
||||||
switch (mod)
|
switch (mod)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
show_portaudio = false;
|
show_cubeb = false;
|
||||||
show_sdl = false;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
show_portaudio = true;
|
show_cubeb = true;
|
||||||
show_sdl = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
show_portaudio = false;
|
|
||||||
show_sdl = true;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
show_portaudio = false;
|
show_cubeb = false;
|
||||||
show_sdl = false;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef SPU2X_PORTAUDIO
|
#ifdef SPU2X_CUBEB
|
||||||
m_top_box->Show(m_portaudio_box, show_portaudio, true);
|
m_top_box->Show(m_cubeb_box, show_cubeb, true);
|
||||||
#endif
|
#endif
|
||||||
m_top_box->Show(m_sdl_box, show_sdl, true);
|
|
||||||
|
|
||||||
// Recalculating both of these accounts for if neither was showing initially.
|
// Recalculating both of these accounts for if neither was showing initially.
|
||||||
m_top_box->Layout();
|
m_top_box->Layout();
|
||||||
|
@ -465,10 +446,18 @@ void Dialog::CallReconfigure(wxCommandEvent& event)
|
||||||
void Dialog::Load()
|
void Dialog::Load()
|
||||||
{
|
{
|
||||||
m_module_select->SetSelection(OutputModule);
|
m_module_select->SetSelection(OutputModule);
|
||||||
#ifdef SPU2X_PORTAUDIO
|
#ifdef SPU2X_CUBEB
|
||||||
m_portaudio_select->SetSelection(OutputAPI);
|
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<int>(i));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
m_sdl_select->SetSelection(SdlOutputAPI);
|
|
||||||
|
|
||||||
m_mixer_panel->Load();
|
m_mixer_panel->Load();
|
||||||
m_sync_panel->Load();
|
m_sync_panel->Load();
|
||||||
|
@ -481,19 +470,12 @@ void Dialog::Save()
|
||||||
{
|
{
|
||||||
OutputModule = m_module_select->GetSelection();
|
OutputModule = m_module_select->GetSelection();
|
||||||
|
|
||||||
#ifdef SPU2X_PORTAUDIO
|
#ifdef SPU2X_CUBEB
|
||||||
OutputAPI = m_portaudio_select->GetSelection();
|
const int backend_selection = m_cubeb_select->GetSelection();
|
||||||
wxString p_api(m_portaudio_select->GetStringSelection());
|
if (backend_selection >= 0)
|
||||||
if (p_api.Find("ALSA") != wxNOT_FOUND)
|
CfgWriteStr(L"Cubeb", L"BackendName", s_backend_names[backend_selection][1]);
|
||||||
p_api = "ALSA";
|
|
||||||
if (p_api.Find("OSS") != wxNOT_FOUND)
|
|
||||||
p_api = "OSS";
|
|
||||||
PortaudioOut->SetApiSettings(p_api);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SdlOutputAPI = m_sdl_select->GetSelection();
|
|
||||||
SDLOut->SetApiSettings(m_sdl_select->GetStringSelection());
|
|
||||||
|
|
||||||
m_mixer_panel->Save();
|
m_mixer_panel->Save();
|
||||||
m_sync_panel->Save();
|
m_sync_panel->Save();
|
||||||
m_debug_panel->Save();
|
m_debug_panel->Save();
|
||||||
|
|
|
@ -78,9 +78,9 @@ public:
|
||||||
|
|
||||||
class Dialog : public wxDialog
|
class Dialog : public wxDialog
|
||||||
{
|
{
|
||||||
wxBoxSizer *m_top_box, *m_portaudio_box, *m_sdl_box;
|
wxBoxSizer *m_top_box, *m_cubeb_box;
|
||||||
wxChoice *m_module_select, *m_portaudio_select, *m_sdl_select;
|
wxChoice *m_module_select, *m_cubeb_select;
|
||||||
wxStaticText *m_portaudio_text, *m_sdl_text;
|
wxStaticText *m_cubeb_text;
|
||||||
|
|
||||||
MixerTab* m_mixer_panel;
|
MixerTab* m_mixer_panel;
|
||||||
SyncTab* m_sync_panel;
|
SyncTab* m_sync_panel;
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
<ForcedIncludeFiles>PrecompiledHeader.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
|
<ForcedIncludeFiles>PrecompiledHeader.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
|
||||||
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||||
<AdditionalOptions>/Zc:externConstexpr %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zc:externConstexpr %(AdditionalOptions)</AdditionalOptions>
|
||||||
<PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;LZMA_API_STATIC;BUILD_DX=1;SPU2X_CUBEB;SPU2X_PORTAUDIO;DIRECTINPUT_VERSION=0x0800;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;LZMA_API_STATIC;BUILD_DX=1;SPU2X_CUBEB;DIRECTINPUT_VERSION=0x0800;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="$(Configuration.Contains(Debug))">PCSX2_DEBUG;PCSX2_DEVBUILD;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="$(Configuration.Contains(Debug))">PCSX2_DEBUG;PCSX2_DEVBUILD;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="$(Configuration.Contains(Devel))">PCSX2_DEVEL;PCSX2_DEVBUILD;NDEBUG;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="$(Configuration.Contains(Devel))">PCSX2_DEVEL;PCSX2_DEVBUILD;NDEBUG;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="$(Configuration.Contains(Release))">NDEBUG;_SECURE_SCL_=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="$(Configuration.Contains(Release))">NDEBUG;_SECURE_SCL_=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
@ -359,7 +359,6 @@
|
||||||
<ClCompile Include="SPU2\debug.cpp" />
|
<ClCompile Include="SPU2\debug.cpp" />
|
||||||
<ClCompile Include="SPU2\RegLog.cpp" />
|
<ClCompile Include="SPU2\RegLog.cpp" />
|
||||||
<ClCompile Include="SPU2\SndOut_Cubeb.cpp" />
|
<ClCompile Include="SPU2\SndOut_Cubeb.cpp" />
|
||||||
<ClCompile Include="SPU2\SndOut_Portaudio.cpp" />
|
|
||||||
<ClCompile Include="SPU2\wavedump_wav.cpp" />
|
<ClCompile Include="SPU2\wavedump_wav.cpp" />
|
||||||
<ClCompile Include="SPU2\SndOut.cpp" />
|
<ClCompile Include="SPU2\SndOut.cpp" />
|
||||||
<ClCompile Include="SPU2\Timestretcher.cpp" />
|
<ClCompile Include="SPU2\Timestretcher.cpp" />
|
||||||
|
@ -1120,9 +1119,6 @@
|
||||||
<ProjectReference Include="$(SolutionDir)3rdparty\libsamplerate\libsamplerate.vcxproj">
|
<ProjectReference Include="$(SolutionDir)3rdparty\libsamplerate\libsamplerate.vcxproj">
|
||||||
<Project>{47afdbef-f15f-4bc0-b436-5be443c3f80f}</Project>
|
<Project>{47afdbef-f15f-4bc0-b436-5be443c3f80f}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="$(SolutionDir)3rdparty\portaudio\build\msvc\portaudio.vcxproj">
|
|
||||||
<Project>{0a18a071-125e-442f-aff7-a3f68abecf99}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
<ProjectReference Include="$(SolutionDir)3rdparty\pthreads4w\build\pthreads4w.vcxproj">
|
<ProjectReference Include="$(SolutionDir)3rdparty\pthreads4w\build\pthreads4w.vcxproj">
|
||||||
<Project>{0fae817d-9a32-4830-857e-81da57246e16}</Project>
|
<Project>{0fae817d-9a32-4830-857e-81da57246e16}</Project>
|
||||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||||
|
|
|
@ -1133,9 +1133,6 @@
|
||||||
<ClCompile Include="SPU2\Wavedump_wav.cpp">
|
<ClCompile Include="SPU2\Wavedump_wav.cpp">
|
||||||
<Filter>System\Ps2\SPU2</Filter>
|
<Filter>System\Ps2\SPU2</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="SPU2\SndOut_Portaudio.cpp">
|
|
||||||
<Filter>System\Ps2\SPU2</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DEV9\ATA\Commands\ATA_Command.cpp">
|
<ClCompile Include="DEV9\ATA\Commands\ATA_Command.cpp">
|
||||||
<Filter>System\Ps2\DEV9\ATA\Commands</Filter>
|
<Filter>System\Ps2\DEV9\ATA\Commands</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
Loading…
Reference in New Issue