updated to 0.3.1

This commit is contained in:
Grishka 2017-03-30 17:06:59 +03:00
parent 2027dabd60
commit eb813e1d13
43 changed files with 2579 additions and 466 deletions

View File

@ -8,6 +8,7 @@
CBlockingQueue::CBlockingQueue(size_t capacity){ CBlockingQueue::CBlockingQueue(size_t capacity){
this->capacity=capacity; this->capacity=capacity;
overflowCallback=NULL;
init_lock(lock); init_lock(lock);
init_mutex(mutex); init_mutex(mutex);
} }
@ -29,7 +30,12 @@ void CBlockingQueue::Put(void *thing){
} }
queue.push_back(thing); queue.push_back(thing);
while(queue.size()>capacity){ while(queue.size()>capacity){
if(overflowCallback){
overflowCallback(queue.front());
queue.pop_front(); queue.pop_front();
}else{
abort();
}
} }
unlock_mutex(mutex); unlock_mutex(mutex);
} }
@ -72,3 +78,7 @@ void CBlockingQueue::PrepareDealloc(){
unlock_mutex(mutex); unlock_mutex(mutex);
} }
void CBlockingQueue::SetOverflowCallback(void (*overflowCallback)(void *)){
this->overflowCallback=overflowCallback;
}

View File

@ -22,6 +22,7 @@ public:
void* Get(); void* Get();
unsigned int Size(); unsigned int Size();
void PrepareDealloc(); void PrepareDealloc();
void SetOverflowCallback(void (*overflowCallback)(void*));
private: private:
void* GetInternal(); void* GetInternal();
@ -29,6 +30,7 @@ private:
size_t capacity; size_t capacity;
tgvoip_lock_t lock; tgvoip_lock_t lock;
tgvoip_mutex_t mutex; tgvoip_mutex_t mutex;
void (*overflowCallback)(void*);
}; };

View File

