Skip to content

Commit

Permalink
Merge PR #3427: RNNoise
Browse files Browse the repository at this point in the history
  • Loading branch information
davidebeatrici committed Jul 7, 2018
2 parents 42b43ee + 854d0b2 commit e54f60f
Show file tree
Hide file tree
Showing 14 changed files with 303 additions and 5 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Expand Up @@ -22,6 +22,9 @@
[submodule "3rdparty/speexdsp-src"]
path = 3rdparty/speexdsp-src
url = https://github.com/mumble-voip/speexdsp.git
[submodule "3rdparty/rnnoise-src"]
path = 3rdparty/rnnoise-src
url = https://github.com/mumble-voip/rnnoise.git
[submodule "themes/Mumble"]
path = themes/Mumble
url = https://github.com/mumble-voip/mumble-theme.git
122 changes: 122 additions & 0 deletions 3rdparty/rnnoise-build/config.h
@@ -0,0 +1,122 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */

/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1

/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1

/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1

/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1

/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1

/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1

/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1

/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1

/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1

/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1

/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"

/* Enable assertions in code */
/* #undef OP_ENABLE_ASSERTIONS */

/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "jmvalin@jmvalin.ca"

/* Define to the full name of this package. */
#define PACKAGE_NAME "rnnoise"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "rnnoise unknown"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "rnnoise"

/* Define to the home page for this package. */
#define PACKAGE_URL ""

/* Define to the version of this package. */
#define PACKAGE_VERSION "unknown"

/* This is a build of the library */
#define RNNOISE_BUILD /**/

/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1

/* Define this if the compiler supports __attribute__((
ifelse([visibility("default")], , [visibility_default],
[visibility("default")]) )) */
#define SUPPORT_ATTRIBUTE_VISIBILITY_DEFAULT 1

/* Define this if the compiler supports the -fvisibility flag */
#define SUPPORT_FLAG_VISIBILITY 1

/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# define _ALL_SOURCE 1
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# define _POSIX_PTHREAD_SEMANTICS 1
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# define _TANDEM_SOURCE 1
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# define __EXTENSIONS__ 1
#endif


/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif

/* Number of bits in a file offset, on hosts where this is settable. */
/* #undef _FILE_OFFSET_BITS */

/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */

/* Define to 1 if on MINIX. */
/* #undef _MINIX */

/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
/* #undef _POSIX_1_SOURCE */

/* Define to 1 if you need to in order for `stat' and other things to work. */
/* #undef _POSIX_SOURCE */

/* We need at least WindowsXP for getaddrinfo/freeaddrinfo */
/* #undef _WIN32_WINNT */

/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif
63 changes: 63 additions & 0 deletions 3rdparty/rnnoise-build/rnnoise-build.pro
@@ -0,0 +1,63 @@
include(../../qmake/compiler.pri)

BUILDDIR=$$basename(PWD)
SOURCEDIR=$$replace(BUILDDIR,-build,-src)

!win32 {
VERSION=0 #$$ Fool packaging script
}

!exists(../$$SOURCEDIR/COPYING) {
message("The $$SOURCEDIR/ directory was not found. Please update your submodules (git submodule update --init).")
error("Aborting configuration")
}

TEMPLATE = lib
CONFIG -= qt
CONFIG += debug_and_release
VPATH = ../$$SOURCEDIR
TARGET = rnnoise
DEFINES += HAVE_CONFIG_H

!CONFIG(third-party-warnings) {
# We ignore warnings in third party builds. We won't actually look
# at them and they clutter out our warnings.
CONFIG -= warn_on
CONFIG += warn_off
}

QMAKE_CFLAGS -= -fPIE -pie

win32 {
DEFINES += WIN32 _WIN32
DEFINES += DLL_EXPORT

CONFIG -= static
CONFIG += shared
}

win32-msvc* {
DEFINES += _USE_MATH_DEFINES # To define M_PI
DEFINES += USE_MALLOC # To use malloc() and free() instead of variable length arrays
}

unix {
CONFIG += staticlib

contains(QMAKE_CFLAGS, -ffast-math) {
DEFINES += FLOAT_APPROX
}
}

INCLUDEPATH *= \
../$$SOURCEDIR/include \

