From d416cbd9ed5efb391ad65c36ded74c17ab713622 Mon Sep 17 00:00:00 2001 From: Michael Maltese Date: Sun, 23 Apr 2017 23:55:37 -0700 Subject: [PATCH] Add CubebUtils namespace and hook up cubeb logging --- Source/Core/AudioCommon/AudioCommon.vcxproj | 2 + .../AudioCommon/AudioCommon.vcxproj.filters | 2 + Source/Core/AudioCommon/CMakeLists.txt | 1 + Source/Core/AudioCommon/CubebStream.cpp | 15 ++-- Source/Core/AudioCommon/CubebStream.h | 2 +- Source/Core/AudioCommon/CubebUtils.cpp | 75 +++++++++++++++++++ Source/Core/AudioCommon/CubebUtils.h | 14 ++++ Source/Core/Common/Logging/LogManager.cpp | 10 ++- Source/Core/Common/Logging/LogManager.h | 2 + Source/Core/Core/HW/EXI/EXI_DeviceMic.cpp | 15 ++-- Source/Core/Core/HW/EXI/EXI_DeviceMic.h | 2 +- 11 files changed, 116 insertions(+), 24 deletions(-) create mode 100644 Source/Core/AudioCommon/CubebUtils.cpp create mode 100644 Source/Core/AudioCommon/CubebUtils.h diff --git a/Source/Core/AudioCommon/AudioCommon.vcxproj b/Source/Core/AudioCommon/AudioCommon.vcxproj index a112b0454d..2ccb711ee5 100644 --- a/Source/Core/AudioCommon/AudioCommon.vcxproj +++ b/Source/Core/AudioCommon/AudioCommon.vcxproj @@ -38,6 +38,7 @@ + @@ -54,6 +55,7 @@ + diff --git a/Source/Core/AudioCommon/AudioCommon.vcxproj.filters b/Source/Core/AudioCommon/AudioCommon.vcxproj.filters index dfd38a0336..7c3fe389ee 100644 --- a/Source/Core/AudioCommon/AudioCommon.vcxproj.filters +++ b/Source/Core/AudioCommon/AudioCommon.vcxproj.filters @@ -8,6 +8,7 @@ + @@ -30,6 +31,7 @@ + diff --git a/Source/Core/AudioCommon/CMakeLists.txt b/Source/Core/AudioCommon/CMakeLists.txt index 5f0c7c143b..94eb45c9ed 100644 --- a/Source/Core/AudioCommon/CMakeLists.txt +++ b/Source/Core/AudioCommon/CMakeLists.txt @@ -1,6 +1,7 @@ set(SRCS AudioCommon.cpp CubebStream.cpp + CubebUtils.cpp DPL2Decoder.cpp Mixer.cpp WaveFile.cpp diff --git a/Source/Core/AudioCommon/CubebStream.cpp b/Source/Core/AudioCommon/CubebStream.cpp index 21bf6d812c..c9052e29c9 100644 --- a/Source/Core/AudioCommon/CubebStream.cpp +++ b/Source/Core/AudioCommon/CubebStream.cpp @@ -5,6 +5,7 @@ #include #include "AudioCommon/CubebStream.h" +#include "AudioCommon/CubebUtils.h" #include "AudioCommon/DPL2Decoder.h" #include "Common/CommonTypes.h" #include "Common/Logging/Log.h" @@ -53,13 +54,9 @@ void CubebStream::StateCallback(cubeb_stream* stream, void* user_data, cubeb_sta bool CubebStream::Start() { - if (cubeb_init(&m_ctx, "Dolphin", nullptr) != CUBEB_OK) - { - ERROR_LOG(AUDIO, "Error initializing cubeb library"); + m_ctx = CubebUtils::GetContext(); + if (!m_ctx) return false; - } - - INFO_LOG(AUDIO, "Cubeb initialized using %s backend", cubeb_get_backend_id(m_ctx)); m_stereo = !SConfig::GetInstance().bDPL2Decoder; @@ -79,11 +76,11 @@ bool CubebStream::Start() } u32 minimum_latency = 0; - if (cubeb_get_min_latency(m_ctx, params, &minimum_latency) != CUBEB_OK) + if (cubeb_get_min_latency(m_ctx.get(), params, &minimum_latency) != CUBEB_OK) ERROR_LOG(AUDIO, "Error getting minimum latency"); INFO_LOG(AUDIO, "Minimum latency: %i frames", minimum_latency); - if (cubeb_stream_init(m_ctx, &m_stream, "Dolphin Audio Output", nullptr, nullptr, nullptr, + if (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) { @@ -106,7 +103,7 @@ void CubebStream::Stop() ERROR_LOG(AUDIO, "Error stopping cubeb stream"); } cubeb_stream_destroy(m_stream); - cubeb_destroy(m_ctx); + m_ctx.reset(); } void CubebStream::SetVolume(int volume) diff --git a/Source/Core/AudioCommon/CubebStream.h b/Source/Core/AudioCommon/CubebStream.h index 32434affd1..d0b153975e 100644 --- a/Source/Core/AudioCommon/CubebStream.h +++ b/Source/Core/AudioCommon/CubebStream.h @@ -20,7 +20,7 @@ public: private: bool m_stereo = false; - cubeb* m_ctx = nullptr; + std::shared_ptr m_ctx; cubeb_stream* m_stream = nullptr; std::vector m_short_buffer; diff --git a/Source/Core/AudioCommon/CubebUtils.cpp b/Source/Core/AudioCommon/CubebUtils.cpp new file mode 100644 index 0000000000..07f4f530d6 --- /dev/null +++ b/Source/Core/AudioCommon/CubebUtils.cpp @@ -0,0 +1,75 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include +#include +#include + +#include "AudioCommon/CubebUtils.h" +#include "Common/CommonPaths.h" +#include "Common/Logging/Log.h" +#include "Common/Logging/LogManager.h" +#include "Common/StringUtil.h" + +#include + +static ptrdiff_t s_path_cutoff_point = 0; + +static void LogCallback(const char* format, ...) +{ + if (!LogManager::GetInstance()) + return; + + va_list args; + va_start(args, format); + + const char* filename = va_arg(args, const char*) + s_path_cutoff_point; + int lineno = va_arg(args, int); + std::string adapted_format = StripSpaces(format + strlen("%s:%d:")); + + LogManager::GetInstance()->LogWithFullPath(LogTypes::LNOTICE, LogTypes::AUDIO, filename, lineno, + adapted_format.c_str(), args); + va_end(args); +} + +static void DestroyContext(cubeb* ctx) +{ + cubeb_destroy(ctx); + if (cubeb_set_log_callback(CUBEB_LOG_DISABLED, nullptr) != CUBEB_OK) + { + ERROR_LOG(AUDIO, "Error removing cubeb log callback"); + } +} + +std::shared_ptr CubebUtils::GetContext() +{ + static std::weak_ptr weak; + + std::shared_ptr shared = weak.lock(); + // Already initialized + if (shared) + return shared; + + const char* filename = __FILE__; + const char* match_point = strstr(filename, DIR_SEP "Source" DIR_SEP "Core" DIR_SEP); + if (match_point) + { + s_path_cutoff_point = match_point - filename + strlen(DIR_SEP "Externals" DIR_SEP); + } + if (cubeb_set_log_callback(CUBEB_LOG_NORMAL, LogCallback) != CUBEB_OK) + { + ERROR_LOG(AUDIO, "Error setting cubeb log callback"); + } + + cubeb* ctx; + if (cubeb_init(&ctx, "Dolphin", nullptr) != CUBEB_OK) + { + ERROR_LOG(AUDIO, "Error initializing cubeb library"); + return nullptr; + } + INFO_LOG(AUDIO, "Cubeb initialized using %s backend", cubeb_get_backend_id(ctx)); + + weak = shared = {ctx, DestroyContext}; + return shared; +} diff --git a/Source/Core/AudioCommon/CubebUtils.h b/Source/Core/AudioCommon/CubebUtils.h new file mode 100644 index 0000000000..adf6c25484 --- /dev/null +++ b/Source/Core/AudioCommon/CubebUtils.h @@ -0,0 +1,14 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include + +struct cubeb; + +namespace CubebUtils +{ +std::shared_ptr GetContext(); +} // namespace CubebUtils diff --git a/Source/Core/Common/Logging/LogManager.cpp b/Source/Core/Common/Logging/LogManager.cpp index 18fd57fd43..3b2d925047 100644 --- a/Source/Core/Common/Logging/LogManager.cpp +++ b/Source/Core/Common/Logging/LogManager.cpp @@ -129,6 +129,12 @@ LogManager::~LogManager() void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file, int line, const char* format, va_list args) +{ + return LogWithFullPath(level, type, file + m_path_cutoff_point, line, format, args); +} + +void LogManager::LogWithFullPath(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, + const char* file, int line, const char* format, va_list args) { char temp[MAX_MSGLEN]; LogContainer* log = m_Log[type]; @@ -138,10 +144,8 @@ void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const CharArrayFromFormatV(temp, MAX_MSGLEN, format, args); - const char* path_to_print = file + m_path_cutoff_point; - std::string msg = StringFromFormat( - "%s %s:%u %c[%s]: %s\n", Common::Timer::GetTimeFormatted().c_str(), path_to_print, line, + "%s %s:%u %c[%s]: %s\n", Common::Timer::GetTimeFormatted().c_str(), file, line, LogTypes::LOG_LEVEL_TO_CHAR[(int)level], log->GetShortName().c_str(), temp); for (auto listener_id : *log) diff --git a/Source/Core/Common/Logging/LogManager.h b/Source/Core/Common/Logging/LogManager.h index ea7f2d86a3..0ec3c1f7de 100644 --- a/Source/Core/Common/Logging/LogManager.h +++ b/Source/Core/Common/Logging/LogManager.h @@ -96,6 +96,8 @@ public: static u32 GetMaxLevel() { return MAX_LOGLEVEL; } void Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file, int line, const char* fmt, va_list args); + void LogWithFullPath(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file, + int line, const char* fmt, va_list args); void SetLogLevel(LogTypes::LOG_TYPE type, LogTypes::LOG_LEVELS level) { diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceMic.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceMic.cpp index 37f3b141bb..0ad3a263a3 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceMic.cpp +++ b/Source/Core/Core/HW/EXI/EXI_DeviceMic.cpp @@ -5,6 +5,7 @@ #include #include +#include "AudioCommon/CubebUtils.h" #include "Common/Common.h" #include "Common/CommonTypes.h" #include "Common/Logging/Log.h" @@ -22,8 +23,7 @@ namespace ExpansionInterface { void CEXIMic::StreamInit() { - if (cubeb_init(&m_cubeb_ctx, "Dolphin", NULL) != CUBEB_OK) - ERROR_LOG(EXPANSIONINTERFACE, "Error initializing cubeb library"); + m_cubeb_ctx = CubebUtils::GetContext(); stream_buffer = nullptr; samples_avail = stream_wpos = stream_rpos = 0; @@ -32,12 +32,7 @@ void CEXIMic::StreamInit() void CEXIMic::StreamTerminate() { StreamStop(); - - if (m_cubeb_ctx) - { - cubeb_destroy(m_cubeb_ctx); - m_cubeb_ctx = nullptr; - } + m_cubeb_ctx.reset(); } static void state_callback(cubeb_stream* stream, void* user_data, cubeb_state state) @@ -84,12 +79,12 @@ void CEXIMic::StreamStart() params.layout = CUBEB_LAYOUT_MONO; u32 minimum_latency; - if (cubeb_get_min_latency(m_cubeb_ctx, params, &minimum_latency) != CUBEB_OK) + if (cubeb_get_min_latency(m_cubeb_ctx.get(), params, &minimum_latency) != CUBEB_OK) { WARN_LOG(EXPANSIONINTERFACE, "Error getting minimum latency"); } - if (cubeb_stream_init(m_cubeb_ctx, &m_cubeb_stream, "Dolphin Emulated GameCube Microphone", + if (cubeb_stream_init(m_cubeb_ctx.get(), &m_cubeb_stream, "Dolphin Emulated GameCube Microphone", nullptr, ¶ms, nullptr, nullptr, std::max(buff_size_samples, minimum_latency), data_callback, state_callback, this) != CUBEB_OK) diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceMic.h b/Source/Core/Core/HW/EXI/EXI_DeviceMic.h index 7201edb35d..7f43798538 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceMic.h +++ b/Source/Core/Core/HW/EXI/EXI_DeviceMic.h @@ -69,7 +69,7 @@ private: void UpdateNextInterruptTicks(); // Streaming input interface - cubeb* m_cubeb_ctx = nullptr; + std::shared_ptr m_cubeb_ctx = nullptr; cubeb_stream* m_cubeb_stream = nullptr; void StreamLog(const char* msg);