1 // Copyright 2017 Dolphin Emulator Project
2 // Licensed under GPLv2+
3 // Refer to the license.txt file included.
4 
5 #include <cstdarg>
6 #include <cstddef>
7 #include <cstring>
8 
9 #include "AudioCommon/CubebUtils.h"
10 #include "Common/CommonPaths.h"
11 #include "Common/Logging/Log.h"
12 #include "Common/Logging/LogManager.h"
13 #include "Common/StringUtil.h"
14 
15 #include <cubeb/cubeb.h>
16 
17 static ptrdiff_t s_path_cutoff_point = 0;
18 
LogCallback(const char * format,...)19 static void LogCallback(const char* format, ...)
20 {
21   if (!Common::Log::LogManager::GetInstance())
22     return;
23 
24   va_list args;
25   va_start(args, format);
26 
27   const char* filename = va_arg(args, const char*) + s_path_cutoff_point;
28   int lineno = va_arg(args, int);
29   std::string adapted_format(StripSpaces(format + strlen("%s:%d:")));
30 
31   Common::Log::LogManager::GetInstance()->LogWithFullPath(
32       Common::Log::LNOTICE, Common::Log::AUDIO, filename, lineno, adapted_format.c_str(), args);
33   va_end(args);
34 }
35 
DestroyContext(cubeb * ctx)36 static void DestroyContext(cubeb* ctx)
37 {
38   cubeb_destroy(ctx);
39   if (cubeb_set_log_callback(CUBEB_LOG_DISABLED, nullptr) != CUBEB_OK)
40   {
41     ERROR_LOG(AUDIO, "Error removing cubeb log callback");
42   }
43 }
44 
GetContext()45 std::shared_ptr<cubeb> CubebUtils::GetContext()
46 {
47   static std::weak_ptr<cubeb> weak;
48 
49   std::shared_ptr<cubeb> shared = weak.lock();
50   // Already initialized
51   if (shared)
52     return shared;
53 
54   const char* filename = __FILE__;
55   const char* match_point = strstr(filename, DIR_SEP "Source" DIR_SEP "Core" DIR_SEP);
56   if (match_point)
57   {
58     s_path_cutoff_point = match_point - filename + strlen(DIR_SEP "Externals" DIR_SEP);
59   }
60   if (cubeb_set_log_callback(CUBEB_LOG_NORMAL, LogCallback) != CUBEB_OK)
61   {
62     ERROR_LOG(AUDIO, "Error setting cubeb log callback");
63   }
64 
65   cubeb* ctx;
66   if (cubeb_init(&ctx, "Dolphin", nullptr) != CUBEB_OK)
67   {
68     ERROR_LOG(AUDIO, "Error initializing cubeb library");
69     return nullptr;
70   }
71   INFO_LOG(AUDIO, "Cubeb initialized using %s backend", cubeb_get_backend_id(ctx));
72 
73   weak = shared = {ctx, DestroyContext};
74   return shared;
75 }
76