mirror of https://github.com/PCSX2/pcsx2.git
Merge pull request #929 from PCSX2/spu-sdl-api-config
Spu sdl api config
This commit is contained in:
commit
36361f04c6
|
@ -19,6 +19,9 @@
|
||||||
#include "Dialogs.h"
|
#include "Dialogs.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
#include <SDL_audio.h>
|
||||||
|
|
||||||
#ifdef PCSX2_DEVBUILD
|
#ifdef PCSX2_DEVBUILD
|
||||||
static const int LATENCY_MAX = 3000;
|
static const int LATENCY_MAX = 3000;
|
||||||
#else
|
#else
|
||||||
|
@ -70,6 +73,7 @@ u32 OutputModule = 0;
|
||||||
int SndOutLatencyMS = 300;
|
int SndOutLatencyMS = 300;
|
||||||
int SynchMode = 0; // Time Stretch, Async or Disabled
|
int SynchMode = 0; // Time Stretch, Async or Disabled
|
||||||
static u32 OutputAPI = 0;
|
static u32 OutputAPI = 0;
|
||||||
|
static u32 SdlOutputAPI = 0;
|
||||||
|
|
||||||
int numSpeakers = 0;
|
int numSpeakers = 0;
|
||||||
int dplLevel = 0;
|
int dplLevel = 0;
|
||||||
|
@ -121,10 +125,21 @@ void ReadSettings()
|
||||||
if (temp == L"OSS") OutputAPI = 1;
|
if (temp == L"OSS") OutputAPI = 1;
|
||||||
if (temp == L"JACK") OutputAPI = 2;
|
if (temp == L"JACK") OutputAPI = 2;
|
||||||
|
|
||||||
|
CfgReadStr( L"SDL", L"HostApi", temp, L"pulseaudio" );
|
||||||
|
SdlOutputAPI = -1;
|
||||||
|
#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
|
||||||
|
|
||||||
SndOutLatencyMS = CfgReadInt(L"OUTPUT",L"Latency", 300);
|
SndOutLatencyMS = CfgReadInt(L"OUTPUT",L"Latency", 300);
|
||||||
SynchMode = CfgReadInt( L"OUTPUT", L"Synch_Mode", 0);
|
SynchMode = CfgReadInt( L"OUTPUT", L"Synch_Mode", 0);
|
||||||
|
|
||||||
PortaudioOut->ReadSettings();
|
PortaudioOut->ReadSettings();
|
||||||
|
SDLOut->ReadSettings();
|
||||||
SoundtouchCfg::ReadSettings();
|
SoundtouchCfg::ReadSettings();
|
||||||
DebugConfig::ReadSettings();
|
DebugConfig::ReadSettings();
|
||||||
|
|
||||||
|
@ -167,6 +182,7 @@ void WriteSettings()
|
||||||
CfgWriteInt(L"OUTPUT",L"Synch_Mode", SynchMode);
|
CfgWriteInt(L"OUTPUT",L"Synch_Mode", SynchMode);
|
||||||
|
|
||||||
PortaudioOut->WriteSettings();
|
PortaudioOut->WriteSettings();
|
||||||
|
SDLOut->WriteSettings();
|
||||||
SoundtouchCfg::WriteSettings();
|
SoundtouchCfg::WriteSettings();
|
||||||
DebugConfig::WriteSettings();
|
DebugConfig::WriteSettings();
|
||||||
}
|
}
|
||||||
|
@ -198,6 +214,9 @@ void DisplayDialog()
|
||||||
GtkWidget *output_frame, *output_box;
|
GtkWidget *output_frame, *output_box;
|
||||||
GtkWidget *mod_label, *mod_box;
|
GtkWidget *mod_label, *mod_box;
|
||||||
GtkWidget *api_label, *api_box;
|
GtkWidget *api_label, *api_box;
|
||||||
|
#if SDL_MAJOR_VERSION >= 2
|
||||||
|
GtkWidget *sdl_api_label, *sdl_api_box;
|
||||||
|
#endif
|
||||||
GtkWidget *latency_label, *latency_slide;
|
GtkWidget *latency_label, *latency_slide;
|
||||||
GtkWidget *sync_label, *sync_box;
|
GtkWidget *sync_label, *sync_box;
|
||||||
GtkWidget *advanced_button;
|
GtkWidget *advanced_button;
|
||||||
|
@ -242,6 +261,16 @@ void DisplayDialog()
|
||||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(api_box), "2 - JACK");
|
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(api_box), "2 - JACK");
|
||||||
gtk_combo_box_set_active(GTK_COMBO_BOX(api_box), OutputAPI);
|
gtk_combo_box_set_active(GTK_COMBO_BOX(api_box), OutputAPI);
|
||||||
|
|
||||||
|
#if SDL_MAJOR_VERSION >= 2
|
||||||
|
sdl_api_label = gtk_label_new ("SDL API:");
|
||||||
|
sdl_api_box = gtk_combo_box_text_new ();
|
||||||
|
// YES It sucks ...
|
||||||
|
for (int i = 0; i < SDL_GetNumAudioDrivers(); ++i) {
|
||||||
|
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(sdl_api_box), SDL_GetAudioDriver(i));
|
||||||
|
}
|
||||||
|
gtk_combo_box_set_active(GTK_COMBO_BOX(sdl_api_box), SdlOutputAPI);
|
||||||
|
#endif
|
||||||
|
|
||||||
latency_label = gtk_label_new ("Latency:");
|
latency_label = gtk_label_new ("Latency:");
|
||||||
#if GTK_MAJOR_VERSION < 3
|
#if GTK_MAJOR_VERSION < 3
|
||||||
latency_slide = gtk_hscale_new_with_range(LATENCY_MIN, LATENCY_MAX, 5);
|
latency_slide = gtk_hscale_new_with_range(LATENCY_MIN, LATENCY_MAX, 5);
|
||||||
|
@ -282,6 +311,10 @@ void DisplayDialog()
|
||||||
gtk_container_add(GTK_CONTAINER(output_box), mod_box);
|
gtk_container_add(GTK_CONTAINER(output_box), mod_box);
|
||||||
gtk_container_add(GTK_CONTAINER(output_box), api_label);
|
gtk_container_add(GTK_CONTAINER(output_box), api_label);
|
||||||
gtk_container_add(GTK_CONTAINER(output_box), api_box);
|
gtk_container_add(GTK_CONTAINER(output_box), api_box);
|
||||||
|
#if SDL_MAJOR_VERSION >= 2
|
||||||
|
gtk_container_add(GTK_CONTAINER(output_box), sdl_api_label);
|
||||||
|
gtk_container_add(GTK_CONTAINER(output_box), sdl_api_box);
|
||||||
|
#endif
|
||||||
gtk_container_add(GTK_CONTAINER(output_box), sync_label);
|
gtk_container_add(GTK_CONTAINER(output_box), sync_label);
|
||||||
gtk_container_add(GTK_CONTAINER(output_box), sync_box);
|
gtk_container_add(GTK_CONTAINER(output_box), sync_box);
|
||||||
gtk_container_add(GTK_CONTAINER(output_box), latency_label);
|
gtk_container_add(GTK_CONTAINER(output_box), latency_label);
|
||||||
|
@ -327,6 +360,14 @@ void DisplayDialog()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SDL_MAJOR_VERSION >= 2
|
||||||
|
if (gtk_combo_box_get_active(GTK_COMBO_BOX(sdl_api_box)) != -1) {
|
||||||
|
SdlOutputAPI = gtk_combo_box_get_active(GTK_COMBO_BOX(sdl_api_box));
|
||||||
|
// YES It sucks ...
|
||||||
|
SDLOut->SetApiSettings(wxString(SDL_GetAudioDriver(SdlOutputAPI), wxConvUTF8));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
SndOutLatencyMS = gtk_range_get_value(GTK_RANGE(latency_slide));
|
SndOutLatencyMS = gtk_range_get_value(GTK_RANGE(latency_slide));
|
||||||
|
|
||||||
if (gtk_combo_box_get_active(GTK_COMBO_BOX(sync_box)) != -1)
|
if (gtk_combo_box_get_active(GTK_COMBO_BOX(sync_box)) != -1)
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include "Global.h"
|
#include "Global.h"
|
||||||
#include "SndOut.h"
|
#include "SndOut.h"
|
||||||
|
#include "Dialogs.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@ -26,11 +27,7 @@
|
||||||
* build wx without sdl support, though) and onepad at the time of writing this. */
|
* build wx without sdl support, though) and onepad at the time of writing this. */
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <SDL_audio.h>
|
#include <SDL_audio.h>
|
||||||
#if SDL_MAJOR_VERSION >= 2
|
|
||||||
typedef StereoOut32 StereoOut_SDL;
|
|
||||||
#else
|
|
||||||
typedef StereoOut16 StereoOut_SDL;
|
typedef StereoOut16 StereoOut_SDL;
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
/* Since spu2 only ever outputs stereo, we don't worry about emitting surround sound
|
/* Since spu2 only ever outputs stereo, we don't worry about emitting surround sound
|
||||||
|
@ -41,12 +38,7 @@ namespace {
|
||||||
* sample count and SDL may provide otherwise. Pulseaudio will cut this value in half if
|
* 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. */
|
* PA_STREAM_ADJUST_LATENCY is set in the backened, for example. */
|
||||||
const Uint16 desiredSamples = 1024;
|
const Uint16 desiredSamples = 1024;
|
||||||
const Uint16 format =
|
const Uint16 format = AUDIO_S16SYS;
|
||||||
#if SDL_MAJOR_VERSION >= 2
|
|
||||||
AUDIO_S32SYS;
|
|
||||||
#else
|
|
||||||
AUDIO_S16SYS;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Uint16 samples = desiredSamples;
|
Uint16 samples = desiredSamples;
|
||||||
|
|
||||||
|
@ -67,16 +59,46 @@ namespace {
|
||||||
|
|
||||||
struct SDLAudioMod : public SndOutModule {
|
struct SDLAudioMod : public SndOutModule {
|
||||||
static SDLAudioMod mod;
|
static SDLAudioMod mod;
|
||||||
|
std::string m_api;
|
||||||
|
|
||||||
s32 Init() {
|
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
|
/* 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 */
|
* the audio backend, we need to make sure we keep our desired samples in the spec */
|
||||||
spec.samples = desiredSamples;
|
spec.samples = desiredSamples;
|
||||||
|
|
||||||
if(SDL_Init(SDL_INIT_AUDIO) < 0 || SDL_OpenAudio(&spec, NULL) < 0) {
|
// Mandatory otherwise, init will be redone in SDL_OpenAudio
|
||||||
|
if (SDL_Init(SDL_INIT_AUDIO) < 0) {
|
||||||
|
std::cerr << "SPU2-X: 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-X: SDL audio init error: " << SDL_GetError() << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (SDL_OpenAudio(&spec, NULL) < 0) {
|
||||||
std::cerr << "SPU2-X: SDL audio error: " << SDL_GetError() << std::endl;
|
std::cerr << "SPU2-X: SDL audio error: " << SDL_GetError() << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SDL_MAJOR_VERSION >= 2
|
||||||
|
std::cerr << "Opened SDL audio driver: " << SDL_GetCurrentAudioDriver() << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* This is so ugly. It is hilariously ugly. I didn't use a vector to save reallocs. */
|
/* This is so ugly. It is hilariously ugly. I didn't use a vector to save reallocs. */
|
||||||
if(samples != spec.samples || buffer == NULL)
|
if(samples != spec.samples || buffer == NULL)
|
||||||
buffer = std::unique_ptr<StereoOut_SDL[]>(new StereoOut_SDL[spec.samples]);
|
buffer = std::unique_ptr<StereoOut_SDL[]>(new StereoOut_SDL[spec.samples]);
|
||||||
|
@ -93,23 +115,51 @@ struct SDLAudioMod : public SndOutModule {
|
||||||
const wchar_t* GetLongName() const { return L"SDL Audio"; }
|
const wchar_t* GetLongName() const { return L"SDL Audio"; }
|
||||||
|
|
||||||
void Close() {
|
void Close() {
|
||||||
SDL_CloseAudio();
|
// Related to SDL_Init(SDL_INIT_AUDIO)
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~SDLAudioMod() { Close(); }
|
||||||
|
|
||||||
s32 Test() const { return 0; }
|
s32 Test() const { return 0; }
|
||||||
void Configure(uptr parent) {}
|
|
||||||
void ReadSettings() {}
|
|
||||||
void SetApiSettings(wxString api) {}
|
|
||||||
void WriteSettings() const {};
|
|
||||||
int GetEmptySampleCount() { return 0; }
|
int GetEmptySampleCount() { return 0; }
|
||||||
|
|
||||||
~SDLAudioMod() { Close(); }
|
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:
|
private:
|
||||||
SDL_AudioSpec spec;
|
SDL_AudioSpec spec;
|
||||||
|
|
||||||
SDLAudioMod()
|
SDLAudioMod() : m_api("pulseaudio"),
|
||||||
: spec({SampleRate, format, channels, 0,
|
spec({SampleRate, format, channels, 0,
|
||||||
desiredSamples, 0, 0, &callback_fillBuffer, nullptr})
|
desiredSamples, 0, 0, &callback_fillBuffer, nullptr})
|
||||||
{
|
{
|
||||||
// Number of samples must be a multiple of packet size.
|
// Number of samples must be a multiple of packet size.
|
||||||
|
|
Loading…
Reference in New Issue