@ -10,7 +10,7 @@
#include <exception> #include <exception>
#include <stdexcept> #include <stdexcept>
CBufferInputStream::CBufferInputStream(char* data, size_t length){ CBufferInputStream::CBufferInputStream(unsigned char* data, size_t length){
this->buffer=data; this->buffer=data;
this->length=length; this->length=length;
offset=0; offset=0;
@ -22,7 +22,9 @@ CBufferInputStream::~CBufferInputStream(){
void CBufferInputStream::Seek(size_t offset){ void CBufferInputStream::Seek(size_t offset){
assert(offset<=length); if(offset>length){
throw std::out_of_range("Not enough bytes in buffer");
}
this->offset=offset; this->offset=offset;
} }
@ -88,7 +90,7 @@ int32_t CBufferInputStream::ReadTlLength(){
return res; return res;
} }
void CBufferInputStream::ReadBytes(char *to, size_t count){ void CBufferInputStream::ReadBytes(unsigned char *to, size_t count){
EnsureEnoughRemaining(count); EnsureEnoughRemaining(count);
memcpy(to, buffer+offset, count); memcpy(to, buffer+offset, count);
offset+=count; offset+=count;

View File

@ -13,7 +13,7 @@
class CBufferInputStream{ class CBufferInputStream{
public: public:
CBufferInputStream(char* data, size_t length); CBufferInputStream(unsigned char* data, size_t length);
~CBufferInputStream(); ~CBufferInputStream();
void Seek(size_t offset); void Seek(size_t offset);
size_t GetLength(); size_t GetLength();
@ -24,11 +24,11 @@ public:
int32_t ReadInt32(); int32_t ReadInt32();
int16_t ReadInt16(); int16_t ReadInt16();
int32_t ReadTlLength(); int32_t ReadTlLength();
void ReadBytes(char* to, size_t count); void ReadBytes(unsigned char* to, size_t count);
private: private:
void EnsureEnoughRemaining(size_t need); void EnsureEnoughRemaining(size_t need);
char* buffer; unsigned char* buffer;
size_t length; size_t length;
size_t offset; size_t offset;
}; };

View File

@ -8,7 +8,7 @@
#include <string.h> #include <string.h>
CBufferOutputStream::CBufferOutputStream(size_t size){ CBufferOutputStream::CBufferOutputStream(size_t size){
buffer=(char*) malloc(size); buffer=(unsigned char*) malloc(size);
offset=0; offset=0;
this->size=size; this->size=size;
} }
@ -24,40 +24,40 @@ void CBufferOutputStream::WriteByte(unsigned char byte){
void CBufferOutputStream::WriteInt32(int32_t i){ void CBufferOutputStream::WriteInt32(int32_t i){
this->ExpandBufferIfNeeded(4); this->ExpandBufferIfNeeded(4);
buffer[offset+3]=(char)((i >> 24) & 0xFF); buffer[offset+3]=(unsigned char)((i >> 24) & 0xFF);
buffer[offset+2]=(char)((i >> 16) & 0xFF); buffer[offset+2]=(unsigned char)((i >> 16) & 0xFF);
buffer[offset+1]=(char)((i >> 8) & 0xFF); buffer[offset+1]=(unsigned char)((i >> 8) & 0xFF);
buffer[offset]=(char)(i & 0xFF); buffer[offset]=(unsigned char)(i & 0xFF);
offset+=4; offset+=4;
} }
void CBufferOutputStream::WriteInt64(int64_t i){ void CBufferOutputStream::WriteInt64(int64_t i){
this->ExpandBufferIfNeeded(8); this->ExpandBufferIfNeeded(8);
buffer[offset+7]=(char)((i >> 56) & 0xFF); buffer[offset+7]=(unsigned char)((i >> 56) & 0xFF);
buffer[offset+6]=(char)((i >> 48) & 0xFF); buffer[offset+6]=(unsigned char)((i >> 48) & 0xFF);
buffer[offset+5]=(char)((i >> 40) & 0xFF); buffer[offset+5]=(unsigned char)((i >> 40) & 0xFF);
buffer[offset+4]=(char)((i >> 32) & 0xFF); buffer[offset+4]=(unsigned char)((i >> 32) & 0xFF);
buffer[offset+3]=(char)((i >> 24) & 0xFF); buffer[offset+3]=(unsigned char)((i >> 24) & 0xFF);
buffer[offset+2]=(char)((i >> 16) & 0xFF); buffer[offset+2]=(unsigned char)((i >> 16) & 0xFF);
buffer[offset+1]=(char)((i >> 8) & 0xFF); buffer[offset+1]=(unsigned char)((i >> 8) & 0xFF);
buffer[offset]=(char)(i & 0xFF); buffer[offset]=(unsigned char)(i & 0xFF);
offset+=8; offset+=8;
} }
void CBufferOutputStream::WriteInt16(int16_t i){ void CBufferOutputStream::WriteInt16(int16_t i){
this->ExpandBufferIfNeeded(2); this->ExpandBufferIfNeeded(2);
buffer[offset+1]=(char)((i >> 8) & 0xFF); buffer[offset+1]=(unsigned char)((i >> 8) & 0xFF);
buffer[offset]=(char)(i & 0xFF); buffer[offset]=(unsigned char)(i & 0xFF);
offset+=2; offset+=2;
} }
void CBufferOutputStream::WriteBytes(char *bytes, size_t count){ void CBufferOutputStream::WriteBytes(unsigned char *bytes, size_t count){
this->ExpandBufferIfNeeded(count); this->ExpandBufferIfNeeded(count);
memcpy(buffer+offset, bytes, count); memcpy(buffer+offset, bytes, count);
offset+=count; offset+=count;
} }
char *CBufferOutputStream::GetBuffer(){ unsigned char *CBufferOutputStream::GetBuffer(){
return buffer; return buffer;
} }
@ -68,10 +68,10 @@ size_t CBufferOutputStream::GetLength(){
void CBufferOutputStream::ExpandBufferIfNeeded(size_t need){ void CBufferOutputStream::ExpandBufferIfNeeded(size_t need){
if(offset+need>size){ if(offset+need>size){
if(need<1024){ if(need<1024){
buffer=(char *) realloc(buffer, size+1024); buffer=(unsigned char *) realloc(buffer, size+1024);
size+=1024; size+=1024;
}else{ }else{
buffer=(char *) realloc(buffer, size+need); buffer=(unsigned char *) realloc(buffer, size+need);
size+=need; size+=need;
} }
} }

View File

@ -18,14 +18,14 @@ public:
void WriteInt64(int64_t i); void WriteInt64(int64_t i);
void WriteInt32(int32_t i); void WriteInt32(int32_t i);
void WriteInt16(int16_t i); void WriteInt16(int16_t i);
void WriteBytes(char* bytes, size_t count); void WriteBytes(unsigned char* bytes, size_t count);
char* GetBuffer(); unsigned char* GetBuffer();
size_t GetLength(); size_t GetLength();
void Reset(); void Reset();
private: private:
void ExpandBufferIfNeeded(size_t need); void ExpandBufferIfNeeded(size_t need);
char* buffer; unsigned char* buffer;
size_t size; size_t size;
size_t offset; size_t offset;
}; };

View File

@ -7,6 +7,7 @@
#include "CongestionControl.h" #include "CongestionControl.h"
#include "VoIPController.h" #include "VoIPController.h"
#include "logging.h" #include "logging.h"
#include "VoIPServerConfig.h"
#include <math.h> #include <math.h>
#include <assert.h> #include <assert.h>
@ -26,7 +27,7 @@ CCongestionControl::CCongestionControl(){
stateTransitionTime=0; stateTransitionTime=0;
inflightDataSize=0; inflightDataSize=0;
lossCount=0; lossCount=0;
cwnd=1024; cwnd=(size_t) CVoIPServerConfig::GetSharedInstance()->GetInt("audio_congestion_window", 1024);
init_mutex(mutex); init_mutex(mutex);
} }

View File

@ -55,8 +55,8 @@ private:
double stateTransitionTime; double stateTransitionTime;
int tmpRttCount; int tmpRttCount;
char rttHistorySize; char rttHistorySize;
char rttHistoryTop; unsigned int rttHistoryTop;
char inflightHistoryTop; unsigned int inflightHistoryTop;
uint32_t lastSentSeq; uint32_t lastSentSeq;
uint32_t tickCount; uint32_t tickCount;
size_t inflightDataSize; size_t inflightDataSize;

View File

@ -8,6 +8,7 @@
#include "audio/AudioOutput.h" #include "audio/AudioOutput.h"
#include "logging.h" #include "logging.h"
#include <string.h> #include <string.h>
#include <stdio.h>
#define AEC_FRAME_SIZE 160 #define AEC_FRAME_SIZE 160
#define OFFSET_STEP AEC_FRAME_SIZE*2 #define OFFSET_STEP AEC_FRAME_SIZE*2
@ -19,49 +20,73 @@
void WebRtcAec_enable_delay_agnostic(AecCore* self, int enable); void WebRtcAec_enable_delay_agnostic(AecCore* self, int enable);
}*/ }*/
CEchoCanceller::CEchoCanceller(){ CEchoCanceller::CEchoCanceller(bool enableAEC, bool enableNS, bool enableAGC){
#ifndef TGVOIP_NO_AEC this->enableAEC=enableAEC;
init_mutex(mutex); this->enableAGC=enableAGC;
state=WebRtcAecm_Create(); this->enableNS=enableNS;
WebRtcAecm_Init(state, 16000);
AecmConfig cfg;
cfg.cngMode=AecmFalse;
cfg.echoMode=1;
WebRtcAecm_set_config(state, cfg);
//ns=WebRtcNsx_Create();
//WebRtcNsx_Init(ns, 16000);
/*state=webrtc::WebRtcAec_Create();
webrtc::WebRtcAec_Init(state, 16000, 16000);
webrtc::WebRtcAec_enable_delay_agnostic(webrtc::WebRtcAec_aec_core(state), 1);*/
splittingFilter=tgvoip_splitting_filter_create(); splittingFilter=tgvoip_splitting_filter_create();
splittingFilterFarend=tgvoip_splitting_filter_create(); splittingFilterFarend=tgvoip_splitting_filter_create();
farendQueue=new CBlockingQueue(10); if(enableAEC){
init_mutex(aecMutex);
aec=WebRtcAecm_Create();
WebRtcAecm_Init(aec, 16000);
AecmConfig cfg;
cfg.cngMode=AecmFalse;
cfg.echoMode=1;
WebRtcAecm_set_config(aec, cfg);
farendQueue=new CBlockingQueue(11);
farendBufferPool=new CBufferPool(960*2, 10); farendBufferPool=new CBufferPool(960*2, 10);
running=true; running=true;
start_thread(bufferFarendThread, CEchoCanceller::StartBufferFarendThread, this); start_thread(bufferFarendThread, CEchoCanceller::StartBufferFarendThread, this);
}
isOn=true; if(enableNS){
#endif ns=WebRtcNsx_Create();
WebRtcNsx_Init(ns, 48000);
WebRtcNsx_set_policy(ns, 2);
}
if(enableAGC){
agc=WebRtcAgc_Create();
WebRtcAgcConfig agcConfig;
agcConfig.compressionGaindB = 9;
agcConfig.limiterEnable = 1;
agcConfig.targetLevelDbfs = 3;
WebRtcAgc_Init(agc, 0, 255, kAgcModeAdaptiveAnalog, 48000);
WebRtcAgc_set_config(agc, agcConfig);
agcMicLevel=128;
}
/*state=webrtc::WebRtcAec_Create();
webrtc::WebRtcAec_Init(state, 16000, 16000);
webrtc::WebRtcAec_enable_delay_agnostic(webrtc::WebRtcAec_aec_core(state), 1);*/
} }
CEchoCanceller::~CEchoCanceller(){ CEchoCanceller::~CEchoCanceller(){
#ifndef TGVOIP_NO_AEC if(enableAEC){
running=false; running=false;
farendQueue->Put(NULL); farendQueue->Put(NULL);
join_thread(bufferFarendThread); join_thread(bufferFarendThread);
delete farendQueue; delete farendQueue;
delete farendBufferPool; delete farendBufferPool;
WebRtcAecm_Free(state); WebRtcAecm_Free(aec);
//WebRtcNsx_Free(ns); }
if(enableNS){
WebRtcNsx_Free(ns);
}
if(enableAGC){
WebRtcAgc_Free(agc);
}
//webrtc::WebRtcAec_Free(state); //webrtc::WebRtcAec_Free(state);
tgvoip_splitting_filter_free(splittingFilter); tgvoip_splitting_filter_free(splittingFilter);
tgvoip_splitting_filter_free(splittingFilterFarend); tgvoip_splitting_filter_free(splittingFilterFarend);
free_mutex(mutex); if (this->enableAEC) {
#endif free_mutex(aecMutex);
}
} }
void CEchoCanceller::Start(){ void CEchoCanceller::Start(){
@ -74,8 +99,7 @@ void CEchoCanceller::Stop(){
void CEchoCanceller::SpeakerOutCallback(unsigned char* data, size_t len){ void CEchoCanceller::SpeakerOutCallback(unsigned char* data, size_t len){
#ifndef TGVOIP_NO_AEC if(len!=960*2 || !enableAEC)
if(len!=960*2 || !isOn)
return; return;
/*size_t offset=0; /*size_t offset=0;
while(offset<len){ while(offset<len){
@ -87,10 +111,8 @@ void CEchoCanceller::SpeakerOutCallback(unsigned char* data, size_t len){
memcpy(buf, data, 960*2); memcpy(buf, data, 960*2);
farendQueue->Put(buf); farendQueue->Put(buf);
} }
#endif
} }
#ifndef TGVOIP_NO_AEC
void *CEchoCanceller::StartBufferFarendThread(void *arg){ void *CEchoCanceller::StartBufferFarendThread(void *arg){
((CEchoCanceller*)arg)->RunBufferFarendThread(); ((CEchoCanceller*)arg)->RunBufferFarendThread();
return NULL; return NULL;
@ -101,35 +123,27 @@ void CEchoCanceller::RunBufferFarendThread(){
int16_t* samplesIn=(int16_t *) farendQueue->GetBlocking(); int16_t* samplesIn=(int16_t *) farendQueue->GetBlocking();
if(samplesIn){ if(samplesIn){
int i; int i;
for(i=0;i<960;i++){ memcpy(splittingFilterFarend->bufferIn, samplesIn, 960*2);
splittingFilterFarend->bufferIn[i]=samplesIn[i]/(float)32767;
}
farendBufferPool->Reuse((unsigned char *) samplesIn); farendBufferPool->Reuse((unsigned char *) samplesIn);
tgvoip_splitting_filter_analyze(splittingFilterFarend); tgvoip_splitting_filter_analyze(splittingFilterFarend);
lock_mutex(aecMutex);
//webrtc::WebRtcAec_BufferFarend(state, splittingFilterFarend->bufferOut[0], 160); //webrtc::WebRtcAec_BufferFarend(state, splittingFilterFarend->bufferOut[0], 160);
//webrtc::WebRtcAec_BufferFarend(state, &splittingFilterFarend->bufferOut[0][160], 160); //webrtc::WebRtcAec_BufferFarend(state, &splittingFilterFarend->bufferOut[0][160], 160);
int16_t farend[320]; WebRtcAecm_BufferFarend(aec, splittingFilterFarend->bufferOut[0], 160);
for(i=0;i<320;i++){ WebRtcAecm_BufferFarend(aec, splittingFilterFarend->bufferOut[0]+160, 160);
farend[i]=(int16_t) (CLAMP(splittingFilterFarend->bufferOut[0][i], -1, 1)*32767); unlock_mutex(aecMutex);
}
lock_mutex(mutex);
WebRtcAecm_BufferFarend(state, farend, 160);
WebRtcAecm_BufferFarend(state, farend+160, 160);
unlock_mutex(mutex);
didBufferFarend=true; didBufferFarend=true;
} }
} }
} }
#endif
void CEchoCanceller::Enable(bool enabled){ void CEchoCanceller::Enable(bool enabled){
isOn=enabled; //isOn=enabled;
} }
void CEchoCanceller::ProcessInput(unsigned char* data, unsigned char* out, size_t len){ void CEchoCanceller::ProcessInput(unsigned char* data, unsigned char* out, size_t len){
#ifndef TGVOIP_NO_AEC
int i; int i;
if(!isOn){ if(!enableAEC && !enableAGC && !enableNS){
memcpy(out, data, len); memcpy(out, data, len);
return; return;
} }
@ -137,43 +151,77 @@ void CEchoCanceller::ProcessInput(unsigned char* data, unsigned char* out, size_
int16_t* samplesOut=(int16_t*)out; int16_t* samplesOut=(int16_t*)out;
//int16_t samplesAfterNs[320]; //int16_t samplesAfterNs[320];
//float fout[3][320]; //float fout[3][320];
for(i=0;i<960;i++){ memcpy(splittingFilter->bufferIn, samplesIn, 960*2);
splittingFilter->bufferIn[i]=samplesIn[i]/(float)32767;
}
tgvoip_splitting_filter_analyze(splittingFilter); tgvoip_splitting_filter_analyze(splittingFilter);
for(i=0;i<320;i++){ if(enableAGC){
samplesIn[i]=(int16_t) (CLAMP(splittingFilter->bufferOut[0][i], -1, 1)*32767); int16_t _agcOut[3][320];
int16_t* agcIn[3];
int16_t* agcOut[3];
for(i=0;i<3;i++){
agcIn[i]=splittingFilter->bufferOut[i];
agcOut[i]=_agcOut[i];
} }
lock_mutex(mutex); uint8_t saturation;
/*float* aecIn[3]; WebRtcAgc_AddMic(agc, agcIn, 3, 160);
float* aecOut[3]; WebRtcAgc_Process(agc, (const int16_t *const *) agcIn, 3, 160, agcOut, agcMicLevel, &agcMicLevel, 0, &saturation);
aecIn[0]=splittingFilter->bufferOut[0]; for(i=0;i<3;i++){
aecIn[1]=splittingFilter->bufferOut[1]; agcOut[i]+=160;
aecIn[2]=splittingFilter->bufferOut[2]; agcIn[i]+=160;
aecOut[0]=fout[0]; }
aecOut[1]=fout[1]; WebRtcAgc_AddMic(agc, agcIn, 3, 160);
aecOut[2]=fout[2]; WebRtcAgc_Process(agc, (const int16_t *const *) agcIn, 3, 160, agcOut, agcMicLevel, &agcMicLevel, 0, &saturation);
webrtc::WebRtcAec_Process(state, (const float *const *) aecIn, 1, (float *const *) aecOut, 160, 0, 0); //LOGV("AGC mic level %d", agcMicLevel);
aecIn[0]+=160; memcpy(splittingFilter->bufferOut[0], _agcOut[0], 960*2);
aecIn[1]+=160; }
aecIn[2]+=160;
aecOut[0]+=160; if(enableAEC && enableNS){
aecOut[1]+=160; int16_t _nsOut[3][320];
aecOut[2]+=160; int16_t* nsIn[3];
webrtc::WebRtcAec_Process(state, (const float *const *) aecIn, 1, (float *const *) aecOut, 160, 0, 0);*/ int16_t* nsOut[3];
//int16_t* nsIn=samplesIn; for(i=0;i<3;i++){
//int16_t* nsOut=samplesAfterNs; nsIn[i]=splittingFilter->bufferOut[i];
//WebRtcNsx_Process(ns, (const short *const *) &nsIn, 1, (short *const *) &nsOut); nsOut[i]=_nsOut[i];
//nsIn+=160; }
//nsOut+=160; WebRtcNsx_Process(ns, (const short *const *) nsIn, 3, nsOut);
//WebRtcNsx_Process(ns, (const short *const *) &nsIn, 1, (short *const *) &nsOut); for(i=0;i<3;i++){
WebRtcAecm_Process(state, samplesIn, NULL, samplesOut, AEC_FRAME_SIZE, (int16_t) CAudioOutput::GetEstimatedDelay()); nsOut[i]+=160;
WebRtcAecm_Process(state, samplesIn+160, NULL, samplesOut+160, AEC_FRAME_SIZE, (int16_t) CAudioOutput::GetEstimatedDelay()); nsIn[i]+=160;
unlock_mutex(mutex); }
for(i=0;i<320;i++){ WebRtcNsx_Process(ns, (const short *const *) nsIn, 3, nsOut);
splittingFilter->bufferOut[0][i]=samplesOut[i]/(float)32767;
memcpy(splittingFilter->bufferOut[1], _nsOut[1], 320*2*2);
lock_mutex(aecMutex);
WebRtcAecm_Process(aec, splittingFilter->bufferOut[0], _nsOut[0], samplesOut, AEC_FRAME_SIZE, (int16_t) CAudioOutput::GetEstimatedDelay());
WebRtcAecm_Process(aec, splittingFilter->bufferOut[0]+160, _nsOut[0]+160, samplesOut+160, AEC_FRAME_SIZE, (int16_t) CAudioOutput::GetEstimatedDelay());
unlock_mutex(aecMutex);
memcpy(splittingFilter->bufferOut[0], samplesOut, 320*2);
}else if(enableAEC){
lock_mutex(aecMutex);
WebRtcAecm_Process(aec, splittingFilter->bufferOut[0], NULL, samplesOut, AEC_FRAME_SIZE, (int16_t) CAudioOutput::GetEstimatedDelay());
WebRtcAecm_Process(aec, splittingFilter->bufferOut[0]+160, NULL, samplesOut+160, AEC_FRAME_SIZE, (int16_t) CAudioOutput::GetEstimatedDelay());
unlock_mutex(aecMutex);
memcpy(splittingFilter->bufferOut[0], samplesOut, 320*2);
}else if(enableNS){
int16_t _nsOut[3][320];
int16_t* nsIn[3];
int16_t* nsOut[3];
for(i=0;i<3;i++){
nsIn[i]=splittingFilter->bufferOut[i];
nsOut[i]=_nsOut[i];
}
WebRtcNsx_Process(ns, (const short *const *) nsIn, 3, nsOut);
for(i=0;i<3;i++){
nsOut[i]+=160;
nsIn[i]+=160;
}
WebRtcNsx_Process(ns, (const short *const *) nsIn, 3, nsOut);
memcpy(splittingFilter->bufferOut[0], _nsOut[0], 960*2);
//memcpy(splittingFilter->bufferOut[1], _nsOut[1], 320*2);
//memcpy(splittingFilter->bufferOut[2], _nsOut[2], 320*2);
} }
//memcpy(splittingFilter->bufferOut[0], fout[0], 320*sizeof(float)); //memcpy(splittingFilter->bufferOut[0], fout[0], 320*sizeof(float));
@ -182,11 +230,6 @@ void CEchoCanceller::ProcessInput(unsigned char* data, unsigned char* out, size_
tgvoip_splitting_filter_synthesize(splittingFilter); tgvoip_splitting_filter_synthesize(splittingFilter);
for(i=0;i<960;i++){ memcpy(samplesOut, splittingFilter->bufferIn, 960*2);
samplesOut[i]=(int16_t) (CLAMP(splittingFilter->bufferIn[i], -1, 1)*32767);
}
#else
memcpy(out, data, len);
#endif
} }

View File

@ -11,9 +11,9 @@
#include <TargetConditionals.h> #include <TargetConditionals.h>
#endif #endif
#if TARGET_OS_IPHONE /*#if TARGET_OS_IPHONE
#define TGVOIP_NO_AEC #define TGVOIP_NO_AEC
#endif #endif*/
#include "threading.h" #include "threading.h"
#include "BufferPool.h" #include "BufferPool.h"
@ -23,12 +23,13 @@
//#include "external/include/webrtc/echo_cancellation.h" //#include "external/include/webrtc/echo_cancellation.h"
#include "external/include/webrtc/splitting_filter_wrapper.h" #include "external/include/webrtc/splitting_filter_wrapper.h"
#include "external/include/webrtc/noise_suppression_x.h" #include "external/include/webrtc/noise_suppression_x.h"
#include "external/include/webrtc/gain_control.h"
#endif #endif
class CEchoCanceller{ class CEchoCanceller{
public: public:
CEchoCanceller(); CEchoCanceller(bool enableAEC, bool enableNS, bool enableAGC);
virtual ~CEchoCanceller(); virtual ~CEchoCanceller();
virtual void Start(); virtual void Start();
virtual void Stop(); virtual void Stop();
@ -37,20 +38,24 @@ public:
void ProcessInput(unsigned char* data, unsigned char* out, size_t len); void ProcessInput(unsigned char* data, unsigned char* out, size_t len);
private: private:
bool isOn; bool enableAEC;
bool enableAGC;
bool enableNS;
#ifndef TGVOIP_NO_AEC #ifndef TGVOIP_NO_AEC
static void* StartBufferFarendThread(void* arg); static void* StartBufferFarendThread(void* arg);
void RunBufferFarendThread(); void RunBufferFarendThread();
bool didBufferFarend; bool didBufferFarend;
tgvoip_mutex_t mutex; tgvoip_mutex_t aecMutex;
void* state; void* aec;
splitting_filter_t* splittingFilter; tgvoip_splitting_filter_t* splittingFilter;
splitting_filter_t* splittingFilterFarend; tgvoip_splitting_filter_t* splittingFilterFarend;
tgvoip_thread_t bufferFarendThread; tgvoip_thread_t bufferFarendThread;
CBlockingQueue* farendQueue; CBlockingQueue* farendQueue;
CBufferPool* farendBufferPool; CBufferPool* farendBufferPool;
bool running; bool running;
NsxHandle* ns; NsxHandle* ns;
void* agc;
int32_t agcMicLevel;
#endif #endif
}; };

24
Info.plist Normal file
View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@ -4,8 +4,11 @@
// you should have received with this source code distribution. // you should have received with this source code distribution.
// //
#include "VoIPController.h"
#include "JitterBuffer.h" #include "JitterBuffer.h"
#include "logging.h" #include "logging.h"
#include "VoIPServerConfig.h"
#include <math.h>
CJitterBuffer::CJitterBuffer(CMediaStreamItf *out, uint32_t step):bufferPool(JITTER_SLOT_SIZE, JITTER_SLOT_COUNT){ CJitterBuffer::CJitterBuffer(CMediaStreamItf *out, uint32_t step):bufferPool(JITTER_SLOT_SIZE, JITTER_SLOT_COUNT){
if(out) if(out)
@ -19,12 +22,21 @@ CJitterBuffer::CJitterBuffer(CMediaStreamItf *out, uint32_t step):bufferPool(JIT
dontIncMinDelay=0; dontIncMinDelay=0;
dontDecMinDelay=0; dontDecMinDelay=0;
lostPackets=0; lostPackets=0;
if(step<30) if(step<30){
minMinDelay=2; minMinDelay=(uint32_t) CVoIPServerConfig::GetSharedInstance()->GetInt("jitter_min_delay_20", 6);
else if(step<50) maxMinDelay=(uint32_t) CVoIPServerConfig::GetSharedInstance()->GetInt("jitter_max_delay_20", 25);
minMinDelay=4; maxUsedSlots=(uint32_t) CVoIPServerConfig::GetSharedInstance()->GetInt("jitter_max_slots_20", 50);
else }else if(step<50){
minMinDelay=6; minMinDelay=(uint32_t) CVoIPServerConfig::GetSharedInstance()->GetInt("jitter_min_delay_40", 4);
maxMinDelay=(uint32_t) CVoIPServerConfig::GetSharedInstance()->GetInt("jitter_max_delay_40", 15);
maxUsedSlots=(uint32_t) CVoIPServerConfig::GetSharedInstance()->GetInt("jitter_max_slots_40", 30);
}else{
minMinDelay=(uint32_t) CVoIPServerConfig::GetSharedInstance()->GetInt("jitter_min_delay_60", 1);
maxMinDelay=(uint32_t) CVoIPServerConfig::GetSharedInstance()->GetInt("jitter_max_delay_60", 10);
maxUsedSlots=(uint32_t) CVoIPServerConfig::GetSharedInstance()->GetInt("jitter_max_slots_60", 20);
}
lossesToReset=(uint32_t) CVoIPServerConfig::GetSharedInstance()->GetInt("jitter_losses_to_reset", 20);
resyncThreshold=CVoIPServerConfig::GetSharedInstance()->GetDouble("jitter_resync_threshold", 1.0);
Reset(); Reset();
init_mutex(mutex); init_mutex(mutex);
} }
@ -76,9 +88,14 @@ void CJitterBuffer::Reset(){
slots[i].buffer=NULL; slots[i].buffer=NULL;
} }
} }
memset(delayHistory, 0, sizeof(int)*64); memset(delayHistory, 0, sizeof(delayHistory));
memset(lateHistory, 0, sizeof(int)*64); memset(lateHistory, 0, sizeof(lateHistory));
adjustingDelay=false; adjustingDelay=false;
lostSinceReset=0;
gotSinceReset=0;
expectNextAtTime=0;
memset(deviationHistory, 0, sizeof(deviationHistory));
deviationPtr=0;
} }
@ -134,16 +151,18 @@ int CJitterBuffer::GetInternal(jitter_packet_t* pkt, int offset){
return JR_OK; return JR_OK;
} }
LOGW("jitter: found no packet for timestamp %lld (last put = %d)", timestampToGet, lastPutTimestamp); LOGW("jitter: found no packet for timestamp %lld (last put = %d, lost = %d)", timestampToGet, lastPutTimestamp, lostCount);
if(offset==0) if(offset==0)
Advance(); Advance();
if(!needBuffering){ if(!needBuffering){
lostCount++; lostCount++;
if(offset==0) if(offset==0){
lostPackets++; lostPackets++;
if(lostCount>=10){ lostSinceReset++;
}
if(lostCount>=lossesToReset || (gotSinceReset>minDelay*25 && lostSinceReset>gotSinceReset/2)){
LOGW("jitter: lost %d packets in a row, resetting", lostCount); LOGW("jitter: lost %d packets in a row, resetting", lostCount);
//minDelay++; //minDelay++;
dontIncMinDelay=16; dontIncMinDelay=16;
@ -164,11 +183,14 @@ void CJitterBuffer::PutInternal(jitter_packet_t* pkt){
LOGE("The packet is too big to fit into the jitter buffer"); LOGE("The packet is too big to fit into the jitter buffer");
return; return;
} }
gotSinceReset++;
int i; int i;
if(wasReset){ if(wasReset){
wasReset=false; wasReset=false;
nextTimestamp=((int64_t)pkt->timestamp)-step*minDelay; nextTimestamp=((int64_t)pkt->timestamp)-step*minDelay;
LOGI("jitter: resyncing, next timestamp = %lld (step=%d, minDelay=%d)", nextTimestamp, step, minDelay); LOGI("jitter: resyncing, next timestamp = %lld (step=%d, minDelay=%d)", nextTimestamp, step, minDelay);
}
for(i=0;i<JITTER_SLOT_COUNT;i++){ for(i=0;i<JITTER_SLOT_COUNT;i++){
if(slots[i].buffer!=NULL){ if(slots[i].buffer!=NULL){
if(slots[i].timestamp<nextTimestamp-1){ if(slots[i].timestamp<nextTimestamp-1){
@ -177,6 +199,24 @@ void CJitterBuffer::PutInternal(jitter_packet_t* pkt){
} }
} }
} }
/*double prevTime=0;
uint32_t closestTime=0;
for(i=0;i<JITTER_SLOT_COUNT;i++){
if(slots[i].buffer!=NULL && pkt->timestamp-slots[i].timestamp<pkt->timestamp-closestTime){
closestTime=slots[i].timestamp;
prevTime=slots[i].recvTime;
}
}*/
double time=CVoIPController::GetCurrentTime();
if(expectNextAtTime!=0){
double dev=expectNextAtTime-time;
//LOGV("packet dev %f", dev);
deviationHistory[deviationPtr]=dev;
deviationPtr=(deviationPtr+1)%64;
expectNextAtTime+=step/1000.0;
}else{
expectNextAtTime=time+step/1000.0;
} }
if(pkt->timestamp<nextTimestamp){ if(pkt->timestamp<nextTimestamp){
@ -196,15 +236,16 @@ void CJitterBuffer::PutInternal(jitter_packet_t* pkt){
if(slots[i].buffer==NULL) if(slots[i].buffer==NULL)
break; break;
} }
if(i==JITTER_SLOT_COUNT){ if(i==JITTER_SLOT_COUNT || GetCurrentDelay()>=maxUsedSlots){
int toRemove=JITTER_SLOT_COUNT; int toRemove=JITTER_SLOT_COUNT;
uint32_t bestTimestamp=0xFFFFFFFF; uint32_t bestTimestamp=0xFFFFFFFF;
for(i=0;i<JITTER_SLOT_COUNT;i++){ for(i=0;i<JITTER_SLOT_COUNT;i++){
if(slots[i].timestamp<bestTimestamp){ if(slots[i].buffer!=NULL && slots[i].timestamp<bestTimestamp){
toRemove=i; toRemove=i;
bestTimestamp=slots[i].timestamp; bestTimestamp=slots[i].timestamp;
} }
} }
Advance();
bufferPool.Reuse(slots[toRemove].buffer); bufferPool.Reuse(slots[toRemove].buffer);
slots[toRemove].buffer=NULL; slots[toRemove].buffer=NULL;
i=toRemove; i=toRemove;
@ -212,10 +253,12 @@ void CJitterBuffer::PutInternal(jitter_packet_t* pkt){
slots[i].timestamp=pkt->timestamp; slots[i].timestamp=pkt->timestamp;
slots[i].size=pkt->size; slots[i].size=pkt->size;
slots[i].buffer=bufferPool.Get(); slots[i].buffer=bufferPool.Get();
slots[i].recvTimeDiff=time-prevRecvTime;
if(slots[i].buffer) if(slots[i].buffer)
memcpy(slots[i].buffer, pkt->buffer, pkt->size); memcpy(slots[i].buffer, pkt->buffer, pkt->size);
else else
LOGE("WTF!!"); LOGE("WTF!!");
prevRecvTime=time;
} }
@ -238,14 +281,7 @@ void CJitterBuffer::Tick(){
lock_mutex(mutex); lock_mutex(mutex);
int i; int i;
for(i=0;i<JITTER_SLOT_COUNT;i++){ int count=0;
if(slots[i].buffer!=NULL){
if(slots[i].timestamp<nextTimestamp-2){
bufferPool.Reuse(slots[i].buffer);
slots[i].buffer=NULL;
}
}
}
memmove(&lateHistory[1], lateHistory, 63*sizeof(int)); memmove(&lateHistory[1], lateHistory, 63*sizeof(int));
lateHistory[0]=latePacketCount; lateHistory[0]=latePacketCount;
@ -267,7 +303,10 @@ void CJitterBuffer::Tick(){
avgLate32/=32; avgLate32/=32;
avgLate16/=16; avgLate16/=16;
//LOGV("jitter: avg late=%.1f, %.1f, %.1f", avgLate16, avgLate32, avgLate64); //LOGV("jitter: avg late=%.1f, %.1f, %.1f", avgLate16, avgLate32, avgLate64);
if(avgLate16>=0.3){ if(avgLate16>=resyncThreshold){
wasReset=true;
}
/*if(avgLate16>=0.3){
if(dontIncMinDelay==0 && minDelay<15){ if(dontIncMinDelay==0 && minDelay<15){
minDelay++; minDelay++;
if(GetCurrentDelay()<minDelay) if(GetCurrentDelay()<minDelay)
@ -286,7 +325,12 @@ void CJitterBuffer::Tick(){
} }
if(dontIncMinDelay>0) if(dontIncMinDelay>0)
dontIncMinDelay--; dontIncMinDelay--;*/
if(absolutelyNoLatePackets){
if(dontDecMinDelay>0)
dontDecMinDelay--;
}
memmove(&delayHistory[1], delayHistory, 63*sizeof(int)); memmove(&delayHistory[1], delayHistory, 63*sizeof(int));
delayHistory[0]=GetCurrentDelay(); delayHistory[0]=GetCurrentDelay();
@ -299,9 +343,49 @@ void CJitterBuffer::Tick(){
min=delayHistory[i]; min=delayHistory[i];
} }
avgDelay/=32; avgDelay/=32;
double stddev=0;
double avgdev=0;
for(i=0;i<64;i++){
avgdev+=deviationHistory[i];
}
avgdev/=64;
for(i=0;i<64;i++){
double d=(deviationHistory[i]-avgdev);
stddev+=(d*d);
}
stddev=sqrt(stddev/64);
uint32_t stddevDelay=(uint32_t)ceil(stddev*2*1000/step);
if(stddevDelay<minMinDelay)
stddevDelay=minMinDelay;
if(stddevDelay>maxMinDelay)
stddevDelay=maxMinDelay;
if(stddevDelay!=minDelay){
int32_t diff=stddevDelay-minDelay;
if(diff>0){
dontDecMinDelay=100;
}
if(diff<-1)
diff=-1;
if(diff>1)
diff=1;
if((diff>0 && dontIncMinDelay==0) || (diff<0 && dontDecMinDelay==0)){
nextTimestamp+=diff*(int32_t)step;
minDelay+=diff;
LOGD("new delay from stddev %d", minDelay);
if(diff<0){
dontDecMinDelay+=25;
}
if(diff>0){
dontIncMinDelay=25;
}
}
}
//LOGV("stddev=%.3f, avg=%.3f, ndelay=%d, dontDec=%u", stddev, avgdev, stddevDelay, dontDecMinDelay);
//LOGV("jitter: avg delay=%d, delay=%d, late16=%.1f, dontDecMinDelay=%d", avgDelay, delayHistory[0], avgLate16, dontDecMinDelay); //LOGV("jitter: avg delay=%d, delay=%d, late16=%.1f, dontDecMinDelay=%d", avgDelay, delayHistory[0], avgLate16, dontDecMinDelay);
if(!adjustingDelay) { if(!adjustingDelay) {
if (avgDelay>=minDelay/2 && delayHistory[0]>minDelay && avgLate16<=0.1 && absolutelyNoLatePackets && dontDecMinDelay<32 && min>minDelay) { if (((minDelay==1 ? (avgDelay>=3) : (avgDelay>=minDelay/2)) && delayHistory[0]>minDelay && avgLate16<=0.1 && absolutelyNoLatePackets && dontDecMinDelay<32 && min>minDelay) /*|| (avgRecvTimeDiff>0 && delayHistory[0]>minDelay/2 && avgRecvTimeDiff*1000<step/2)*/) {
LOGI("jitter: need adjust"); LOGI("jitter: need adjust");
adjustingDelay=true; adjustingDelay=true;
} }
@ -312,6 +396,7 @@ void CJitterBuffer::Tick(){
}else if(tickCount%5==0){ }else if(tickCount%5==0){
LOGD("jitter: removing a packet to reduce delay"); LOGD("jitter: removing a packet to reduce delay");
GetInternal(NULL, 0); GetInternal(NULL, 0);
expectNextAtTime=0;
if(GetCurrentDelay()<=minDelay || min<=minDelay){ if(GetCurrentDelay()<=minDelay || min<=minDelay){
adjustingDelay = false; adjustingDelay = false;
LOGI("jitter: done adjusting"); LOGI("jitter: done adjusting");

View File

@ -24,6 +24,7 @@ struct jitter_packet_t{
unsigned char* buffer; unsigned char* buffer;
size_t size; size_t size;
uint32_t timestamp; uint32_t timestamp;
double recvTimeDiff;
}; };
typedef struct jitter_packet_t jitter_packet_t; typedef struct jitter_packet_t jitter_packet_t;
@ -55,8 +56,14 @@ private:
uint32_t step; uint32_t step;
uint32_t minDelay; uint32_t minDelay;
uint32_t minMinDelay; uint32_t minMinDelay;
uint32_t maxMinDelay;
uint32_t maxUsedSlots;
uint32_t lastPutTimestamp; uint32_t lastPutTimestamp;
uint32_t lossesToReset;
double resyncThreshold;
int lostCount; int lostCount;
int lostSinceReset;
int gotSinceReset;
bool wasReset; bool wasReset;
bool needBuffering; bool needBuffering;
int delayHistory[64]; int delayHistory[64];
@ -67,6 +74,10 @@ private:
unsigned int dontIncMinDelay; unsigned int dontIncMinDelay;
unsigned int dontDecMinDelay; unsigned int dontDecMinDelay;
int lostPackets; int lostPackets;
double prevRecvTime;
double expectNextAtTime;
double deviationHistory[64];
int deviationPtr;
}; };

View File

@ -22,7 +22,7 @@ COpusDecoder::COpusDecoder(CMediaStreamItf *dst){
outputBufferSize=0; outputBufferSize=0;
packetsNeeded=0; packetsNeeded=0;
lastDecodedOffset=0; lastDecodedOffset=0;
decodedQueue=new CBlockingQueue(32); decodedQueue=new CBlockingQueue(33);
bufferPool=new CBufferPool(PACKET_SIZE, 32); bufferPool=new CBufferPool(PACKET_SIZE, 32);
echoCanceller=NULL; echoCanceller=NULL;
frameDuration=20; frameDuration=20;

View File

@ -7,8 +7,9 @@
#include "OpusEncoder.h" #include "OpusEncoder.h"
#include <assert.h> #include <assert.h>
#include "logging.h" #include "logging.h"
#include "VoIPServerConfig.h"
COpusEncoder::COpusEncoder(CMediaStreamItf *source):queue(10), bufferPool(960*2, 10){ COpusEncoder::COpusEncoder(CMediaStreamItf *source):queue(11), bufferPool(960*2, 10){
this->source=source; this->source=source;
source->SetCallback(COpusEncoder::Callback, this); source->SetCallback(COpusEncoder::Callback, this);
enc=opus_encoder_create(48000, 1, OPUS_APPLICATION_VOIP, NULL); enc=opus_encoder_create(48000, 1, OPUS_APPLICATION_VOIP, NULL);
@ -16,13 +17,17 @@ COpusEncoder::COpusEncoder(CMediaStreamItf *source):queue(10), bufferPool(960*2,
opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(15)); opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(15));
opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1)); opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1));
opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)); opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
//opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
requestedBitrate=32000; requestedBitrate=32000;
currentBitrate=0; currentBitrate=0;
running=false; running=false;
echoCanceller=NULL; echoCanceller=NULL;
complexity=10; complexity=10;
frameDuration=20; frameDuration=20;
mediumCorrectionBitrate=CVoIPServerConfig::GetSharedInstance()->GetInt("audio_medium_fec_bitrate", 10000);
strongCorrectionBitrate=CVoIPServerConfig::GetSharedInstance()->GetInt("audio_strong_fec_bitrate", 8000);
mediumCorrectionMultiplier=CVoIPServerConfig::GetSharedInstance()->GetDouble("audio_medium_fec_multiplier", 1.5);
strongCorrectionMultiplier=CVoIPServerConfig::GetSharedInstance()->GetDouble("audio_strong_fec_multiplier", 2.0);
} }
COpusEncoder::~COpusEncoder(){ COpusEncoder::~COpusEncoder(){
@ -140,5 +145,16 @@ void COpusEncoder::SetOutputFrameDuration(uint32_t duration){
void COpusEncoder::SetPacketLoss(int percent){ void COpusEncoder::SetPacketLoss(int percent){
opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(percent)); packetLossPercent=percent;
double multiplier=1;
if(currentBitrate<=strongCorrectionBitrate)
multiplier=strongCorrectionMultiplier;
else if(currentBitrate<=mediumCorrectionBitrate)
multiplier=mediumCorrectionMultiplier;
opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC((int)(percent*multiplier)));
opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(percent>17 ? OPUS_AUTO : OPUS_BANDWIDTH_FULLBAND));
}
int COpusEncoder::GetPacketLoss(){
return packetLossPercent;
} }

View File

@ -27,6 +27,7 @@ public:
void SetEchoCanceller(CEchoCanceller* aec); void SetEchoCanceller(CEchoCanceller* aec);
void SetOutputFrameDuration(uint32_t duration); void SetOutputFrameDuration(uint32_t duration);
void SetPacketLoss(int percent); void SetPacketLoss(int percent);
int GetPacketLoss();
uint32_t GetBitrate(); uint32_t GetBitrate();
private: private:
@ -46,6 +47,11 @@ private:
int complexity; int complexity;
bool running; bool running;
uint32_t frameDuration; uint32_t frameDuration;
int packetLossPercent;
uint32_t mediumCorrectionBitrate;
uint32_t strongCorrectionBitrate;
double mediumCorrectionMultiplier;
double strongCorrectionMultiplier;
}; };

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,8 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <stdint.h> #include <stdint.h>
#include <vector> #include <vector>
#include <string>
#include <map>
#include "audio/AudioInput.h" #include "audio/AudioInput.h"
#include "BlockingQueue.h" #include "BlockingQueue.h"
#include "BufferOutputStream.h" #include "BufferOutputStream.h"
@ -15,7 +17,11 @@
#include "EchoCanceller.h" #include "EchoCanceller.h"
#include "CongestionControl.h" #include "CongestionControl.h"
#define LIBTGVOIP_VERSION "0.2.4" #ifdef __APPLE__
#import <Foundation/Foundation.h>
#endif
#define LIBTGVOIP_VERSION "0.3.1"
#define PKT_INIT 1 #define PKT_INIT 1
#define PKT_INIT_ACK 2 #define PKT_INIT_ACK 2
@ -40,6 +46,7 @@
#define ERROR_UNKNOWN 0 #define ERROR_UNKNOWN 0
#define ERROR_INCOMPATIBLE 1 #define ERROR_INCOMPATIBLE 1
#define ERROR_TIMEOUT 2 #define ERROR_TIMEOUT 2
#define ERROR_AUDIO_IO 3
#define NET_TYPE_UNKNOWN 0 #define NET_TYPE_UNKNOWN 0
#define NET_TYPE_GPRS 1 #define NET_TYPE_GPRS 1
@ -59,6 +66,8 @@
#define PROTOCOL_NAME 0x50567247 // "GrVP" in little endian (reversed here) #define PROTOCOL_NAME 0x50567247 // "GrVP" in little endian (reversed here)
#define PROTOCOL_VERSION 3 #define PROTOCOL_VERSION 3
#define MIN_PROTOCOL_VERSION 3 #define MIN_PROTOCOL_VERSION 3
#define MIN_UDP_PORT 16384
#define MAX_UDP_PORT 32768
#define STREAM_DATA_FLAG_LEN16 0x40 #define STREAM_DATA_FLAG_LEN16 0x40
#define STREAM_DATA_FLAG_HAS_MORE_FLAGS 0x80 #define STREAM_DATA_FLAG_HAS_MORE_FLAGS 0x80
@ -91,6 +100,14 @@
#define TLID_DECRYPTED_AUDIO_BLOCK 0xDBF948C1 #define TLID_DECRYPTED_AUDIO_BLOCK 0xDBF948C1
#define TLID_SIMPLE_AUDIO_BLOCK 0xCC0D0E76 #define TLID_SIMPLE_AUDIO_BLOCK 0xCC0D0E76
#define TLID_UDP_REFLECTOR_PEER_INFO 0x27D9371C #define TLID_UDP_REFLECTOR_PEER_INFO 0x27D9371C
#define PAD4(x) (4-(x+(x<=253 ? 1 : 0))%4)
inline int pad4(int x){
int r=PAD4(x);
if(r==4)
return 0;
return r;
}
struct voip_endpoint_t{ // make this a class maybe? struct voip_endpoint_t{ // make this a class maybe?
int64_t id; int64_t id;
@ -98,7 +115,7 @@ struct voip_endpoint_t{ // make this a class maybe?
in_addr address; in_addr address;
in6_addr address6; in6_addr address6;
char type; char type;
char peerTag[16]; unsigned char peerTag[16];
double _lastPingTime; double _lastPingTime;
uint32_t _lastPingSeq; uint32_t _lastPingSeq;
@ -119,7 +136,7 @@ typedef struct voip_stream_t voip_stream_t;
struct voip_queued_packet_t{ struct voip_queued_packet_t{
unsigned char type; unsigned char type;
char* data; unsigned char* data;
size_t length; size_t length;
uint32_t seqs[16]; uint32_t seqs[16];
double firstSentTime; double firstSentTime;
@ -133,10 +150,11 @@ struct voip_config_t{
double init_timeout; double init_timeout;
double recv_timeout; double recv_timeout;
int data_saving; int data_saving;
int frame_size; char logFilePath[256];
#ifdef __ANDROID__
bool enableAEC; bool enableAEC;
#endif bool enableNS;
bool enableAGC;
}; };
typedef struct voip_config_t voip_config_t; typedef struct voip_config_t voip_config_t;
@ -180,7 +198,7 @@ public:
static double GetCurrentTime(); static double GetCurrentTime();
void* implData; void* implData;
void SetMicMute(bool mute); void SetMicMute(bool mute);
void SetEncryptionKey(char* key); void SetEncryptionKey(char* key, bool isOutgoing);
void SetConfig(voip_config_t* cfg); void SetConfig(voip_config_t* cfg);
float GetOutputLevel(); float GetOutputLevel();
void DebugCtl(int request, int param); void DebugCtl(int request, int param);
@ -188,7 +206,14 @@ public:
int64_t GetPreferredRelayID(); int64_t GetPreferredRelayID();
int GetLastError(); int GetLastError();
static voip_crypto_functions_t crypto; static voip_crypto_functions_t crypto;
static char* GetVersion(); static const char* GetVersion();
#ifdef TGVOIP_USE_AUDIO_SESSION
void SetAcquireAudioSession(void (^)(void (^)()));
void ReleaseAudioSession(void (^completion)());
#endif
std::string GetDebugLog();
void GetDebugLog(char* buffer);
size_t GetDebugLogLength();
private: private:
static void* StartRecvThread(void* arg); static void* StartRecvThread(void* arg);
@ -197,7 +222,7 @@ private:
void RunRecvThread(); void RunRecvThread();
void RunSendThread(); void RunSendThread();
void RunTickThread(); void RunTickThread();
void SendPacket(char* data, size_t len, voip_endpoint_t* ep); void SendPacket(unsigned char* data, size_t len, voip_endpoint_t* ep);
void HandleAudioInput(unsigned char* data, size_t len); void HandleAudioInput(unsigned char* data, size_t len);
void UpdateAudioBitrate(); void UpdateAudioBitrate();
void SetState(int state); void SetState(int state);
@ -206,14 +231,17 @@ private:
void SendInitAck(); void SendInitAck();
void UpdateDataSavingState(); void UpdateDataSavingState();
void SendP2pPing(int endpointType); void SendP2pPing(int endpointType);
void KDF(unsigned char* msgKey, unsigned char* aesKey, unsigned char* aesIv); void KDF(unsigned char* msgKey, size_t x, unsigned char* aesKey, unsigned char* aesIv);
void GetLocalNetworkItfInfo(in_addr *addr, char *outName); void GetLocalNetworkItfInfo(in_addr *addr, char *outName);
uint16_t GenerateLocalUDPPort();
CBufferOutputStream* GetOutgoingPacketBuffer(); CBufferOutputStream* GetOutgoingPacketBuffer();
uint32_t WritePacketHeader(CBufferOutputStream* s, unsigned char type, uint32_t length); uint32_t WritePacketHeader(CBufferOutputStream* s, unsigned char type, uint32_t length);
static size_t AudioInputCallback(unsigned char* data, size_t length, void* param); static size_t AudioInputCallback(unsigned char* data, size_t length, void* param);
void SendPublicEndpointsRequest(); void SendPublicEndpointsRequest();
voip_endpoint_t* GetEndpointByType(int type); voip_endpoint_t* GetEndpointByType(int type);
char * SendPacketReliably(unsigned char type, char* data, size_t len, double retryInterval, double timeout); void SendPacketReliably(unsigned char type, unsigned char* data, size_t len, double retryInterval, double timeout);
void LogDebugInfo();
sockaddr_in6 MakeInetAddress(in_addr addr, uint16_t port);
int state; int state;
int udpSocket; int udpSocket;
std::vector<voip_endpoint_t*> endpoints; std::vector<voip_endpoint_t*> endpoints;
@ -261,9 +289,9 @@ private:
void (*stateCallback)(CVoIPController*, int); void (*stateCallback)(CVoIPController*, int);
std::vector<voip_stream_t*> outgoingStreams; std::vector<voip_stream_t*> outgoingStreams;
std::vector<voip_stream_t*> incomingStreams; std::vector<voip_stream_t*> incomingStreams;
char encryptionKey[256]; unsigned char encryptionKey[256];
char keyFingerprint[8]; unsigned char keyFingerprint[8];
char callID[16]; unsigned char callID[16];
double stateChangeTime; double stateChangeTime;
bool needSendP2pPing; bool needSendP2pPing;
bool waitingForRelayPeerInfo; bool waitingForRelayPeerInfo;
@ -284,9 +312,38 @@ private:
int32_t peerVersion; int32_t peerVersion;
CCongestionControl* conctl; CCongestionControl* conctl;
voip_stats_t stats; voip_stats_t stats;
bool enableAEC; bool receivedInit;
bool receivedInitAck;
std::vector<std::string> debugLogs;
bool isOutgoing;
unsigned char nat64Prefix[12];
bool needUpdateNat64Prefix;
bool nat64Present;
/*** server config values ***/
uint32_t maxAudioBitrate;
uint32_t maxAudioBitrateEDGE;
uint32_t maxAudioBitrateGPRS;
uint32_t maxAudioBitrateSaving;
uint32_t initAudioBitrate;
uint32_t initAudioBitrateEDGE;
uint32_t initAudioBitrateGPRS;
uint32_t initAudioBitrateSaving;
uint32_t minAudioBitrate;
uint32_t audioBitrateStepIncr;
uint32_t audioBitrateStepDecr;
double relaySwitchThreshold;
double p2pToRelaySwitchThreshold;
double relayToP2pSwitchThreshold;
#ifdef TGVOIP_USE_AUDIO_SESSION
void (^acquireAudioSession)(void (^)());
bool needNotifyAcquiredAudioSession;
#endif
#ifdef __APPLE__ #ifdef __APPLE__
public:
static double machTimebase; static double machTimebase;
static uint64_t machTimestart; static uint64_t machTimestart;
#endif #endif

99
VoIPServerConfig.cpp Normal file
View File

@ -0,0 +1,99 @@
//
// 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 "VoIPServerConfig.h"
#include <stdlib.h>
#include "logging.h"
CVoIPServerConfig* CVoIPServerConfig::sharedInstance=NULL;
CVoIPServerConfig::CVoIPServerConfig(){
init_mutex(mutex);
}
CVoIPServerConfig::~CVoIPServerConfig(){
free_mutex(mutex);
}
CVoIPServerConfig *CVoIPServerConfig::GetSharedInstance(){
if(!sharedInstance)
sharedInstance=new CVoIPServerConfig();
return sharedInstance;
}
bool CVoIPServerConfig::GetBoolean(std::string name, bool fallback){
CMutexGuard sync(mutex);
if(ContainsKey(name)){
std::string val=config[name];
if(val=="true")
return true;
if(val=="false")
return false;
}
return fallback;
}
double CVoIPServerConfig::GetDouble(std::string name, double fallback){
CMutexGuard sync(mutex);
if(ContainsKey(name)){
std::string val=config[name];
char* end;
const char* start=val.c_str();
double d=strtod(start, &end);
if(end!=start){
return d;
}
}
return fallback;
}
int32_t CVoIPServerConfig::GetInt(std::string name, int32_t fallback){
CMutexGuard sync(mutex);
if(ContainsKey(name)){
std::string val=config[name];
char* end;
const char* start=val.c_str();
int32_t d=strtol(start, &end, 0);
if(end!=start){
return d;
}
}
return fallback;
}
std::string CVoIPServerConfig::GetString(std::string name, std::string fallback){
CMutexGuard sync(mutex);
if(ContainsKey(name))
return config[name];
return fallback;
}
void CVoIPServerConfig::Update(std::map<std::string, std::string> newValues){
CMutexGuard sync(mutex);
LOGD("=== Updating voip config ===");
config.clear();
for(std::map<std::string, std::string>::iterator itr=newValues.begin();itr!=newValues.end();++itr){
std::string key=itr->first;
std::string val=itr->second;
LOGV("%s -> %s", key.c_str(), val.c_str());
config[key]=val;
}
}
void CVoIPServerConfig::Update(const char **values, int count) {
std::map<std::string, std::string> result;
for (int i = 0; i < count / 2; i++) {
result[values[i * 2 + 0]] = std::string(values[i * 2 + 1]);
}
Update(result);
}
bool CVoIPServerConfig::ContainsKey(std::string key){
return config.find(key)!=config.end();
}

35
VoIPServerConfig.h Normal file
View File

@ -0,0 +1,35 @@
//
// 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_VOIPSERVERCONFIG_H
#define TGVOIP_VOIPSERVERCONFIG_H
#include <map>
#include <string>
#include "threading.h"
class CVoIPServerConfig{
public:
CVoIPServerConfig();
~CVoIPServerConfig();
static CVoIPServerConfig* GetSharedInstance();
int32_t GetInt(std::string name, int32_t fallback);
double GetDouble(std::string name, double fallback);
std::string GetString(std::string name, std::string fallback);
bool GetBoolean(std::string name, bool fallback);
void Update(std::map<std::string, std::string> newValues);
void Update(const char **values, int count);
private:
static CVoIPServerConfig* sharedInstance;
bool ContainsKey(std::string key);
std::map<std::string, std::string> config;
tgvoip_mutex_t mutex;
};
#endif //TGVOIP_VOIPSERVERCONFIG_H

View File

@ -14,6 +14,10 @@
#error "Unsupported operating system" #error "Unsupported operating system"
#endif #endif
CAudioInput::CAudioInput(){
failed=false;
}
CAudioInput *CAudioInput::Create(){ CAudioInput *CAudioInput::Create(){
#if defined(__ANDROID__) #if defined(__ANDROID__)
return new CAudioInputAndroid(); return new CAudioInputAndroid();
@ -29,3 +33,6 @@ CAudioInput::~CAudioInput(){
#endif #endif
} }
bool CAudioInput::IsInitialized(){
return !failed;
}

View File

@ -12,10 +12,15 @@
class CAudioInput : public CMediaStreamItf{ class CAudioInput : public CMediaStreamItf{
public: public:
CAudioInput();
virtual ~CAudioInput(); virtual ~CAudioInput();
virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels)=0; virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels)=0;
bool IsInitialized();
static CAudioInput* Create(); static CAudioInput* Create();
protected:
bool failed;
}; };

View File

@ -7,6 +7,9 @@
#include <jni.h> #include <jni.h>
#include <string.h> #include <string.h>
#include <wchar.h> #include <wchar.h>
#include <map>
#include <string>
#include <libtgvoip/VoIPServerConfig.h>
#include "../../VoIPController.h" #include "../../VoIPController.h"
#include "../../os/android/AudioOutputOpenSLES.h" #include "../../os/android/AudioOutputOpenSLES.h"
#include "../../os/android/AudioInputOpenSLES.h" #include "../../os/android/AudioInputOpenSLES.h"
@ -24,6 +27,8 @@ struct impl_data_android_t{
void updateConnectionState(CVoIPController* cntrlr, int state){ void updateConnectionState(CVoIPController* cntrlr, int state){
impl_data_android_t* impl=(impl_data_android_t*) cntrlr->implData; impl_data_android_t* impl=(impl_data_android_t*) cntrlr->implData;
if(!impl->javaObject)
return;
JNIEnv* env=NULL; JNIEnv* env=NULL;
bool didAttach=false; bool didAttach=false;
sharedJVM->GetEnv((void**) &env, JNI_VERSION_1_6); sharedJVM->GetEnv((void**) &env, JNI_VERSION_1_6);
@ -44,11 +49,12 @@ extern "C" JNIEXPORT jlong Java_org_telegram_messenger_voip_VoIPController_nativ
CAudioOutputAndroid::systemVersion=systemVersion; CAudioOutputAndroid::systemVersion=systemVersion;
env->GetJavaVM(&sharedJVM); env->GetJavaVM(&sharedJVM);
if(!CAudioInputAndroid::jniClass){
jclass cls=env->FindClass("org/telegram/messenger/voip/AudioRecordJNI"); jclass cls=env->FindClass("org/telegram/messenger/voip/AudioRecordJNI");
CAudioInputAndroid::jniClass=(jclass) env->NewGlobalRef(cls); CAudioInputAndroid::jniClass=(jclass) env->NewGlobalRef(cls);
CAudioInputAndroid::initMethod=env->GetMethodID(cls, "init", "(IIII)V"); CAudioInputAndroid::initMethod=env->GetMethodID(cls, "init", "(IIII)V");
CAudioInputAndroid::releaseMethod=env->GetMethodID(cls, "release", "()V"); CAudioInputAndroid::releaseMethod=env->GetMethodID(cls, "release", "()V");
CAudioInputAndroid::startMethod=env->GetMethodID(cls, "start", "()V"); CAudioInputAndroid::startMethod=env->GetMethodID(cls, "start", "()Z");
CAudioInputAndroid::stopMethod=env->GetMethodID(cls, "stop", "()V"); CAudioInputAndroid::stopMethod=env->GetMethodID(cls, "stop", "()V");
cls=env->FindClass("org/telegram/messenger/voip/AudioTrackJNI"); cls=env->FindClass("org/telegram/messenger/voip/AudioTrackJNI");
@ -57,6 +63,7 @@ extern "C" JNIEXPORT jlong Java_org_telegram_messenger_voip_VoIPController_nativ
CAudioOutputAndroid::releaseMethod=env->GetMethodID(cls, "release", "()V"); CAudioOutputAndroid::releaseMethod=env->GetMethodID(cls, "release", "()V");
CAudioOutputAndroid::startMethod=env->GetMethodID(cls, "start", "()V"); CAudioOutputAndroid::startMethod=env->GetMethodID(cls, "start", "()V");
CAudioOutputAndroid::stopMethod=env->GetMethodID(cls, "stop", "()V"); CAudioOutputAndroid::stopMethod=env->GetMethodID(cls, "stop", "()V");
}
setStateMethod=env->GetMethodID(env->GetObjectClass(thiz), "handleStateChange", "(I)V"); setStateMethod=env->GetMethodID(env->GetObjectClass(thiz), "handleStateChange", "(I)V");
@ -76,9 +83,9 @@ extern "C" JNIEXPORT void Java_org_telegram_messenger_voip_VoIPController_native
((CVoIPController*)(intptr_t)inst)->Connect(); ((CVoIPController*)(intptr_t)inst)->Connect();
} }
extern "C" JNIEXPORT void Java_org_telegram_messenger_voip_VoIPController_nativeSetEncryptionKey(JNIEnv* env, jobject thiz, jlong inst, jbyteArray key){ extern "C" JNIEXPORT void Java_org_telegram_messenger_voip_VoIPController_nativeSetEncryptionKey(JNIEnv* env, jobject thiz, jlong inst, jbyteArray key, jboolean isOutgoing){
jbyte* akey=env->GetByteArrayElements(key, NULL); jbyte* akey=env->GetByteArrayElements(key, NULL);
((CVoIPController*)(intptr_t)inst)->SetEncryptionKey((char *) akey); ((CVoIPController*)(intptr_t)inst)->SetEncryptionKey((char *) akey, isOutgoing);
env->ReleaseByteArrayElements(key, akey, JNI_ABORT); env->ReleaseByteArrayElements(key, akey, JNI_ABORT);
} }
@ -130,12 +137,14 @@ extern "C" JNIEXPORT void Java_org_telegram_messenger_voip_VoIPController_native
} }
extern "C" JNIEXPORT void Java_org_telegram_messenger_voip_VoIPController_nativeRelease(JNIEnv* env, jobject thiz, jlong inst){ extern "C" JNIEXPORT void Java_org_telegram_messenger_voip_VoIPController_nativeRelease(JNIEnv* env, jobject thiz, jlong inst){
env->DeleteGlobalRef(CAudioInputAndroid::jniClass); //env->DeleteGlobalRef(CAudioInputAndroid::jniClass);
CVoIPController* ctlr=((CVoIPController*)(intptr_t)inst); CVoIPController* ctlr=((CVoIPController*)(intptr_t)inst);
env->DeleteGlobalRef(((impl_data_android_t*)ctlr->implData)->javaObject); impl_data_android_t* impl=(impl_data_android_t*)ctlr->implData;
free(ctlr->implData);
delete ctlr; delete ctlr;
env->DeleteGlobalRef(impl->javaObject);
((impl_data_android_t*)ctlr->implData)->javaObject=NULL;
free(impl);
} }
@ -171,13 +180,22 @@ extern "C" JNIEXPORT void Java_org_telegram_messenger_voip_VoIPController_native
((CVoIPController*)(intptr_t)inst)->SetMicMute(mute); ((CVoIPController*)(intptr_t)inst)->SetMicMute(mute);
} }
extern "C" JNIEXPORT void Java_org_telegram_messenger_voip_VoIPController_nativeSetConfig(JNIEnv* env, jobject thiz, jlong inst, jdouble recvTimeout, jdouble initTimeout, jint dataSavingMode, jint frameSize, jboolean enableAEC){ extern "C" JNIEXPORT void Java_org_telegram_messenger_voip_VoIPController_nativeSetConfig(JNIEnv* env, jobject thiz, jlong inst, jdouble recvTimeout, jdouble initTimeout, jint dataSavingMode, jboolean enableAEC, jboolean enableNS, jboolean enableAGC, jstring logFilePath){
voip_config_t cfg; voip_config_t cfg;
cfg.init_timeout=initTimeout; cfg.init_timeout=initTimeout;
cfg.recv_timeout=recvTimeout; cfg.recv_timeout=recvTimeout;
cfg.data_saving=dataSavingMode; cfg.data_saving=dataSavingMode;
cfg.frame_size=frameSize;
cfg.enableAEC=enableAEC; cfg.enableAEC=enableAEC;
cfg.enableNS=enableNS;
cfg.enableAGC=enableAGC;
if(logFilePath){
char* path=(char *) env->GetStringUTFChars(logFilePath, NULL);
strncpy(cfg.logFilePath, path, sizeof(cfg.logFilePath));
cfg.logFilePath[sizeof(cfg.logFilePath)-1]=0;
env->ReleaseStringUTFChars(logFilePath, path);
}else{
memset(cfg.logFilePath, 0, sizeof(cfg.logFilePath));
}
((CVoIPController*)(intptr_t)inst)->SetConfig(&cfg); ((CVoIPController*)(intptr_t)inst)->SetConfig(&cfg);
} }
@ -206,3 +224,29 @@ extern "C" JNIEXPORT void Java_org_telegram_messenger_voip_VoIPController_native
env->SetLongField(stats, env->GetFieldID(cls, "bytesRecvdWifi", "J"), _stats.bytesRecvdWifi); env->SetLongField(stats, env->GetFieldID(cls, "bytesRecvdWifi", "J"), _stats.bytesRecvdWifi);
env->SetLongField(stats, env->GetFieldID(cls, "bytesRecvdMobile", "J"), _stats.bytesRecvdMobile); env->SetLongField(stats, env->GetFieldID(cls, "bytesRecvdMobile", "J"), _stats.bytesRecvdMobile);
} }
extern "C" JNIEXPORT void Java_org_telegram_messenger_voip_VoIPServerConfig_nativeSetConfig(JNIEnv* env, jclass clasz, jobjectArray keys, jobjectArray values){
std::map<std::string, std::string> config;
int len=env->GetArrayLength(keys);
int i;
for(i=0;i<len;i++){
jstring jkey=(jstring)env->GetObjectArrayElement(keys, i);
jstring jval=(jstring)env->GetObjectArrayElement(values, i);
if(jkey==NULL|| jval==NULL)
continue;
const char* ckey=env->GetStringUTFChars(jkey, NULL);
const char* cval=env->GetStringUTFChars(jval, NULL);
std::string key(ckey);
std::string val(cval);
env->ReleaseStringUTFChars(jkey, ckey);
env->ReleaseStringUTFChars(jval, cval);
config[key]=val;
}
CVoIPServerConfig::GetSharedInstance()->Update(config);
}
extern "C" JNIEXPORT jstring Java_org_telegram_messenger_voip_VoIPController_nativeGetDebugLog(JNIEnv* env, jobject thiz, jlong inst){
CVoIPController* ctlr=((CVoIPController*)(intptr_t)inst);
std::string log=ctlr->GetDebugLog();
return env->NewStringUTF(log.c_str());
}

