mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Merge pull request #20534 from hrydgard/refactor-audio
Add internal AudioBackend interface
This commit is contained in:
+3
-2
@@ -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
|
||||
@@ -2625,8 +2626,8 @@ add_dependencies(${CoreLibName} GitVersion)
|
||||
set(WindowsFiles
|
||||
Windows/WindowsAudio.cpp
|
||||
Windows/WindowsAudio.h
|
||||
Windows/WASAPIStream.cpp
|
||||
Windows/WASAPIStream.h
|
||||
Windows/WASAPIContext.cpp
|
||||
Windows/WASAPIContext.h
|
||||
Windows/Debugger/BreakpointWindow.cpp
|
||||
Windows/Debugger/BreakpointWindow.h
|
||||
Windows/Debugger/DumpMemoryWindow.cpp
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -164,16 +164,17 @@ LogManager::LogManager() {
|
||||
stdioUseColor_ = isatty(fileno(stdout));
|
||||
#endif
|
||||
|
||||
#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP)
|
||||
#if PPSSPP_PLATFORM(WINDOWS)
|
||||
if (IsDebuggerPresent()) {
|
||||
outputs_ |= LogOutput::DebugString;
|
||||
}
|
||||
|
||||
#if !PPSSPP_PLATFORM(UWP)
|
||||
if (!consoleLog_) {
|
||||
consoleLog_ = new ConsoleListener();
|
||||
}
|
||||
outputs_ |= LogOutput::WinConsole;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
LogManager::~LogManager() {
|
||||
|
||||
@@ -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.
|
||||
@@ -64,7 +65,7 @@ void NativeFrame(GraphicsContext *graphicsContext);
|
||||
// the rest of the game, so be careful with synchronization.
|
||||
// Returns the number of samples actually output. The app should do everything it can
|
||||
// to fill the buffer completely.
|
||||
int NativeMix(short *audio, int num_samples, int sampleRateHz);
|
||||
int NativeMix(short *audio, int num_samples, int sampleRateHz, void *userdata);
|
||||
|
||||
// Called when it's time to shutdown. After this has been called,
|
||||
// no more calls to any other function will be made from the framework
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
+1
-1
@@ -344,7 +344,7 @@ static u32 sceSasSetVoice(u32 core, int voiceNum, u32 vagAddr, int size, int loo
|
||||
|
||||
u32 prevVagAddr = v.vagAddr;
|
||||
bool reset = false;
|
||||
if (v.type != VOICETYPE_VAG || v.vagAddr != vagAddr || v.vagSize != size || v.loop != loop) {
|
||||
if (v.type != VOICETYPE_VAG || v.vagAddr != vagAddr || v.vagSize != size || v.loop != (loop != 0)) {
|
||||
v.type = VOICETYPE_VAG;
|
||||
reset = true;
|
||||
}
|
||||
|
||||
+7
-1
@@ -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"
|
||||
@@ -78,7 +79,7 @@ SDL_AudioSpec g_retFmt;
|
||||
static SDL_AudioDeviceID audioDev = 0;
|
||||
|
||||
extern void mixaudio(void *userdata, Uint8 *stream, int len) {
|
||||
NativeMix((short *)stream, len / 4, AUDIO_FREQ);
|
||||
NativeMix((short *)stream, len / 4, AUDIO_FREQ, userdata);
|
||||
}
|
||||
|
||||
static void InitSDLAudioDevice() {
|
||||
@@ -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();
|
||||
|
||||
+7
-1
@@ -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"
|
||||
@@ -134,7 +135,7 @@ int getDisplayNumber(void) {
|
||||
}
|
||||
|
||||
void sdl_mixaudio_callback(void *userdata, Uint8 *stream, int len) {
|
||||
NativeMix((short *)stream, len / (2 * 2), g_sampleRate);
|
||||
NativeMix((short *)stream, len / (2 * 2), g_sampleRate, userdata);
|
||||
}
|
||||
|
||||
static SDL_AudioDeviceID audioDev = 0;
|
||||
@@ -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:
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ StereoResampler g_resampler;
|
||||
|
||||
// numFrames is number of stereo frames.
|
||||
// This is called from *outside* the emulator thread.
|
||||
int NativeMix(int16_t *outStereo, int numFrames, int sampleRateHz) {
|
||||
int NativeMix(int16_t *outStereo, int numFrames, int sampleRateHz, void *userdata) {
|
||||
int validFrames = g_resampler.Mix(outStereo, numFrames, false, sampleRateHz);
|
||||
|
||||
// Mix sound effects on top.
|
||||
|
||||
@@ -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
-17
@@ -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(0, &NativeMix, 44100);
|
||||
#else
|
||||
winAudioBackend->Init(MainWindow::GetHWND(), &NativeMix, 44100);
|
||||
#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;
|
||||
@@ -1097,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;
|
||||
@@ -1534,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,20 @@
|
||||
|
||||
#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(HWND window, StreamCallback callback, int sampleRate) override; // If fails, can safely delete the object
|
||||
int GetSampleRate() const override { return sampleRate_; }
|
||||
bool Init(StreamCallback callback, void *userdata = nullptr) override; // If fails, can safely delete the object
|
||||
int SampleRate() const override { return sampleRate_; }
|
||||
int PeriodFrames() const override { return 0; }
|
||||
|
||||
private:
|
||||
bool RunSound();
|
||||
@@ -32,7 +33,10 @@ private:
|
||||
IXAudio2MasteringVoice *xaudioMaster = nullptr;
|
||||
IXAudio2SourceVoice *xaudioVoice = nullptr;
|
||||
|
||||
int sampleRate_ = 0;
|
||||
void *userdata_ = nullptr;
|
||||
|
||||
int sampleRate_ = 44100;
|
||||
int periodFrames_ = 0;
|
||||
|
||||
char realtimeBuffer_[BUFSIZE]{};
|
||||
uint32_t cursor_ = 0;
|
||||
@@ -126,9 +130,9 @@ XAudioBackend::~XAudioBackend() {
|
||||
xaudioDevice->Release();
|
||||
}
|
||||
|
||||
bool XAudioBackend::Init(HWND window, StreamCallback _callback, int sampleRate) {
|
||||
bool XAudioBackend::Init(StreamCallback _callback, void *userdata) {
|
||||
callback_ = _callback;
|
||||
sampleRate_ = sampleRate;
|
||||
userdata_ = userdata;
|
||||
return RunSound();
|
||||
}
|
||||
|
||||
@@ -155,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{};
|
||||
@@ -170,12 +174,13 @@ void XAudioBackend::PollLoop() {
|
||||
cursor_ = 0;
|
||||
bytesLeftInBuffer = BUFSIZE;
|
||||
}
|
||||
periodFrames_ = stereoSamplesRendered;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -718,7 +718,7 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="W32Util\UAHMenuBar.cpp" />
|
||||
<ClCompile Include="WASAPIStream.cpp" />
|
||||
<ClCompile Include="WASAPIContext.cpp" />
|
||||
<ClCompile Include="WindowsAudio.cpp" />
|
||||
<ClCompile Include="WindowsHost.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
@@ -1166,7 +1166,7 @@
|
||||
<ClInclude Include="MainWindow.h" />
|
||||
<ClInclude Include="GPU\WindowsGLContext.h" />
|
||||
<ClInclude Include="W32Util\UAHMenuBar.h" />
|
||||
<ClInclude Include="WASAPIStream.h" />
|
||||
<ClInclude Include="WASAPIContext.h" />
|
||||
<ClInclude Include="WindowsAudio.h" />
|
||||
<ClInclude Include="WindowsHost.h" />
|
||||
<ClInclude Include="main.h" />
|
||||
@@ -1434,4 +1434,4 @@
|
||||
<UserProperties RESOURCE_FILE="DaSh.rc" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -181,7 +181,7 @@
|
||||
<ClCompile Include="WindowsAudio.cpp">
|
||||
<Filter>Windows\System</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="WASAPIStream.cpp">
|
||||
<ClCompile Include="WASAPIContext.cpp">
|
||||
<Filter>Windows\System</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CaptureDevice.cpp">
|
||||
@@ -390,7 +390,7 @@
|
||||
<ClInclude Include="WindowsAudio.h">
|
||||
<Filter>Windows\System</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="WASAPIStream.h">
|
||||
<ClInclude Include="WASAPIContext.h">
|
||||
<Filter>Windows\System</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ppsspp_config.h" />
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <initguid.h>
|
||||
#include "WindowsAudio.h"
|
||||
#include "WASAPIStream.h"
|
||||
#include "WASAPIContext.h"
|
||||
#include "Common/Log.h"
|
||||
#include "Common/LogReporting.h"
|
||||
#include "Core/Config.h"
|
||||
@@ -186,8 +186,7 @@ private:
|
||||
#define REFTIMES_PER_SEC (10000000/200)
|
||||
#define REFTIMES_PER_MILLISEC (REFTIMES_PER_SEC / 1000)
|
||||
|
||||
WASAPIAudioBackend::WASAPIAudioBackend() : threadData_(0) {
|
||||
}
|
||||
WASAPIAudioBackend::WASAPIAudioBackend() : threadData_(0) { }
|
||||
|
||||
WASAPIAudioBackend::~WASAPIAudioBackend() {
|
||||
if (threadData_ == 0) {
|
||||
@@ -210,10 +209,10 @@ unsigned int WINAPI WASAPIAudioBackend::soundThread(void *param) {
|
||||
return backend->RunThread();
|
||||
}
|
||||
|
||||
bool WASAPIAudioBackend::Init(HWND window, StreamCallback callback, int sampleRate) {
|
||||
bool WASAPIAudioBackend::Init(StreamCallback callback, void *userdata) {
|
||||
threadData_ = 0;
|
||||
userdata_ = userdata;
|
||||
callback_ = callback;
|
||||
sampleRate_ = sampleRate;
|
||||
hThread_ = (HANDLE)_beginthreadex(0, 0, soundThread, (void *)this, 0, 0);
|
||||
if (!hThread_)
|
||||
return false;
|
||||
@@ -493,7 +492,7 @@ void WASAPIAudioThread::Run() {
|
||||
int chans = deviceFormat_->Format.nChannels;
|
||||
switch (format_) {
|
||||
case Format::IEEE_FLOAT:
|
||||
callback_(shortBuf_, pNumAvFrames, sampleRate_);
|
||||
callback_(shortBuf_, pNumAvFrames, sampleRate_, nullptr);
|
||||
if (chans == 1) {
|
||||
float *ptr = (float *)pData;
|
||||
memset(ptr, 0, pNumAvFrames * chans * sizeof(float));
|
||||
@@ -512,7 +511,7 @@ void WASAPIAudioThread::Run() {
|
||||
}
|
||||
break;
|
||||
case Format::PCM16:
|
||||
callback_((short *)pData, pNumAvFrames, sampleRate_);
|
||||
callback_((short *)pData, pNumAvFrames, sampleRate_, nullptr);
|
||||
break;
|
||||
case Format::UNKNOWN:
|
||||
break;
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include "WindowsAudio.h"
|
||||
|
||||
// This should only be included from WindowsAudio.cpp and WASAPIStream.cpp.
|
||||
|
||||
class WASAPIAudioBackend : public AudioBackend {
|
||||
public:
|
||||
WASAPIAudioBackend();
|
||||
~WASAPIAudioBackend();
|
||||
|
||||
bool Init(StreamCallback callback, void *userdata) override; // If fails, can safely delete the object
|
||||
int SampleRate() const override { return sampleRate_; }
|
||||
int PeriodFrames() const override { return periodFrames_; } // amount of frames normally requested
|
||||
void FrameUpdate() override {}
|
||||
|
||||
private:
|
||||
int RunThread();
|
||||
static unsigned int WINAPI soundThread(void *param);
|
||||
|
||||
HANDLE hThread_ = nullptr;
|
||||
StreamCallback callback_ = nullptr;
|
||||
int sampleRate_ = 0;
|
||||
int periodFrames_ = 0;
|
||||
void *userdata_ = 0;
|
||||
std::atomic<int> threadData_{};
|
||||
};
|
||||
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include "WindowsAudio.h"
|
||||
|
||||
// This should only be included from WindowsAudio.cpp and WASAPIStream.cpp.
|
||||
|
||||
class WASAPIAudioBackend : public WindowsAudioBackend {
|
||||
public:
|
||||
WASAPIAudioBackend();
|
||||
~WASAPIAudioBackend();
|
||||
|
||||
bool Init(HWND window, StreamCallback callback, int sampleRate) override; // If fails, can safely delete the object
|
||||
int GetSampleRate() const override { return sampleRate_; }
|
||||
|
||||
private:
|
||||
int RunThread();
|
||||
static unsigned int WINAPI soundThread(void *param);
|
||||
|
||||
HANDLE hThread_ = nullptr;
|
||||
StreamCallback callback_ = nullptr;
|
||||
int sampleRate_ = 0;
|
||||
std::atomic<int> threadData_;
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "Common/OSVersion.h"
|
||||
#include "WindowsAudio.h"
|
||||
#include "WASAPIStream.h"
|
||||
#include "WASAPIContext.h"
|
||||
|
||||
WindowsAudioBackend *CreateAudioBackend(AudioBackendType type) {
|
||||
AudioBackend *System_CreateAudioBackend() {
|
||||
return new WASAPIAudioBackend();
|
||||
}
|
||||
|
||||
+1
-15
@@ -1,19 +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);
|
||||
|
||||
// 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(HWND window, StreamCallback _callback, int sampleRate) = 0;
|
||||
virtual int GetSampleRate() const = 0;
|
||||
};
|
||||
|
||||
// Factory
|
||||
WindowsAudioBackend *CreateAudioBackend(AudioBackendType type);
|
||||
|
||||
+7
-2
@@ -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,12 +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 g_audioBackend ? g_audioBackend->PeriodFrames() : -1;
|
||||
case SYSPROP_DEVICE_TYPE:
|
||||
return DEVICE_TYPE_DESKTOP;
|
||||
case SYSPROP_DISPLAY_COUNT:
|
||||
@@ -485,6 +489,7 @@ void System_Notify(SystemNotification notification) {
|
||||
|
||||
case SystemNotification::POLL_CONTROLLERS:
|
||||
g_inputManager.PollControllers();
|
||||
// Also poll the audio backend for changes.
|
||||
break;
|
||||
|
||||
case SystemNotification::TOGGLE_DEBUG_CONSOLE:
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
|
||||
typedef int (*AndroidAudioCallback)(short *buffer, int numSamples, int sampleRateHz);
|
||||
typedef int (*AndroidAudioCallback)(short *buffer, int numSamples, int sampleRateHz, void *userdata);
|
||||
|
||||
class AudioContext {
|
||||
public:
|
||||
|
||||
@@ -49,7 +49,7 @@ void OpenSLContext::BqPlayerCallback(SLAndroidSimpleBufferQueueItf bq) {
|
||||
return;
|
||||
}
|
||||
|
||||
int renderedFrames = audioCallback(buffer[curBuffer], framesPerBuffer, SampleRate());
|
||||
int renderedFrames = audioCallback(buffer[curBuffer], framesPerBuffer, SampleRate(), nullptr);
|
||||
|
||||
int sizeInBytes = framesPerBuffer * 2 * sizeof(short);
|
||||
int byteCount = (framesPerBuffer - renderedFrames) * 4;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
+2
-2
@@ -19,7 +19,7 @@ static volatile BOOL done = 0;
|
||||
#define SAMPLE_SIZE 44100
|
||||
static short stream[SAMPLE_SIZE];
|
||||
|
||||
int NativeMix(short *audio, int numSamples, int sampleRateHz);
|
||||
int NativeMix(short *audio, int numSamples, int sampleRateHz, void *userdata);
|
||||
|
||||
@interface AudioEngine ()
|
||||
|
||||
@@ -125,7 +125,7 @@ int NativeMix(short *audio, int numSamples, int sampleRateHz);
|
||||
{
|
||||
size_t frames_ready;
|
||||
if (![self playing])
|
||||
frames_ready = NativeMix(stream, SAMPLE_SIZE / 2, sampleRateHz);
|
||||
frames_ready = NativeMix(stream, SAMPLE_SIZE / 2, sampleRateHz, 0);
|
||||
else
|
||||
frames_ready = 0;
|
||||
|
||||
|
||||
+2
-2
@@ -74,7 +74,7 @@ void iOSCoreAudioSetDisplayConnected(bool connected) {
|
||||
iOSCoreAudioUpdateSession();
|
||||
}
|
||||
|
||||
int NativeMix(short *audio, int numSamples, int sampleRate);
|
||||
int NativeMix(short *audio, int numSamples, int sampleRate, void *userdata);
|
||||
|
||||
OSStatus iOSCoreAudioCallback(void *inRefCon,
|
||||
AudioUnitRenderActionFlags *ioActionFlags,
|
||||
@@ -85,7 +85,7 @@ OSStatus iOSCoreAudioCallback(void *inRefCon,
|
||||
{
|
||||
// see if we have any sound to play
|
||||
short *output = (short *)ioData->mBuffers[0].mData;
|
||||
UInt32 framesReady = NativeMix(output, inNumberFrames, SAMPLE_RATE);
|
||||
UInt32 framesReady = NativeMix(output, inNumberFrames, SAMPLE_RATE, nullptr);
|
||||
|
||||
if (framesReady == 0) {
|
||||
// oops, we don't currently have any sound, so return silence
|
||||
|
||||
@@ -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