Added AGC on audio output because some echo cancellation implementations don't like loud audio in speakerphone mode; this should only be enabled when using the earpiece speaker, on devices that have one. Also, the AGC on the input is now configured with a much lower target level.

This commit is contained in:
Grishka
2017-09-07 08:39:33 +03:00
parent a8aff0e64c
commit d348e56436
10 changed files with 173 additions and 18 deletions

View File

@@ -233,6 +233,9 @@ VoIPController::VoIPController() : activeNetItfName(""),
realUdpSocket=udpSocket;
udpConnectivityState=UDP_UNKNOWN;
outputAGC=NULL;
outputAGCEnabled=false;
maxAudioBitrate=(uint32_t) ServerConfig::GetSharedInstance()->GetInt("audio_max_bitrate", 20000);
maxAudioBitrateGPRS=(uint32_t) ServerConfig::GetSharedInstance()->GetInt("audio_max_bitrate_gprs", 8000);
maxAudioBitrateEDGE=(uint32_t) ServerConfig::GetSharedInstance()->GetInt("audio_max_bitrate_edge", 16000);
@@ -263,6 +266,8 @@ VoIPController::VoIPController() : activeNetItfName(""),
stm->enabled=1;
stm->frameDuration=60;
outgoingStreams.push_back(stm);
memset(signalBarsHistory, 0, sizeof(signalBarsHistory));
}
VoIPController::~VoIPController(){
@@ -359,6 +364,8 @@ VoIPController::~VoIPController(){
if(resolvedProxyAddress)
delete resolvedProxyAddress;
delete selectCanceller;
if(outputAGC)
delete outputAGC;
LOGD("Left VoIPController::~VoIPController");
}
@@ -1165,10 +1172,13 @@ simpleAudioBlock random_id:long random_bytes:string raw_data:string = DecryptedA
UpdateAudioBitrate();
jitterBuffer=new JitterBuffer(NULL, incomingAudioStream->frameDuration);
outputAGC=new AutomaticGainControl();
outputAGC->SetPassThrough(!outputAGCEnabled);
decoder=new OpusDecoder(audioOutput);
decoder->SetEchoCanceller(echoCanceller);
decoder->SetJitterBuffer(jitterBuffer);
decoder->SetFrameDuration(incomingAudioStream->frameDuration);
decoder->AddAudioEffect(outputAGC);
decoder->Start();
if(incomingAudioStream->frameDuration>50)
jitterBuffer->SetMinPacketCount((uint32_t) ServerConfig::GetSharedInstance()->GetInt("jitter_initial_delay_60", 3));
@@ -1226,7 +1236,7 @@ simpleAudioBlock random_id:long random_bytes:string raw_data:string = DecryptedA
audioOutput->Start();
audioOutStarted=true;
}
if(jitterBuffer)
if(jitterBuffer && in.Remaining()>=sdlen)
jitterBuffer->HandleInput((unsigned char*) (buffer+in.GetOffset()), sdlen, pts);
if(i<count-1)
in.Seek(in.GetOffset()+sdlen);
@@ -1359,7 +1369,7 @@ void VoIPController::RunTickThread(){
#else
Sleep(100);
#endif
int prevSignalBarCount=signalBarCount;
int prevSignalBarCount=GetSignalBarsCount();
signalBarCount=4;
tickCount++;
if(connectionInitTime==0)
@@ -1542,12 +1552,12 @@ void VoIPController::RunTickThread(){
double avgDelay=jitterBuffer->GetAverageDelay();
double avgLateCount[3];
jitterBuffer->GetAverageLateCount(avgLateCount);
if(avgDelay>=5)
/*if(avgDelay>=5)
signalBarCount=1;
else if(avgDelay>=4)
signalBarCount=MIN(signalBarCount, 2);
else if(avgDelay>=3)
signalBarCount=MIN(signalBarCount, 3);
signalBarCount=MIN(signalBarCount, 3);*/
if(avgLateCount[2]>=0.2)
signalBarCount=1;
@@ -1694,10 +1704,12 @@ void VoIPController::RunTickThread(){
setEstablishedAt=0;
}
if(signalBarCount!=prevSignalBarCount){
LOGD("SIGNAL BAR COUNT CHANGED: %d", signalBarCount);
signalBarsHistory[tickCount%sizeof(signalBarsHistory)]=(unsigned char)signalBarCount;
int _signalBarCount=GetSignalBarsCount();
if(_signalBarCount!=prevSignalBarCount){
LOGD("SIGNAL BAR COUNT CHANGED: %d", _signalBarCount);
if(signalBarCountCallback)
signalBarCountCallback(this, signalBarCount);
signalBarCountCallback(this, _signalBarCount);
}
@@ -2443,13 +2455,23 @@ void VoIPController::SendUdpPing(Endpoint *endpoint){
}
int VoIPController::GetSignalBarsCount(){
return signalBarCount;
unsigned char avg=0;
for(int i=0;i<sizeof(signalBarsHistory);i++)
avg+=signalBarsHistory[i];
return avg >> 2;
}
void VoIPController::SetSignalBarsCountCallback(void (*f)(VoIPController *, int)){
signalBarCountCallback=f;
}
void VoIPController::SetAudioOutputGainControlEnabled(bool enabled){
LOGD("New output AGC state: %d", enabled);
outputAGCEnabled=enabled;
if(outputAGC)
outputAGC->SetPassThrough(!enabled);
}
Endpoint::Endpoint(int64_t id, uint16_t port, IPv4Address& _address, IPv6Address& _v6address, char type, unsigned char peerTag[16]) : address(_address), v6address(_v6address){
this->id=id;
this->port=port;