247
external/include/webrtc/gain_control.h vendored Normal file
View File

@ -0,0 +1,247 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AGC_LEGACY_GAIN_CONTROL_H_
#define WEBRTC_MODULES_AUDIO_PROCESSING_AGC_LEGACY_GAIN_CONTROL_H_
//#include "webrtc/typedefs.h"
// Errors
#define AGC_UNSPECIFIED_ERROR 18000
#define AGC_UNSUPPORTED_FUNCTION_ERROR 18001
#define AGC_UNINITIALIZED_ERROR 18002
#define AGC_NULL_POINTER_ERROR 18003
#define AGC_BAD_PARAMETER_ERROR 18004
// Warnings
#define AGC_BAD_PARAMETER_WARNING 18050
enum {
kAgcModeUnchanged,
kAgcModeAdaptiveAnalog,
kAgcModeAdaptiveDigital,
kAgcModeFixedDigital
};
enum { kAgcFalse = 0, kAgcTrue };
typedef struct {
int16_t targetLevelDbfs; // default 3 (-3 dBOv)
int16_t compressionGaindB; // default 9 dB
uint8_t limiterEnable; // default kAgcTrue (on)
} WebRtcAgcConfig;
#if defined(__cplusplus)
extern "C" {
#endif
/*
* This function analyses the number of samples passed to
* farend and produces any error code that could arise.
*
* Input:
* - agcInst : AGC instance.
* - samples : Number of samples in input vector.
*
* Return value:
* : 0 - Normal operation.
* : -1 - Error.
*/
int WebRtcAgc_GetAddFarendError(void* state, size_t samples);
/*
* This function processes a 10 ms frame of far-end speech to determine
* if there is active speech. The length of the input speech vector must be
* given in samples (80 when FS=8000, and 160 when FS=16000, FS=32000 or
* FS=48000).
*
* Input:
* - agcInst : AGC instance.
* - inFar : Far-end input speech vector
* - samples : Number of samples in input vector
*
* Return value:
* : 0 - Normal operation.
* : -1 - Error
*/
int WebRtcAgc_AddFarend(void* agcInst, const int16_t* inFar, size_t samples);
/*
* This function processes a 10 ms frame of microphone speech to determine
* if there is active speech. The length of the input speech vector must be
* given in samples (80 when FS=8000, and 160 when FS=16000, FS=32000 or
* FS=48000). For very low input levels, the input signal is increased in level
* by multiplying and overwriting the samples in inMic[].
*
* This function should be called before any further processing of the
* near-end microphone signal.
*
* Input:
* - agcInst : AGC instance.
* - inMic : Microphone input speech vector for each band
* - num_bands : Number of bands in input vector
* - samples : Number of samples in input vector
*
* Return value:
* : 0 - Normal operation.
* : -1 - Error
*/
int WebRtcAgc_AddMic(void* agcInst,
int16_t* const* inMic,
size_t num_bands,
size_t samples);
/*
* This function replaces the analog microphone with a virtual one.
* It is a digital gain applied to the input signal and is used in the
* agcAdaptiveDigital mode where no microphone level is adjustable. The length
* of the input speech vector must be given in samples (80 when FS=8000, and 160
* when FS=16000, FS=32000 or FS=48000).
*
* Input:
* - agcInst : AGC instance.
* - inMic : Microphone input speech vector for each band
* - num_bands : Number of bands in input vector
* - samples : Number of samples in input vector
* - micLevelIn : Input level of microphone (static)
*
* Output:
* - inMic : Microphone output after processing (L band)
* - inMic_H : Microphone output after processing (H band)
* - micLevelOut : Adjusted microphone level after processing
*
* Return value:
* : 0 - Normal operation.
* : -1 - Error
*/
int WebRtcAgc_VirtualMic(void* agcInst,
int16_t* const* inMic,
size_t num_bands,
size_t samples,
int32_t micLevelIn,
int32_t* micLevelOut);
/*
* This function processes a 10 ms frame and adjusts (normalizes) the gain both
* analog and digitally. The gain adjustments are done only during active
* periods of speech. The length of the speech vectors must be given in samples
* (80 when FS=8000, and 160 when FS=16000, FS=32000 or FS=48000). The echo
* parameter can be used to ensure the AGC will not adjust upward in the
* presence of echo.
*
* This function should be called after processing the near-end microphone
* signal, in any case after any echo cancellation.
*
* Input:
* - agcInst : AGC instance
* - inNear : Near-end input speech vector for each band
* - num_bands : Number of bands in input/output vector
* - samples : Number of samples in input/output vector
* - inMicLevel : Current microphone volume level
* - echo : Set to 0 if the signal passed to add_mic is
* almost certainly free of echo; otherwise set
* to 1. If you have no information regarding echo
* set to 0.
*
* Output:
* - outMicLevel : Adjusted microphone volume level
* - out : Gain-adjusted near-end speech vector
* : May be the same vector as the input.
* - saturationWarning : A returned value of 1 indicates a saturation event
* has occurred and the volume cannot be further
* reduced. Otherwise will be set to 0.
*
* Return value:
* : 0 - Normal operation.
* : -1 - Error
*/
int WebRtcAgc_Process(void* agcInst,
const int16_t* const* inNear,
size_t num_bands,
size_t samples,
int16_t* const* out,
int32_t inMicLevel,
int32_t* outMicLevel,
int16_t echo,
uint8_t* saturationWarning);
/*
* This function sets the config parameters (targetLevelDbfs,
* compressionGaindB and limiterEnable).
*
* Input:
* - agcInst : AGC instance
* - config : config struct
*
* Output:
*
* Return value:
* : 0 - Normal operation.
* : -1 - Error
*/
int WebRtcAgc_set_config(void* agcInst, WebRtcAgcConfig config);
/*
* This function returns the config parameters (targetLevelDbfs,
* compressionGaindB and limiterEnable).
*
* Input:
* - agcInst : AGC instance
*
* Output:
* - config : config struct
*
* Return value:
* : 0 - Normal operation.
* : -1 - Error
*/
int WebRtcAgc_get_config(void* agcInst, WebRtcAgcConfig* config);
/*
* This function creates and returns an AGC instance, which will contain the
* state information for one (duplex) channel.
*/
void* WebRtcAgc_Create();
/*
* This function frees the AGC instance created at the beginning.
*
* Input:
* - agcInst : AGC instance.
*/
void WebRtcAgc_Free(void* agcInst);
/*
* This function initializes an AGC instance.
*
* Input:
* - agcInst : AGC instance.
* - minLevel : Minimum possible mic level
* - maxLevel : Maximum possible mic level
* - agcMode : 0 - Unchanged
* : 1 - Adaptive Analog Automatic Gain Control -3dBOv
* : 2 - Adaptive Digital Automatic Gain Control -3dBOv
* : 3 - Fixed Digital Gain 0dB
* - fs : Sampling frequency
*
* Return value : 0 - Ok
* -1 - Error
*/
int WebRtcAgc_Init(void* agcInst,
int32_t minLevel,
int32_t maxLevel,
int16_t agcMode,
uint32_t fs);
#if defined(__cplusplus)
}
#endif
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AGC_LEGACY_GAIN_CONTROL_H_