SOURCES *= \
src/rnn_data.c \
src/rnn.c \
src/pitch.c \
src/kiss_fft.c \
src/denoise.c \
src/celt_lpc.c

include(../../qmake/symbols.pri)
1 change: 1 addition & 0 deletions 3rdparty/rnnoise-src
Submodule rnnoise-src added at b30f2b
6 changes: 6 additions & 0 deletions INSTALL
Expand Up @@ -72,6 +72,12 @@ CONFIG+=no-opus (Mumble)
CONFIG+=no-bundled-opus (Mumble)
Don't use the included version of Opus, but look for one on the system.

CONFIG+=no-rnnoise (Mumble)
Don't build RNNoise support at all.

CONFIG+=no-bundled-rnnoise (Mumble)
Don't use the included version of RNNoise, but look for one on the system.

CONFIG+=sbcelt (Mumble, Linux, OSX, FreeBSD)
Use the SBCELT library for decoding CELT frames. Enabling this option will
build Mumble in a mode that forces all CELT frames to be decoded in a
Expand Down
8 changes: 8 additions & 0 deletions main.pro
Expand Up @@ -37,6 +37,14 @@ SUBDIRS *= src/mumble_proto
SUBDIRS *= 3rdparty/opus-build
}

!CONFIG(no-rnnoise) {
CONFIG *= rnnoise
}

CONFIG(rnnoise):!CONFIG(no-bundled-rnnoise) {
SUBDIRS *= 3rdparty/rnnoise-build
}

