mirror of
https://github.com/danog/libtgvoip.git
synced 2024-11-30 04:39:03 +01:00
Logging to file(s) now works on all systems and logs now contain OS version in their header
On OS X, audio now plays only out of the right speaker on MacBook Pro's to avoid insane echo when using built-in speakers Fixed crash on Linux
This commit is contained in:
parent
510a977ff0
commit
5109903e02
@ -1854,8 +1854,10 @@ void VoIPController::SetConfig(voip_config_t *cfg){
|
|||||||
if(tgvoipLogFile){
|
if(tgvoipLogFile){
|
||||||
fclose(tgvoipLogFile);
|
fclose(tgvoipLogFile);
|
||||||
}
|
}
|
||||||
if(strlen(cfg->logFilePath))
|
if(strlen(cfg->logFilePath)){
|
||||||
tgvoipLogFile=fopen(cfg->logFilePath, "w");
|
tgvoipLogFile=fopen(cfg->logFilePath, "a");
|
||||||
|
tgvoip_log_file_write_header();
|
||||||
|
}
|
||||||
if(statsDump)
|
if(statsDump)
|
||||||
fclose(statsDump);
|
fclose(statsDump);
|
||||||
if(strlen(cfg->statsDumpFilePath)){
|
if(strlen(cfg->statsDumpFilePath)){
|
||||||
|
@ -30,6 +30,7 @@ using namespace tgvoip::audio;
|
|||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
int AudioOutput::systemVersion;
|
int AudioOutput::systemVersion;
|
||||||
#endif
|
#endif
|
||||||
|
int32_t AudioOutput::estimatedDelay=60;
|
||||||
|
|
||||||
AudioOutput *AudioOutput::Create(std::string deviceID){
|
AudioOutput *AudioOutput::Create(std::string deviceID){
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
@ -70,7 +71,7 @@ int32_t AudioOutput::GetEstimatedDelay(){
|
|||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
return systemVersion<21 ? 150 : 50;
|
return systemVersion<21 ? 150 : 50;
|
||||||
#endif
|
#endif
|
||||||
return 60;
|
return estimatedDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
float AudioOutput::GetLevel(){
|
float AudioOutput::GetLevel(){
|
||||||
|
@ -40,6 +40,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
std::string currentDevice;
|
std::string currentDevice;
|
||||||
bool failed;
|
bool failed;
|
||||||
|
static int32_t estimatedDelay;
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
@ -209,6 +209,8 @@
|
|||||||
'<(tgvoip_src_loc)/os/darwin/AudioInputAudioUnitOSX.h',
|
'<(tgvoip_src_loc)/os/darwin/AudioInputAudioUnitOSX.h',
|
||||||
'<(tgvoip_src_loc)/os/darwin/AudioOutputAudioUnitOSX.cpp',
|
'<(tgvoip_src_loc)/os/darwin/AudioOutputAudioUnitOSX.cpp',
|
||||||
'<(tgvoip_src_loc)/os/darwin/AudioOutputAudioUnitOSX.h',
|
'<(tgvoip_src_loc)/os/darwin/AudioOutputAudioUnitOSX.h',
|
||||||
|
'<(tgvoip_src_loc)/os/darwin/DarwinSpecific.mm',
|
||||||
|
'<(tgvoip_src_loc)/os/darwin/DarwinSpecific.h',
|
||||||
'<(tgvoip_src_loc)/os/posix/NetworkSocketPosix.cpp',
|
'<(tgvoip_src_loc)/os/posix/NetworkSocketPosix.cpp',
|
||||||
'<(tgvoip_src_loc)/os/posix/NetworkSocketPosix.h',
|
'<(tgvoip_src_loc)/os/posix/NetworkSocketPosix.h',
|
||||||
],
|
],
|
||||||
|
@ -46,6 +46,8 @@
|
|||||||
692AB91F1E675F7000706ACC /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 692AB91C1E675F7000706ACC /* AudioToolbox.framework */; };
|
692AB91F1E675F7000706ACC /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 692AB91C1E675F7000706ACC /* AudioToolbox.framework */; };
|
||||||
692AB9201E675F7000706ACC /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 692AB91D1E675F7000706ACC /* AudioUnit.framework */; };
|
692AB9201E675F7000706ACC /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 692AB91D1E675F7000706ACC /* AudioUnit.framework */; };
|
||||||
692AB9211E675F7000706ACC /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 692AB91E1E675F7000706ACC /* CoreAudio.framework */; };
|
692AB9211E675F7000706ACC /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 692AB91E1E675F7000706ACC /* CoreAudio.framework */; };
|
||||||
|
695B20621EBD39FF00E31757 /* DarwinSpecific.h in Headers */ = {isa = PBXBuildFile; fileRef = 695B20601EBD39FF00E31757 /* DarwinSpecific.h */; };
|
||||||
|
695B20631EBD39FF00E31757 /* DarwinSpecific.mm in Sources */ = {isa = PBXBuildFile; fileRef = 695B20611EBD39FF00E31757 /* DarwinSpecific.mm */; };
|
||||||
69A6DEB91E96149300000E69 /* array_view.h in Headers */ = {isa = PBXBuildFile; fileRef = 69A6DE231E96149300000E69 /* array_view.h */; };
|
69A6DEB91E96149300000E69 /* array_view.h in Headers */ = {isa = PBXBuildFile; fileRef = 69A6DE231E96149300000E69 /* array_view.h */; };
|
||||||
69A6DEBA1E96149300000E69 /* atomicops.h in Headers */ = {isa = PBXBuildFile; fileRef = 69A6DE241E96149300000E69 /* atomicops.h */; };
|
69A6DEBA1E96149300000E69 /* atomicops.h in Headers */ = {isa = PBXBuildFile; fileRef = 69A6DE241E96149300000E69 /* atomicops.h */; };
|
||||||
69A6DEBB1E96149300000E69 /* basictypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 69A6DE251E96149300000E69 /* basictypes.h */; };
|
69A6DEBB1E96149300000E69 /* basictypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 69A6DE251E96149300000E69 /* basictypes.h */; };
|
||||||
@ -269,6 +271,8 @@
|
|||||||
692AB91C1E675F7000706ACC /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
|
692AB91C1E675F7000706ACC /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
|
||||||
692AB91D1E675F7000706ACC /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
|
692AB91D1E675F7000706ACC /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
|
||||||
692AB91E1E675F7000706ACC /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
|
692AB91E1E675F7000706ACC /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
|
||||||
|
695B20601EBD39FF00E31757 /* DarwinSpecific.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DarwinSpecific.h; path = ../../../../../TDesktop/TBuild/tdesktop/third_party/libtgvoip/os/darwin/DarwinSpecific.h; sourceTree = "<group>"; };
|
||||||
|
695B20611EBD39FF00E31757 /* DarwinSpecific.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = DarwinSpecific.mm; path = ../../../../../TDesktop/TBuild/tdesktop/third_party/libtgvoip/os/darwin/DarwinSpecific.mm; sourceTree = "<group>"; };
|
||||||
69A6DE231E96149300000E69 /* array_view.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = array_view.h; sourceTree = "<group>"; };
|
69A6DE231E96149300000E69 /* array_view.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = array_view.h; sourceTree = "<group>"; };
|
||||||
69A6DE241E96149300000E69 /* atomicops.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = atomicops.h; sourceTree = "<group>"; };
|
69A6DE241E96149300000E69 /* atomicops.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = atomicops.h; sourceTree = "<group>"; };
|
||||||
69A6DE251E96149300000E69 /* basictypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = basictypes.h; sourceTree = "<group>"; };
|
69A6DE251E96149300000E69 /* basictypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = basictypes.h; sourceTree = "<group>"; };
|
||||||
@ -497,6 +501,8 @@
|
|||||||
69A6DF401E9614B700000E69 /* AudioInputAudioUnitOSX.h */,
|
69A6DF401E9614B700000E69 /* AudioInputAudioUnitOSX.h */,
|
||||||
69A6DF411E9614B700000E69 /* AudioOutputAudioUnitOSX.cpp */,
|
69A6DF411E9614B700000E69 /* AudioOutputAudioUnitOSX.cpp */,
|
||||||
69A6DF421E9614B700000E69 /* AudioOutputAudioUnitOSX.h */,
|
69A6DF421E9614B700000E69 /* AudioOutputAudioUnitOSX.h */,
|
||||||
|
695B20601EBD39FF00E31757 /* DarwinSpecific.h */,
|
||||||
|
695B20611EBD39FF00E31757 /* DarwinSpecific.mm */,
|
||||||
);
|
);
|
||||||
path = darwin;
|
path = darwin;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -847,6 +853,7 @@
|
|||||||
69A6DF341E96149300000E69 /* ooura_fft.h in Headers */,
|
69A6DF341E96149300000E69 /* ooura_fft.h in Headers */,
|
||||||
69A6DEBA1E96149300000E69 /* atomicops.h in Headers */,
|
69A6DEBA1E96149300000E69 /* atomicops.h in Headers */,
|
||||||
69A6DF0A1E96149300000E69 /* aec_resampler.h in Headers */,
|
69A6DF0A1E96149300000E69 /* aec_resampler.h in Headers */,
|
||||||
|
695B20621EBD39FF00E31757 /* DarwinSpecific.h in Headers */,
|
||||||
69A6DEE51E96149300000E69 /* spl_inl.h in Headers */,
|
69A6DEE51E96149300000E69 /* spl_inl.h in Headers */,
|
||||||
69A6DF3B1E96149300000E69 /* cpu_features_wrapper.h in Headers */,
|
69A6DF3B1E96149300000E69 /* cpu_features_wrapper.h in Headers */,
|
||||||
69A6DF211E96149300000E69 /* ns_core.h in Headers */,
|
69A6DF211E96149300000E69 /* ns_core.h in Headers */,
|
||||||
@ -1056,6 +1063,7 @@
|
|||||||
69A6DF101E96149300000E69 /* aecm_core_neon.cc in Sources */,
|
69A6DF101E96149300000E69 /* aecm_core_neon.cc in Sources */,
|
||||||
69A6DED71E96149300000E69 /* division_operations.c in Sources */,
|
69A6DED71E96149300000E69 /* division_operations.c in Sources */,
|
||||||
69A6DEDB1E96149300000E69 /* energy.c in Sources */,
|
69A6DEDB1E96149300000E69 /* energy.c in Sources */,
|
||||||
|
695B20631EBD39FF00E31757 /* DarwinSpecific.mm in Sources */,
|
||||||
69A6DEC61E96149300000E69 /* audio_util.cc in Sources */,
|
69A6DEC61E96149300000E69 /* audio_util.cc in Sources */,
|
||||||
69A6DF141E96149300000E69 /* analog_agc.c in Sources */,
|
69A6DF141E96149300000E69 /* analog_agc.c in Sources */,
|
||||||
69A6DEF81E96149300000E69 /* spl_sqrt_floor.c in Sources */,
|
69A6DEF81E96149300000E69 /* spl_sqrt_floor.c in Sources */,
|
||||||
|
70
logging.cpp
70
logging.cpp
@ -9,6 +9,21 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "VoIPController.h"
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
#include <sys/system_properties.h>
|
||||||
|
#elif defined(__linux__)
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <TargetConditionals.h>
|
||||||
|
#if TARGET_OS_OSX
|
||||||
|
#include "os/darwin/DarwinSpecific.h"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
FILE* tgvoipLogFile=NULL;
|
FILE* tgvoipLogFile=NULL;
|
||||||
|
|
||||||
void tgvoip_log_file_printf(char level, const char* msg, ...){
|
void tgvoip_log_file_printf(char level, const char* msg, ...){
|
||||||
@ -23,3 +38,58 @@ void tgvoip_log_file_printf(char level, const char* msg, ...){
|
|||||||
fflush(tgvoipLogFile);
|
fflush(tgvoipLogFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tgvoip_log_file_write_header(){
|
||||||
|
if(tgvoipLogFile){
|
||||||
|
time_t t = time(0);
|
||||||
|
struct tm *now = localtime(&t);
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#if WINAPI_PARTITION_DESKTOP
|
||||||
|
char systemVersion[64];
|
||||||
|
OSVERSIONINFOA vInfo;
|
||||||
|
vInfo.dwOSVersionInfoSize=sizeof(vInfo);
|
||||||
|
GetVersionExA(&vInfo);
|
||||||
|
snprintf(systemVersion, sizeof(systemVersion), "Windows %d.%d.%d %s", vInfo.dwMajorVersion, vInfo.dwMinorVersion, vInfo.dwBuildNumber, vInfo.szCSDVersion);
|
||||||
|
#else
|
||||||
|
char* systemVersion="Windows RT";
|
||||||
|
#endif
|
||||||
|
#elif defined(__linux__)
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
char systemVersion[128];
|
||||||
|
char sysRel[PROP_VALUE_MAX];
|
||||||
|
char deviceVendor[PROP_VALUE_MAX];
|
||||||
|
char deviceModel[PROP_VALUE_MAX];
|
||||||
|
__system_property_get("ro.build.version.release", sysRel);
|
||||||
|
__system_property_get("ro.product.manufacturer", deviceVendor);
|
||||||
|
__system_property_get("ro.product.model", deviceModel);
|
||||||
|
snprintf(systemVersion, sizeof(systemVersion), "Android %s (%s %s)", sysRel, deviceVendor, deviceModel);
|
||||||
|
#else
|
||||||
|
struct utsname sysname;
|
||||||
|
uname(&sysname);
|
||||||
|
char systemVersion[128];
|
||||||
|
snprintf(systemVersion, sizeof(systemVersion), "%s %s (%s)", sysname.sysname, sysname.release, sysname.version);
|
||||||
|
#endif
|
||||||
|
#elif defined(__APPLE__) && TARGET_OS_OSX
|
||||||
|
char osxVer[128];
|
||||||
|
tgvoip::DarwinSpecific::GetSystemName(osxVer, sizeof(osxVer));
|
||||||
|
char systemVersion[128];
|
||||||
|
snprintf(systemVersion, sizeof(systemVersion), "OS X %s", osxVer);
|
||||||
|
#else
|
||||||
|
const char* systemVersion="Unknown OS";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__aarch64__)
|
||||||
|
const char* cpuArch="ARM64";
|
||||||
|
#elif defined(__arm__) || defined(_M_ARM)
|
||||||
|
const char* cpuArch="ARM";
|
||||||
|
#elif defined(_M_X64) || defined(__x86_64__)
|
||||||
|
const char* cpuArch="x86_64";
|
||||||
|
#elif defined(_M_IX86) || defined(__i386__)
|
||||||
|
const char* cpuArch="x86";
|
||||||
|
#else
|
||||||
|
const char* cpuArch="Unknown CPU";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fprintf(tgvoipLogFile, "---------------\nlibtgvoip v" LIBTGVOIP_VERSION " on %s %s\nLog started on %d/%02d/%d at %d:%02d:%02d\n---------------\n", systemVersion, cpuArch, now->tm_mday, now->tm_mon+1, now->tm_year+1900, now->tm_hour, now->tm_min, now->tm_sec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
48
logging.h
48
logging.h
@ -14,6 +14,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void tgvoip_log_file_printf(char level, const char* msg, ...);
|
void tgvoip_log_file_printf(char level, const char* msg, ...);
|
||||||
|
void tgvoip_log_file_write_header();
|
||||||
|
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
|
|
||||||
@ -43,24 +44,49 @@ void tgvoip_log_file_printf(char level, const char* msg, ...);
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define _TGVOIP_W32_LOG_PRINT(msg, ...){ char __log_buf[1024]; snprintf(__log_buf, 1024, msg, ##__VA_ARGS__); OutputDebugStringA(__log_buf); }
|
#define _TGVOIP_W32_LOG_PRINT(verb, msg, ...){ char __log_buf[1024]; snprintf(__log_buf, 1024, "%c/tgvoip: " msg "\n", verb, ##__VA_ARGS__); OutputDebugStringA(__log_buf); tgvoip_log_file_printf((char)verb, msg, __VA_ARGS__);}
|
||||||
|
|
||||||
#define LOGV(msg, ...) _TGVOIP_W32_LOG_PRINT("V/tgvoip: " msg "\n", ##__VA_ARGS__)
|
#define LOGV(msg, ...) _TGVOIP_W32_LOG_PRINT('V', msg, ##__VA_ARGS__)
|
||||||
#define LOGD(msg, ...) _TGVOIP_W32_LOG_PRINT("D/tgvoip: " msg "\n", ##__VA_ARGS__)
|
#define LOGD(msg, ...) _TGVOIP_W32_LOG_PRINT('D', msg, ##__VA_ARGS__)
|
||||||
#define LOGI(msg, ...) _TGVOIP_W32_LOG_PRINT("I/tgvoip: " msg "\n", ##__VA_ARGS__)
|
#define LOGI(msg, ...) _TGVOIP_W32_LOG_PRINT('I', msg, ##__VA_ARGS__)
|
||||||
#define LOGW(msg, ...) _TGVOIP_W32_LOG_PRINT("W/tgvoip: " msg "\n", ##__VA_ARGS__)
|
#define LOGW(msg, ...) _TGVOIP_W32_LOG_PRINT('W', msg, ##__VA_ARGS__)
|
||||||
#define LOGE(msg, ...) _TGVOIP_W32_LOG_PRINT("E/tgvoip: " msg "\n", ##__VA_ARGS__)
|
#define LOGE(msg, ...) _TGVOIP_W32_LOG_PRINT('E', msg, ##__VA_ARGS__)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define LOGV(msg, ...) printf("V/tgvoip: " msg "\n", ##__VA_ARGS__)
|
#define _TGVOIP_LOG_PRINT(verb, msg, ...) {printf("%c/tgvoip: " msg "\n", verb, ##__VA_ARGS__); tgvoip_log_file_printf(verb, msg, ##__VA_ARGS__);}
|
||||||
#define LOGD(msg, ...) printf("D/tgvoip: " msg "\n", ##__VA_ARGS__)
|
|
||||||
#define LOGI(msg, ...) printf("I/tgvoip: " msg "\n", ##__VA_ARGS__)
|
#define LOGV(msg, ...) _TGVOIP_LOG_PRINT('V', msg, ##__VA_ARGS__)
|
||||||
#define LOGW(msg, ...) printf("W/tgvoip: " msg "\n", ##__VA_ARGS__)
|
#define LOGD(msg, ...) _TGVOIP_LOG_PRINT('D', msg, ##__VA_ARGS__)
|
||||||
#define LOGE(msg, ...) printf("E/tgvoip: " msg "\n", ##__VA_ARGS__)
|
#define LOGI(msg, ...) _TGVOIP_LOG_PRINT('I', msg, ##__VA_ARGS__)
|
||||||
|
#define LOGW(msg, ...) _TGVOIP_LOG_PRINT('W', msg, ##__VA_ARGS__)
|
||||||
|
#define LOGE(msg, ...) _TGVOIP_LOG_PRINT('E', msg, ##__VA_ARGS__)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef TGVOIP_LOG_VERBOSITY
|
||||||
|
#if TGVOIP_LOG_VERBOSITY<5
|
||||||
|
#undef LOGV
|
||||||
|
#define LOGV(msg, ...)
|
||||||
|
#endif
|
||||||
|
#if TGVOIP_LOG_VERBOSITY<4
|
||||||
|
#undef LOGD
|
||||||
|
#define LOGD(msg, ...)
|
||||||
|
#endif
|
||||||
|
#if TGVOIP_LOG_VERBOSITY<3
|
||||||
|
#undef LOGI
|
||||||
|
#define LOGI(msg, ...)
|
||||||
|
#endif
|
||||||
|
#if TGVOIP_LOG_VERBOSITY<2
|
||||||
|
#undef LOGW
|
||||||
|
#define LOGW(msg, ...)
|
||||||
|
#endif
|
||||||
|
#if TGVOIP_LOG_VERBOSITY<1
|
||||||
|
#undef LOGE
|
||||||
|
#define LOGE(msg, ...)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif //__LOGGING_H
|
#endif //__LOGGING_H
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
#include "AudioOutputAudioUnitOSX.h"
|
#include "AudioOutputAudioUnitOSX.h"
|
||||||
#include "../../logging.h"
|
#include "../../logging.h"
|
||||||
#include "../../VoIPController.h"
|
#include "../../VoIPController.h"
|
||||||
@ -22,6 +23,7 @@ using namespace tgvoip::audio;
|
|||||||
AudioOutputAudioUnit::AudioOutputAudioUnit(std::string deviceID){
|
AudioOutputAudioUnit::AudioOutputAudioUnit(std::string deviceID){
|
||||||
remainingDataSize=0;
|
remainingDataSize=0;
|
||||||
isPlaying=false;
|
isPlaying=false;
|
||||||
|
sysDevID=NULL;
|
||||||
|
|
||||||
OSStatus status;
|
OSStatus status;
|
||||||
AudioComponentDescription inputDesc={
|
AudioComponentDescription inputDesc={
|
||||||
@ -39,6 +41,15 @@ AudioOutputAudioUnit::AudioOutputAudioUnit(std::string deviceID){
|
|||||||
status = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof(flag));
|
status = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof(flag));
|
||||||
CHECK_AU_ERROR(status, "Error enabling AudioUnit input");
|
CHECK_AU_ERROR(status, "Error enabling AudioUnit input");
|
||||||
|
|
||||||
|
char model[128];
|
||||||
|
memset(model, 0, sizeof(model));
|
||||||
|
size_t msize=sizeof(model);
|
||||||
|
int mres=sysctlbyname("hw.model", model, &msize, NULL, 0);
|
||||||
|
if(mres==0){
|
||||||
|
LOGV("Mac model: %s", model);
|
||||||
|
isMacBookPro=(strncmp("MacBookPro", model, 10)==0);
|
||||||
|
}
|
||||||
|
|
||||||
SetCurrentDevice(deviceID);
|
SetCurrentDevice(deviceID);
|
||||||
|
|
||||||
CFRunLoopRef theRunLoop = NULL;
|
CFRunLoopRef theRunLoop = NULL;
|
||||||
@ -76,6 +87,15 @@ AudioOutputAudioUnit::~AudioOutputAudioUnit(){
|
|||||||
propertyAddress.mElement = kAudioObjectPropertyElementMaster;
|
propertyAddress.mElement = kAudioObjectPropertyElementMaster;
|
||||||
AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &propertyAddress, AudioOutputAudioUnit::DefaultDeviceChangedCallback, this);
|
AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &propertyAddress, AudioOutputAudioUnit::DefaultDeviceChangedCallback, this);
|
||||||
|
|
||||||
|
AudioObjectPropertyAddress dataSourceProp={
|
||||||
|
kAudioDevicePropertyDataSource,
|
||||||
|
kAudioDevicePropertyScopeOutput,
|
||||||
|
kAudioObjectPropertyElementMaster
|
||||||
|
};
|
||||||
|
if(isMacBookPro && sysDevID && AudioObjectHasProperty(sysDevID, &dataSourceProp)){
|
||||||
|
AudioObjectRemovePropertyListener(sysDevID, &dataSourceProp, AudioOutputAudioUnit::DefaultDeviceChangedCallback, this);
|
||||||
|
}
|
||||||
|
|
||||||
AudioUnitUninitialize(unit);
|
AudioUnitUninitialize(unit);
|
||||||
AudioComponentInstanceDispose(unit);
|
AudioComponentInstanceDispose(unit);
|
||||||
}
|
}
|
||||||
@ -216,8 +236,17 @@ void AudioOutputAudioUnit::EnumerateDevices(std::vector<AudioOutputDevice>& devs
|
|||||||
|
|
||||||
void AudioOutputAudioUnit::SetCurrentDevice(std::string deviceID){
|
void AudioOutputAudioUnit::SetCurrentDevice(std::string deviceID){
|
||||||
UInt32 size=sizeof(AudioDeviceID);
|
UInt32 size=sizeof(AudioDeviceID);
|
||||||
AudioDeviceID inputDevice=NULL;
|
AudioDeviceID outputDevice=NULL;
|
||||||
OSStatus status;
|
OSStatus status;
|
||||||
|
AudioObjectPropertyAddress dataSourceProp={
|
||||||
|
kAudioDevicePropertyDataSource,
|
||||||
|
kAudioDevicePropertyScopeOutput,
|
||||||
|
kAudioObjectPropertyElementMaster
|
||||||
|
};
|
||||||
|
|
||||||
|
if(isMacBookPro && sysDevID && AudioObjectHasProperty(sysDevID, &dataSourceProp)){
|
||||||
|
AudioObjectRemovePropertyListener(sysDevID, &dataSourceProp, AudioOutputAudioUnit::DefaultDeviceChangedCallback, this);
|
||||||
|
}
|
||||||
|
|
||||||
if(deviceID=="default"){
|
if(deviceID=="default"){
|
||||||
AudioObjectPropertyAddress propertyAddress;
|
AudioObjectPropertyAddress propertyAddress;
|
||||||
@ -225,7 +254,7 @@ void AudioOutputAudioUnit::SetCurrentDevice(std::string deviceID){
|
|||||||
propertyAddress.mScope = kAudioObjectPropertyScopeGlobal;
|
propertyAddress.mScope = kAudioObjectPropertyScopeGlobal;
|
||||||
propertyAddress.mElement = kAudioObjectPropertyElementMaster;
|
propertyAddress.mElement = kAudioObjectPropertyElementMaster;
|
||||||
UInt32 propsize = sizeof(AudioDeviceID);
|
UInt32 propsize = sizeof(AudioDeviceID);
|
||||||
status = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &propsize, &inputDevice);
|
status = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &propsize, &outputDevice);
|
||||||
CHECK_AU_ERROR(status, "Error getting default input device");
|
CHECK_AU_ERROR(status, "Error getting default input device");
|
||||||
}else{
|
}else{
|
||||||
AudioObjectPropertyAddress propertyAddress = {
|
AudioObjectPropertyAddress propertyAddress = {
|
||||||
@ -251,11 +280,11 @@ void AudioOutputAudioUnit::SetCurrentDevice(std::string deviceID){
|
|||||||
CFStringGetCString(deviceUID, buf, 1024, kCFStringEncodingUTF8);
|
CFStringGetCString(deviceUID, buf, 1024, kCFStringEncodingUTF8);
|
||||||
if(deviceID==buf){
|
if(deviceID==buf){
|
||||||
LOGV("Found device for id %s", buf);
|
LOGV("Found device for id %s", buf);
|
||||||
inputDevice=audioDevices[i];
|
outputDevice=audioDevices[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!inputDevice){
|
if(!outputDevice){
|
||||||
LOGW("Requested device not found, using default");
|
LOGW("Requested device not found, using default");
|
||||||
SetCurrentDevice("default");
|
SetCurrentDevice("default");
|
||||||
return;
|
return;
|
||||||
@ -266,7 +295,7 @@ void AudioOutputAudioUnit::SetCurrentDevice(std::string deviceID){
|
|||||||
kAudioOutputUnitProperty_CurrentDevice,
|
kAudioOutputUnitProperty_CurrentDevice,
|
||||||
kAudioUnitScope_Global,
|
kAudioUnitScope_Global,
|
||||||
kOutputBus,
|
kOutputBus,
|
||||||
&inputDevice,
|
&outputDevice,
|
||||||
size);
|
size);
|
||||||
CHECK_AU_ERROR(status, "Error setting output device");
|
CHECK_AU_ERROR(status, "Error setting output device");
|
||||||
|
|
||||||
@ -287,13 +316,53 @@ void AudioOutputAudioUnit::SetCurrentDevice(std::string deviceID){
|
|||||||
LOGD("Switched playback device, new sample rate %d", hardwareSampleRate);
|
LOGD("Switched playback device, new sample rate %d", hardwareSampleRate);
|
||||||
|
|
||||||
this->currentDevice=deviceID;
|
this->currentDevice=deviceID;
|
||||||
|
sysDevID=outputDevice;
|
||||||
|
|
||||||
|
AudioObjectPropertyAddress propertyAddress = {
|
||||||
|
kAudioDevicePropertyBufferFrameSize,
|
||||||
|
kAudioObjectPropertyScopeGlobal,
|
||||||
|
kAudioObjectPropertyElementMaster
|
||||||
|
};
|
||||||
|
size=4;
|
||||||
|
UInt32 bufferFrameSize;
|
||||||
|
status=AudioObjectGetPropertyData(outputDevice, &propertyAddress, 0, NULL, &size, &bufferFrameSize);
|
||||||
|
if(status==noErr){
|
||||||
|
estimatedDelay=bufferFrameSize/48;
|
||||||
|
LOGD("CoreAudio buffer size for output device is %u frames (%u ms)", bufferFrameSize, estimatedDelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isMacBookPro){
|
||||||
|
if(AudioObjectHasProperty(outputDevice, &dataSourceProp)){
|
||||||
|
UInt32 dataSource;
|
||||||
|
size=4;
|
||||||
|
AudioObjectGetPropertyData(outputDevice, &dataSourceProp, 0, NULL, &size, &dataSource);
|
||||||
|
SetPanRight(dataSource=='ispk');
|
||||||
|
AudioObjectAddPropertyListener(outputDevice, &dataSourceProp, AudioOutputAudioUnit::DefaultDeviceChangedCallback, this);
|
||||||
|
}else{
|
||||||
|
SetPanRight(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioOutputAudioUnit::SetPanRight(bool panRight){
|
||||||
|
LOGI("%sabling pan right on macbook pro", panRight ? "En" : "Dis");
|
||||||
|
int32_t channelMap[]={panRight ? -1 : 0, 0};
|
||||||
|
OSStatus status=AudioUnitSetProperty(unit, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Global, kOutputBus, channelMap, sizeof(channelMap));
|
||||||
|
CHECK_AU_ERROR(status, "Error setting channel map");
|
||||||
}
|
}
|
||||||
|
|
||||||
OSStatus AudioOutputAudioUnit::DefaultDeviceChangedCallback(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *inClientData){
|
OSStatus AudioOutputAudioUnit::DefaultDeviceChangedCallback(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *inClientData){
|
||||||
LOGV("System default input device changed");
|
|
||||||
AudioOutputAudioUnit* self=(AudioOutputAudioUnit*)inClientData;
|
AudioOutputAudioUnit* self=(AudioOutputAudioUnit*)inClientData;
|
||||||
|
if(inAddresses[0].mSelector==kAudioHardwarePropertyDefaultOutputDevice){
|
||||||
|
LOGV("System default input device changed");
|
||||||
if(self->currentDevice=="default"){
|
if(self->currentDevice=="default"){
|
||||||
self->SetCurrentDevice(self->currentDevice);
|
self->SetCurrentDevice(self->currentDevice);
|
||||||
}
|
}
|
||||||
|
}else if(inAddresses[0].mSelector==kAudioDevicePropertyDataSource){
|
||||||
|
UInt32 dataSource;
|
||||||
|
UInt32 size=4;
|
||||||
|
AudioObjectGetPropertyData(inObjectID, inAddresses, 0, NULL, &size, &dataSource);
|
||||||
|
self->SetPanRight(dataSource=='ispk');
|
||||||
|
}
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
|
@ -29,11 +29,14 @@ public:
|
|||||||
private:
|
private:
|
||||||
static OSStatus BufferCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData);
|
static OSStatus BufferCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData);
|
||||||
static OSStatus DefaultDeviceChangedCallback(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *inClientData);
|
static OSStatus DefaultDeviceChangedCallback(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *inClientData);
|
||||||
|
void SetPanRight(bool panRight);
|
||||||
unsigned char remainingData[10240];
|
unsigned char remainingData[10240];
|
||||||
size_t remainingDataSize;
|
size_t remainingDataSize;
|
||||||
bool isPlaying;
|
bool isPlaying;
|
||||||
AudioUnit unit;
|
AudioUnit unit;
|
||||||
int hardwareSampleRate;
|
int hardwareSampleRate;
|
||||||
|
bool isMacBookPro;
|
||||||
|
AudioDeviceID sysDevID;
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
19
os/darwin/DarwinSpecific.h
Normal file
19
os/darwin/DarwinSpecific.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// libtgvoip is free and unencumbered public domain software.
|
||||||
|
// For more information, see http://unlicense.org or the UNLICENSE file
|
||||||
|
// you should have received with this source code distribution.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef TGVOIP_DARWINSPECIFIC_H
|
||||||
|
#define TGVOIP_DARWINSPECIFIC_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace tgvoip {
|
||||||
|
class DarwinSpecific{
|
||||||
|
public:
|
||||||
|
static void GetSystemName(char* buf, size_t len);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //TGVOIP_DARWINSPECIFIC_H
|
17
os/darwin/DarwinSpecific.mm
Normal file
17
os/darwin/DarwinSpecific.mm
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// libtgvoip is free and unencumbered public domain software.
|
||||||
|
// For more information, see http://unlicense.org or the UNLICENSE file
|
||||||
|
// you should have received with this source code distribution.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "DarwinSpecific.h"
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
using namespace tgvoip;
|
||||||
|
|
||||||
|
void DarwinSpecific::GetSystemName(char* buf, size_t len){
|
||||||
|
NSString* v=[[NSProcessInfo processInfo] operatingSystemVersionString];
|
||||||
|
strcpy(buf, [v UTF8String]);
|
||||||
|
//[v getCString:buf maxLength:sizeof(buf) encoding:NSUTF8StringEncoding];
|
||||||
|
}
|
@ -21,6 +21,7 @@ using namespace tgvoip::audio;
|
|||||||
|
|
||||||
AudioInputALSA::AudioInputALSA(std::string devID){
|
AudioInputALSA::AudioInputALSA(std::string devID){
|
||||||
isRecording=false;
|
isRecording=false;
|
||||||
|
handle=NULL;
|
||||||
|
|
||||||
lib=dlopen("libasound.so", RTLD_LAZY);
|
lib=dlopen("libasound.so", RTLD_LAZY);
|
||||||
if(!lib){
|
if(!lib){
|
||||||
@ -36,13 +37,13 @@ AudioInputALSA::AudioInputALSA(std::string devID){
|
|||||||
LOAD_FUNCTION(lib, "snd_pcm_recover", _snd_pcm_recover);
|
LOAD_FUNCTION(lib, "snd_pcm_recover", _snd_pcm_recover);
|
||||||
LOAD_FUNCTION(lib, "snd_strerror", _snd_strerror);
|
LOAD_FUNCTION(lib, "snd_strerror", _snd_strerror);
|
||||||
|
|
||||||
handle=NULL;
|
|
||||||
|
|
||||||
SetCurrentDevice(devID);
|
SetCurrentDevice(devID);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioInputALSA::~AudioInputALSA(){
|
AudioInputALSA::~AudioInputALSA(){
|
||||||
|
if(handle)
|
||||||
_snd_pcm_close(handle);
|
_snd_pcm_close(handle);
|
||||||
|
if(lib)
|
||||||
dlclose(lib);
|
dlclose(lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ using namespace tgvoip::audio;
|
|||||||
|
|
||||||
AudioOutputALSA::AudioOutputALSA(std::string devID){
|
AudioOutputALSA::AudioOutputALSA(std::string devID){
|
||||||
isPlaying=false;
|
isPlaying=false;
|
||||||
|
handle=NULL;
|
||||||
|
|
||||||
lib=dlopen("libasound.so", RTLD_LAZY);
|
lib=dlopen("libasound.so", RTLD_LAZY);
|
||||||
if(!lib){
|
if(!lib){
|
||||||
@ -35,13 +36,13 @@ AudioOutputALSA::AudioOutputALSA(std::string devID){
|
|||||||
LOAD_FUNCTION(lib, "snd_pcm_recover", _snd_pcm_recover);
|
LOAD_FUNCTION(lib, "snd_pcm_recover", _snd_pcm_recover);
|
||||||
LOAD_FUNCTION(lib, "snd_strerror", _snd_strerror);
|
LOAD_FUNCTION(lib, "snd_strerror", _snd_strerror);
|
||||||
|
|
||||||
handle=NULL;
|
|
||||||
|
|
||||||
SetCurrentDevice(devID);
|
SetCurrentDevice(devID);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioOutputALSA::~AudioOutputALSA(){
|
AudioOutputALSA::~AudioOutputALSA(){
|
||||||
|
if(handle)
|
||||||
_snd_pcm_close(handle);
|
_snd_pcm_close(handle);
|
||||||
|
if(lib)
|
||||||
dlclose(lib);
|
dlclose(lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user