View File

@ -1,20 +1,22 @@
#ifndef __WEBRTC_SPLITTING_FILTER_WRAPPER #ifndef __WEBRTC_SPLITTING_FILTER_WRAPPER
#define __WEBRTC_SPLITTING_FILTER_WRAPPER #define __WEBRTC_SPLITTING_FILTER_WRAPPER
struct splitting_filter_t{ #include <stdint.h>
struct tgvoip_splitting_filter_t{
/*IFCHannelBuffer*/ void* _bufferIn; /*IFCHannelBuffer*/ void* _bufferIn;
/*IFCHannelBuffer*/ void* _bufferOut; /*IFCHannelBuffer*/ void* _bufferOut;
/*SplittingFilter*/ void* _splittingFilter; /*SplittingFilter*/ void* _splittingFilter;
float* bufferIn; int16_t bufferIn[960];
float* bufferOut[3]; int16_t bufferOut[3][320];
}; };
extern "C"{ extern "C"{
splitting_filter_t* tgvoip_splitting_filter_create(); tgvoip_splitting_filter_t* tgvoip_splitting_filter_create();
void tgvoip_splitting_filter_free(splitting_filter_t* filter); void tgvoip_splitting_filter_free(tgvoip_splitting_filter_t* filter);
void tgvoip_splitting_filter_analyze(splitting_filter_t* filter); void tgvoip_splitting_filter_analyze(tgvoip_splitting_filter_t* filter);
void tgvoip_splitting_filter_synthesize(splitting_filter_t* filter); void tgvoip_splitting_filter_synthesize(tgvoip_splitting_filter_t* filter);
} }
#endif // __WEBRTC_SPLITTING_FILTER_WRAPPER #endif // __WEBRTC_SPLITTING_FILTER_WRAPPER

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,865 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
6915307B1E6B5BAB004F643F /* logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6915307A1E6B5BAB004F643F /* logging.cpp */; };
692AB8CB1E6759DD00706ACC /* AudioInput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 692AB8881E6759DD00706ACC /* AudioInput.cpp */; };
692AB8CC1E6759DD00706ACC /* AudioInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8891E6759DD00706ACC /* AudioInput.h */; };
692AB8CD1E6759DD00706ACC /* AudioOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 692AB88A1E6759DD00706ACC /* AudioOutput.cpp */; };
692AB8CE1E6759DD00706ACC /* AudioOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB88B1E6759DD00706ACC /* AudioOutput.h */; };
692AB8CF1E6759DD00706ACC /* BlockingQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 692AB88C1E6759DD00706ACC /* BlockingQueue.cpp */; };
692AB8D01E6759DD00706ACC /* BlockingQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB88D1E6759DD00706ACC /* BlockingQueue.h */; };
692AB8D11E6759DD00706ACC /* BufferInputStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 692AB88E1E6759DD00706ACC /* BufferInputStream.cpp */; };
692AB8D21E6759DD00706ACC /* BufferInputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB88F1E6759DD00706ACC /* BufferInputStream.h */; };
692AB8D31E6759DD00706ACC /* BufferOutputStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 692AB8901E6759DD00706ACC /* BufferOutputStream.cpp */; };
692AB8D41E6759DD00706ACC /* BufferOutputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8911E6759DD00706ACC /* BufferOutputStream.h */; };
692AB8D51E6759DD00706ACC /* BufferPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 692AB8921E6759DD00706ACC /* BufferPool.cpp */; };
692AB8D61E6759DD00706ACC /* BufferPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8931E6759DD00706ACC /* BufferPool.h */; };
692AB8D81E6759DD00706ACC /* CongestionControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 692AB8971E6759DD00706ACC /* CongestionControl.cpp */; };
692AB8D91E6759DD00706ACC /* CongestionControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8981E6759DD00706ACC /* CongestionControl.h */; };
692AB8DA1E6759DD00706ACC /* EchoCanceller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 692AB8991E6759DD00706ACC /* EchoCanceller.cpp */; };
692AB8DB1E6759DD00706ACC /* EchoCanceller.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB89A1E6759DD00706ACC /* EchoCanceller.h */; };
692AB8DC1E6759DD00706ACC /* echo_cancellation.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB89E1E6759DD00706ACC /* echo_cancellation.h */; };
692AB8DD1E6759DD00706ACC /* echo_control_mobile.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB89F1E6759DD00706ACC /* echo_control_mobile.h */; };
692AB8DE1E6759DD00706ACC /* gain_control.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8A01E6759DD00706ACC /* gain_control.h */; };
692AB8DF1E6759DD00706ACC /* noise_suppression.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8A11E6759DD00706ACC /* noise_suppression.h */; };
692AB8E01E6759DD00706ACC /* noise_suppression_x.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8A21E6759DD00706ACC /* noise_suppression_x.h */; };
692AB8E11E6759DD00706ACC /* splitting_filter_wrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8A31E6759DD00706ACC /* splitting_filter_wrapper.h */; };
692AB8E41E6759DD00706ACC /* libWebRtcAec_darwin.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 692AB8A61E6759DD00706ACC /* libWebRtcAec_darwin.a */; };
692AB8E51E6759DD00706ACC /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 692AB8A71E6759DD00706ACC /* Info.plist */; };
692AB8E61E6759DD00706ACC /* JitterBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 692AB8A81E6759DD00706ACC /* JitterBuffer.cpp */; };
692AB8E71E6759DD00706ACC /* JitterBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8A91E6759DD00706ACC /* JitterBuffer.h */; };
692AB8E81E6759DD00706ACC /* logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8AA1E6759DD00706ACC /* logging.h */; };
692AB8E91E6759DD00706ACC /* MediaStreamItf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 692AB8AB1E6759DD00706ACC /* MediaStreamItf.cpp */; };
692AB8EA1E6759DD00706ACC /* MediaStreamItf.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8AC1E6759DD00706ACC /* MediaStreamItf.h */; };
692AB8EB1E6759DD00706ACC /* OpusDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 692AB8AD1E6759DD00706ACC /* OpusDecoder.cpp */; };
692AB8EC1E6759DD00706ACC /* OpusDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8AE1E6759DD00706ACC /* OpusDecoder.h */; };
692AB8ED1E6759DD00706ACC /* OpusEncoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 692AB8AF1E6759DD00706ACC /* OpusEncoder.cpp */; };
692AB8EE1E6759DD00706ACC /* OpusEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8B01E6759DD00706ACC /* OpusEncoder.h */; };
692AB8F91E6759DD00706ACC /* AudioInputAudioUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 692AB8BE1E6759DD00706ACC /* AudioInputAudioUnit.cpp */; };
692AB8FA1E6759DD00706ACC /* AudioInputAudioUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8BF1E6759DD00706ACC /* AudioInputAudioUnit.h */; };
692AB8FB1E6759DD00706ACC /* AudioOutputAudioUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 692AB8C01E6759DD00706ACC /* AudioOutputAudioUnit.cpp */; };
692AB8FC1E6759DD00706ACC /* AudioOutputAudioUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8C11E6759DD00706ACC /* AudioOutputAudioUnit.h */; };
692AB8FD1E6759DD00706ACC /* AudioUnitIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 692AB8C21E6759DD00706ACC /* AudioUnitIO.cpp */; };
692AB8FE1E6759DD00706ACC /* AudioUnitIO.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8C31E6759DD00706ACC /* AudioUnitIO.h */; };
692AB8FF1E6759DD00706ACC /* TGLogWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8C41E6759DD00706ACC /* TGLogWrapper.h */; };
692AB9001E6759DD00706ACC /* TGLogWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 692AB8C51E6759DD00706ACC /* TGLogWrapper.m */; };
692AB9011E6759DD00706ACC /* threading.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8C61E6759DD00706ACC /* threading.h */; };
692AB9021E6759DD00706ACC /* VoIPController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 692AB8C71E6759DD00706ACC /* VoIPController.cpp */; };
692AB9031E6759DD00706ACC /* VoIPController.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8C81E6759DD00706ACC /* VoIPController.h */; };
692AB9041E6759DD00706ACC /* VoIPServerConfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 692AB8C91E6759DD00706ACC /* VoIPServerConfig.cpp */; };
692AB9051E6759DD00706ACC /* VoIPServerConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 692AB8CA1E6759DD00706ACC /* VoIPServerConfig.h */; };
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 */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
692AB9101E675E8800706ACC /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 692AB9071E675E8800706ACC /* Telegraph.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = D08805AC156E8F3600311537;
remoteInfo = Telegraph;
};
692AB9121E675E8800706ACC /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 692AB9071E675E8800706ACC /* Telegraph.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = D02601D71A55CA2300716290;
remoteInfo = Share;
};
692AB9141E675E8800706ACC /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 692AB9071E675E8800706ACC /* Telegraph.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 68744C0D1BB1A9F700FE6542;
remoteInfo = watchkitapp;
};
692AB9161E675E8800706ACC /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 692AB9071E675E8800706ACC /* Telegraph.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 68744C191BB1A9F700FE6542;
remoteInfo = "watchkitapp Extension";
};
692AB9181E675E8800706ACC /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 692AB9071E675E8800706ACC /* Telegraph.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = D020FADD1D99466A00F279AA;
remoteInfo = SiriIntents;
};
692AB91A1E675E8800706ACC /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 692AB9071E675E8800706ACC /* Telegraph.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = D020FB0A1D99637100F279AA;
remoteInfo = LegacyDatabase;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
6915307A1E6B5BAB004F643F /* logging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = logging.cpp; sourceTree = "<group>"; };
692AB8881E6759DD00706ACC /* AudioInput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioInput.cpp; sourceTree = "<group>"; };
692AB8891E6759DD00706ACC /* AudioInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioInput.h; sourceTree = "<group>"; };
692AB88A1E6759DD00706ACC /* AudioOutput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioOutput.cpp; sourceTree = "<group>"; };
692AB88B1E6759DD00706ACC /* AudioOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioOutput.h; sourceTree = "<group>"; };
692AB88C1E6759DD00706ACC /* BlockingQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BlockingQueue.cpp; sourceTree = "<group>"; };
692AB88D1E6759DD00706ACC /* BlockingQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockingQueue.h; sourceTree = "<group>"; };
692AB88E1E6759DD00706ACC /* BufferInputStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BufferInputStream.cpp; sourceTree = "<group>"; };
692AB88F1E6759DD00706ACC /* BufferInputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BufferInputStream.h; sourceTree = "<group>"; };
692AB8901E6759DD00706ACC /* BufferOutputStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BufferOutputStream.cpp; sourceTree = "<group>"; };
692AB8911E6759DD00706ACC /* BufferOutputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BufferOutputStream.h; sourceTree = "<group>"; };
692AB8921E6759DD00706ACC /* BufferPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BufferPool.cpp; sourceTree = "<group>"; };
692AB8931E6759DD00706ACC /* BufferPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BufferPool.h; sourceTree = "<group>"; };
692AB8971E6759DD00706ACC /* CongestionControl.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = CongestionControl.cpp; sourceTree = "<group>"; };
692AB8981E6759DD00706ACC /* CongestionControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CongestionControl.h; sourceTree = "<group>"; };
692AB8991E6759DD00706ACC /* EchoCanceller.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EchoCanceller.cpp; sourceTree = "<group>"; };
692AB89A1E6759DD00706ACC /* EchoCanceller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EchoCanceller.h; sourceTree = "<group>"; };
692AB89E1E6759DD00706ACC /* echo_cancellation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = echo_cancellation.h; sourceTree = "<group>"; };
692AB89F1E6759DD00706ACC /* echo_control_mobile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = echo_control_mobile.h; sourceTree = "<group>"; };
692AB8A01E6759DD00706ACC /* gain_control.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gain_control.h; sourceTree = "<group>"; };
692AB8A11E6759DD00706ACC /* noise_suppression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = noise_suppression.h; sourceTree = "<group>"; };
692AB8A21E6759DD00706ACC /* noise_suppression_x.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = noise_suppression_x.h; sourceTree = "<group>"; };
692AB8A31E6759DD00706ACC /* splitting_filter_wrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = splitting_filter_wrapper.h; sourceTree = "<group>"; };
692AB8A61E6759DD00706ACC /* libWebRtcAec_darwin.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libWebRtcAec_darwin.a; sourceTree = "<group>"; };
692AB8A71E6759DD00706ACC /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
692AB8A81E6759DD00706ACC /* JitterBuffer.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = JitterBuffer.cpp; sourceTree = "<group>"; };
692AB8A91E6759DD00706ACC /* JitterBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JitterBuffer.h; sourceTree = "<group>"; };
692AB8AA1E6759DD00706ACC /* logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = logging.h; sourceTree = "<group>"; };
692AB8AB1E6759DD00706ACC /* MediaStreamItf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaStreamItf.cpp; sourceTree = "<group>"; };
692AB8AC1E6759DD00706ACC /* MediaStreamItf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamItf.h; sourceTree = "<group>"; };
692AB8AD1E6759DD00706ACC /* OpusDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpusDecoder.cpp; sourceTree = "<group>"; };
692AB8AE1E6759DD00706ACC /* OpusDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpusDecoder.h; sourceTree = "<group>"; };
692AB8AF1E6759DD00706ACC /* OpusEncoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpusEncoder.cpp; sourceTree = "<group>"; };
692AB8B01E6759DD00706ACC /* OpusEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpusEncoder.h; sourceTree = "<group>"; };
692AB8BE1E6759DD00706ACC /* AudioInputAudioUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioInputAudioUnit.cpp; sourceTree = "<group>"; };
692AB8BF1E6759DD00706ACC /* AudioInputAudioUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioInputAudioUnit.h; sourceTree = "<group>"; };
692AB8C01E6759DD00706ACC /* AudioOutputAudioUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioOutputAudioUnit.cpp; sourceTree = "<group>"; };
692AB8C11E6759DD00706ACC /* AudioOutputAudioUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioOutputAudioUnit.h; sourceTree = "<group>"; };
692AB8C21E6759DD00706ACC /* AudioUnitIO.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = AudioUnitIO.cpp; sourceTree = "<group>"; };
692AB8C31E6759DD00706ACC /* AudioUnitIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioUnitIO.h; sourceTree = "<group>"; };
692AB8C41E6759DD00706ACC /* TGLogWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGLogWrapper.h; sourceTree = "<group>"; };
692AB8C51E6759DD00706ACC /* TGLogWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGLogWrapper.m; sourceTree = "<group>"; };
692AB8C61E6759DD00706ACC /* threading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = threading.h; sourceTree = "<group>"; };
692AB8C71E6759DD00706ACC /* VoIPController.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = VoIPController.cpp; sourceTree = "<group>"; };
692AB8C81E6759DD00706ACC /* VoIPController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VoIPController.h; sourceTree = "<group>"; };
692AB8C91E6759DD00706ACC /* VoIPServerConfig.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VoIPServerConfig.cpp; sourceTree = "<group>"; };
692AB8CA1E6759DD00706ACC /* VoIPServerConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VoIPServerConfig.h; sourceTree = "<group>"; };
692AB9071E675E8800706ACC /* Telegraph.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Telegraph.xcodeproj; path = ../../Telegraph.xcodeproj; sourceTree = "<group>"; };
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; };
69F842361E67540700C110F7 /* libtgvoip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = libtgvoip.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
69F842321E67540700C110F7 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
692AB91F1E675F7000706ACC /* AudioToolbox.framework in Frameworks */,
692AB9201E675F7000706ACC /* AudioUnit.framework in Frameworks */,
692AB9211E675F7000706ACC /* CoreAudio.framework in Frameworks */,
692AB8E41E6759DD00706ACC /* libWebRtcAec_darwin.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
692AB8861E6759BF00706ACC /* libtgvoip */ = {
isa = PBXGroup;
children = (
692AB8871E6759DD00706ACC /* audio */,
692AB88C1E6759DD00706ACC /* BlockingQueue.cpp */,
692AB88D1E6759DD00706ACC /* BlockingQueue.h */,
692AB88E1E6759DD00706ACC /* BufferInputStream.cpp */,
692AB88F1E6759DD00706ACC /* BufferInputStream.h */,
692AB8901E6759DD00706ACC /* BufferOutputStream.cpp */,
692AB8911E6759DD00706ACC /* BufferOutputStream.h */,
692AB8921E6759DD00706ACC /* BufferPool.cpp */,
692AB8931E6759DD00706ACC /* BufferPool.h */,
692AB8971E6759DD00706ACC /* CongestionControl.cpp */,
692AB8981E6759DD00706ACC /* CongestionControl.h */,
692AB8991E6759DD00706ACC /* EchoCanceller.cpp */,
692AB89A1E6759DD00706ACC /* EchoCanceller.h */,
692AB89B1E6759DD00706ACC /* external */,
692AB8A71E6759DD00706ACC /* Info.plist */,
692AB8A81E6759DD00706ACC /* JitterBuffer.cpp */,
692AB8A91E6759DD00706ACC /* JitterBuffer.h */,
6915307A1E6B5BAB004F643F /* logging.cpp */,
692AB8AA1E6759DD00706ACC /* logging.h */,
692AB8AB1E6759DD00706ACC /* MediaStreamItf.cpp */,
692AB8AC1E6759DD00706ACC /* MediaStreamItf.h */,
692AB8AD1E6759DD00706ACC /* OpusDecoder.cpp */,
692AB8AE1E6759DD00706ACC /* OpusDecoder.h */,
692AB8AF1E6759DD00706ACC /* OpusEncoder.cpp */,
692AB8B01E6759DD00706ACC /* OpusEncoder.h */,
692AB8B11E6759DD00706ACC /* os */,
692AB8C61E6759DD00706ACC /* threading.h */,
692AB8C71E6759DD00706ACC /* VoIPController.cpp */,
692AB8C81E6759DD00706ACC /* VoIPController.h */,
692AB8C91E6759DD00706ACC /* VoIPServerConfig.cpp */,
692AB8CA1E6759DD00706ACC /* VoIPServerConfig.h */,
);
name = libtgvoip;
sourceTree = "<group>";
};
692AB8871E6759DD00706ACC /* audio */ = {
isa = PBXGroup;
children = (
692AB8881E6759DD00706ACC /* AudioInput.cpp */,
692AB8891E6759DD00706ACC /* AudioInput.h */,
692AB88A1E6759DD00706ACC /* AudioOutput.cpp */,
692AB88B1E6759DD00706ACC /* AudioOutput.h */,
);
path = audio;
sourceTree = "<group>";
};
692AB89B1E6759DD00706ACC /* external */ = {
isa = PBXGroup;
children = (
692AB89C1E6759DD00706ACC /* include */,
692AB8A61E6759DD00706ACC /* libWebRtcAec_darwin.a */,
);
path = external;
sourceTree = "<group>";
};
692AB89C1E6759DD00706ACC /* include */ = {
isa = PBXGroup;
children = (
692AB89D1E6759DD00706ACC /* webrtc */,
);
path = include;
sourceTree = "<group>";
};
692AB89D1E6759DD00706ACC /* webrtc */ = {
isa = PBXGroup;
children = (
692AB89E1E6759DD00706ACC /* echo_cancellation.h */,
692AB89F1E6759DD00706ACC /* echo_control_mobile.h */,
692AB8A01E6759DD00706ACC /* gain_control.h */,
692AB8A11E6759DD00706ACC /* noise_suppression.h */,
692AB8A21E6759DD00706ACC /* noise_suppression_x.h */,
692AB8A31E6759DD00706ACC /* splitting_filter_wrapper.h */,
);
path = webrtc;
sourceTree = "<group>";
};
692AB8B11E6759DD00706ACC /* os */ = {
isa = PBXGroup;
children = (
692AB8BD1E6759DD00706ACC /* darwin */,
);
path = os;
sourceTree = "<group>";
};
692AB8BD1E6759DD00706ACC /* darwin */ = {
isa = PBXGroup;
children = (
692AB8BE1E6759DD00706ACC /* AudioInputAudioUnit.cpp */,
692AB8BF1E6759DD00706ACC /* AudioInputAudioUnit.h */,
692AB8C01E6759DD00706ACC /* AudioOutputAudioUnit.cpp */,
692AB8C11E6759DD00706ACC /* AudioOutputAudioUnit.h */,
692AB8C21E6759DD00706ACC /* AudioUnitIO.cpp */,
692AB8C31E6759DD00706ACC /* AudioUnitIO.h */,
692AB8C41E6759DD00706ACC /* TGLogWrapper.h */,
692AB8C51E6759DD00706ACC /* TGLogWrapper.m */,
);
path = darwin;
sourceTree = "<group>";
};
692AB9061E675E8700706ACC /* Frameworks */ = {
isa = PBXGroup;
children = (
692AB91C1E675F7000706ACC /* AudioToolbox.framework */,
692AB91D1E675F7000706ACC /* AudioUnit.framework */,
692AB91E1E675F7000706ACC /* CoreAudio.framework */,
692AB9071E675E8800706ACC /* Telegraph.xcodeproj */,
);
name = Frameworks;
sourceTree = "<group>";
};
692AB9081E675E8800706ACC /* Products */ = {
isa = PBXGroup;
children = (
692AB9111E675E8800706ACC /* Telegram.app */,
692AB9131E675E8800706ACC /* Share.appex */,
692AB9151E675E8800706ACC /* watchkitapp.app */,
692AB9171E675E8800706ACC /* watchkitapp Extension.appex */,
692AB9191E675E8800706ACC /* SiriIntents.appex */,
692AB91B1E675E8800706ACC /* LegacyDatabase.framework */,
);
name = Products;
sourceTree = "<group>";
};
69F8422C1E67540700C110F7 = {
isa = PBXGroup;
children = (
692AB8861E6759BF00706ACC /* libtgvoip */,
69F842371E67540700C110F7 /* Products */,
692AB9061E675E8700706ACC /* Frameworks */,
);
sourceTree = "<group>";
};
69F842371E67540700C110F7 /* Products */ = {
isa = PBXGroup;
children = (
69F842361E67540700C110F7 /* libtgvoip.framework */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
69F842331E67540700C110F7 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
692AB8DE1E6759DD00706ACC /* gain_control.h in Headers */,
692AB9011E6759DD00706ACC /* threading.h in Headers */,
692AB8EA1E6759DD00706ACC /* MediaStreamItf.h in Headers */,
692AB8EE1E6759DD00706ACC /* OpusEncoder.h in Headers */,
692AB8E11E6759DD00706ACC /* splitting_filter_wrapper.h in Headers */,
692AB8CE1E6759DD00706ACC /* AudioOutput.h in Headers */,
692AB8D91E6759DD00706ACC /* CongestionControl.h in Headers */,
692AB8CC1E6759DD00706ACC /* AudioInput.h in Headers */,
692AB8EC1E6759DD00706ACC /* OpusDecoder.h in Headers */,
692AB8E01E6759DD00706ACC /* noise_suppression_x.h in Headers */,
692AB8E81E6759DD00706ACC /* logging.h in Headers */,
692AB8FF1E6759DD00706ACC /* TGLogWrapper.h in Headers */,
692AB8D41E6759DD00706ACC /* BufferOutputStream.h in Headers */,
692AB8DF1E6759DD00706ACC /* noise_suppression.h in Headers */,
692AB9051E6759DD00706ACC /* VoIPServerConfig.h in Headers */,
692AB9031E6759DD00706ACC /* VoIPController.h in Headers */,
692AB8FC1E6759DD00706ACC /* AudioOutputAudioUnit.h in Headers */,
692AB8D01E6759DD00706ACC /* BlockingQueue.h in Headers */,
692AB8FE1E6759DD00706ACC /* AudioUnitIO.h in Headers */,
692AB8FA1E6759DD00706ACC /* AudioInputAudioUnit.h in Headers */,
692AB8DD1E6759DD00706ACC /* echo_control_mobile.h in Headers */,
692AB8DB1E6759DD00706ACC /* EchoCanceller.h in Headers */,
692AB8D61E6759DD00706ACC /* BufferPool.h in Headers */,
692AB8E71E6759DD00706ACC /* JitterBuffer.h in Headers */,
692AB8D21E6759DD00706ACC /* BufferInputStream.h in Headers */,
692AB8DC1E6759DD00706ACC /* echo_cancellation.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
69F842351E67540700C110F7 /* libtgvoip */ = {
isa = PBXNativeTarget;
buildConfigurationList = 69F8423E1E67540700C110F7 /* Build configuration list for PBXNativeTarget "libtgvoip" */;
buildPhases = (
69F842311E67540700C110F7 /* Sources */,
69F842321E67540700C110F7 /* Frameworks */,
69F842331E67540700C110F7 /* Headers */,
69F842341E67540700C110F7 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = libtgvoip;
productName = libtgvoip;
productReference = 69F842361E67540700C110F7 /* libtgvoip.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
69F8422D1E67540700C110F7 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0820;
ORGANIZATIONNAME = Grishka;
TargetAttributes = {
69F842351E67540700C110F7 = {
CreatedOnToolsVersion = 8.2.1;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = 69F842301E67540700C110F7 /* Build configuration list for PBXProject "libtgvoip" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 69F8422C1E67540700C110F7;
productRefGroup = 69F842371E67540700C110F7 /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 692AB9081E675E8800706ACC /* Products */;
ProjectRef = 692AB9071E675E8800706ACC /* Telegraph.xcodeproj */;
},
);
projectRoot = "";
targets = (
69F842351E67540700C110F7 /* libtgvoip */,
);
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
692AB9111E675E8800706ACC /* Telegram.app */ = {
isa = PBXReferenceProxy;
fileType = wrapper.application;
path = Telegram.app;
remoteRef = 692AB9101E675E8800706ACC /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
692AB9131E675E8800706ACC /* Share.appex */ = {
isa = PBXReferenceProxy;
fileType = "wrapper.app-extension";
path = Share.appex;
remoteRef = 692AB9121E675E8800706ACC /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
692AB9151E675E8800706ACC /* watchkitapp.app */ = {
isa = PBXReferenceProxy;
fileType = wrapper.application;
path = watchkitapp.app;
remoteRef = 692AB9141E675E8800706ACC /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
692AB9171E675E8800706ACC /* watchkitapp Extension.appex */ = {
isa = PBXReferenceProxy;
fileType = "wrapper.app-extension";
path = "watchkitapp Extension.appex";
remoteRef = 692AB9161E675E8800706ACC /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
692AB9191E675E8800706ACC /* SiriIntents.appex */ = {
isa = PBXReferenceProxy;
fileType = "wrapper.app-extension";
path = SiriIntents.appex;
remoteRef = 692AB9181E675E8800706ACC /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
692AB91B1E675E8800706ACC /* LegacyDatabase.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = LegacyDatabase.framework;
remoteRef = 692AB91A1E675E8800706ACC /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
69F842341E67540700C110F7 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
692AB8E51E6759DD00706ACC /* Info.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
69F842311E67540700C110F7 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6915307B1E6B5BAB004F643F /* logging.cpp in Sources */,
692AB9041E6759DD00706ACC /* VoIPServerConfig.cpp in Sources */,
692AB9021E6759DD00706ACC /* VoIPController.cpp in Sources */,
692AB8D81E6759DD00706ACC /* CongestionControl.cpp in Sources */,
692AB8FB1E6759DD00706ACC /* AudioOutputAudioUnit.cpp in Sources */,
692AB8EB1E6759DD00706ACC /* OpusDecoder.cpp in Sources */,
692AB8E61E6759DD00706ACC /* JitterBuffer.cpp in Sources */,
692AB9001E6759DD00706ACC /* TGLogWrapper.m in Sources */,
692AB8F91E6759DD00706ACC /* AudioInputAudioUnit.cpp in Sources */,
692AB8D11E6759DD00706ACC /* BufferInputStream.cpp in Sources */,
692AB8E91E6759DD00706ACC /* MediaStreamItf.cpp in Sources */,
692AB8DA1E6759DD00706ACC /* EchoCanceller.cpp in Sources */,
692AB8D31E6759DD00706ACC /* BufferOutputStream.cpp in Sources */,
692AB8CF1E6759DD00706ACC /* BlockingQueue.cpp in Sources */,
692AB8D51E6759DD00706ACC /* BufferPool.cpp in Sources */,
692AB8CB1E6759DD00706ACC /* AudioInput.cpp in Sources */,
692AB8FD1E6759DD00706ACC /* AudioUnitIO.cpp in Sources */,
692AB8CD1E6759DD00706ACC /* AudioOutput.cpp in Sources */,
692AB8ED1E6759DD00706ACC /* OpusEncoder.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
69F8423C1E67540700C110F7 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 10.2;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
69F8423D1E67540700C110F7 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 10.2;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
69F8423F1E67540700C110F7 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_CXX_LIBRARY = "libc++";
CODE_SIGN_IDENTITY = "";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
HEADER_SEARCH_PATHS = (
../../Telegraph/thirdparty/opus/include/opus,
"$(inherited)",
../../Telegraph,
);
INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/libtgvoip/external",
"$(PROJECT_DIR)/external",
);
MACH_O_TYPE = staticlib;
MACOSX_DEPLOYMENT_TARGET = 10.6;
OTHER_CFLAGS = (
"-DTGVOIP_USE_AUDIO_SESSION",
"-DTGVOIP_USE_CUSTOM_CRYPTO",
);
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.libtgvoip;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Debug;
};
69F842401E67540700C110F7 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_CXX_LIBRARY = "libc++";
CODE_SIGN_IDENTITY = "";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
HEADER_SEARCH_PATHS = (
../../Telegraph/thirdparty/opus/include/opus,
"$(inherited)",
../../Telegraph,
);
INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/libtgvoip/external",
"$(PROJECT_DIR)/external",
);
MACH_O_TYPE = staticlib;
MACOSX_DEPLOYMENT_TARGET = 10.6;
OTHER_CFLAGS = (
"-DTGVOIP_USE_AUDIO_SESSION",
"-DTGVOIP_USE_CUSTOM_CRYPTO",
);
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.libtgvoip;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Release;
};
D04D01C31E678C0D0086DDC0 /* Debug AppStore */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 10.2;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = "Debug AppStore";
};
D04D01C41E678C0D0086DDC0 /* Debug AppStore */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_CXX_LIBRARY = "libc++";
CODE_SIGN_IDENTITY = "";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
HEADER_SEARCH_PATHS = (
../../Telegraph/thirdparty/opus/include/opus,
"$(inherited)",
../../Telegraph,
);
INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/libtgvoip/external",
"$(PROJECT_DIR)/external",
);
MACH_O_TYPE = staticlib;
MACOSX_DEPLOYMENT_TARGET = 10.6;
OTHER_CFLAGS = (
"-DTGVOIP_USE_AUDIO_SESSION",
"-DTGVOIP_USE_CUSTOM_CRYPTO",
);
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.libtgvoip;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = "Debug AppStore";
};
D04D01CB1E678C230086DDC0 /* Hockeyapp */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 10.2;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Hockeyapp;
};
D04D01CC1E678C230086DDC0 /* Hockeyapp */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_CXX_LIBRARY = "libc++";
CODE_SIGN_IDENTITY = "";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
HEADER_SEARCH_PATHS = (
../../Telegraph/thirdparty/opus/include/opus,
"$(inherited)",
../../Telegraph,
);
INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/libtgvoip/external",
"$(PROJECT_DIR)/external",
);
MACH_O_TYPE = staticlib;
MACOSX_DEPLOYMENT_TARGET = 10.6;
OTHER_CFLAGS = (
"-DTGVOIP_USE_AUDIO_SESSION",
"-DTGVOIP_USE_CUSTOM_CRYPTO",
);
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.libtgvoip;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Hockeyapp;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
69F842301E67540700C110F7 /* Build configuration list for PBXProject "libtgvoip" */ = {
isa = XCConfigurationList;
buildConfigurations = (
69F8423C1E67540700C110F7 /* Debug */,
D04D01C31E678C0D0086DDC0 /* Debug AppStore */,
69F8423D1E67540700C110F7 /* Release */,
D04D01CB1E678C230086DDC0 /* Hockeyapp */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
69F8423E1E67540700C110F7 /* Build configuration list for PBXNativeTarget "libtgvoip" */ = {
isa = XCConfigurationList;
buildConfigurations = (
69F8423F1E67540700C110F7 /* Debug */,
D04D01C41E678C0D0086DDC0 /* Debug AppStore */,
69F842401E67540700C110F7 /* Release */,
D04D01CC1E678C230086DDC0 /* Hockeyapp */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 69F8422D1E67540700C110F7 /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:libtgvoip.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0820"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "69F842351E67540700C110F7"
BuildableName = "libtgvoip.framework"
BlueprintName = "libtgvoip"
ReferencedContainer = "container:libtgvoip.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "69F842351E67540700C110F7"
BuildableName = "libtgvoip.framework"
BlueprintName = "libtgvoip"
ReferencedContainer = "container:libtgvoip.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "69F842351E67540700C110F7"
BuildableName = "libtgvoip.framework"
BlueprintName = "libtgvoip"
ReferencedContainer = "container:libtgvoip.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>libtgvoip.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>69F842351E67540700C110F7</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>69F842351E67540700C110F7</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

25
logging.cpp Normal file
View File

@ -0,0 +1,25 @@
//
// 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 <stdio.h>
#include <stdarg.h>
#include <time.h>
FILE* tgvoipLogFile=NULL;
void tgvoip_log_file_printf(char level, const char* msg, ...){
if(tgvoipLogFile){
va_list argptr;
va_start(argptr, msg);
time_t t = time(0);
struct tm *now = localtime(&t);
fprintf(tgvoipLogFile, "%02d-%02d %02d:%02d:%02d %c: ", now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec, level);
vfprintf(tgvoipLogFile, msg, argptr);
fprintf(tgvoipLogFile, "\n");
fflush(tgvoipLogFile);
}
}

View File

@ -6,10 +6,15 @@
#ifndef __LOGGING_H #ifndef __LOGGING_H
#define __LOGGING_H #define __LOGGING_H
#define LSTR_INT(x) LSTR_DO_INT(x) #define LSTR_INT(x) LSTR_DO_INT(x)
#define LSTR_DO_INT(x) #x #define LSTR_DO_INT(x) #x
#ifdef __APPLE__
#include <TargetConditionals.h>
#endif
void tgvoip_log_file_printf(char level, const char* msg, ...);
#if defined(__ANDROID__) #if defined(__ANDROID__)
#include <android/log.h> #include <android/log.h>
@ -17,11 +22,11 @@
//#define _LOG_WRAP(...) __BASE_FILE__":"LSTR_INT(__LINE__)": "__VA_ARGS__ //#define _LOG_WRAP(...) __BASE_FILE__":"LSTR_INT(__LINE__)": "__VA_ARGS__
#define _LOG_WRAP(...) __VA_ARGS__ #define _LOG_WRAP(...) __VA_ARGS__
#define TAG "tg-voip-native" #define TAG "tg-voip-native"
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, _LOG_WRAP(__VA_ARGS__)) #define LOGV(...) {__android_log_print(ANDROID_LOG_VERBOSE, TAG, _LOG_WRAP(__VA_ARGS__)); tgvoip_log_file_printf('V', __VA_ARGS__);}
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, _LOG_WRAP(__VA_ARGS__)) #define LOGD(...) {__android_log_print(ANDROID_LOG_DEBUG, TAG, _LOG_WRAP(__VA_ARGS__)); tgvoip_log_file_printf('D', __VA_ARGS__);}
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, _LOG_WRAP(__VA_ARGS__)) #define LOGI(...) {__android_log_print(ANDROID_LOG_INFO, TAG, _LOG_WRAP(__VA_ARGS__)); tgvoip_log_file_printf('I', __VA_ARGS__);}
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, _LOG_WRAP(__VA_ARGS__)) #define LOGW(...) {__android_log_print(ANDROID_LOG_WARN, TAG, _LOG_WRAP(__VA_ARGS__)); tgvoip_log_file_printf('W', __VA_ARGS__);}
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, _LOG_WRAP(__VA_ARGS__)) #define LOGE(...) {__android_log_print(ANDROID_LOG_ERROR, TAG, _LOG_WRAP(__VA_ARGS__)); tgvoip_log_file_printf('E', __VA_ARGS__);}
#elif defined(__APPLE__) && TARGET_OS_IPHONE #elif defined(__APPLE__) && TARGET_OS_IPHONE

View File

@ -10,11 +10,11 @@
extern JavaVM* sharedJVM; extern JavaVM* sharedJVM;
jmethodID CAudioInputAndroid::initMethod; jmethodID CAudioInputAndroid::initMethod=NULL;
jmethodID CAudioInputAndroid::releaseMethod; jmethodID CAudioInputAndroid::releaseMethod=NULL;
jmethodID CAudioInputAndroid::startMethod; jmethodID CAudioInputAndroid::startMethod=NULL;
jmethodID CAudioInputAndroid::stopMethod; jmethodID CAudioInputAndroid::stopMethod=NULL;
jclass CAudioInputAndroid::jniClass; jclass CAudioInputAndroid::jniClass=NULL;
CAudioInputAndroid::CAudioInputAndroid(){ CAudioInputAndroid::CAudioInputAndroid(){
JNIEnv* env=NULL; JNIEnv* env=NULL;
@ -33,9 +33,12 @@ CAudioInputAndroid::CAudioInputAndroid(){
sharedJVM->DetachCurrentThread(); sharedJVM->DetachCurrentThread();
} }
running=false; running=false;
init_mutex(mutex);
} }
CAudioInputAndroid::~CAudioInputAndroid(){ CAudioInputAndroid::~CAudioInputAndroid(){
{
CMutexGuard guard(mutex);
JNIEnv *env=NULL; JNIEnv *env=NULL;
bool didAttach=false; bool didAttach=false;
sharedJVM->GetEnv((void **) &env, JNI_VERSION_1_6); sharedJVM->GetEnv((void **) &env, JNI_VERSION_1_6);
@ -52,8 +55,11 @@ CAudioInputAndroid::~CAudioInputAndroid(){
sharedJVM->DetachCurrentThread(); sharedJVM->DetachCurrentThread();
} }
} }
free_mutex(mutex);
}
void CAudioInputAndroid::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){ void CAudioInputAndroid::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
CMutexGuard guard(mutex);
JNIEnv* env=NULL; JNIEnv* env=NULL;
bool didAttach=false; bool didAttach=false;
sharedJVM->GetEnv((void**) &env, JNI_VERSION_1_6); sharedJVM->GetEnv((void**) &env, JNI_VERSION_1_6);
@ -70,6 +76,7 @@ void CAudioInputAndroid::Configure(uint32_t sampleRate, uint32_t bitsPerSample,
} }
void CAudioInputAndroid::Start(){ void CAudioInputAndroid::Start(){
CMutexGuard guard(mutex);
JNIEnv* env=NULL; JNIEnv* env=NULL;
bool didAttach=false; bool didAttach=false;
sharedJVM->GetEnv((void**) &env, JNI_VERSION_1_6); sharedJVM->GetEnv((void**) &env, JNI_VERSION_1_6);
@ -78,7 +85,7 @@ void CAudioInputAndroid::Start(){
didAttach=true; didAttach=true;
} }
env->CallVoidMethod(javaObject, startMethod); failed=!env->CallBooleanMethod(javaObject, startMethod);
if(didAttach){ if(didAttach){
sharedJVM->DetachCurrentThread(); sharedJVM->DetachCurrentThread();
@ -87,6 +94,7 @@ void CAudioInputAndroid::Start(){
} }
void CAudioInputAndroid::Stop(){ void CAudioInputAndroid::Stop(){
CMutexGuard guard(mutex);
running=false; running=false;
JNIEnv* env=NULL; JNIEnv* env=NULL;
bool didAttach=false; bool didAttach=false;

View File

@ -9,6 +9,7 @@
#include <jni.h> #include <jni.h>
#include "../../audio/AudioInput.h" #include "../../audio/AudioInput.h"
#include "../../threading.h"
class CAudioInputAndroid : public CAudioInput{ class CAudioInputAndroid : public CAudioInput{
@ -28,6 +29,7 @@ public:
private: private:
jobject javaObject; jobject javaObject;
bool running; bool running;
tgvoip_mutex_t mutex;
}; };

View File

@ -10,11 +10,11 @@
extern JavaVM* sharedJVM; extern JavaVM* sharedJVM;
jmethodID CAudioOutputAndroid::initMethod; jmethodID CAudioOutputAndroid::initMethod=NULL;
jmethodID CAudioOutputAndroid::releaseMethod; jmethodID CAudioOutputAndroid::releaseMethod=NULL;
jmethodID CAudioOutputAndroid::startMethod; jmethodID CAudioOutputAndroid::startMethod=NULL;
jmethodID CAudioOutputAndroid::stopMethod; jmethodID CAudioOutputAndroid::stopMethod=NULL;
jclass CAudioOutputAndroid::jniClass; jclass CAudioOutputAndroid::jniClass=NULL;
CAudioOutputAndroid::CAudioOutputAndroid(){ CAudioOutputAndroid::CAudioOutputAndroid(){
JNIEnv* env=NULL; JNIEnv* env=NULL;

View File

@ -9,6 +9,7 @@
#include "AudioInputAudioUnit.h" #include "AudioInputAudioUnit.h"
#include "AudioOutputAudioUnit.h" #include "AudioOutputAudioUnit.h"
#include "../../logging.h" #include "../../logging.h"
#include "../../VoIPController.h"
#define CHECK_AU_ERROR(res, msg) if(res!=noErr){ LOGE(msg": OSStatus=%d", (int)res); return; } #define CHECK_AU_ERROR(res, msg) if(res!=noErr){ LOGE(msg": OSStatus=%d", (int)res); return; }
#define BUFFER_SIZE 960 // 20 ms #define BUFFER_SIZE 960 // 20 ms
@ -18,8 +19,34 @@
int CAudioUnitIO::refCount=0; int CAudioUnitIO::refCount=0;
CAudioUnitIO* CAudioUnitIO::sharedInstance=NULL; CAudioUnitIO* CAudioUnitIO::sharedInstance=NULL;
bool CAudioUnitIO::haveAudioSession=false;
CAudioUnitIO::CAudioUnitIO(){ CAudioUnitIO::CAudioUnitIO(){
input=NULL;
output=NULL;
configured=false;
inputEnabled=false;
outputEnabled=false;
inBufferList.mBuffers[0].mData=malloc(10240);
inBufferList.mBuffers[0].mDataByteSize=10240;
inBufferList.mNumberBuffers=1;
if(haveAudioSession)
ProcessAudioSessionAcquired();
}
CAudioUnitIO::~CAudioUnitIO(){
if(runFakeIO){
runFakeIO=false;
join_thread(fakeIOThread);
}
AudioOutputUnitStop(unit);
AudioUnitUninitialize(unit);
AudioComponentInstanceDispose(unit);
free(inBufferList.mBuffers[0].mData);
haveAudioSession=false;
}
void CAudioUnitIO::ProcessAudioSessionAcquired(){
OSStatus status; OSStatus status;
AudioComponentDescription desc; AudioComponentDescription desc;
AudioComponent inputComponent; AudioComponent inputComponent;
@ -36,21 +63,8 @@ CAudioUnitIO::CAudioUnitIO(){
inputComponent = AudioComponentFindNext(NULL, &desc); inputComponent = AudioComponentFindNext(NULL, &desc);
status = AudioComponentInstanceNew(inputComponent, &unit); status = AudioComponentInstanceNew(inputComponent, &unit);
input=NULL; if(configured)
output=NULL; ActuallyConfigure(cfgSampleRate, cfgBitsPerSample, cfgChannels);
configured=false;
inputEnabled=false;
outputEnabled=false;
inBufferList.mBuffers[0].mData=malloc(10240);
inBufferList.mBuffers[0].mDataByteSize=10240;
inBufferList.mNumberBuffers=1;
}
CAudioUnitIO::~CAudioUnitIO(){
AudioOutputUnitStop(unit);
AudioUnitUninitialize(unit);
AudioComponentInstanceDispose(unit);
free(inBufferList.mBuffers[0].mData);
} }
CAudioUnitIO* CAudioUnitIO::Get(){ CAudioUnitIO* CAudioUnitIO::Get(){
@ -71,26 +85,42 @@ void CAudioUnitIO::Release(){
} }
} }
void CAudioUnitIO::AudioSessionAcquired(){
haveAudioSession=true;
if(sharedInstance)
sharedInstance->ProcessAudioSessionAcquired();
}
void CAudioUnitIO::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){ void CAudioUnitIO::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
if(configured) if(configured)
return; return;
runFakeIO=true;
start_thread(fakeIOThread, CAudioUnitIO::StartFakeIOThread, this);
set_thread_priority(fakeIOThread, get_thread_max_priority());
if(haveAudioSession){
ActuallyConfigure(sampleRate, bitsPerSample, channels);
}else{
cfgSampleRate=sampleRate;
cfgBitsPerSample=bitsPerSample;
cfgChannels=channels;
}
configured=true;
}
void CAudioUnitIO::ActuallyConfigure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
UInt32 flag=1; UInt32 flag=1;
OSStatus status = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &flag, sizeof(flag)); OSStatus status = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &flag, sizeof(flag));
CHECK_AU_ERROR(status, "Error enabling AudioUnit output"); CHECK_AU_ERROR(status, "Error enabling AudioUnit output");
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");
flag=1; flag=0;
status=AudioUnitSetProperty(unit, kAUVoiceIOProperty_VoiceProcessingEnableAGC, kAudioUnitScope_Global, kInputBus, &flag, sizeof(flag)); status=AudioUnitSetProperty(unit, kAUVoiceIOProperty_VoiceProcessingEnableAGC, kAudioUnitScope_Global, kInputBus, &flag, sizeof(flag));
CHECK_AU_ERROR(status, "Error disabling AGC"); CHECK_AU_ERROR(status, "Error disabling AGC");
/*AudioStreamBasicDescription nativeInFormat, nativeOutFormat;
UInt32 size=sizeof(AudioStreamBasicDescription);
AudioUnitGetProperty(unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &nativeInFormat, &size);
size=sizeof(AudioStreamBasicDescription);
AudioUnitGetProperty(unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &nativeOutFormat, &size);
LOGI("native in format: %d hz, flags %08X, %d channels, %d bits", (int)nativeInFormat.mSampleRate, nativeInFormat.mFormatFlags, nativeInFormat.mChannelsPerFrame, nativeInFormat.mBitsPerChannel);
LOGI("native out format: %d hz, flags %08X, %d channels, %d bits", (int)nativeOutFormat.mSampleRate, nativeOutFormat.mFormatFlags, nativeOutFormat.mChannelsPerFrame, nativeOutFormat.mBitsPerChannel);*/
Float64 nativeSampleRate; Float64 nativeSampleRate;
UInt32 size=sizeof(Float64); UInt32 size=sizeof(Float64);
status=AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &size, &nativeSampleRate); status=AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &size, &nativeSampleRate);
@ -123,8 +153,6 @@ void CAudioUnitIO::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32
CHECK_AU_ERROR(status, "Error initializing AudioUnit"); CHECK_AU_ERROR(status, "Error initializing AudioUnit");
status=AudioOutputUnitStart(unit); status=AudioOutputUnitStart(unit);
CHECK_AU_ERROR(status, "Error starting AudioUnit"); CHECK_AU_ERROR(status, "Error starting AudioUnit");
configured=true;
} }
OSStatus CAudioUnitIO::BufferCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData){ OSStatus CAudioUnitIO::BufferCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData){
@ -133,6 +161,7 @@ OSStatus CAudioUnitIO::BufferCallback(void *inRefCon, AudioUnitRenderActionFlags
} }
void CAudioUnitIO::BufferCallback(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 bus, UInt32 numFrames, AudioBufferList *ioData){ void CAudioUnitIO::BufferCallback(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 bus, UInt32 numFrames, AudioBufferList *ioData){
runFakeIO=false;
if(bus==kOutputBus){ if(bus==kOutputBus){
if(output && outputEnabled){ if(output && outputEnabled){
output->HandleBufferCallback(ioData); output->HandleBufferCallback(ioData);
@ -178,3 +207,34 @@ void CAudioUnitIO::EnableOutput(bool enabled){
outputEnabled=enabled; outputEnabled=enabled;
} }
void* CAudioUnitIO::StartFakeIOThread(void *arg){
((CAudioUnitIO*)arg)->RunFakeIOThread();
return NULL;
}
void CAudioUnitIO::RunFakeIOThread(){
double neededDataDuration=0;
double prevTime=CVoIPController::GetCurrentTime();
while(runFakeIO){
double t=CVoIPController::GetCurrentTime();
neededDataDuration+=t-prevTime;
prevTime=t;
while(neededDataDuration>=0.020){
if(output && outputEnabled){
inBufferList.mBuffers[0].mDataByteSize=960*2;
output->HandleBufferCallback(&inBufferList);
}
if((output && outputEnabled) || (input && inputEnabled)){
memset(inBufferList.mBuffers[0].mData, 0, 960*2);
}
if(input && inputEnabled){
inBufferList.mBuffers[0].mDataByteSize=960*2;
input->HandleBufferCallback(&inBufferList);
}
neededDataDuration-=0.020;
}
usleep(5000);
}
LOGD("FakeIO thread exiting");
}

View File

@ -8,6 +8,7 @@
#define LIBTGVOIP_AUDIOUNITIO_H #define LIBTGVOIP_AUDIOUNITIO_H
#include <AudioUnit/AudioUnit.h> #include <AudioUnit/AudioUnit.h>
#include "../../threading.h"
class CAudioInputAudioUnit; class CAudioInputAudioUnit;
class CAudioOutputAudioUnit; class CAudioOutputAudioUnit;
@ -25,10 +26,16 @@ public:
void EnableOutput(bool enabled); void EnableOutput(bool enabled);
static CAudioUnitIO* Get(); static CAudioUnitIO* Get();
static void Release(); static void Release();
static void* StartFakeIOThread(void* arg);
static void AudioSessionAcquired();
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);
void BufferCallback(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 bus, UInt32 numFrames, AudioBufferList* ioData); void BufferCallback(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 bus, UInt32 numFrames, AudioBufferList* ioData);
void RunFakeIOThread();
void Init();
void ActuallyConfigure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
void ProcessAudioSessionAcquired();
AudioComponentInstance unit; AudioComponentInstance unit;
CAudioInputAudioUnit* input; CAudioInputAudioUnit* input;
CAudioOutputAudioUnit* output; CAudioOutputAudioUnit* output;
@ -36,8 +43,14 @@ private:
bool configured; bool configured;
bool inputEnabled; bool inputEnabled;
bool outputEnabled; bool outputEnabled;
bool runFakeIO;
uint32_t cfgSampleRate;
uint32_t cfgBitsPerSample;
uint32_t cfgChannels;
tgvoip_thread_t fakeIOThread;
static int refCount; static int refCount;
static CAudioUnitIO* sharedInstance; static CAudioUnitIO* sharedInstance;
static bool haveAudioSession;
}; };
#endif /* LIBTGVOIP_AUDIOUNITIO_H */ #endif /* LIBTGVOIP_AUDIOUNITIO_H */

View File

@ -1,8 +1,10 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "ASCommon.h"
void __tgvoip_call_tglog(char* format, ...){ void __tgvoip_call_tglog(char* format, ...){
va_list args; va_list args;
va_start(args, format); va_start(args, format);
TGLog([[[NSString alloc] initWithFormat:[NSString stringWithCString:format encoding:NSUTF8StringEncoding] arguments:args] stringByReplacingOccurrencesOfString:@"%" withString:@"%%"]); TGLogv([[NSString alloc]initWithCString:format], args);
va_end(args); va_end(args);
} }

View File

@ -39,4 +39,16 @@ typedef pthread_cond_t tgvoip_lock_t;
#error "No threading implementation for your operating system" #error "No threading implementation for your operating system"
#endif #endif
class CMutexGuard{
public:
CMutexGuard(tgvoip_mutex_t &mutex) : mutex(mutex) {
lock_mutex(mutex);
}
~CMutexGuard(){
unlock_mutex(mutex);
}
private:
tgvoip_mutex_t &mutex;
};
#endif //__THREADING_H #endif //__THREADING_H