mirror of
https://github.com/danog/libtgvoip.git
synced 2024-11-26 20:24:38 +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){
|
||||
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)){
|
||||
|
@ -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(){
|
||||
|
@ -40,6 +40,7 @@ public:
|
||||
protected:
|
||||
std::string currentDevice;
|
||||
bool failed;
|
||||
static int32_t estimatedDelay;
|
||||
};
|
||||
}}
|
||||
|
||||
|
@ -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',
|
||||
],
|
||||
|
@ -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 = "<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>"; };
|
||||
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>"; };
|
||||
@ -497,6 +501,8 @@
|
||||
69A6DF401E9614B700000E69 /* AudioInputAudioUnitOSX.h */,
|
||||
69A6DF411E9614B700000E69 /* AudioOutputAudioUnitOSX.cpp */,
|
||||
69A6DF421E9614B700000E69 /* AudioOutputAudioUnitOSX.h */,
|
||||
695B20601EBD39FF00E31757 /* DarwinSpecific.h */,
|
||||
695B20611EBD39FF00E31757 /* DarwinSpecific.mm */,
|
||||
);
|
||||
path = darwin;
|
||||
sourceTree = "<group>";
|
||||
@ -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 */,
|
||||
|
70
logging.cpp
70
logging.cpp
@ -9,6 +9,21 @@
|
||||
#include <stdarg.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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
48
logging.h
48
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 <windows.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 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 <stdio.h>
|
||||
|
||||
#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
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#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<AudioOutputDevice>& 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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
}}
|
||||
|
||||
|
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){
|
||||
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){
|
||||
|
@ -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){
|
||||
|
Loading…
Reference in New Issue
Block a user