diff --git a/Compatibility/Audio/AudioCommon.cpp b/Compatibility/Audio/AudioCommon.cpp new file mode 100644 index 000000000..6b07ce495 --- /dev/null +++ b/Compatibility/Audio/AudioCommon.cpp @@ -0,0 +1,178 @@ +// Copyright 2009 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "AudioCommon/AudioCommon.h" +#include "AudioCommon/Mixer.h" +#include "AudioCommon/NullSoundStream.h" +#include "OpenEmuAudioStream.h" +#include "Common/Common.h" +#include "Common/FileUtil.h" +#include "Common/Logging/Log.h" +#include "Core/ConfigManager.h" + +// This shouldn't be a global, at least not here. +std::unique_ptr g_sound_stream; + +static bool s_audio_dump_start = false; +static bool s_sound_stream_running = false; + +namespace AudioCommon +{ + static const int AUDIO_VOLUME_MIN = 0; + static const int AUDIO_VOLUME_MAX = 100; + + void InitSoundStream() + { + g_sound_stream = std::make_unique(); + + if (!g_sound_stream->Init()) + { + WARN_LOG(AUDIO, "Could not initialize backend"); + g_sound_stream = std::make_unique(); + } + + UpdateSoundStream(); + SetSoundStreamRunning(true); + + if (SConfig::GetInstance().m_DumpAudio && !s_audio_dump_start) + StartAudioDump(); + } + + void ShutdownSoundStream() + { + INFO_LOG(AUDIO, "Shutting down sound stream"); + + if (SConfig::GetInstance().m_DumpAudio && s_audio_dump_start) + StopAudioDump(); + + SetSoundStreamRunning(false); + g_sound_stream.reset(); + + INFO_LOG(AUDIO, "Done shutting down sound stream"); + } + + std::string GetDefaultSoundBackend() + { + std::string backend = "oeaudio"; + return backend; + } + + std::vector GetSoundBackends() + { + std::vector backends; + backends.push_back("oeaudio"); + return backends; + } + + bool SupportsDPL2Decoder(const std::string& backend) + { + return false; + } + + bool SupportsLatencyControl(const std::string& backend) + { + return false; + } + + bool SupportsVolumeChanges(const std::string& backend) + { + // FIXME: this one should ask the backend whether it supports it. + // but getting the backend from string etc. is probably + // too much just to enable/disable a stupid slider... + return false; + } + + void UpdateSoundStream() + { + if (g_sound_stream) + { + int volume = SConfig::GetInstance().m_IsMuted ? 0 : SConfig::GetInstance().m_Volume; + g_sound_stream->SetVolume(volume); + } + } + + void SetSoundStreamRunning(bool running) + { + if (!g_sound_stream) + return; + + if (s_sound_stream_running == running) + return; + s_sound_stream_running = running; + + if (g_sound_stream->SetRunning(running)) + return; + if (running) + ERROR_LOG(AUDIO, "Error starting stream."); + else + ERROR_LOG(AUDIO, "Error stopping stream."); + } + + void SendAIBuffer(const short* samples, unsigned int num_samples) + { + if (!g_sound_stream) + return; + + if (SConfig::GetInstance().m_DumpAudio && !s_audio_dump_start) + StartAudioDump(); + else if (!SConfig::GetInstance().m_DumpAudio && s_audio_dump_start) + StopAudioDump(); + + Mixer* pMixer = g_sound_stream->GetMixer(); + + if (pMixer && samples) + { + pMixer->PushSamples(samples, num_samples); + } + + g_sound_stream->Update(); + } + + void StartAudioDump() + { + std::string audio_file_name_dtk = File::GetUserPath(D_DUMPAUDIO_IDX) + "dtkdump.wav"; + std::string audio_file_name_dsp = File::GetUserPath(D_DUMPAUDIO_IDX) + "dspdump.wav"; + File::CreateFullPath(audio_file_name_dtk); + File::CreateFullPath(audio_file_name_dsp); + g_sound_stream->GetMixer()->StartLogDTKAudio(audio_file_name_dtk); + g_sound_stream->GetMixer()->StartLogDSPAudio(audio_file_name_dsp); + s_audio_dump_start = true; + } + + void StopAudioDump() + { + if (!g_sound_stream) + return; + g_sound_stream->GetMixer()->StopLogDTKAudio(); + g_sound_stream->GetMixer()->StopLogDSPAudio(); + s_audio_dump_start = false; + } + + void IncreaseVolume(unsigned short offset) + { + SConfig::GetInstance().m_IsMuted = false; + int& currentVolume = SConfig::GetInstance().m_Volume; + currentVolume += offset; + if (currentVolume > AUDIO_VOLUME_MAX) + currentVolume = AUDIO_VOLUME_MAX; + UpdateSoundStream(); + } + + void DecreaseVolume(unsigned short offset) + { + SConfig::GetInstance().m_IsMuted = false; + int& currentVolume = SConfig::GetInstance().m_Volume; + currentVolume -= offset; + if (currentVolume < AUDIO_VOLUME_MIN) + currentVolume = AUDIO_VOLUME_MIN; + UpdateSoundStream(); + } + + void ToggleMuteVolume() + { + bool& isMuted = SConfig::GetInstance().m_IsMuted; + isMuted = !isMuted; + UpdateSoundStream(); + } +} // namespace AudioCommon diff --git a/Compatibility/Audio/CubebStream.cpp b/Compatibility/Audio/CubebStream.cpp deleted file mode 100644 index 18d51b3fa..000000000 --- a/Compatibility/Audio/CubebStream.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2017 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include "DolphinGameCore.h" - -#include - -#include "AudioCommon/CubebStream.h" -#include "AudioCommon/CubebUtils.h" -#include "Common/CommonTypes.h" -#include "Common/Logging/Log.h" -#include "Common/Thread.h" -#include "Core/ConfigManager.h" - -// ~10 ms - needs to be at least 240 for surround -constexpr u32 BUFFER_SAMPLES = 512; - -long CubebStream::DataCallback(cubeb_stream* stream, void* user_data, const void* /*input_buffer*/, - void* output_buffer, long num_frames) -{ - auto* self = static_cast(user_data); - - if (self->m_stereo) { - self->m_mixer->Mix(static_cast(output_buffer), num_frames); - [[_current ringBufferAtIndex:0] write:(const uint8_t *)output_buffer maxLength:num_frames * 4]; //FRAME_STEREO_SHORT]; -}else{ - self->m_mixer->MixSurround(static_cast(output_buffer), num_frames); - [[_current ringBufferAtIndex:0] write:(const uint8_t *)output_buffer maxLength:num_frames * 2]; //FRAME_MONO_SHORT]; -} - return num_frames; -} - -void CubebStream::StateCallback(cubeb_stream* stream, void* user_data, cubeb_state state) -{ -} - -bool CubebStream::Init() -{ - m_ctx = CubebUtils::GetContext(); - if (!m_ctx) - return false; - - m_stereo = !SConfig::GetInstance().bDPL2Decoder; - - cubeb_stream_params params; - params.rate = m_mixer->GetSampleRate(); - if (m_stereo) - { - params.channels = 2; - params.format = CUBEB_SAMPLE_S16NE; - params.layout = CUBEB_LAYOUT_STEREO; - } - else - { - params.channels = 6; - params.format = CUBEB_SAMPLE_FLOAT32NE; - params.layout = CUBEB_LAYOUT_3F2_LFE; - } - - u32 minimum_latency = 0; - if (cubeb_get_min_latency(m_ctx.get(), ¶ms, &minimum_latency) != CUBEB_OK) - ERROR_LOG(AUDIO, "Error getting minimum latency"); - INFO_LOG(AUDIO, "Minimum latency: %i frames", minimum_latency); - - return cubeb_stream_init(m_ctx.get(), &m_stream, "Dolphin Audio Output", nullptr, nullptr, - nullptr, ¶ms, std::max(BUFFER_SAMPLES, minimum_latency), - DataCallback, StateCallback, this) == CUBEB_OK; -} - -bool CubebStream::SetRunning(bool running) -{ - if (running) - return cubeb_stream_start(m_stream) == CUBEB_OK; - else - return cubeb_stream_stop(m_stream) == CUBEB_OK; -} - -CubebStream::~CubebStream() -{ - SetRunning(false); - cubeb_stream_destroy(m_stream); - m_ctx.reset(); -} - -void CubebStream::SetVolume(int volume) -{ - cubeb_stream_set_volume(m_stream, volume / 100.0f); -} diff --git a/Compatibility/Audio/OpenEmuAudioStream.h b/Compatibility/Audio/OpenEmuAudioStream.h new file mode 100644 index 000000000..5be106028 --- /dev/null +++ b/Compatibility/Audio/OpenEmuAudioStream.h @@ -0,0 +1,55 @@ +// Copyright (c) 2018, OpenEmu Team +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the OpenEmu Team nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY OpenEmu Team ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL OpenEmu Team BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Copyright 2008 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#ifndef OpenEmuAudioStream_hpp +#define OpenEmuAudioStream_hpp + +#include "AudioCommon/SoundStream.h" + +/* the sample rate is hardcoded in the initializer of the SoundStream + * base class */ +#define OE_SAMPLERATE 48000 + +/* max amount of bytes pullable at once + * should be <= Mixer::MAX_SAMPLES * sizeof(short) * 2 (= 16384) + * however we can't use Mixer::MAX_SAMPLES because it is private */ +#define OE_SIZESOUNDBUFFER (16384 / 2) + +class OpenEmuAudioStream final : public SoundStream +{ +public: + bool Init() override { return true; } + bool SetRunning(bool running) override; + static bool isValid() { return true; } + int readAudio(void *buffer, int len); + ~OpenEmuAudioStream() {}; +private: + bool running; +}; + +#endif /* OpenEmuAudioStream_hpp */ diff --git a/Compatibility/Audio/OpenEmuAudioStream.mm b/Compatibility/Audio/OpenEmuAudioStream.mm new file mode 100644 index 000000000..50be2c3cf --- /dev/null +++ b/Compatibility/Audio/OpenEmuAudioStream.mm @@ -0,0 +1,48 @@ +// Copyright (c) 2018, OpenEmu Team +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the OpenEmu Team nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY OpenEmu Team ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL OpenEmu Team BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Copyright 2008 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include +#include "DolphinGameCore.h" +#include "OpenEmuAudioStream.h" + + +bool OpenEmuAudioStream::SetRunning(bool r) +{ + running = r; + return r; +} + + +int OpenEmuAudioStream::readAudio(void *buffer, int len) +{ + if (!running) + return 0; + Mixer *mix = m_mixer.get(); + int bytePerSample = 2 * sizeof(short); + return mix->Mix((short *)buffer, len / bytePerSample) * bytePerSample; +} diff --git a/Dolphin-Core.xcodeproj/project.pbxproj b/Dolphin-Core.xcodeproj/project.pbxproj index 59828690f..b97034c59 100644 --- a/Dolphin-Core.xcodeproj/project.pbxproj +++ b/Dolphin-Core.xcodeproj/project.pbxproj @@ -870,7 +870,6 @@ 3EFF294D1F8581B000B4FD11 /* AGL.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3E3D70261C82AF2A00091C4D /* AGL.mm */; }; 3EFF294F1F85830500B4FD11 /* Render.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3EFF28DD1F85604F00B4FD11 /* Render.cpp */; }; 3EFF29571F85A24400B4FD11 /* Render.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E89F4831CCE8AC600EAE7AC /* Render.cpp */; }; - 3EFF295A1F85B93600B4FD11 /* CubebStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3EFF29581F85B92E00B4FD11 /* CubebStream.cpp */; }; 3EFF295F1F85D08700B4FD11 /* libpugixml-dol.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3EFF277D1F8461BC00B4FD11 /* libpugixml-dol.a */; }; 8355D4C71A65393600E73302 /* libcore-dol.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C0C8A955FC946C29B9EDABF /* libcore-dol.a */; }; 8355D4E41A653B6600E73302 /* DolphinGameCore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8355D4E31A653B6600E73302 /* DolphinGameCore.mm */; }; @@ -1019,6 +1018,9 @@ EEC94A68224AC13A00F85ABA /* libOGLCompilersDLL-dol.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EEC94A62224ABFDC00F85ABA /* libOGLCompilersDLL-dol.a */; }; EECD3721224AAADE000AE115 /* libuicommon-dol.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 125948FD17D5434DA13C8293 /* libuicommon-dol.a */; }; EECD3722224AAB5C000AE115 /* libvideovulkan-dol.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EE3EC435224AA01500BA7436 /* libvideovulkan-dol.a */; }; + EEE07D3822C271D1006D46FD /* OpenEmuAudioStream.mm in Sources */ = {isa = PBXBuildFile; fileRef = EEE07D3422C26D0A006D46FD /* OpenEmuAudioStream.mm */; }; + EEE07D3922C271D1006D46FD /* AudioCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EEE07D3622C26DA7006D46FD /* AudioCommon.cpp */; }; + EEE07D3C22C272D5006D46FD /* libaudiocommon-dol.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F4EAB8D2A0AA45A183467CCD /* libaudiocommon-dol.a */; }; EEF4EEE6224AAF5D0077748D /* OpenEmuBase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E3D774A1C83DC9000091C4D /* OpenEmuBase.framework */; }; EEF4EEED224AAF980077748D /* ossource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EEF4EE81224AAE650077748D /* ossource.cpp */; }; EEF4EEEE224AAFB50077748D /* ParseHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EEF4EE98224AAE650077748D /* ParseHelper.cpp */; }; @@ -1571,6 +1573,13 @@ remoteGlobalIDString = A33327301E8D455CABCEF3CE; remoteInfo = uicommon; }; + EEE07D3A22C272CE006D46FD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8AE37EB7920C4C86939DE6E9 /* Project object */; + proxyType = 1; + remoteGlobalIDString = FFA5E2D5A7C543E9AEF69BE8; + remoteInfo = audiocommon; + }; EEF4EF0B224AAFFE0077748D /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 8AE37EB7920C4C86939DE6E9 /* Project object */; @@ -3158,7 +3167,6 @@ 3EFF29301F85626600B4FD11 /* net_sockets.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = net_sockets.c; path = dolphin/Externals/mbedtls/library/net_sockets.c; sourceTree = ""; }; 3EFF29311F85626700B4FD11 /* cmac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmac.c; path = dolphin/Externals/mbedtls/library/cmac.c; sourceTree = ""; }; 3EFF29511F858A2000B4FD11 /* VideoConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VideoConfig.h; path = VideoCommon/VideoConfig.h; sourceTree = ""; }; - 3EFF29581F85B92E00B4FD11 /* CubebStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CubebStream.cpp; path = Audio/CubebStream.cpp; sourceTree = ""; }; 4B3F200BFA3B4AA9B8072A6A /* libsfml-network-dol.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = "libsfml-network-dol.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 57799651D35F4D0F946361A2 /* libpng-dol.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = "libpng-dol.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 5AE2ADF9B49F4F4EB95615D5 /* libcommon-dol.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = "libcommon-dol.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -3479,6 +3487,9 @@ EEC94A50224ABFD200F85ABA /* InitializeDll.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InitializeDll.h; sourceTree = ""; }; EEC94A51224ABFD200F85ABA /* InitializeDll.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InitializeDll.cpp; sourceTree = ""; }; EEC94A62224ABFDC00F85ABA /* libOGLCompilersDLL-dol.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libOGLCompilersDLL-dol.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + EEE07D3322C26CD7006D46FD /* OpenEmuAudioStream.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OpenEmuAudioStream.h; path = Audio/OpenEmuAudioStream.h; sourceTree = ""; }; + EEE07D3422C26D0A006D46FD /* OpenEmuAudioStream.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = OpenEmuAudioStream.mm; path = Audio/OpenEmuAudioStream.mm; sourceTree = ""; }; + EEE07D3622C26DA7006D46FD /* AudioCommon.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AudioCommon.cpp; path = Audio/AudioCommon.cpp; sourceTree = ""; }; EEF4EE7E224AAE650077748D /* CMakeLists.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = ""; }; EEF4EE81224AAE650077748D /* ossource.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ossource.cpp; sourceTree = ""; }; EEF4EE82224AAE650077748D /* CMakeLists.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = ""; }; @@ -3638,6 +3649,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + EEE07D3C22C272D5006D46FD /* libaudiocommon-dol.a in Frameworks */, EE3A465F22B6880800031B56 /* libfmt-dol.a in Frameworks */, EE475779224AB4C50027BA05 /* libvideovulkan-dol.a in Frameworks */, EE475778224AB4BF0027BA05 /* libglslang-dol.a in Frameworks */, @@ -4401,7 +4413,9 @@ 3E89F4751CCA7A0500EAE7AC /* Audio */ = { isa = PBXGroup; children = ( - 3EFF29581F85B92E00B4FD11 /* CubebStream.cpp */, + EEE07D3322C26CD7006D46FD /* OpenEmuAudioStream.h */, + EEE07D3422C26D0A006D46FD /* OpenEmuAudioStream.mm */, + EEE07D3622C26DA7006D46FD /* AudioCommon.cpp */, ); name = Audio; sourceTree = ""; @@ -7316,6 +7330,7 @@ buildRules = ( ); dependencies = ( + EEE07D3B22C272CE006D46FD /* PBXTargetDependency */, EE3A465E22B687FA00031B56 /* PBXTargetDependency */, EE47577B224AB4D20027BA05 /* PBXTargetDependency */, 3EFF295E1F85D07E00B4FD11 /* PBXTargetDependency */, @@ -8936,12 +8951,13 @@ buildActionMask = 2147483647; files = ( 3E3D70A01C82B03600091C4D /* WaveFile.cpp in Sources */, - 3EFF295A1F85B93600B4FD11 /* CubebStream.cpp in Sources */, 3E8EC58E1F8428F100D79F27 /* CubebUtils.cpp in Sources */, 3E3D709C1C82B03600091C4D /* NullSoundStream.cpp in Sources */, + EEE07D3922C271D1006D46FD /* AudioCommon.cpp in Sources */, 3E3D709E1C82B03600091C4D /* OpenSLESStream.cpp in Sources */, 3E8EC58B1F8428DF00D79F27 /* OpenALStream.cpp in Sources */, EE8DD2C6224A7E1A005E1AF5 /* SurroundDecoder.cpp in Sources */, + EEE07D3822C271D1006D46FD /* OpenEmuAudioStream.mm in Sources */, 3E3D70981C82B03600091C4D /* AudioCommon.cpp in Sources */, 3E3D709B1C82B03600091C4D /* Mixer.cpp in Sources */, 3E8EC58C1F8428E500D79F27 /* AudioStretcher.cpp in Sources */, @@ -9450,6 +9466,11 @@ target = A33327301E8D455CABCEF3CE /* uicommon */; targetProxy = EECD371F224AAAD5000AE115 /* PBXContainerItemProxy */; }; + EEE07D3B22C272CE006D46FD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = FFA5E2D5A7C543E9AEF69BE8 /* audiocommon */; + targetProxy = EEE07D3A22C272CE006D46FD /* PBXContainerItemProxy */; + }; EEF4EF0C224AAFFE0077748D /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = EEF4EECC224AAF5D0077748D /* glslang */; @@ -10114,6 +10135,8 @@ $SRCROOT/dolphin/Externals/cubeb/msvc, $SRCROOT/dolphin/Externals, $SRCROOT/dolphin/Externals/FreeSurround/include, + "$(SRCROOT)/../OpenEmu/GameCube", + "$(SRCROOT)/../OpenEmu/Wii", ); INSTALL_PATH = ""; LIBRARY_STYLE = STATIC; @@ -10154,7 +10177,7 @@ OTHER_REZFLAGS = ""; PRODUCT_NAME = "$(TARGET_NAME)-dol"; SECTORDER_FLAGS = ""; - USE_HEADERMAP = NO; + USE_HEADERMAP = YES; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", @@ -10229,6 +10252,8 @@ $SRCROOT/dolphin/Externals/cubeb/msvc, $SRCROOT/dolphin/Externals, $SRCROOT/dolphin/Externals/FreeSurround/include, + "$(SRCROOT)/../OpenEmu/GameCube", + "$(SRCROOT)/../OpenEmu/Wii", ); INSTALL_PATH = ""; LIBRARY_STYLE = STATIC; @@ -10271,7 +10296,7 @@ OTHER_REZFLAGS = ""; PRODUCT_NAME = "$(TARGET_NAME)-dol"; SECTORDER_FLAGS = ""; - USE_HEADERMAP = NO; + USE_HEADERMAP = YES; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", @@ -10652,6 +10677,8 @@ $SRCROOT/dolphin/Externals/cubeb/msvc, $SRCROOT/dolphin/Externals, $SRCROOT/dolphin/Externals/FreeSurround/include, + "$(SRCROOT)/../OpenEmu/GameCube", + "$(SRCROOT)/../OpenEmu/Wii", ); INSTALL_PATH = ""; LIBRARY_STYLE = STATIC; @@ -10694,7 +10721,7 @@ OTHER_REZFLAGS = ""; PRODUCT_NAME = "$(TARGET_NAME)-dol"; SECTORDER_FLAGS = ""; - USE_HEADERMAP = NO; + USE_HEADERMAP = YES; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", @@ -16633,6 +16660,8 @@ $SRCROOT/dolphin/Externals/cubeb/msvc, $SRCROOT/dolphin/Externals, $SRCROOT/dolphin/Externals/FreeSurround/include, + "$(SRCROOT)/../OpenEmu/GameCube", + "$(SRCROOT)/../OpenEmu/Wii", ); INSTALL_PATH = ""; LIBRARY_STYLE = STATIC; @@ -16675,7 +16704,7 @@ OTHER_REZFLAGS = ""; PRODUCT_NAME = "$(TARGET_NAME)-dol"; SECTORDER_FLAGS = ""; - USE_HEADERMAP = NO; + USE_HEADERMAP = YES; WARNING_CFLAGS = ( "-Wmost", "-Wno-four-char-constants", diff --git a/DolphinGameCore.h b/DolphinGameCore.h index 3caf0d01d..b2b4bb0d5 100755 --- a/DolphinGameCore.h +++ b/DolphinGameCore.h @@ -27,13 +27,14 @@ #import #import #import +#import #import "OEGCSystemResponderClient.h" #import "Wii/OEWiiSystemResponderClient.h" @class OERingBuffer; OE_EXPORTED_CLASS -@interface DolphinGameCore : OEGameCore +@interface DolphinGameCore : OEGameCore - (void) swapBuffers; - (const char *) getBundlePath; diff --git a/DolphinGameCore.mm b/DolphinGameCore.mm index 37af29929..311890fe5 100755 --- a/DolphinGameCore.mm +++ b/DolphinGameCore.mm @@ -38,7 +38,9 @@ #import "DolphinGameCore.h" #include "DolHost.h" -#import +#include "AudioCommon/SoundStream.h" +#include "OpenEmuAudioStream.h" +#include #import #include @@ -54,26 +56,28 @@ DolphinGameCore *_current = 0; +extern std::unique_ptr g_sound_stream; + @implementation DolphinGameCore { DolHost *dol_host; uint16_t *_soundBuffer; bool _isWii; - bool _isInitialized; + atomic_bool _isInitialized; float _frameInterval; NSString *autoLoadStatefileName; NSString *_dolphinCoreModule; OEIntSize _dolphinCoreAspect; OEIntSize _dolphinCoreScreen; - } - (instancetype)init { - if(self = [super init]) + if(self = [super init]){ dol_host = DolHost::GetInstance(); + } _current = self; @@ -238,7 +242,29 @@ DolphinGameCore *_current = 0; - (double)audioSampleRate { - return SAMPLERATE; + return OE_SAMPLERATE; +} + +- (id)audioBufferAtIndex:(NSUInteger)index +{ + return self; +} + +- (NSUInteger)length +{ + return OE_SIZESOUNDBUFFER; +} + +- (NSUInteger)read:(void *)buffer maxLength:(NSUInteger)len +{ + if (_isInitialized && g_sound_stream) + return static_cast(g_sound_stream.get())->readAudio(buffer, (int)len); + return 0; +} + +- (NSUInteger)write:(const void *)buffer maxLength:(NSUInteger)length +{ + return 0; } # pragma mark - Save States