win32 {
SUBDIRS *= 3rdparty/xinputcheck-build
}
Expand Down
8 changes: 8 additions & 0 deletions src/mumble/AudioConfigDialog.cpp
Expand Up @@ -137,6 +137,13 @@ void AudioInputDialog::load(const Settings &r) {
loadSlider(qsNoise, - r.iNoiseSuppress);
else
loadSlider(qsNoise, 14);
loadCheckBox(qcbDenoise, r.bDenoise);

#ifdef USE_RNNOISE
qcbDenoise->setEnabled(SAMPLE_RATE == 48000);
#else
qcbDenoise->setVisible(false);
#endif

loadSlider(qsAmp, 20000 - r.iMinLoudness);

Expand All @@ -155,6 +162,7 @@ void AudioInputDialog::load(const Settings &r) {
void AudioInputDialog::save() const {
s.iQuality = qsQuality->value();
s.iNoiseSuppress = (qsNoise->value() == 14) ? 0 : - qsNoise->value();
s.bDenoise = qcbDenoise->isChecked();
s.iMinLoudness = 18000 - qsAmp->value() + 2000;
s.iVoiceHold = qsTransmitHold->value();
s.fVADmin = static_cast<float>(qsTransmitMin->value()) / 32767.0f;
Expand Down
31 changes: 31 additions & 0 deletions src/mumble/AudioInput.cpp
Expand Up @@ -20,6 +20,12 @@
#include "NetworkConfig.h"
#include "VoiceRecorder.h"

#ifdef USE_RNNOISE
extern "C" {
#include "rnnoise.h"
}
#endif

// Remember that we cannot use static member classes that are not pointers, as the constructor
// for AudioInputRegistrar() might be called before they are initialized, as the constructor
// is called from global initialization.
Expand Down Expand Up @@ -97,6 +103,10 @@ AudioInput::AudioInput() : opusBuffer(g.s.iFramesPerPacket * (SAMPLE_RATE / 100)
}
#endif

#ifdef USE_RNNOISE
denoiseState = rnnoise_create();
#endif

qWarning("AudioInput: %d bits/s, %d hz, %d sample", iAudioQuality, iSampleRate, iFrameSize);
iEchoFreq = iMicFreq = iSampleRate;

Expand Down Expand Up @@ -154,6 +164,11 @@ AudioInput::~AudioInput() {
}
#endif

#ifdef USE_RNNOISE
if (denoiseState)
rnnoise_destroy(denoiseState);
#endif

if (ceEncoder) {
cCodec->celt_encoder_destroy(ceEncoder);
}
Expand Down Expand Up @@ -810,6 +825,22 @@ void AudioInput::encodeAudioFrame() {
psSource = psMic;
}

#ifdef USE_RNNOISE
// At the time of writing this code, RNNoise only supports a sample rate of 48000 Hz.
if (g.s.bDenoise && (iFrameSize == 480)) {
float denoiseFrames[480];
for (int i = 0; i < 480; i++) {
denoiseFrames[i] = psSource[i];
}

rnnoise_process_frame(denoiseState, denoiseFrames, denoiseFrames);

for (int i = 0; i < 480; i++) {
psSource[i] = denoiseFrames[i];
}
}
#endif

sum=1.0f;
for (i=0;i<iFrameSize;i++)
sum += static_cast<float>(psSource[i] * psSource[i]);
Expand Down
2 changes: 2 additions & 0 deletions src/mumble/AudioInput.h
Expand Up @@ -26,6 +26,7 @@ class CELTCodec;
class OpusCodec;
struct CELTEncoder;
struct OpusEncoder;
struct DenoiseState;
typedef boost::shared_ptr<AudioInput> AudioInputPtr;

class AudioInputRegistrar {
Expand Down Expand Up @@ -75,6 +76,7 @@ class AudioInput : public QThread {

OpusCodec *oCodec;
OpusEncoder *opusState;
DenoiseState *denoiseState;
bool selectCodec();

typedef boost::array<unsigned char, 960> EncodingOutputBuffer;
Expand Down
24 changes: 22 additions & 2 deletions src/mumble/AudioInput.ui
Expand Up @@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>569</width>
<height>730</height>
<height>764</height>
</rect>
</property>
<property name="windowTitle">
Expand Down Expand Up @@ -87,7 +87,7 @@
<string>&lt;b&gt;This is the input device to use for audio.&lt;/b&gt;</string>
</property>
<property name="sizeAdjustPolicy">
<enum>MUComboBox::AdjustToMinimumContentsLength</enum>
<enum>QComboBox::AdjustToContents</enum>
</property>
<property name="minimumContentsLength">
<number>16</number>
Expand Down Expand Up @@ -677,6 +677,25 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="qcbDenoise">
<property name="minimumSize">
<size>
<width>0</width>
<height>27</height>
</size>
</property>
<property name="toolTip">
<string>Apply RNNoise's noise suppression filter.</string>
</property>
<property name="whatsThis">
<string>&lt;b&gt;This applies RNNoise's noise suppression filter.&lt;/b&gt;&lt;br /&gt;RNNoise is based on machine learning and used in WebRTC.</string>
</property>
<property name="text">
<string>RNNoise</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down Expand Up @@ -909,6 +928,7 @@
<tabstop>qsQuality</tabstop>
<tabstop>qsFrames</tabstop>
<tabstop>qsNoise</tabstop>
<tabstop>qcbDenoise</tabstop>
<tabstop>qsAmp</tabstop>
</tabstops>
<resources/>
Expand Down
3 changes: 3 additions & 0 deletions src/mumble/Settings.cpp
Expand Up @@ -240,6 +240,7 @@ Settings::Settings() {
iJitterBufferSize = 1;
iFramesPerPacket = 2;
iNoiseSuppress = -30;
bDenoise = false;
uiAudioInputChannelMask = 0xffffffffffffffffULL;

// Idle auto actions
Expand Down Expand Up @@ -614,6 +615,7 @@ void Settings::load(QSettings* settings_ptr) {
SAVELOAD(fVADmin, "audio/vadmin");
SAVELOAD(fVADmax, "audio/vadmax");
SAVELOAD(iNoiseSuppress, "audio/noisesupress");
SAVELOAD(bDenoise, "audio/denoise");
SAVELOAD(uiAudioInputChannelMask, "audio/inputchannelmask");
SAVELOAD(iVoiceHold, "audio/voicehold");
SAVELOAD(iOutputDelay, "audio/outputdelay");
Expand Down Expand Up @@ -954,6 +956,7 @@ void Settings::save() {
SAVELOAD(fVADmin, "audio/vadmin");
SAVELOAD(fVADmax, "audio/vadmax");
SAVELOAD(iNoiseSuppress, "audio/noisesupress");
SAVELOAD(bDenoise, "audio/denoise");
SAVELOAD(uiAudioInputChannelMask, "audio/inputchannelmask");
SAVELOAD(iVoiceHold, "audio/voicehold");
SAVELOAD(iOutputDelay, "audio/outputdelay");
Expand Down

0 comments on commit e54f60f

Please sign in to comment.