mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
More refactoring. Add the AudioBackend interface
This commit is contained in:
@@ -842,6 +842,7 @@ add_library(Common STATIC
|
||||
Common/Render/Text/draw_text_win.h
|
||||
Common/Render/Text/draw_text_uwp.cpp
|
||||
Common/Render/Text/draw_text_uwp.h
|
||||
Common/Audio/AudioBackend.h
|
||||
Common/System/Display.cpp
|
||||
Common/System/Display.h
|
||||
Common/System/System.h
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
// Always 2 channels, 16-bit audio.
|
||||
typedef int (*StreamCallback)(short *buffer, int numSamples, int rate, void *userdata);
|
||||
|
||||
// Note that the backend may override the passed in sample rate. The actual sample rate
|
||||
// should be returned by SampleRate though.
|
||||
class AudioBackend {
|
||||
public:
|
||||
virtual ~AudioBackend() {}
|
||||
virtual bool Init(StreamCallback _callback, void *userdata = nullptr) = 0;
|
||||
virtual int SampleRate() const = 0;
|
||||
virtual int PeriodFrames() const = 0;
|
||||
virtual void FrameUpdate() {}
|
||||
};
|
||||
@@ -361,6 +361,7 @@
|
||||
<ClInclude Include="Arm64Emitter.h" />
|
||||
<ClInclude Include="ArmCommon.h" />
|
||||
<ClInclude Include="ArmEmitter.h" />
|
||||
<ClInclude Include="Audio\AudioBackend.h" />
|
||||
<ClInclude Include="BitScan.h" />
|
||||
<ClInclude Include="BitSet.h" />
|
||||
<ClInclude Include="Buffer.h" />
|
||||
|
||||
@@ -685,6 +685,9 @@
|
||||
<ClInclude Include="..\ext\imgui\imgui_extras.h">
|
||||
<Filter>ext\imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Audio\AudioBackend.h">
|
||||
<Filter>Audio</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ABI.cpp" />
|
||||
@@ -1410,6 +1413,9 @@
|
||||
<Filter Include="ext\sol">
|
||||
<UniqueIdentifier>{ec7d8691-bb7f-4689-b66a-cb60c1f48afd}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Audio">
|
||||
<UniqueIdentifier>{92746a51-33a9-4a00-af10-3538322f04f0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="..\ext\libpng17\CMakeLists.txt">
|
||||
|
||||
@@ -15,6 +15,7 @@ struct KeyInput;
|
||||
struct AxisInput;
|
||||
|
||||
class GraphicsContext;
|
||||
class AudioBackend;
|
||||
|
||||
// The first function to get called, just write strings to the two pointers.
|
||||
// This might get called multiple times in some implementations, you must be able to handle that.
|
||||
@@ -92,3 +93,4 @@ bool Native_IsWindowHidden();
|
||||
// TODO: Feels like this belongs elsewhere.
|
||||
bool Native_UpdateScreenScale(int width, int height, float customScale);
|
||||
|
||||
AudioBackend *System_CreateAudioBackend();
|
||||
|
||||
@@ -254,7 +254,6 @@ enum class SystemNotification {
|
||||
UI_STATE_CHANGED,
|
||||
AUDIO_MODE_CHANGED,
|
||||
APP_SWITCH_MODE_CHANGED,
|
||||
POLL_AUDIO_DEVICE,
|
||||
};
|
||||
|
||||
// I guess it's not super great architecturally to centralize this, since it's not general - but same with a lot of
|
||||
|
||||
@@ -771,7 +771,6 @@ static int DefaultAchievementVolume() {
|
||||
|
||||
static const ConfigSetting soundSettings[] = {
|
||||
ConfigSetting("Enable", &g_Config.bEnableSound, true, CfgFlag::PER_GAME),
|
||||
ConfigSetting("AudioBackend", &g_Config.iAudioBackend, 0, CfgFlag::PER_GAME),
|
||||
ConfigSetting("ExtraAudioBuffering", &g_Config.bExtraAudioBuffering, false, CfgFlag::DEFAULT),
|
||||
ConfigSetting("AudioBufferSize", &g_Config.iSDLAudioBufferSize, 256, CfgFlag::DEFAULT),
|
||||
|
||||
|
||||
@@ -287,7 +287,6 @@ public:
|
||||
|
||||
// Sound
|
||||
bool bEnableSound;
|
||||
int iAudioBackend;
|
||||
int iSDLAudioBufferSize;
|
||||
|
||||
// Legacy volume settings, 0-10. These get auto-upgraded and should not be used.
|
||||
|
||||
@@ -142,12 +142,6 @@ ENUM_CLASS_BITOPS(DisableHLEFlags);
|
||||
std::string GPUBackendToString(GPUBackend backend);
|
||||
GPUBackend GPUBackendFromString(std::string_view backend);
|
||||
|
||||
enum AudioBackendType {
|
||||
AUDIO_BACKEND_AUTO,
|
||||
AUDIO_BACKEND_DSOUND,
|
||||
AUDIO_BACKEND_WASAPI,
|
||||
};
|
||||
|
||||
// For iIOTimingMethod.
|
||||
enum IOTimingMethods {
|
||||
IOTIMING_FAST = 0,
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "SDL_keyboard.h"
|
||||
#endif
|
||||
|
||||
#include "Common/Audio/AudioBackend.h"
|
||||
#include "Common/System/NativeApp.h"
|
||||
#include "Common/System/Request.h"
|
||||
#include "Common/GPU/OpenGL/GLFeatures.h"
|
||||
@@ -444,6 +445,11 @@ void System_LaunchUrl(LaunchUrlType urlType, const char *url)
|
||||
QDesktopServices::openUrl(QUrl(url));
|
||||
}
|
||||
|
||||
AudioBackend *System_CreateAudioBackend() {
|
||||
// Use legacy mechanisms.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static int mainInternal(QApplication &a) {
|
||||
#ifdef MOBILE_DEVICE
|
||||
emugl = new MainUI();
|
||||
|
||||
@@ -34,6 +34,7 @@ SDLJoystick *joystick = NULL;
|
||||
#include "Common/System/System.h"
|
||||
#include "Common/System/Request.h"
|
||||
#include "Common/System/NativeApp.h"
|
||||
#include "Common/Audio/AudioBackend.h"
|
||||
#include "ext/glslang/glslang/Public/ShaderLang.h"
|
||||
#include "Common/Data/Format/PNGLoad.h"
|
||||
#include "Common/Net/Resolve.h"
|
||||
@@ -244,6 +245,11 @@ void System_Vibrate(int length_ms) {
|
||||
// Ignore on PC
|
||||
}
|
||||
|
||||
AudioBackend *System_CreateAudioBackend() {
|
||||
// Use legacy mechanisms.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void InitializeFilters(std::vector<std::string> &filters, BrowseFileType type) {
|
||||
switch (type) {
|
||||
case BrowseFileType::BOOTABLE:
|
||||
|
||||
@@ -694,7 +694,13 @@ void GameSettingsScreen::CreateAudioSettings(UI::ViewGroup *audioSettings) {
|
||||
});
|
||||
#endif
|
||||
|
||||
if (sdlAudio || g_Config.iAudioBackend == AUDIO_BACKEND_WASAPI) {
|
||||
#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP)
|
||||
const bool isWindows = true;
|
||||
#else
|
||||
const bool isWindows = false;
|
||||
#endif
|
||||
|
||||
if (sdlAudio || isWindows) {
|
||||
audioSettings->Add(new CheckBox(&g_Config.bAutoAudioDevice, a->T("Use new audio devices automatically")));
|
||||
}
|
||||
|
||||
|
||||
+17
-19
@@ -86,6 +86,7 @@
|
||||
#include "Common/GPU/ShaderTranslation.h"
|
||||
#include "Common/VR/PPSSPPVR.h"
|
||||
#include "Common/Thread/ThreadManager.h"
|
||||
#include "Common/Audio/AudioBackend.h"
|
||||
|
||||
#include "Core/ControlMapper.h"
|
||||
#include "Core/Config.h"
|
||||
@@ -193,9 +194,7 @@ static int g_restartGraphics;
|
||||
static bool g_windowHidden = false;
|
||||
std::vector<std::function<void()>> g_pendingClosures;
|
||||
|
||||
#ifdef _WIN32
|
||||
WindowsAudioBackend *winAudioBackend;
|
||||
#endif
|
||||
AudioBackend *g_audioBackend = nullptr;
|
||||
|
||||
std::thread *graphicsLoadThread;
|
||||
|
||||
@@ -839,14 +838,10 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) {
|
||||
g_screenManager->setPostRenderCallback(&CallbackPostRender, nullptr);
|
||||
g_screenManager->deviceRestored(g_draw);
|
||||
|
||||
#ifdef _WIN32
|
||||
winAudioBackend = CreateAudioBackend((AudioBackendType)g_Config.iAudioBackend);
|
||||
#if PPSSPP_PLATFORM(UWP)
|
||||
winAudioBackend->Init(&NativeMix);
|
||||
#else
|
||||
winAudioBackend->Init(&NativeMix);
|
||||
#endif
|
||||
#endif
|
||||
g_audioBackend = System_CreateAudioBackend();
|
||||
if (g_audioBackend) {
|
||||
g_audioBackend->Init(&NativeMix);
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
|
||||
if (IsWin7OrHigher()) {
|
||||
@@ -932,11 +927,6 @@ void NativeShutdownGraphics() {
|
||||
if (gpu)
|
||||
gpu->DeviceLost();
|
||||
|
||||
#if PPSSPP_PLATFORM(WINDOWS)
|
||||
delete winAudioBackend;
|
||||
winAudioBackend = nullptr;
|
||||
#endif
|
||||
|
||||
#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP)
|
||||
if (winCamera) {
|
||||
winCamera->waitShutDown();
|
||||
@@ -950,6 +940,11 @@ void NativeShutdownGraphics() {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (g_audioBackend) {
|
||||
delete g_audioBackend;
|
||||
g_audioBackend = nullptr;
|
||||
}
|
||||
|
||||
UIBackgroundShutdown();
|
||||
|
||||
delete g_gameInfoCache;
|
||||
@@ -1071,8 +1066,6 @@ void NativeFrame(GraphicsContext *graphicsContext) {
|
||||
ProcessWheelRelease(NKCODE_EXT_MOUSEWHEEL_UP, startTime, false);
|
||||
ProcessWheelRelease(NKCODE_EXT_MOUSEWHEEL_DOWN, startTime, false);
|
||||
|
||||
System_Notify(SystemNotification::POLL_AUDIO_DEVICE);
|
||||
|
||||
SetOverrideScreenFrame(nullptr);
|
||||
|
||||
// it's ok to call this redundantly with DoFrame from EmuScreen
|
||||
@@ -1099,6 +1092,10 @@ void NativeFrame(GraphicsContext *graphicsContext) {
|
||||
|
||||
g_screenManager->update();
|
||||
|
||||
if (g_audioBackend) {
|
||||
g_audioBackend->FrameUpdate();
|
||||
}
|
||||
|
||||
// Do this after g_screenManager.update() so we can receive setting changes before rendering.
|
||||
{
|
||||
std::vector<PendingMessage> toProcess;
|
||||
@@ -1536,8 +1533,9 @@ void NativeShutdown() {
|
||||
ShaderTranslationShutdown();
|
||||
|
||||
// Avoid shutting this down when restarting core.
|
||||
if (!restarting)
|
||||
if (!restarting) {
|
||||
g_logManager.Shutdown();
|
||||
}
|
||||
|
||||
g_threadManager.Teardown();
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "Common/GPU/thin3d_create.h"
|
||||
|
||||
#include "Common/Common.h"
|
||||
#include "Common/Audio/AudioBackend.h"
|
||||
#include "Common/Input/InputState.h"
|
||||
#include "Common/File/VFS/VFS.h"
|
||||
#include "Common/Thread/ThreadUtil.h"
|
||||
@@ -51,8 +52,6 @@ using namespace Windows::ApplicationModel::DataTransfer;
|
||||
using namespace Windows::Devices::Enumeration;
|
||||
using namespace Concurrency;
|
||||
|
||||
// UGLY!
|
||||
extern WindowsAudioBackend *winAudioBackend;
|
||||
std::list<std::unique_ptr<InputDevice>> g_input;
|
||||
|
||||
// TODO: Use Microsoft::WRL::ComPtr<> for D3D11 objects?
|
||||
@@ -362,10 +361,12 @@ std::vector<std::string> System_GetPropertyStringVec(SystemProperty prop) {
|
||||
}
|
||||
}
|
||||
|
||||
extern AudioBackend *g_audioBackend;
|
||||
|
||||
int64_t System_GetPropertyInt(SystemProperty prop) {
|
||||
switch (prop) {
|
||||
case SYSPROP_AUDIO_SAMPLE_RATE:
|
||||
return winAudioBackend ? winAudioBackend->GetSampleRate() : -1;
|
||||
return g_audioBackend ? g_audioBackend->SampleRate() : -1;
|
||||
|
||||
case SYSPROP_DEVICE_TYPE:
|
||||
{
|
||||
|
||||
@@ -7,19 +7,19 @@
|
||||
|
||||
#include "Common/Log.h"
|
||||
#include "Common/Thread/ThreadUtil.h"
|
||||
#include "Common/Audio/AudioBackend.h"
|
||||
#include "XAudioSoundStream.h"
|
||||
|
||||
#include <process.h>
|
||||
|
||||
const size_t BUFSIZE = 32 * 1024;
|
||||
|
||||
class XAudioBackend : public WindowsAudioBackend {
|
||||
class XAudioBackend : public AudioBackend {
|
||||
public:
|
||||
XAudioBackend();
|
||||
~XAudioBackend() override;
|
||||
|
||||
bool Init(StreamCallback callback, void *userdata = nullptr) override; // If fails, can safely delete the object
|
||||
int GetSampleRate() const override { return sampleRate_; }
|
||||
int SampleRate() const override { return sampleRate_; }
|
||||
int PeriodFrames() const override { return 0; }
|
||||
|
||||
private:
|
||||
@@ -159,7 +159,7 @@ void XAudioBackend::PollLoop() {
|
||||
// take ownership of the data. It needs to be big enough to fit the max number of buffers we check for
|
||||
// above, which it is, easily.
|
||||
|
||||
int stereoSamplesRendered = (*callback_)((short*)&realtimeBuffer_[cursor_], readCount / 4, sampleRate_);
|
||||
int stereoSamplesRendered = (*callback_)((short*)&realtimeBuffer_[cursor_], readCount / 4, sampleRate_, userdata_);
|
||||
int numBytesRendered = 2 * sizeof(short) * stereoSamplesRendered;
|
||||
|
||||
XAUDIO2_BUFFER xaudioBuffer{};
|
||||
@@ -180,7 +180,7 @@ void XAudioBackend::PollLoop() {
|
||||
SetEvent(exitEvent_);
|
||||
}
|
||||
|
||||
WindowsAudioBackend *CreateAudioBackend(AudioBackendType type) {
|
||||
AudioBackend *System_CreateAudioBackend() {
|
||||
// Only one type available on UWP.
|
||||
return new XAudioBackend();
|
||||
}
|
||||
|
||||
@@ -1,9 +1 @@
|
||||
#pragma once
|
||||
|
||||
#include "Common/CommonWindows.h"
|
||||
#include "Core/Config.h"
|
||||
|
||||
#include "Windows/WindowsAudio.h"
|
||||
|
||||
// Factory
|
||||
WindowsAudioBackend *CreateAudioBackend(AudioBackendType type);
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
// This should only be included from WindowsAudio.cpp and WASAPIStream.cpp.
|
||||
|
||||
class WASAPIAudioBackend : public WindowsAudioBackend {
|
||||
class WASAPIAudioBackend : public AudioBackend {
|
||||
public:
|
||||
WASAPIAudioBackend();
|
||||
~WASAPIAudioBackend();
|
||||
|
||||
bool Init(StreamCallback callback, void *userdata) override; // If fails, can safely delete the object
|
||||
int GetSampleRate() const override { return sampleRate_; }
|
||||
int SampleRate() const override { return sampleRate_; }
|
||||
int PeriodFrames() const override { return periodFrames_; } // amount of frames normally requested
|
||||
void FrameUpdate() override {}
|
||||
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
#include "WindowsAudio.h"
|
||||
#include "WASAPIContext.h"
|
||||
|
||||
WindowsAudioBackend *CreateAudioBackend(AudioBackendType type) {
|
||||
AudioBackend *System_CreateAudioBackend() {
|
||||
return new WASAPIAudioBackend();
|
||||
}
|
||||
|
||||
+1
-17
@@ -1,21 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "Common/CommonWindows.h"
|
||||
#include "Common/Audio/AudioBackend.h"
|
||||
#include "Core/ConfigValues.h"
|
||||
|
||||
// Always 2 channels, 16-bit audio.
|
||||
typedef int (*StreamCallback)(short *buffer, int numSamples, int rate, void *userdata);
|
||||
|
||||
// Note that the backend may override the passed in sample rate. The actual sample rate
|
||||
// should be returned by GetSampleRate though.
|
||||
class WindowsAudioBackend {
|
||||
public:
|
||||
virtual ~WindowsAudioBackend() {}
|
||||
virtual bool Init(StreamCallback _callback, void *userdata = nullptr) = 0;
|
||||
virtual int GetSampleRate() const = 0;
|
||||
virtual int PeriodFrames() const = 0;
|
||||
virtual void FrameUpdate() {}
|
||||
};
|
||||
|
||||
// Factory
|
||||
WindowsAudioBackend *CreateAudioBackend(AudioBackendType type);
|
||||
|
||||
+5
-9
@@ -277,7 +277,7 @@ std::vector<std::string> System_GetPropertyStringVec(SystemProperty prop) {
|
||||
}
|
||||
|
||||
// Ugly!
|
||||
extern WindowsAudioBackend *winAudioBackend;
|
||||
extern AudioBackend *winAudioBackend;
|
||||
|
||||
#ifdef _WIN32
|
||||
#if PPSSPP_PLATFORM(UWP)
|
||||
@@ -319,14 +319,16 @@ static float ScreenRefreshRateHz() {
|
||||
return rate;
|
||||
}
|
||||
|
||||
extern AudioBackend *g_audioBackend;
|
||||
|
||||
int64_t System_GetPropertyInt(SystemProperty prop) {
|
||||
switch (prop) {
|
||||
case SYSPROP_MAIN_WINDOW_HANDLE:
|
||||
return (int64_t)MainWindow::GetHWND();
|
||||
case SYSPROP_AUDIO_SAMPLE_RATE:
|
||||
return winAudioBackend ? winAudioBackend->GetSampleRate() : -1;
|
||||
return g_audioBackend ? g_audioBackend->SampleRate() : -1;
|
||||
case SYSPROP_AUDIO_FRAMES_PER_BUFFER:
|
||||
return winAudioBackend ? winAudioBackend->PeriodFrames() : -1;
|
||||
return g_audioBackend ? g_audioBackend->PeriodFrames() : -1;
|
||||
case SYSPROP_DEVICE_TYPE:
|
||||
return DEVICE_TYPE_DESKTOP;
|
||||
case SYSPROP_DISPLAY_COUNT:
|
||||
@@ -460,12 +462,6 @@ void System_Notify(SystemNotification notification) {
|
||||
PostDialogMessage(memoryWindow, WM_DEB_UPDATE);
|
||||
break;
|
||||
|
||||
case SystemNotification::POLL_AUDIO_DEVICE:
|
||||
if (winAudioBackend) {
|
||||
winAudioBackend->FrameUpdate();
|
||||
}
|
||||
break;
|
||||
|
||||
case SystemNotification::DISASSEMBLY:
|
||||
if (disasmWindow)
|
||||
PostDialogMessage(disasmWindow, WM_DEB_UPDATE);
|
||||
|
||||
@@ -820,6 +820,11 @@ retry:
|
||||
}
|
||||
}
|
||||
|
||||
AudioBackend *System_CreateAudioBackend() {
|
||||
// Use legacy mechanisms.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
extern "C" void Java_org_ppsspp_ppsspp_NativeApp_audioInit(JNIEnv *, jclass) {
|
||||
sampleRate = optimalSampleRate;
|
||||
if (optimalSampleRate == 0) {
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#import "IAPManager.h"
|
||||
|
||||
#include "Common/MemoryUtil.h"
|
||||
#include "Common/Audio/AudioBackend.h"
|
||||
#include "Common/System/NativeApp.h"
|
||||
#include "Common/System/System.h"
|
||||
#include "Common/System/Request.h"
|
||||
@@ -612,6 +613,11 @@ void System_Vibrate(int mode) {
|
||||
}
|
||||
}
|
||||
|
||||
AudioBackend *System_CreateAudioBackend() {
|
||||
// Use legacy mechanisms.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// SetCurrentThreadName("MainThread");
|
||||
|
||||
Reference in New Issue
Block a user