diff --git a/EchoCanceller.cpp b/EchoCanceller.cpp index 2106532..23ccc94 100644 --- a/EchoCanceller.cpp +++ b/EchoCanceller.cpp @@ -97,12 +97,12 @@ EchoCanceller::EchoCanceller(bool enableAEC, bool enableNS, bool enableAGC){ if(enableAGC){ agc=WebRtcAgc_Create(); WebRtcAgcConfig agcConfig; - agcConfig.compressionGaindB = 9; + agcConfig.compressionGaindB = 20; agcConfig.limiterEnable = 1; - agcConfig.targetLevelDbfs = 3; - WebRtcAgc_Init(agc, 0, 255, kAgcModeAdaptiveAnalog, 48000); + agcConfig.targetLevelDbfs = 9; + WebRtcAgc_Init(agc, 0, 255, kAgcModeAdaptiveDigital, 48000); WebRtcAgc_set_config(agc, agcConfig); - agcMicLevel=128; + agcMicLevel=0; } #endif } @@ -354,3 +354,75 @@ void EchoCanceller::ProcessInput(unsigned char* data, unsigned char* out, size_t memcpy(samplesOut, bufIn->ibuf_const()->bands(0)[0], 960*2); } +AudioEffect::~AudioEffect(){ + +} + +void AudioEffect::SetPassThrough(bool passThrough){ + this->passThrough=passThrough; +} + +AutomaticGainControl::AutomaticGainControl(){ + splittingFilter=new webrtc::SplittingFilter(1, 3, 960); + splittingFilterIn=new webrtc::IFChannelBuffer(960, 1, 1); + splittingFilterOut=new webrtc::IFChannelBuffer(960, 1, 3); + + agc=WebRtcAgc_Create(); + WebRtcAgcConfig agcConfig; + agcConfig.compressionGaindB = 9; + agcConfig.limiterEnable = 1; + agcConfig.targetLevelDbfs = 3; + WebRtcAgc_Init(agc, 0, 255, kAgcModeAdaptiveDigital, 48000); + WebRtcAgc_set_config(agc, agcConfig); + agcMicLevel=0; +} + +AutomaticGainControl::~AutomaticGainControl(){ + delete (webrtc::SplittingFilter*)splittingFilter; + delete (webrtc::IFChannelBuffer*)splittingFilterIn; + delete (webrtc::IFChannelBuffer*)splittingFilterOut; + WebRtcAgc_Free(agc); +} + +void AutomaticGainControl::Process(int16_t *inOut, size_t numSamples){ + if(passThrough) + return; + if(numSamples!=960){ + LOGW("AutomaticGainControl only works on 960-sample buffers (got %u samples)", numSamples); + return; + } + //LOGV("processing frame through AGC"); + + webrtc::IFChannelBuffer* bufIn=(webrtc::IFChannelBuffer*) splittingFilterIn; + webrtc::IFChannelBuffer* bufOut=(webrtc::IFChannelBuffer*) splittingFilterOut; + + memcpy(bufIn->ibuf()->bands(0)[0], inOut, 960*2); + + ((webrtc::SplittingFilter*)splittingFilter)->Analysis(bufIn, bufOut); + + int i; + int16_t _agcOut[3][320]; + int16_t* agcIn[3]; + int16_t* agcOut[3]; + for(i=0;i<3;i++){ + agcIn[i]=(int16_t*)bufOut->ibuf_const()->bands(0)[i]; + agcOut[i]=_agcOut[i]; + } + uint8_t saturation; + WebRtcAgc_AddMic(agc, agcIn, 3, 160); + WebRtcAgc_Process(agc, (const int16_t *const *) agcIn, 3, 160, agcOut, agcMicLevel, &agcMicLevel, 0, &saturation); + for(i=0;i<3;i++){ + agcOut[i]+=160; + agcIn[i]+=160; + } + WebRtcAgc_AddMic(agc, agcIn, 3, 160); + WebRtcAgc_Process(agc, (const int16_t *const *) agcIn, 3, 160, agcOut, agcMicLevel, &agcMicLevel, 0, &saturation); + memcpy(bufOut->ibuf()->bands(0)[0], _agcOut[0], 320*2); + memcpy(bufOut->ibuf()->bands(0)[1], _agcOut[1], 320*2); + memcpy(bufOut->ibuf()->bands(0)[2], _agcOut[2], 320*2); + + ((webrtc::SplittingFilter*)splittingFilter)->Synthesis(bufOut, bufIn); + + memcpy(inOut, bufIn->ibuf_const()->bands(0)[0], 960*2); +} + diff --git a/EchoCanceller.h b/EchoCanceller.h index 982bd4a..a915ec1 100644 --- a/EchoCanceller.h +++ b/EchoCanceller.h @@ -10,6 +10,7 @@ #include "threading.h" #include "BufferPool.h" #include "BlockingQueue.h" +#include "MediaStreamItf.h" namespace tgvoip{ class EchoCanceller{ @@ -48,6 +49,29 @@ private: int32_t agcMicLevel; #endif }; -} + + class AudioEffect{ + public: + virtual ~AudioEffect()=0; + virtual void Process(int16_t* inOut, size_t numSamples)=0; + virtual void SetPassThrough(bool passThrough); + protected: + bool passThrough; + }; + + class AutomaticGainControl : public AudioEffect{ + public: + AutomaticGainControl(); + virtual ~AutomaticGainControl(); + virtual void Process(int16_t* inOut, size_t numSamples); + + private: + void* agc; + void* splittingFilter; + void* splittingFilterIn; + void* splittingFilterOut; + int32_t agcMicLevel; + }; +}; #endif //LIBTGVOIP_ECHOCANCELLER_H diff --git a/OpusDecoder.cpp b/OpusDecoder.cpp index 6f6626a..77fcb8d 100644 --- a/OpusDecoder.cpp +++ b/OpusDecoder.cpp @@ -8,6 +8,7 @@ #include "audio/Resampler.h" #include "logging.h" #include +#include #define PACKET_SIZE (960*2) @@ -222,6 +223,9 @@ void tgvoip::OpusDecoder::RunThread(){ unsigned char *buf=bufferPool->Get(); if(buf){ if(size>0){ + for(std::vector::iterator effect=postProcEffects.begin();effect!=postProcEffects.end();++effect){ + (*effect)->Process(reinterpret_cast(processedBuffer+(PACKET_SIZE*i)), 960); + } memcpy(buf, processedBuffer+(PACKET_SIZE*i), PACKET_SIZE); }else{ LOGE("Error decoding, result=%d", size); @@ -255,3 +259,13 @@ void tgvoip::OpusDecoder::ResetQueue(){ void tgvoip::OpusDecoder::SetJitterBuffer(JitterBuffer* jitterBuffer){ this->jitterBuffer=jitterBuffer; } + +void tgvoip::OpusDecoder::AddAudioEffect(AudioEffect *effect){ + postProcEffects.push_back(effect); +} + +void tgvoip::OpusDecoder::RemoveAudioEffect(AudioEffect *effect){ + std::vector::iterator i=std::find(postProcEffects.begin(), postProcEffects.end(), effect); + if(i!=postProcEffects.end()) + postProcEffects.erase(i); +} diff --git a/OpusDecoder.h b/OpusDecoder.h index 51bbbac..1a88ce5 100644 --- a/OpusDecoder.h +++ b/OpusDecoder.h @@ -16,6 +16,7 @@ #include "EchoCanceller.h" #include "JitterBuffer.h" #include +#include namespace tgvoip{ class OpusDecoder { @@ -31,6 +32,8 @@ public: void SetFrameDuration(uint32_t duration); void ResetQueue(); void SetJitterBuffer(JitterBuffer* jitterBuffer); + void AddAudioEffect(AudioEffect* effect); + void RemoveAudioEffect(AudioEffect* effect); private: static size_t Callback(unsigned char* data, size_t len, void* param); @@ -50,6 +53,7 @@ private: uint32_t frameDuration; EchoCanceller* echoCanceller; JitterBuffer* jitterBuffer; + std::vector postProcEffects; }; } diff --git a/VoIPController.cpp b/VoIPController.cpp index 7f4e87c..9623c00 100644 --- a/VoIPController.cpp +++ b/VoIPController.cpp @@ -234,6 +234,9 @@ VoIPController::VoIPController() : activeNetItfName(""), realUdpSocket=udpSocket; udpConnectivityState=UDP_UNKNOWN; + outputAGC=NULL; + outputAGCEnabled=false; + maxAudioBitrate=(uint32_t) ServerConfig::GetSharedInstance()->GetInt("audio_max_bitrate", 20000); maxAudioBitrateGPRS=(uint32_t) ServerConfig::GetSharedInstance()->GetInt("audio_max_bitrate_gprs", 8000); maxAudioBitrateEDGE=(uint32_t) ServerConfig::GetSharedInstance()->GetInt("audio_max_bitrate_edge", 16000); @@ -264,6 +267,8 @@ VoIPController::VoIPController() : activeNetItfName(""), stm->enabled=1; stm->frameDuration=60; outgoingStreams.push_back(stm); + + memset(signalBarsHistory, 0, sizeof(signalBarsHistory)); } VoIPController::~VoIPController(){ @@ -361,6 +366,8 @@ VoIPController::~VoIPController(){ if(resolvedProxyAddress) delete resolvedProxyAddress; delete selectCanceller; + if(outputAGC) + delete outputAGC; LOGD("Left VoIPController::~VoIPController"); } @@ -1182,10 +1189,13 @@ simpleAudioBlock random_id:long random_bytes:string raw_data:string = DecryptedA UpdateAudioBitrate(); jitterBuffer=new JitterBuffer(NULL, incomingAudioStream->frameDuration); + outputAGC=new AutomaticGainControl(); + outputAGC->SetPassThrough(!outputAGCEnabled); decoder=new OpusDecoder(audioOutput); decoder->SetEchoCanceller(echoCanceller); decoder->SetJitterBuffer(jitterBuffer); decoder->SetFrameDuration(incomingAudioStream->frameDuration); + decoder->AddAudioEffect(outputAGC); decoder->Start(); if(incomingAudioStream->frameDuration>50) jitterBuffer->SetMinPacketCount((uint32_t) ServerConfig::GetSharedInstance()->GetInt("jitter_initial_delay_60", 3)); @@ -1243,7 +1253,7 @@ simpleAudioBlock random_id:long random_bytes:string raw_data:string = DecryptedA audioOutput->Start(); audioOutStarted=true; } - if(jitterBuffer) + if(jitterBuffer && in.Remaining()>=sdlen) jitterBuffer->HandleInput((unsigned char*) (buffer+in.GetOffset()), sdlen, pts); if(iGetAverageDelay(); double avgLateCount[3]; jitterBuffer->GetAverageLateCount(avgLateCount); - if(avgDelay>=5) + /*if(avgDelay>=5) signalBarCount=1; else if(avgDelay>=4) signalBarCount=MIN(signalBarCount, 2); else if(avgDelay>=3) - signalBarCount=MIN(signalBarCount, 3); + signalBarCount=MIN(signalBarCount, 3);*/ if(avgLateCount[2]>=0.2) signalBarCount=1; @@ -1711,10 +1721,12 @@ void VoIPController::RunTickThread(){ setEstablishedAt=0; } - if(signalBarCount!=prevSignalBarCount){ - LOGD("SIGNAL BAR COUNT CHANGED: %d", signalBarCount); + signalBarsHistory[tickCount%sizeof(signalBarsHistory)]=(unsigned char)signalBarCount; + int _signalBarCount=GetSignalBarsCount(); + if(_signalBarCount!=prevSignalBarCount){ + LOGD("SIGNAL BAR COUNT CHANGED: %d", _signalBarCount); if(signalBarCountCallback) - signalBarCountCallback(this, signalBarCount); + signalBarCountCallback(this, _signalBarCount); } @@ -2460,13 +2472,23 @@ void VoIPController::SendUdpPing(Endpoint *endpoint){ } int VoIPController::GetSignalBarsCount(){ - return signalBarCount; + unsigned char avg=0; + for(int i=0;i> 2; } void VoIPController::SetSignalBarsCountCallback(void (*f)(VoIPController *, int)){ signalBarCountCallback=f; } +void VoIPController::SetAudioOutputGainControlEnabled(bool enabled){ + LOGD("New output AGC state: %d", enabled); + outputAGCEnabled=enabled; + if(outputAGC) + outputAGC->SetPassThrough(!enabled); +} + Endpoint::Endpoint(int64_t id, uint16_t port, IPv4Address& _address, IPv6Address& _v6address, char type, unsigned char peerTag[16]) : address(_address), v6address(_v6address){ this->id=id; this->port=port; diff --git a/VoIPController.h b/VoIPController.h index 2b1f4db..88f3a64 100644 --- a/VoIPController.h +++ b/VoIPController.h @@ -318,7 +318,7 @@ public: std::string GetCurrentAudioOutputID(); /** * Set the proxy server to route the data through. Call this before connecting. - * @param protocol PROXY_NONE, PROXY_SOCKS4, or PROXY_SOCKS5 + * @param protocol PROXY_NONE or PROXY_SOCKS5 * @param address IP address or domain name of the server * @param port Port of the server * @param username Username; empty string for anonymous @@ -335,6 +335,13 @@ public: * @param f */ void SetSignalBarsCountCallback(void (*f)(VoIPController*, int)); + /** + * Enable or disable AGC (automatic gain control) on audio output. Should only be enabled on phones when the earpiece speaker is being used. + * The audio output will be louder with this on. + * AGC with speakerphone or other kinds of loud speakers has detrimental effects on some echo cancellation implementations. + * @param enabled I usually pick argument names to be self-explanatory + */ + void SetAudioOutputGainControlEnabled(bool enabled); private: struct PendingOutgoingPacket{ @@ -452,6 +459,7 @@ private: double setEstablishedAt; SocketSelectCanceller* selectCanceller; NetworkSocket* openingTcpSocket; + unsigned char signalBarsHistory[4]; BufferPool outgoingPacketsBufferPool; int udpConnectivityState; @@ -467,6 +475,9 @@ private: int signalBarCount; void (*signalBarCountCallback)(VoIPController*, int); + + AutomaticGainControl* outputAGC; + bool outputAGCEnabled; /*** server config values ***/ uint32_t maxAudioBitrate; diff --git a/client/android/tg_voip_jni.cpp b/client/android/tg_voip_jni.cpp index dcb18df..f88b338 100644 --- a/client/android/tg_voip_jni.cpp +++ b/client/android/tg_voip_jni.cpp @@ -299,6 +299,10 @@ extern "C" JNIEXPORT jstring Java_org_telegram_messenger_voip_VoIPController_nat return env->NewStringUTF(log.c_str()); } +extern "C" JNIEXPORT void Java_org_telegram_messenger_voip_VoIPController_nativeSetAudioOutputGainControlEnabled(JNIEnv* env, jclass clasz, jlong inst, jboolean enabled){ + ((VoIPController*)(intptr_t)inst)->SetAudioOutputGainControlEnabled(enabled); +} + extern "C" JNIEXPORT jint Java_org_telegram_messenger_voip_Resampler_convert44to48(JNIEnv* env, jclass cls, jobject from, jobject to){ return tgvoip::audio::Resampler::Convert44To48((int16_t *) env->GetDirectBufferAddress(from), (int16_t *) env->GetDirectBufferAddress(to), (size_t) (env->GetDirectBufferCapacity(from)/2), (size_t) (env->GetDirectBufferCapacity(to)/2)); } diff --git a/libtgvoip_osx.xcodeproj/project.pbxproj b/libtgvoip_osx.xcodeproj/project.pbxproj index c4d966f..d5195f1 100644 --- a/libtgvoip_osx.xcodeproj/project.pbxproj +++ b/libtgvoip_osx.xcodeproj/project.pbxproj @@ -47,12 +47,8 @@ 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 */; }; - 698848411F4B39F700076DF0 /* AudioInputAudioUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6988483B1F4B39F700076DF0 /* AudioInputAudioUnit.cpp */; }; 698848421F4B39F700076DF0 /* AudioInputAudioUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6988483C1F4B39F700076DF0 /* AudioInputAudioUnit.h */; }; - 698848431F4B39F700076DF0 /* AudioOutputAudioUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6988483D1F4B39F700076DF0 /* AudioOutputAudioUnit.cpp */; }; 698848441F4B39F700076DF0 /* AudioOutputAudioUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6988483E1F4B39F700076DF0 /* AudioOutputAudioUnit.h */; }; - 698848451F4B39F700076DF0 /* AudioUnitIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6988483F1F4B39F700076DF0 /* AudioUnitIO.cpp */; }; 698848461F4B39F700076DF0 /* AudioUnitIO.h in Headers */ = {isa = PBXBuildFile; fileRef = 698848401F4B39F700076DF0 /* AudioUnitIO.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 */; }; @@ -189,8 +185,12 @@ 69A6DF441E9614B700000E69 /* AudioInputAudioUnitOSX.h in Headers */ = {isa = PBXBuildFile; fileRef = 69A6DF401E9614B700000E69 /* AudioInputAudioUnitOSX.h */; }; 69A6DF451E9614B700000E69 /* AudioOutputAudioUnitOSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 69A6DF411E9614B700000E69 /* AudioOutputAudioUnitOSX.cpp */; }; 69A6DF461E9614B700000E69 /* AudioOutputAudioUnitOSX.h in Headers */ = {isa = PBXBuildFile; fileRef = 69A6DF421E9614B700000E69 /* AudioOutputAudioUnitOSX.h */; }; - 69AC14901F4B41CF00AC3173 /* Resampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 69AC148E1F4B41CF00AC3173 /* Resampler.cpp */; }; 69AC14911F4B41CF00AC3173 /* Resampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 69AC148F1F4B41CF00AC3173 /* Resampler.h */; }; + C2A87DD81F4B6A33002D3F73 /* Resampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2A87DD71F4B6A33002D3F73 /* Resampler.cpp */; }; + C2A87DDA1F4B6A57002D3F73 /* DarwinSpecific.mm in Sources */ = {isa = PBXBuildFile; fileRef = C2A87DD91F4B6A57002D3F73 /* DarwinSpecific.mm */; }; + C2A87DDF1F4B6A61002D3F73 /* AudioInputAudioUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2A87DDB1F4B6A61002D3F73 /* AudioInputAudioUnit.cpp */; }; + C2A87DE01F4B6A61002D3F73 /* AudioOutputAudioUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2A87DDD1F4B6A61002D3F73 /* AudioOutputAudioUnit.cpp */; }; + C2A87DE41F4B6AD3002D3F73 /* AudioUnitIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2A87DE31F4B6AD3002D3F73 /* AudioUnitIO.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -425,6 +425,15 @@ 69AC148E1F4B41CF00AC3173 /* Resampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Resampler.cpp; path = "../../../../Telegram-iOS/submodules/libtgvoip/audio/Resampler.cpp"; sourceTree = ""; }; 69AC148F1F4B41CF00AC3173 /* Resampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Resampler.h; path = "../../../../Telegram-iOS/submodules/libtgvoip/audio/Resampler.h"; sourceTree = ""; }; 69F842361E67540700C110F7 /* libtgvoip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = libtgvoip.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C2A87DD71F4B6A33002D3F73 /* Resampler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Resampler.cpp; path = audio/Resampler.cpp; sourceTree = ""; }; + C2A87DD91F4B6A57002D3F73 /* DarwinSpecific.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = DarwinSpecific.mm; path = os/darwin/DarwinSpecific.mm; sourceTree = ""; }; + C2A87DDB1F4B6A61002D3F73 /* AudioInputAudioUnit.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AudioInputAudioUnit.cpp; path = os/darwin/AudioInputAudioUnit.cpp; sourceTree = ""; }; + C2A87DDC1F4B6A61002D3F73 /* AudioInputAudioUnitOSX.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AudioInputAudioUnitOSX.cpp; path = os/darwin/AudioInputAudioUnitOSX.cpp; sourceTree = ""; }; + C2A87DDD1F4B6A61002D3F73 /* AudioOutputAudioUnit.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AudioOutputAudioUnit.cpp; path = os/darwin/AudioOutputAudioUnit.cpp; sourceTree = ""; }; + C2A87DDE1F4B6A61002D3F73 /* AudioOutputAudioUnitOSX.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AudioOutputAudioUnitOSX.cpp; path = os/darwin/AudioOutputAudioUnitOSX.cpp; sourceTree = ""; }; + C2A87DE11F4B6A89002D3F73 /* AudioInput.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AudioInput.cpp; path = audio/AudioInput.cpp; sourceTree = ""; }; + C2A87DE21F4B6A89002D3F73 /* AudioOutput.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AudioOutput.cpp; path = audio/AudioOutput.cpp; sourceTree = ""; }; + C2A87DE31F4B6AD3002D3F73 /* AudioUnitIO.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AudioUnitIO.cpp; path = os/darwin/AudioUnitIO.cpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -840,6 +849,15 @@ 69F8422C1E67540700C110F7 = { isa = PBXGroup; children = ( + C2A87DE31F4B6AD3002D3F73 /* AudioUnitIO.cpp */, + C2A87DE11F4B6A89002D3F73 /* AudioInput.cpp */, + C2A87DE21F4B6A89002D3F73 /* AudioOutput.cpp */, + C2A87DDB1F4B6A61002D3F73 /* AudioInputAudioUnit.cpp */, + C2A87DDC1F4B6A61002D3F73 /* AudioInputAudioUnitOSX.cpp */, + C2A87DDD1F4B6A61002D3F73 /* AudioOutputAudioUnit.cpp */, + C2A87DDE1F4B6A61002D3F73 /* AudioOutputAudioUnitOSX.cpp */, + C2A87DD91F4B6A57002D3F73 /* DarwinSpecific.mm */, + C2A87DD71F4B6A33002D3F73 /* Resampler.cpp */, 692AB8861E6759BF00706ACC /* libtgvoip */, 69F842371E67540700C110F7 /* Products */, 692AB9061E675E8700706ACC /* Frameworks */, @@ -1072,6 +1090,7 @@ 69A6DEF41E96149300000E69 /* resample_fractional.c in Sources */, 6915307B1E6B5BAB004F643F /* logging.cpp in Sources */, 69A6DEE11E96149300000E69 /* get_scaling_square.c in Sources */, + C2A87DE41F4B6AD3002D3F73 /* AudioUnitIO.cpp in Sources */, 690725C21EBBD5F2005D860B /* NetworkSocket.cpp in Sources */, 69A6DEC71E96149300000E69 /* channel_buffer.cc in Sources */, 69A6DF191E96149300000E69 /* apm_data_dumper.cc in Sources */, @@ -1086,12 +1105,10 @@ 69A6DEF71E96149300000E69 /* spl_sqrt.c in Sources */, 69A6DEED1E96149300000E69 /* real_fft.c in Sources */, 692AB9021E6759DD00706ACC /* VoIPController.cpp in Sources */, - 69A6DF431E9614B700000E69 /* AudioInputAudioUnitOSX.cpp in Sources */, 69A6DF0D1E96149300000E69 /* aecm_core.cc in Sources */, 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 */, @@ -1109,24 +1126,28 @@ 692AB8EB1E6759DD00706ACC /* OpusDecoder.cpp in Sources */, 69A6DED81E96149300000E69 /* dot_product_with_scale.c in Sources */, 69A6DF331E96149300000E69 /* ooura_fft.cc in Sources */, - 698848451F4B39F700076DF0 /* AudioUnitIO.cpp in Sources */, 69A6DEF11E96149300000E69 /* resample_by_2.c in Sources */, 69A6DEEC1E96149300000E69 /* randomization_functions.c in Sources */, 69A6DEEE1E96149300000E69 /* refl_coef_to_lpc.c in Sources */, + C2A87DDF1F4B6A61002D3F73 /* AudioInputAudioUnit.cpp in Sources */, + 69A6DF431E9614B700000E69 /* AudioInputAudioUnitOSX.cpp in Sources */, + C2A87DE01F4B6A61002D3F73 /* AudioOutputAudioUnit.cpp in Sources */, + 69A6DF451E9614B700000E69 /* AudioOutputAudioUnitOSX.cpp in Sources */, 69A6DEFC1E96149300000E69 /* vector_scaling_operations.c in Sources */, 692AB8E61E6759DD00706ACC /* JitterBuffer.cpp in Sources */, + 692AB8CB1E6759DD00706ACC /* AudioInput.cpp in Sources */, + 692AB8CD1E6759DD00706ACC /* AudioOutput.cpp in Sources */, + C2A87DDA1F4B6A57002D3F73 /* DarwinSpecific.mm in Sources */, + C2A87DD81F4B6A33002D3F73 /* Resampler.cpp in Sources */, 69A6DEFA1E96149300000E69 /* splitting_filter_impl.c in Sources */, - 69AC14901F4B41CF00AC3173 /* Resampler.cpp in Sources */, 69A6DEE01E96149300000E69 /* get_hanning_window.c in Sources */, 69A6DF161E96149300000E69 /* digital_agc.c in Sources */, 69A6DF061E96149300000E69 /* aec_core_neon.cc in Sources */, 69A6DF201E96149300000E69 /* ns_core.c in Sources */, - 698848431F4B39F700076DF0 /* AudioOutputAudioUnit.cpp in Sources */, 69A6DF091E96149300000E69 /* aec_resampler.cc in Sources */, 692AB8D11E6759DD00706ACC /* BufferInputStream.cpp in Sources */, 692AB8E91E6759DD00706ACC /* MediaStreamItf.cpp in Sources */, 69A6DF2C1E96149300000E69 /* block_mean_calculator.cc in Sources */, - 69A6DF451E9614B700000E69 /* AudioOutputAudioUnitOSX.cpp in Sources */, 69A6DEBC1E96149300000E69 /* checks.cc in Sources */, 692AB8DA1E6759DD00706ACC /* EchoCanceller.cpp in Sources */, 69A6DF281E96149300000E69 /* splitting_filter.cc in Sources */, @@ -1143,18 +1164,15 @@ 69A6DF1E1E96149300000E69 /* noise_suppression_x.c in Sources */, 692AB8D51E6759DD00706ACC /* BufferPool.cpp in Sources */, 69A6DED01E96149300000E69 /* complex_bit_reverse.c in Sources */, - 692AB8CB1E6759DD00706ACC /* AudioInput.cpp in Sources */, 69A6DEDF1E96149300000E69 /* filter_ma_fast_q12.c in Sources */, 69A6DEFF1E96149300000E69 /* wav_file.cc in Sources */, 69A6DF351E96149300000E69 /* ooura_fft_neon.cc in Sources */, 69A6DECE1E96149300000E69 /* auto_corr_to_refl_coef.c in Sources */, 69A6DEFD1E96149300000E69 /* sparse_fir_filter.cc in Sources */, 69A6DED91E96149300000E69 /* downsample_fast.c in Sources */, - 692AB8CD1E6759DD00706ACC /* AudioOutput.cpp in Sources */, 69A6DF251E96149300000E69 /* nsx_core_neon.c in Sources */, 69A6DF081E96149300000E69 /* aec_core_sse2.cc in Sources */, 69A6DEEA1E96149300000E69 /* min_max_operations.c in Sources */, - 698848411F4B39F700076DF0 /* AudioInputAudioUnit.cpp in Sources */, 69A6DF361E96149300000E69 /* ooura_fft_sse2.cc in Sources */, 69A6DED51E96149300000E69 /* cross_correlation.c in Sources */, 69A6DF3D1E96149300000E69 /* cpu_features.cc in Sources */, @@ -1170,7 +1188,7 @@ /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ - 69F8423C1E67540700C110F7 /* Debug */ = { + 69F8423C1E67540700C110F7 /* Debug Hockeyapp */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -1219,9 +1237,9 @@ VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Debug; + name = "Debug Hockeyapp"; }; - 69F8423D1E67540700C110F7 /* Release */ = { + 69F8423D1E67540700C110F7 /* Release Hockeyapp */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -1264,9 +1282,9 @@ VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Release; + name = "Release Hockeyapp"; }; - 69F8423F1E67540700C110F7 /* Debug */ = { + 69F8423F1E67540700C110F7 /* Debug Hockeyapp */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; @@ -1303,9 +1321,9 @@ SDKROOT = macosx; SKIP_INSTALL = YES; }; - name = Debug; + name = "Debug Hockeyapp"; }; - 69F842401E67540700C110F7 /* Release */ = { + 69F842401E67540700C110F7 /* Release Hockeyapp */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; @@ -1342,7 +1360,7 @@ SDKROOT = macosx; SKIP_INSTALL = YES; }; - name = Release; + name = "Release Hockeyapp"; }; D04D01C31E678C0D0086DDC0 /* Debug AppStore */ = { isa = XCBuildConfiguration; @@ -1434,7 +1452,7 @@ }; name = "Debug AppStore"; }; - D04D01CB1E678C230086DDC0 /* Hockeyapp */ = { + D04D01CB1E678C230086DDC0 /* Release AppStore */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -1477,9 +1495,9 @@ VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Hockeyapp; + name = "Release AppStore"; }; - D04D01CC1E678C230086DDC0 /* Hockeyapp */ = { + D04D01CC1E678C230086DDC0 /* Release AppStore */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; @@ -1516,7 +1534,7 @@ SDKROOT = macosx; SKIP_INSTALL = YES; }; - name = Hockeyapp; + name = "Release AppStore"; }; /* End XCBuildConfiguration section */ @@ -1524,24 +1542,24 @@ 69F842301E67540700C110F7 /* Build configuration list for PBXProject "libtgvoip_osx" */ = { isa = XCConfigurationList; buildConfigurations = ( - 69F8423C1E67540700C110F7 /* Debug */, + 69F8423C1E67540700C110F7 /* Debug Hockeyapp */, D04D01C31E678C0D0086DDC0 /* Debug AppStore */, - 69F8423D1E67540700C110F7 /* Release */, - D04D01CB1E678C230086DDC0 /* Hockeyapp */, + 69F8423D1E67540700C110F7 /* Release Hockeyapp */, + D04D01CB1E678C230086DDC0 /* Release AppStore */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; + defaultConfigurationName = "Release Hockeyapp"; }; 69F8423E1E67540700C110F7 /* Build configuration list for PBXNativeTarget "libtgvoip" */ = { isa = XCConfigurationList; buildConfigurations = ( - 69F8423F1E67540700C110F7 /* Debug */, + 69F8423F1E67540700C110F7 /* Debug Hockeyapp */, D04D01C41E678C0D0086DDC0 /* Debug AppStore */, - 69F842401E67540700C110F7 /* Release */, - D04D01CC1E678C230086DDC0 /* Hockeyapp */, + 69F842401E67540700C110F7 /* Release Hockeyapp */, + D04D01CC1E678C230086DDC0 /* Release AppStore */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; + defaultConfigurationName = "Release Hockeyapp"; }; /* End XCConfigurationList section */ }; diff --git a/logging.h b/logging.h index cbe811b..3168bc4 100644 --- a/logging.h +++ b/logging.h @@ -44,10 +44,6 @@ void tgvoip_log_file_write_header(); #include #include -#if !defined(snprintf) && defined(_WIN32) && defined(__cplusplus_winrt) -#define snprintf _snprintf -#endif - #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', msg, ##__VA_ARGS__) @@ -70,6 +66,9 @@ void tgvoip_log_file_write_header(); #endif +#if !defined(snprintf) && defined(_WIN32) && defined(__cplusplus_winrt) +#define snprintf _snprintf +#endif #ifdef TGVOIP_LOG_VERBOSITY #if TGVOIP_LOG_VERBOSITY<5 diff --git a/os/darwin/AudioOutputAudioUnit.cpp b/os/darwin/AudioOutputAudioUnit.cpp index 7114d4d..791dfb2 100644 --- a/os/darwin/AudioOutputAudioUnit.cpp +++ b/os/darwin/AudioOutputAudioUnit.cpp @@ -75,12 +75,12 @@ void AudioOutputAudioUnit::HandleBufferCallback(AudioBufferList *ioData){ memset(buf.mData, 0, buf.mDataByteSize); return; } - while(remainingDataSize(buf.mData); int16_t* src=reinterpret_cast(remainingData); for(k=0;kimplData=(void*)this; controller->SetStateCallback(VoIPControllerWrapper::OnStateChanged); + controller->SetSignalBarsCountCallback(VoIPControllerWrapper::OnSignalBarsChanged); stateCallback=nullptr; } @@ -136,11 +137,20 @@ void VoIPControllerWrapper::OnStateChanged(VoIPController* c, int state){ reinterpret_cast(c->implData)->OnStateChangedInternal(state); } +void VoIPControllerWrapper::OnSignalBarsChanged(VoIPController* c, int count){ + reinterpret_cast(c->implData)->OnSignalBarsChangedInternal(count); +} + void VoIPControllerWrapper::OnStateChangedInternal(int state){ if(stateCallback) stateCallback->OnCallStateChanged((CallState)state); } +void VoIPControllerWrapper::OnSignalBarsChangedInternal(int count){ + if(stateCallback) + stateCallback->OnSignalBarsChanged(count); +} + void VoIPControllerWrapper::SetConfig(double initTimeout, double recvTimeout, DataSavingMode dataSavingMode, bool enableAEC, bool enableNS, bool enableAGC, Platform::String^ logFilePath, Platform::String^ statsDumpFilePath){ voip_config_t config{0}; config.init_timeout=initTimeout; @@ -170,6 +180,10 @@ void VoIPControllerWrapper::SetProxy(ProxyProtocol protocol, Platform::String^ a controller->SetProxy((int)protocol, _address, port, _username, _password); } +void VoIPControllerWrapper::SetAudioOutputGainControlEnabled(bool enabled){ + controller->SetAudioOutputGainControlEnabled(enabled); +} + void VoIPControllerWrapper::UpdateServerConfig(Platform::String^ json){ JsonObject^ jconfig=JsonValue::Parse(json)->GetObject(); std::map config; diff --git a/os/windows/CXWrapper.h b/os/windows/CXWrapper.h index d00d5fb..38e0f0b 100755 --- a/os/windows/CXWrapper.h +++ b/os/windows/CXWrapper.h @@ -60,6 +60,7 @@ namespace libtgvoip{ public interface class IStateCallback{ void OnCallStateChanged(CallState newState); + void OnSignalBarsChanged(int count); }; public ref class VoIPControllerWrapper sealed{ @@ -80,12 +81,15 @@ namespace libtgvoip{ Error GetLastError(); static Platform::String^ GetVersion(); int64 GetPreferredRelayID(); + void SetAudioOutputGainControlEnabled(bool enabled); static void UpdateServerConfig(Platform::String^ json); static void SwitchSpeaker(bool external); //static Platform::String^ TestAesIge(); private: static void OnStateChanged(tgvoip::VoIPController* c, int state); + static void OnSignalBarsChanged(tgvoip::VoIPController* c, int count); void OnStateChangedInternal(int state); + void OnSignalBarsChangedInternal(int count); tgvoip::VoIPController* controller; IStateCallback^ stateCallback; };