From 5109903e02fef0162db150ac9f2c23111603c83b Mon Sep 17 00:00:00 2001 From: Grishka Date: Sat, 6 May 2017 02:18:34 +0300 Subject: [PATCH] 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 --- VoIPController.cpp | 6 +- audio/AudioOutput.cpp | 3 +- audio/AudioOutput.h | 1 + libtgvoip.gyp | 2 + libtgvoip_osx.xcodeproj/project.pbxproj | 8 +++ logging.cpp | 70 ++++++++++++++++++++ logging.h | 48 ++++++++++---- os/darwin/AudioOutputAudioUnitOSX.cpp | 85 ++++++++++++++++++++++--- os/darwin/AudioOutputAudioUnitOSX.h | 3 + os/darwin/DarwinSpecific.h | 19 ++++++ os/darwin/DarwinSpecific.mm | 17 +++++ os/linux/AudioInputALSA.cpp | 9 +-- os/linux/AudioOutputALSA.cpp | 9 +-- 13 files changed, 250 insertions(+), 30 deletions(-) create mode 100644 os/darwin/DarwinSpecific.h create mode 100644 os/darwin/DarwinSpecific.mm diff --git a/VoIPController.cpp b/VoIPController.cpp index abc5761..83f6cdd 100644 --- a/VoIPController.cpp +++ b/VoIPController.cpp @@ -1854,8 +1854,10 @@ void VoIPController::SetConfig(voip_config_t *cfg){ if(tgvoipLogFile){ fclose(tgvoipLogFile); } - if(strlen(cfg->logFilePath)) - tgvoipLogFile=fopen(cfg->logFilePath, "w"); + if(strlen(cfg->logFilePath)){ + tgvoipLogFile=fopen(cfg->logFilePath, "a"); + tgvoip_log_file_write_header(); + } if(statsDump) fclose(statsDump); if(strlen(cfg->statsDumpFilePath)){ diff --git a/audio/AudioOutput.cpp b/audio/AudioOutput.cpp index f1f8853..10cb290 100644 --- a/audio/AudioOutput.cpp +++ b/audio/AudioOutput.cpp @@ -30,6 +30,7 @@ using namespace tgvoip::audio; #if defined(__ANDROID__) int AudioOutput::systemVersion; #endif +int32_t AudioOutput::estimatedDelay=60; AudioOutput *AudioOutput::Create(std::string deviceID){ #if defined(__ANDROID__) @@ -70,7 +71,7 @@ int32_t AudioOutput::GetEstimatedDelay(){ #if defined(__ANDROID__) return systemVersion<21 ? 150 : 50; #endif - return 60; + return estimatedDelay; } float AudioOutput::GetLevel(){ diff --git a/audio/AudioOutput.h b/audio/AudioOutput.h index d700e8b..02225b4 100644 --- a/audio/AudioOutput.h +++ b/audio/AudioOutput.h @@ -40,6 +40,7 @@ public: protected: std::string currentDevice; bool failed; + static int32_t estimatedDelay; }; }} diff --git a/libtgvoip.gyp b/libtgvoip.gyp index 817770f..c9b94b6 100644 --- a/libtgvoip.gyp +++ b/libtgvoip.gyp @@ -209,6 +209,8 @@ '<(tgvoip_src_loc)/os/darwin/AudioInputAudioUnitOSX.h', '<(tgvoip_src_loc)/os/darwin/AudioOutputAudioUnitOSX.cpp', '<(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.h', ], diff --git a/libtgvoip_osx.xcodeproj/project.pbxproj b/libtgvoip_osx.xcodeproj/project.pbxproj index b52da1d..9e0ce1c 100644 --- a/libtgvoip_osx.xcodeproj/project.pbxproj +++ b/libtgvoip_osx.xcodeproj/project.pbxproj @@ -46,6 +46,8 @@ 692AB91F1E675F7000706ACC /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 692AB91C1E675F7000706ACC /* AudioToolbox.framework */; }; 692AB9201E675F7000706ACC /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 692AB91D1E675F7000706ACC /* AudioUnit.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 */; }; 69A6DEBA1E96149300000E69 /* atomicops.h in Headers */ = {isa = PBXBuildFile; fileRef = 69A6DE241E96149300000E69 /* atomicops.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; }; 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; }; + 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 = ""; }; + 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 = ""; }; 69A6DE231E96149300000E69 /* array_view.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = array_view.h; sourceTree = ""; }; 69A6DE241E96149300000E69 /* atomicops.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = atomicops.h; sourceTree = ""; }; 69A6DE251E96149300000E69 /* basictypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = basictypes.h; sourceTree = ""; }; @@ -497,6 +501,8 @@ 69A6DF401E9614B700000E69 /* AudioInputAudioUnitOSX.h */, 69A6DF411E9614B700000E69 /* AudioOutputAudioUnitOSX.cpp */, 69A6DF421E9614B700000E69 /* AudioOutputAudioUnitOSX.h */, + 695B20601EBD39FF00E31757 /* DarwinSpecific.h */, + 695B20611EBD39FF00E31757 /* DarwinSpecific.mm */, ); path = darwin; sourceTree = ""; @@ -847,6 +853,7 @@ 69A6DF341E96149300000E69 /* ooura_fft.h in Headers */, 69A6DEBA1E96149300000E69 /* atomicops.h in Headers */, 69A6DF0A1E96149300000E69 /* aec_resampler.h in Headers */, + 695B20621EBD39FF00E31757 /* DarwinSpecific.h in Headers */, 69A6DEE51E96149300000E69 /* spl_inl.h in Headers */, 69A6DF3B1E96149300000E69 /* cpu_features_wrapper.h in Headers */, 69A6DF211E96149300000E69 /* ns_core.h in Headers */, @@ -1056,6 +1063,7 @@ 69A6DF101E96149300000E69 /* aecm_core_neon.cc in Sources */, 69A6DED71E96149300000E69 /* division_operations.c in Sources */, 69A6DEDB1E96149300000E69 /* energy.c in Sources */, + 695B20631EBD39FF00E31757 /* DarwinSpecific.mm in Sources */, 69A6DEC61E96149300000E69 /* audio_util.cc in Sources */, 69A6DF141E96149300000E69 /* analog_agc.c in Sources */, 69A6DEF81E96149300000E69 /* spl_sqrt_floor.c in Sources */, diff --git a/logging.cpp b/logging.cpp index fe2e420..064d792 100644 --- a/logging.cpp +++ b/logging.cpp @@ -9,6 +9,21 @@ #include #include +#include "VoIPController.h" + +#ifdef __ANDROID__ +#include +#elif defined(__linux__) +#include +#endif + +#ifdef __APPLE__ +#include +#if TARGET_OS_OSX +#include "os/darwin/DarwinSpecific.h" +#endif +#endif + FILE* tgvoipLogFile=NULL; 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); } } + +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); + } +} diff --git a/logging.h b/logging.h index ae16cab..4c1c6b7 100644 --- a/logging.h +++ b/logging.h @@ -14,6 +14,7 @@ #endif void tgvoip_log_file_printf(char level, const char* msg, ...); +void tgvoip_log_file_write_header(); #if defined(__ANDROID__) @@ -43,24 +44,49 @@ void tgvoip_log_file_printf(char level, const char* msg, ...); #include #include -#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 LOGD(msg, ...) _TGVOIP_W32_LOG_PRINT("D/tgvoip: " msg "\n", ##__VA_ARGS__) -#define LOGI(msg, ...) _TGVOIP_W32_LOG_PRINT("I/tgvoip: " msg "\n", ##__VA_ARGS__) -#define LOGW(msg, ...) _TGVOIP_W32_LOG_PRINT("W/tgvoip: " msg "\n", ##__VA_ARGS__) -#define LOGE(msg, ...) _TGVOIP_W32_LOG_PRINT("E/tgvoip: " msg "\n", ##__VA_ARGS__) +#define LOGV(msg, ...) _TGVOIP_W32_LOG_PRINT('V', msg, ##__VA_ARGS__) +#define LOGD(msg, ...) _TGVOIP_W32_LOG_PRINT('D', msg, ##__VA_ARGS__) +#define LOGI(msg, ...) _TGVOIP_W32_LOG_PRINT('I', msg, ##__VA_ARGS__) +#define LOGW(msg, ...) _TGVOIP_W32_LOG_PRINT('W', msg, ##__VA_ARGS__) +#define LOGE(msg, ...) _TGVOIP_W32_LOG_PRINT('E', msg, ##__VA_ARGS__) #else #include -#define LOGV(msg, ...) printf("V/tgvoip: " msg "\n", ##__VA_ARGS__) -#define LOGD(msg, ...) printf("D/tgvoip: " msg "\n", ##__VA_ARGS__) -#define LOGI(msg, ...) printf("I/tgvoip: " msg "\n", ##__VA_ARGS__) -#define LOGW(msg, ...) printf("W/tgvoip: " msg "\n", ##__VA_ARGS__) -#define LOGE(msg, ...) printf("E/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 LOGV(msg, ...) _TGVOIP_LOG_PRINT('V', msg, ##__VA_ARGS__) +#define LOGD(msg, ...) _TGVOIP_LOG_PRINT('D', msg, ##__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 +#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 diff --git a/os/darwin/AudioOutputAudioUnitOSX.cpp b/os/darwin/AudioOutputAudioUnitOSX.cpp index 28d1b29..d46e7f5 100644 --- a/os/darwin/AudioOutputAudioUnitOSX.cpp +++ b/os/darwin/AudioOutputAudioUnitOSX.cpp @@ -6,6 +6,7 @@ #include #include +#include #include "AudioOutputAudioUnitOSX.h" #include "../../logging.h" #include "../../VoIPController.h" @@ -22,6 +23,7 @@ using namespace tgvoip::audio; AudioOutputAudioUnit::AudioOutputAudioUnit(std::string deviceID){ remainingDataSize=0; isPlaying=false; + sysDevID=NULL; OSStatus status; AudioComponentDescription inputDesc={ @@ -39,6 +41,15 @@ AudioOutputAudioUnit::AudioOutputAudioUnit(std::string deviceID){ status = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof(flag)); 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); CFRunLoopRef theRunLoop = NULL; @@ -76,6 +87,15 @@ AudioOutputAudioUnit::~AudioOutputAudioUnit(){ propertyAddress.mElement = kAudioObjectPropertyElementMaster; 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); AudioComponentInstanceDispose(unit); } @@ -216,8 +236,17 @@ void AudioOutputAudioUnit::EnumerateDevices(std::vector& devs void AudioOutputAudioUnit::SetCurrentDevice(std::string deviceID){ UInt32 size=sizeof(AudioDeviceID); - AudioDeviceID inputDevice=NULL; + AudioDeviceID outputDevice=NULL; OSStatus status; + AudioObjectPropertyAddress dataSourceProp={ + kAudioDevicePropertyDataSource, + kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMaster + }; + + if(isMacBookPro && sysDevID && AudioObjectHasProperty(sysDevID, &dataSourceProp)){ + AudioObjectRemovePropertyListener(sysDevID, &dataSourceProp, AudioOutputAudioUnit::DefaultDeviceChangedCallback, this); + } if(deviceID=="default"){ AudioObjectPropertyAddress propertyAddress; @@ -225,7 +254,7 @@ void AudioOutputAudioUnit::SetCurrentDevice(std::string deviceID){ propertyAddress.mScope = kAudioObjectPropertyScopeGlobal; propertyAddress.mElement = kAudioObjectPropertyElementMaster; 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"); }else{ AudioObjectPropertyAddress propertyAddress = { @@ -251,11 +280,11 @@ void AudioOutputAudioUnit::SetCurrentDevice(std::string deviceID){ CFStringGetCString(deviceUID, buf, 1024, kCFStringEncodingUTF8); if(deviceID==buf){ LOGV("Found device for id %s", buf); - inputDevice=audioDevices[i]; + outputDevice=audioDevices[i]; break; } } - if(!inputDevice){ + if(!outputDevice){ LOGW("Requested device not found, using default"); SetCurrentDevice("default"); return; @@ -266,7 +295,7 @@ void AudioOutputAudioUnit::SetCurrentDevice(std::string deviceID){ kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, kOutputBus, - &inputDevice, + &outputDevice, size); 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); 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){ - LOGV("System default input device changed"); AudioOutputAudioUnit* self=(AudioOutputAudioUnit*)inClientData; - if(self->currentDevice=="default"){ - self->SetCurrentDevice(self->currentDevice); + if(inAddresses[0].mSelector==kAudioHardwarePropertyDefaultOutputDevice){ + LOGV("System default input device changed"); + if(self->currentDevice=="default"){ + 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; } diff --git a/os/darwin/AudioOutputAudioUnitOSX.h b/os/darwin/AudioOutputAudioUnitOSX.h index dad1df9..91fb2d4 100644 --- a/os/darwin/AudioOutputAudioUnitOSX.h +++ b/os/darwin/AudioOutputAudioUnitOSX.h @@ -29,11 +29,14 @@ public: private: 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); + void SetPanRight(bool panRight); unsigned char remainingData[10240]; size_t remainingDataSize; bool isPlaying; AudioUnit unit; int hardwareSampleRate; + bool isMacBookPro; + AudioDeviceID sysDevID; }; }} diff --git a/os/darwin/DarwinSpecific.h b/os/darwin/DarwinSpecific.h new file mode 100644 index 0000000..9bdb5c1 --- /dev/null +++ b/os/darwin/DarwinSpecific.h @@ -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 + +namespace tgvoip { +class DarwinSpecific{ +public: + static void GetSystemName(char* buf, size_t len); +}; +} + +#endif //TGVOIP_DARWINSPECIFIC_H diff --git a/os/darwin/DarwinSpecific.mm b/os/darwin/DarwinSpecific.mm new file mode 100644 index 0000000..f2f04c0 --- /dev/null +++ b/os/darwin/DarwinSpecific.mm @@ -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 + +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]; +} diff --git a/os/linux/AudioInputALSA.cpp b/os/linux/AudioInputALSA.cpp index 021cf45..c93c942 100644 --- a/os/linux/AudioInputALSA.cpp +++ b/os/linux/AudioInputALSA.cpp @@ -21,6 +21,7 @@ using namespace tgvoip::audio; AudioInputALSA::AudioInputALSA(std::string devID){ isRecording=false; + handle=NULL; lib=dlopen("libasound.so", RTLD_LAZY); if(!lib){ @@ -36,14 +37,14 @@ AudioInputALSA::AudioInputALSA(std::string devID){ LOAD_FUNCTION(lib, "snd_pcm_recover", _snd_pcm_recover); LOAD_FUNCTION(lib, "snd_strerror", _snd_strerror); - handle=NULL; - SetCurrentDevice(devID); } AudioInputALSA::~AudioInputALSA(){ - _snd_pcm_close(handle); - dlclose(lib); + if(handle) + _snd_pcm_close(handle); + if(lib) + dlclose(lib); } void AudioInputALSA::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){ diff --git a/os/linux/AudioOutputALSA.cpp b/os/linux/AudioOutputALSA.cpp index a94dcfb..46feaff 100644 --- a/os/linux/AudioOutputALSA.cpp +++ b/os/linux/AudioOutputALSA.cpp @@ -20,6 +20,7 @@ using namespace tgvoip::audio; AudioOutputALSA::AudioOutputALSA(std::string devID){ isPlaying=false; + handle=NULL; lib=dlopen("libasound.so", RTLD_LAZY); if(!lib){ @@ -35,14 +36,14 @@ AudioOutputALSA::AudioOutputALSA(std::string devID){ LOAD_FUNCTION(lib, "snd_pcm_recover", _snd_pcm_recover); LOAD_FUNCTION(lib, "snd_strerror", _snd_strerror); - handle=NULL; - SetCurrentDevice(devID); } AudioOutputALSA::~AudioOutputALSA(){ - _snd_pcm_close(handle); - dlclose(lib); + if(handle) + _snd_pcm_close(handle); + if(lib) + dlclose(lib); } void AudioOutputALSA::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){