Skip to content
This repository was archived by the owner on Jun 12, 2020. It is now read-only.

Commit

Permalink
Updated WebRTC APM
Browse files Browse the repository at this point in the history
I'm now using the entire audio processing module from WebRTC as opposed to individual DSP algorithms pulled from there before. Seems to work better this way.
  • Loading branch information
grishka committed Nov 23, 2018
1 parent cc0cf35 commit 5caaaaf
Show file tree
Hide file tree
Showing 644 changed files with 90,737 additions and 9,227 deletions.
359 changes: 64 additions & 295 deletions EchoCanceller.cpp

Large diffs are not rendered by default.

21 changes: 8 additions & 13 deletions EchoCanceller.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
#include "MediaStreamItf.h"
#include "utils.h"

namespace webrtc{
class AudioProcessing;
class AudioFrame;
}

namespace tgvoip{
class EchoCanceller{

Expand All @@ -24,7 +29,7 @@ class EchoCanceller{
virtual void Stop();
void SpeakerOutCallback(unsigned char* data, size_t len);
void Enable(bool enabled);
void ProcessInput(unsigned char* data, unsigned char* out, size_t len);
void ProcessInput(int16_t* inOut, size_t numSamples);
void SetAECStrength(int strength);

private:
Expand All @@ -33,24 +38,14 @@ class EchoCanceller{
bool enableNS;
bool isOn;
#ifndef TGVOIP_NO_DSP
webrtc::AudioProcessing* apm=NULL;
webrtc::AudioFrame* audioFrame=NULL;
void RunBufferFarendThread();
bool didBufferFarend;
Mutex aecMutex;
void* aec;
void* splittingFilter; // webrtc::SplittingFilter
void* splittingFilterIn; // webrtc::IFChannelBuffer
void* splittingFilterOut; // webrtc::IFChannelBuffer
void* splittingFilterFarend; // webrtc::SplittingFilter
void* splittingFilterFarendIn; // webrtc::IFChannelBuffer
void* splittingFilterFarendOut; // webrtc::IFChannelBuffer
Thread* bufferFarendThread;
BlockingQueue<int16_t*>* farendQueue;
BufferPool* farendBufferPool;
bool running;
void* ns; // NsxHandle
void* agc;
int32_t agcMicLevel;
//int32_t outstandingFarendFrames=0;
#endif
};

Expand Down
746 changes: 603 additions & 143 deletions Makefile.am

Large diffs are not rendered by default.

4,763 changes: 3,805 additions & 958 deletions Makefile.in

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion MediaStreamItf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ void MediaStreamItf::SetCallback(size_t (*f)(unsigned char *, size_t, void*), vo
size_t MediaStreamItf::InvokeCallback(unsigned char *data, size_t length){
if(callback)
return (*callback)(data, length, callbackParam);
return NULL;
return 0;
}

AudioMixer::AudioMixer() : bufferPool(960*2, 16), processedQueue(16), semaphore(16, 0){
Expand Down
31 changes: 14 additions & 17 deletions OpusEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ tgvoip::OpusEncoder::OpusEncoder(MediaStreamItf *source, bool needSecondary):que
complexity=10;
frameDuration=20;
levelMeter=NULL;
mediumCorrectionBitrate=ServerConfig::GetSharedInstance()->GetInt("audio_medium_fec_bitrate", 10000);
strongCorrectionBitrate=ServerConfig::GetSharedInstance()->GetInt("audio_strong_fec_bitrate", 8000);
mediumCorrectionBitrate=static_cast<uint32_t>(ServerConfig::GetSharedInstance()->GetInt("audio_medium_fec_bitrate", 10000));
strongCorrectionBitrate=static_cast<uint32_t>(ServerConfig::GetSharedInstance()->GetInt("audio_strong_fec_bitrate", 8000));
mediumCorrectionMultiplier=ServerConfig::GetSharedInstance()->GetDouble("audio_medium_fec_multiplier", 1.5);
strongCorrectionMultiplier=ServerConfig::GetSharedInstance()->GetDouble("audio_strong_fec_multiplier", 2.0);
secondaryEncoderEnabled=false;
Expand Down Expand Up @@ -80,15 +80,15 @@ void tgvoip::OpusEncoder::SetBitrate(uint32_t bitrate){
requestedBitrate=bitrate;
}

void tgvoip::OpusEncoder::Encode(unsigned char *data, size_t len){
void tgvoip::OpusEncoder::Encode(int16_t* data, size_t len){
if(requestedBitrate!=currentBitrate){
opus_encoder_ctl(enc, OPUS_SET_BITRATE(requestedBitrate));
currentBitrate=requestedBitrate;
LOGV("opus_encoder: setting bitrate to %u", currentBitrate);
}
if(levelMeter)
levelMeter->Update(reinterpret_cast<int16_t *>(data), len/2);
int32_t r=opus_encode(enc, (int16_t*)data, len/2, buffer, 4096);
levelMeter->Update(data, len);
int32_t r=opus_encode(enc, data, static_cast<int>(len), buffer, 4096);
if(r<=0){
LOGE("Error encoding: %d", r);
}else if(r==1){
Expand All @@ -98,7 +98,7 @@ void tgvoip::OpusEncoder::Encode(unsigned char *data, size_t len){
int32_t secondaryLen=0;
unsigned char secondaryBuffer[128];
if(secondaryEncoderEnabled && secondaryEncoder){
secondaryLen=opus_encode(secondaryEncoder, (int16_t*)data, len/2, secondaryBuffer, sizeof(secondaryBuffer));
secondaryLen=opus_encode(secondaryEncoder, data, static_cast<int>(len), secondaryBuffer, sizeof(secondaryBuffer));
//LOGV("secondaryLen %d", secondaryLen);
}
InvokeCallback(buffer, (size_t)r, secondaryBuffer, (size_t)secondaryLen);
Expand Down Expand Up @@ -132,33 +132,30 @@ void tgvoip::OpusEncoder::SetEchoCanceller(EchoCanceller* aec){
}

void tgvoip::OpusEncoder::RunThread(){
unsigned char buf[960*2];
uint32_t bufferedCount=0;
uint32_t packetsPerFrame=frameDuration/20;
LOGV("starting encoder, packets per frame=%d", packetsPerFrame);
unsigned char* frame;
int16_t* frame;
if(packetsPerFrame>1)
frame=(unsigned char *) malloc(960*2*packetsPerFrame);
frame=(int16_t*) malloc(960*2*packetsPerFrame);
else
frame=NULL;
while(running){
unsigned char* packet=(unsigned char*)queue.GetBlocking();
int16_t* packet=(int16_t*)queue.GetBlocking();
if(packet){
if(echoCanceller)
echoCanceller->ProcessInput(packet, buf, 960*2);
else
memcpy(buf, packet, 960*2);
echoCanceller->ProcessInput(packet, 960);
if(packetsPerFrame==1){
Encode(buf, 960*2);
Encode(packet, 960);
}else{
memcpy(frame+(960*2*bufferedCount), buf, 960*2);
memcpy(frame+(960*bufferedCount), packet, 960*2);
bufferedCount++;
if(bufferedCount==packetsPerFrame){
Encode(frame, 960*2*packetsPerFrame);
Encode(frame, 960*packetsPerFrame);
bufferedCount=0;
}
}
bufferPool.Reuse(packet);
bufferPool.Reuse(reinterpret_cast<unsigned char *>(packet));
}
}
if(frame)
Expand Down
2 changes: 1 addition & 1 deletion OpusEncoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class OpusEncoder{
private:
static size_t Callback(unsigned char* data, size_t len, void* param);
void RunThread();
void Encode(unsigned char* data, size_t len);
void Encode(int16_t* data, size_t len);
void InvokeCallback(unsigned char* data, size_t length, unsigned char* secondaryData, size_t secondaryLength);
MediaStreamItf* source;
::OpusEncoder* enc;
Expand Down
18 changes: 17 additions & 1 deletion VoIPController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ bool VoIPController::didInitWin32TimeScale = false;

#ifdef __ANDROID__
#include "os/android/JNIUtilities.h"
#include "os/android/AudioInputAndroid.h"
extern jclass jniUtilitiesClass;
#endif

Expand Down Expand Up @@ -1042,6 +1043,20 @@ void VoIPController::InitializeAudio(){
audioIO=audio::AudioIO::Create();
audioInput=audioIO->GetInput();
audioOutput=audioIO->GetOutput();
#ifdef __ANDROID__
audio::AudioInputAndroid* androidInput=dynamic_cast<audio::AudioInputAndroid*>(audioInput);
if(androidInput){
unsigned int effects=androidInput->GetEnabledEffects();
if(!(effects & audio::AudioInputAndroid::EFFECT_AEC)){
config.enableAEC=true;
LOGI("Forcing software AEC because built-in is not good");
}
if(!(effects & audio::AudioInputAndroid::EFFECT_NS)){
config.enableNS=true;
LOGI("Forcing software NS because built-in is not good");
}
}
#endif
LOGI("AEC: %d NS: %d AGC: %d", config.enableAEC, config.enableNS, config.enableAGC);
echoCanceller=new EchoCanceller(config.enableAEC, config.enableNS, config.enableAGC);
encoder=new OpusEncoder(audioInput, true);
Expand All @@ -1056,7 +1071,7 @@ void VoIPController::InitializeAudio(){
#endif

if(!audioOutput->IsInitialized()){
LOGE("Erorr initializing audio playback");
LOGE("Error initializing audio playback");
lastError=ERROR_AUDIO_IO;

SetState(STATE_FAILED);
Expand Down Expand Up @@ -1102,6 +1117,7 @@ void VoIPController::UpdateAudioOutputState(){
areAnyAudioStreamsEnabled=true;
}
if(audioOutput){
LOGV("New audio output state: %d", areAnyAudioStreamsEnabled);
if(audioOutput->IsPlaying()!=areAnyAudioStreamsEnabled){
if(areAnyAudioStreamsEnabled)
audioOutput->Start();
Expand Down
2 changes: 1 addition & 1 deletion VoIPController.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#include "MessageThread.h"
#include "utils.h"

#define LIBTGVOIP_VERSION "2.3"
#define LIBTGVOIP_VERSION "2.4"

#ifdef _WIN32
#undef GetCurrentTime
Expand Down
1 change: 1 addition & 0 deletions client/android/tg_voip_jni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ extern "C" void tgvoipRegisterNatives(JNIEnv* env){
AudioInputAndroid::releaseMethod=env->GetMethodID(cls, "release", "()V");
AudioInputAndroid::startMethod=env->GetMethodID(cls, "start", "()Z");
AudioInputAndroid::stopMethod=env->GetMethodID(cls, "stop", "()V");
AudioInputAndroid::getEnabledEffectsMaskMethod=env->GetMethodID(cls, "getEnabledEffectsMask", "()I");

cls=env->FindClass(TGVOIP_PACKAGE_PATH "/AudioTrackJNI");
AudioOutputAndroid::jniClass=(jclass) env->NewGlobalRef(cls);
Expand Down
20 changes: 10 additions & 10 deletions configure
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for libtgvoip 2.2.4.
# Generated by GNU Autoconf 2.69 for libtgvoip 2.4.
#
# Report bugs to <https://github.com/grishka/libtgvoip/issues>.
#
Expand Down Expand Up @@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='libtgvoip'
PACKAGE_TARNAME='libtgvoip'
PACKAGE_VERSION='2.2.4'
PACKAGE_STRING='libtgvoip 2.2.4'
PACKAGE_VERSION='2.4'
PACKAGE_STRING='libtgvoip 2.4'
PACKAGE_BUGREPORT='https://github.com/grishka/libtgvoip/issues'
PACKAGE_URL=''

Expand Down Expand Up @@ -1360,7 +1360,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures libtgvoip 2.2.4 to adapt to many kinds of systems.
\`configure' configures libtgvoip 2.4 to adapt to many kinds of systems.

Usage: $0 [OPTION]... [VAR=VALUE]...

Expand Down Expand Up @@ -1430,7 +1430,7 @@ fi

if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of libtgvoip 2.2.4:";;
short | recursive ) echo "Configuration of libtgvoip 2.4:";;
esac
cat <<\_ACEOF

Expand Down Expand Up @@ -1552,7 +1552,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
libtgvoip configure 2.2.4
libtgvoip configure 2.4
generated by GNU Autoconf 2.69

Copyright (C) 2012 Free Software Foundation, Inc.
Expand Down Expand Up @@ -2264,7 +2264,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by libtgvoip $as_me 2.2.4, which was
It was created by libtgvoip $as_me 2.4, which was
generated by GNU Autoconf 2.69. Invocation command line was

$ $0 $@
Expand Down Expand Up @@ -3130,7 +3130,7 @@ fi

# Define the identity of the package.
PACKAGE='libtgvoip'
VERSION='2.2.4'
VERSION='2.4'


cat >>confdefs.h <<_ACEOF
Expand Down Expand Up @@ -19133,7 +19133,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by libtgvoip $as_me 2.2.4, which was
This file was extended by libtgvoip $as_me 2.4, which was
generated by GNU Autoconf 2.69. Invocation command line was

CONFIG_FILES = $CONFIG_FILES
Expand Down Expand Up @@ -19199,7 +19199,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
libtgvoip config.status 2.2.4
libtgvoip config.status 2.4
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
AC_INIT([libtgvoip], [2.2.4], [https://github.com/grishka/libtgvoip/issues])
AC_INIT([libtgvoip], [2.4], [https://github.com/grishka/libtgvoip/issues])
AC_CONFIG_SRCDIR([config.h.in])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([subdir-objects])
Expand Down
Loading

0 comments on commit 5caaaaf

Please sign in to comment.