Add CubebUtils namespace and hook up cubeb logging
This commit is contained in:
parent
34ad1eb547
commit
d416cbd9ed
|
@ -38,6 +38,7 @@
|
||||||
<ClCompile Include="aldlist.cpp" />
|
<ClCompile Include="aldlist.cpp" />
|
||||||
<ClCompile Include="AudioCommon.cpp" />
|
<ClCompile Include="AudioCommon.cpp" />
|
||||||
<ClCompile Include="CubebStream.cpp" />
|
<ClCompile Include="CubebStream.cpp" />
|
||||||
|
<ClCompile Include="CubebUtils.cpp" />
|
||||||
<ClCompile Include="DPL2Decoder.cpp" />
|
<ClCompile Include="DPL2Decoder.cpp" />
|
||||||
<ClCompile Include="Mixer.cpp" />
|
<ClCompile Include="Mixer.cpp" />
|
||||||
<ClCompile Include="NullSoundStream.cpp" />
|
<ClCompile Include="NullSoundStream.cpp" />
|
||||||
|
@ -54,6 +55,7 @@
|
||||||
<ClInclude Include="AudioCommon.h" />
|
<ClInclude Include="AudioCommon.h" />
|
||||||
<ClInclude Include="CoreAudioSoundStream.h" />
|
<ClInclude Include="CoreAudioSoundStream.h" />
|
||||||
<ClInclude Include="CubebStream.h" />
|
<ClInclude Include="CubebStream.h" />
|
||||||
|
<ClInclude Include="CubebUtils.h" />
|
||||||
<ClInclude Include="DPL2Decoder.h" />
|
<ClInclude Include="DPL2Decoder.h" />
|
||||||
<ClInclude Include="Mixer.h" />
|
<ClInclude Include="Mixer.h" />
|
||||||
<ClInclude Include="NullSoundStream.h" />
|
<ClInclude Include="NullSoundStream.h" />
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="aldlist.cpp" />
|
<ClCompile Include="aldlist.cpp" />
|
||||||
<ClCompile Include="AudioCommon.cpp" />
|
<ClCompile Include="AudioCommon.cpp" />
|
||||||
|
<ClCompile Include="CubebUtils.cpp" />
|
||||||
<ClCompile Include="DPL2Decoder.cpp" />
|
<ClCompile Include="DPL2Decoder.cpp" />
|
||||||
<ClCompile Include="Mixer.cpp" />
|
<ClCompile Include="Mixer.cpp" />
|
||||||
<ClCompile Include="WaveFile.cpp" />
|
<ClCompile Include="WaveFile.cpp" />
|
||||||
|
@ -30,6 +31,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="aldlist.h" />
|
<ClInclude Include="aldlist.h" />
|
||||||
<ClInclude Include="AudioCommon.h" />
|
<ClInclude Include="AudioCommon.h" />
|
||||||
|
<ClInclude Include="CubebUtils.h" />
|
||||||
<ClInclude Include="DPL2Decoder.h" />
|
<ClInclude Include="DPL2Decoder.h" />
|
||||||
<ClInclude Include="Mixer.h" />
|
<ClInclude Include="Mixer.h" />
|
||||||
<ClInclude Include="WaveFile.h" />
|
<ClInclude Include="WaveFile.h" />
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
set(SRCS
|
set(SRCS
|
||||||
AudioCommon.cpp
|
AudioCommon.cpp
|
||||||
CubebStream.cpp
|
CubebStream.cpp
|
||||||
|
CubebUtils.cpp
|
||||||
DPL2Decoder.cpp
|
DPL2Decoder.cpp
|
||||||
Mixer.cpp
|
Mixer.cpp
|
||||||
WaveFile.cpp
|
WaveFile.cpp
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <cubeb/cubeb.h>
|
#include <cubeb/cubeb.h>
|
||||||
|
|
||||||
#include "AudioCommon/CubebStream.h"
|
#include "AudioCommon/CubebStream.h"
|
||||||
|
#include "AudioCommon/CubebUtils.h"
|
||||||
#include "AudioCommon/DPL2Decoder.h"
|
#include "AudioCommon/DPL2Decoder.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
@ -53,13 +54,9 @@ void CubebStream::StateCallback(cubeb_stream* stream, void* user_data, cubeb_sta
|
||||||
|
|
||||||
bool CubebStream::Start()
|
bool CubebStream::Start()
|
||||||
{
|
{
|
||||||
if (cubeb_init(&m_ctx, "Dolphin", nullptr) != CUBEB_OK)
|
m_ctx = CubebUtils::GetContext();
|
||||||
{
|
if (!m_ctx)
|
||||||
ERROR_LOG(AUDIO, "Error initializing cubeb library");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
INFO_LOG(AUDIO, "Cubeb initialized using %s backend", cubeb_get_backend_id(m_ctx));
|
|
||||||
|
|
||||||
m_stereo = !SConfig::GetInstance().bDPL2Decoder;
|
m_stereo = !SConfig::GetInstance().bDPL2Decoder;
|
||||||
|
|
||||||
|
@ -79,11 +76,11 @@ bool CubebStream::Start()
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 minimum_latency = 0;
|
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");
|
ERROR_LOG(AUDIO, "Error getting minimum latency");
|
||||||
INFO_LOG(AUDIO, "Minimum latency: %i frames", 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,
|
¶ms, std::max(BUFFER_SAMPLES, minimum_latency), DataCallback,
|
||||||
StateCallback, this) != CUBEB_OK)
|
StateCallback, this) != CUBEB_OK)
|
||||||
{
|
{
|
||||||
|
@ -106,7 +103,7 @@ void CubebStream::Stop()
|
||||||
ERROR_LOG(AUDIO, "Error stopping cubeb stream");
|
ERROR_LOG(AUDIO, "Error stopping cubeb stream");
|
||||||
}
|
}
|
||||||
cubeb_stream_destroy(m_stream);
|
cubeb_stream_destroy(m_stream);
|
||||||
cubeb_destroy(m_ctx);
|
m_ctx.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubebStream::SetVolume(int volume)
|
void CubebStream::SetVolume(int volume)
|
||||||
|
|
|
@ -20,7 +20,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_stereo = false;
|
bool m_stereo = false;
|
||||||
cubeb* m_ctx = nullptr;
|
std::shared_ptr<cubeb> m_ctx;
|
||||||
cubeb_stream* m_stream = nullptr;
|
cubeb_stream* m_stream = nullptr;
|
||||||
|
|
||||||
std::vector<short> m_short_buffer;
|
std::vector<short> m_short_buffer;
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
// Copyright 2017 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <cstdarg>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "AudioCommon/CubebUtils.h"
|
||||||
|
#include "Common/CommonPaths.h"
|
||||||
|
#include "Common/Logging/Log.h"
|
||||||
|
#include "Common/Logging/LogManager.h"
|
||||||
|
#include "Common/StringUtil.h"
|
||||||
|
|
||||||
|
#include <cubeb/cubeb.h>
|
||||||
|
|
||||||
|
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<cubeb> CubebUtils::GetContext()
|
||||||
|
{
|
||||||
|
static std::weak_ptr<cubeb> weak;
|
||||||
|
|
||||||
|
std::shared_ptr<cubeb> 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;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2017 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
struct cubeb;
|
||||||
|
|
||||||
|
namespace CubebUtils
|
||||||
|
{
|
||||||
|
std::shared_ptr<cubeb> GetContext();
|
||||||
|
} // namespace CubebUtils
|
|
@ -129,6 +129,12 @@ LogManager::~LogManager()
|
||||||
|
|
||||||
void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file,
|
void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file,
|
||||||
int line, const char* format, va_list args)
|
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];
|
char temp[MAX_MSGLEN];
|
||||||
LogContainer* log = m_Log[type];
|
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);
|
CharArrayFromFormatV(temp, MAX_MSGLEN, format, args);
|
||||||
|
|
||||||
const char* path_to_print = file + m_path_cutoff_point;
|
|
||||||
|
|
||||||
std::string msg = StringFromFormat(
|
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);
|
LogTypes::LOG_LEVEL_TO_CHAR[(int)level], log->GetShortName().c_str(), temp);
|
||||||
|
|
||||||
for (auto listener_id : *log)
|
for (auto listener_id : *log)
|
||||||
|
|
|
@ -96,6 +96,8 @@ public:
|
||||||
static u32 GetMaxLevel() { return MAX_LOGLEVEL; }
|
static u32 GetMaxLevel() { return MAX_LOGLEVEL; }
|
||||||
void Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file, int line,
|
void Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file, int line,
|
||||||
const char* fmt, va_list args);
|
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)
|
void SetLogLevel(LogTypes::LOG_TYPE type, LogTypes::LOG_LEVELS level)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
#include "AudioCommon/CubebUtils.h"
|
||||||
#include "Common/Common.h"
|
#include "Common/Common.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
@ -22,8 +23,7 @@ namespace ExpansionInterface
|
||||||
{
|
{
|
||||||
void CEXIMic::StreamInit()
|
void CEXIMic::StreamInit()
|
||||||
{
|
{
|
||||||
if (cubeb_init(&m_cubeb_ctx, "Dolphin", NULL) != CUBEB_OK)
|
m_cubeb_ctx = CubebUtils::GetContext();
|
||||||
ERROR_LOG(EXPANSIONINTERFACE, "Error initializing cubeb library");
|
|
||||||
|
|
||||||
stream_buffer = nullptr;
|
stream_buffer = nullptr;
|
||||||
samples_avail = stream_wpos = stream_rpos = 0;
|
samples_avail = stream_wpos = stream_rpos = 0;
|
||||||
|
@ -32,12 +32,7 @@ void CEXIMic::StreamInit()
|
||||||
void CEXIMic::StreamTerminate()
|
void CEXIMic::StreamTerminate()
|
||||||
{
|
{
|
||||||
StreamStop();
|
StreamStop();
|
||||||
|
m_cubeb_ctx.reset();
|
||||||
if (m_cubeb_ctx)
|
|
||||||
{
|
|
||||||
cubeb_destroy(m_cubeb_ctx);
|
|
||||||
m_cubeb_ctx = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void state_callback(cubeb_stream* stream, void* user_data, cubeb_state state)
|
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;
|
params.layout = CUBEB_LAYOUT_MONO;
|
||||||
|
|
||||||
u32 minimum_latency;
|
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");
|
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,
|
nullptr, ¶ms, nullptr, nullptr,
|
||||||
std::max<u32>(buff_size_samples, minimum_latency), data_callback,
|
std::max<u32>(buff_size_samples, minimum_latency), data_callback,
|
||||||
state_callback, this) != CUBEB_OK)
|
state_callback, this) != CUBEB_OK)
|
||||||
|
|
|
@ -69,7 +69,7 @@ private:
|
||||||
void UpdateNextInterruptTicks();
|
void UpdateNextInterruptTicks();
|
||||||
|
|
||||||
// Streaming input interface
|
// Streaming input interface
|
||||||
cubeb* m_cubeb_ctx = nullptr;
|
std::shared_ptr<cubeb> m_cubeb_ctx = nullptr;
|
||||||
cubeb_stream* m_cubeb_stream = nullptr;
|
cubeb_stream* m_cubeb_stream = nullptr;
|
||||||
|
|
||||||
void StreamLog(const char* msg);
|
void StreamLog(const char* msg);
|
||||||
|
|
Loading…
Reference in New Issue