FEAT(client): Add ReNameNoise as a replacement for RNNoise

pull/6364/head
Hartmnt 2024-03-19 10:51:53 +00:00
parent cb14dd3294
commit 84f759d99d
15 changed files with 67 additions and 272 deletions

6
.gitmodules vendored
View File

@ -7,9 +7,6 @@
[submodule "3rdparty/speexdsp"]
path = 3rdparty/speexdsp
url = https://github.com/xiph/speexdsp.git
[submodule "3rdparty/rnnoise-src"]
path = 3rdparty/rnnoise-src
url = https://github.com/mumble-voip/rnnoise.git
[submodule "3rdparty/FindPythonInterpreter"]
path = 3rdparty/FindPythonInterpreter
url = https://github.com/Krzmbrzl/FindPythonInterpreter.git
@ -28,3 +25,6 @@
[submodule "3rdparty/cmake-compiler-flags"]
path = 3rdparty/cmake-compiler-flags
url = https://github.com/Krzmbrzl/cmake-compiler-flags.git
[submodule "3rdparty/renamenoise"]
path = 3rdparty/renamenoise
url = https://github.com/mumble-voip/ReNameNoise.git

1
3rdparty/renamenoise vendored Submodule

@ -0,0 +1 @@
Subproject commit 2a551ab1261a1d5a5123c34eb6f4d108367d5cb4

View File

@ -1,57 +0,0 @@
# Copyright 2005-2019 The Mumble Developers. All rights reserved.
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file at the root of the
# Mumble source tree or at <https://www.mumble.info/LICENSE>.
set(RNNOISE_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../rnnoise-src")
if(NOT EXISTS "${RNNOISE_SRC_DIR}/COPYING")
message(FATAL_ERROR
"${RNNOISE_SRC_DIR} was not found.\n"
"Please checkout the submodule:\n"
"git submodule update --init --recursive"
)
endif()
if(WIN32)
add_library(rnnoise SHARED)
set_target_properties(rnnoise PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
if(MINGW)
# Remove "lib" prefix.
set_target_properties(rnnoise PROPERTIES PREFIX "")
endif()
target_compile_definitions(rnnoise
PRIVATE
"WIN32"
"DLL_EXPORT"
)
else()
add_library(rnnoise STATIC)
endif()
target_compile_definitions(rnnoise PRIVATE "HAVE_CONFIG_H")
target_include_directories(rnnoise
PRIVATE SYSTEM
${CMAKE_CURRENT_SOURCE_DIR}
PUBLIC SYSTEM
"${RNNOISE_SRC_DIR}/include"
)
if(MSVC)
# Use malloc() and free() instead of variable length arrays (unsupported)
target_compile_definitions(rnnoise PRIVATE "USE_MALLOC")
# Define M_PI
target_compile_definitions(rnnoise PRIVATE "_USE_MATH_DEFINES")
endif()
target_sources(rnnoise PRIVATE
"${RNNOISE_SRC_DIR}/src/rnn_data.c"
"${RNNOISE_SRC_DIR}/src/rnn.c"
"${RNNOISE_SRC_DIR}/src/pitch.c"
"${RNNOISE_SRC_DIR}/src/kiss_fft.c"
"${RNNOISE_SRC_DIR}/src/denoise.c"
"${RNNOISE_SRC_DIR}/src/celt_lpc.c"
)
target_disable_warnings(rnnoise)

View File

@ -1,122 +0,0 @@
/* 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

@ -1 +0,0 @@
Subproject commit a9afcccb3c4f01e6e76a1ef67ccb58b7799856bf

View File

@ -44,10 +44,10 @@ Use the bundled GSL version instead of looking for one on the system
Build the included version of nlohmann_json instead of looking for one on the system
(Default: ON)
### bundled-rnnoise
### bundled-renamenoise
Build the included version of RNNoise instead of looking for one on the system.
(Default: ${rnnoise})
Build the included version of ReNameNoise instead of looking for one on the system.
(Default: ${renamenoise})
### bundled-speex
@ -189,16 +189,16 @@ Build support for custom Diffie-Hellman parameters.
Use Qt's text-to-speech system (part of the Qt Speech module) instead of Mumble's own OS-specific text-to-speech implementations.
(Default: OFF)
### renamenoise
Use ReNameNoise for machine learning noise reduction.
(Default: ON)
### retracted-plugins
Build redacted (outdated) plugins as well
(Default: OFF)
### rnnoise
Use RNNoise for machine learning noise reduction.
(Default: OFF)
### server
Build the server (Murmur)

View File

@ -18,7 +18,6 @@ using WixSharp.CommonTasks;
public struct Features {
public bool overlay;
public bool g15;
public bool rnnoise;
}
public class ClientInstaller : MumbleInstall {
@ -87,14 +86,11 @@ public class ClientInstaller : MumbleInstall {
// 64 bit
this.Platform = WixSharp.Platform.x64;
binaries = new List<string>() {
"renamenoise.dll",
"speexdsp.dll",
"mumble.exe",
};
if (features.rnnoise) {
binaries.Add("rnnoise.dll");
}
if (features.overlay) {
binaries.Add("mumble_ol.dll");
binaries.Add("mumble_ol_helper.exe");
@ -109,14 +105,11 @@ public class ClientInstaller : MumbleInstall {
// 32 bit
this.Platform = WixSharp.Platform.x86;
binaries = new List<string>() {
"renamenoise.dll",
"speexdsp.dll",
"mumble.exe",
};
if (features.rnnoise) {
binaries.Add("rnnoise.dll");
}
if (features.overlay) {
binaries.Add("mumble_ol.dll");
binaries.Add("mumble_ol_helper.exe");
@ -221,10 +214,6 @@ class BuildInstaller
if (args[i] == "--overlay") {
features.overlay = true;
}
if (args[i] == "--rnnoise") {
features.rnnoise = true;
}
}
if (version != null && arch != null) {

View File

@ -76,9 +76,9 @@ AudioInputDialog::AudioInputDialog(Settings &st) : ConfigWidget(st) {
// Hide the slider by default
showSpeexNoiseSuppressionSlider(false);
#ifndef USE_RNNOISE
// Hide options related to RNNoise
qrbNoiseSupRNNoise->setVisible(false);
#ifndef USE_RENAMENOISE
// Hide options related to ReNameNoise
qrbNoiseSupReNameNoise->setVisible(false);
qrbNoiseSupBoth->setVisible(false);
#endif
}
@ -143,12 +143,12 @@ void AudioInputDialog::load(const Settings &r) {
loadSlider(qsSpeexNoiseSupStrength, 14);
}
bool allowRNNoise = SAMPLE_RATE == 48000;
bool allowReNameNoise = SAMPLE_RATE == 48000;
if (!allowRNNoise) {
if (!allowReNameNoise) {
const QString tooltip = QObject::tr("RNNoise is not available due to a sample rate mismatch.");
qrbNoiseSupRNNoise->setEnabled(false);
qrbNoiseSupRNNoise->setToolTip(tooltip);
qrbNoiseSupReNameNoise->setEnabled(false);
qrbNoiseSupReNameNoise->setToolTip(tooltip);
qrbNoiseSupBoth->setEnabled(false);
qrbNoiseSupBoth->setToolTip(tooltip);
}
@ -161,9 +161,9 @@ void AudioInputDialog::load(const Settings &r) {
loadCheckBox(qrbNoiseSupSpeex, true);
break;
case Settings::NoiseCancelRNN:
#ifdef USE_RNNOISE
if (allowRNNoise) {
loadCheckBox(qrbNoiseSupRNNoise, true);
#ifdef USE_RENAMENOISE
if (allowReNameNoise) {
loadCheckBox(qrbNoiseSupReNameNoise, true);
} else {
// We have to switch to speex as a fallback
loadCheckBox(qrbNoiseSupSpeex, true);
@ -174,8 +174,8 @@ void AudioInputDialog::load(const Settings &r) {
#endif
break;
case Settings::NoiseCancelBoth:
#ifdef USE_RNNOISE
if (allowRNNoise) {
#ifdef USE_RENAMENOISE
if (allowReNameNoise) {
loadCheckBox(qrbNoiseSupBoth, true);
} else {
// We have to switch to speex as a fallback
@ -233,7 +233,7 @@ void AudioInputDialog::save() const {
s.noiseCancelMode = Settings::NoiseCancelOff;
} else if (qrbNoiseSupBoth->isChecked()) {
s.noiseCancelMode = Settings::NoiseCancelBoth;
} else if (qrbNoiseSupRNNoise->isChecked()) {
} else if (qrbNoiseSupReNameNoise->isChecked()) {
s.noiseCancelMode = Settings::NoiseCancelRNN;
} else {
s.noiseCancelMode = Settings::NoiseCancelSpeex;

View File

@ -20,9 +20,9 @@
#include <opus.h>
#ifdef USE_RNNOISE
#ifdef USE_RENAMENOISE
extern "C" {
# include "rnnoise.h"
# include "renamenoise.h"
}
#endif
@ -31,14 +31,6 @@ extern "C" {
#include <exception>
#include <limits>
#ifdef USE_RNNOISE
/// Clip the given float value to a range that can be safely converted into a short (without causing integer overflow)
static short clampFloatSample(float v) {
return static_cast< short >(std::min(std::max(v, static_cast< float >(std::numeric_limits< short >::min())),
static_cast< float >(std::numeric_limits< short >::max())));
}
#endif
void Resynchronizer::addMic(short *mic) {
bool drop = false;
{
@ -245,8 +237,8 @@ AudioInput::AudioInput()
opus_encoder_ctl(opusState, OPUS_SET_VBR(0)); // CBR
#ifdef USE_RNNOISE
denoiseState = rnnoise_create(nullptr);
#ifdef USE_RENAMENOISE
denoiseState = renamenoise_create(nullptr);
#endif
qWarning("AudioInput: %d bits/s, %d hz, %d sample", iAudioQuality, iSampleRate, iFrameSize);
@ -298,9 +290,9 @@ AudioInput::~AudioInput() {
opus_encoder_destroy(opusState);
}
#ifdef USE_RNNOISE
#ifdef USE_RENAMENOISE
if (denoiseState) {
rnnoise_destroy(denoiseState);
renamenoise_destroy(denoiseState);
}
#endif
@ -816,13 +808,13 @@ void AudioInput::selectNoiseCancel() {
noiseCancel = Global::get().s.noiseCancelMode;
if (noiseCancel == Settings::NoiseCancelRNN || noiseCancel == Settings::NoiseCancelBoth) {
#ifdef USE_RNNOISE
#ifdef USE_RENAMENOISE
if (!denoiseState || iFrameSize != 480) {
qWarning("AudioInput: Ignoring request to enable RNNoise: internal error");
qWarning("AudioInput: Ignoring request to enable ReNameNoise: internal error");
noiseCancel = Settings::NoiseCancelSpeex;
}
#else
qWarning("AudioInput: Ignoring request to enable RNNoise: Mumble was built without support for it");
qWarning("AudioInput: Ignoring request to enable ReNameNoise: Mumble was built without support for it");
noiseCancel = Settings::NoiseCancelSpeex;
#endif
}
@ -837,11 +829,11 @@ void AudioInput::selectNoiseCancel() {
iArg = 1;
break;
case Settings::NoiseCancelRNN:
qWarning("AudioInput: Using RNNoise as noise canceller");
qWarning("AudioInput: Using ReNameNoise as noise canceller");
break;
case Settings::NoiseCancelBoth:
iArg = 1;
qWarning("AudioInput: Using RNNoise and Speex as noise canceller");
qWarning("AudioInput: Using ReNameNoise and Speex as noise canceller");
break;
}
speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_DENOISE, &iArg);
@ -918,19 +910,15 @@ void AudioInput::encodeAudioFrame(AudioChunk chunk) {
psSource = chunk.mic;
}
#ifdef USE_RNNOISE
// At the time of writing this code, RNNoise only supports a sample rate of 48000 Hz.
#ifdef USE_RENAMENOISE
// At the time of writing this code, ReNameNoise only supports a sample rate of 48000 Hz.
if (noiseCancel == Settings::NoiseCancelRNN || noiseCancel == Settings::NoiseCancelBoth) {
float denoiseFrames[480];
for (unsigned int i = 0; i < 480; i++) {
denoiseFrames[i] = psSource[i];
}
rnnoise_process_frame(denoiseState, denoiseFrames, denoiseFrames);
for (unsigned int i = 0; i < 480; i++) {
psSource[i] = clampFloatSample(denoiseFrames[i]);
}
renamenoise_process_frame_clamped(denoiseState, psSource, denoiseFrames);
}
#endif

View File

@ -33,7 +33,7 @@
class AudioInput;
struct OpusEncoder;
struct DenoiseState;
struct ReNameNoiseDenoiseState;
typedef boost::shared_ptr< AudioInput > AudioInputPtr;
/**
@ -189,7 +189,9 @@ private:
void resetAudioProcessor();
OpusEncoder *opusState;
DenoiseState *denoiseState;
#ifdef USE_RENAMENOISE
ReNameNoiseDenoiseState *denoiseState;
#endif
bool selectCodec();
void selectNoiseCancel();

View File

@ -749,7 +749,7 @@
</widget>
</item>
<item>
<widget class="QRadioButton" name="qrbNoiseSupRNNoise">
<widget class="QRadioButton" name="qrbNoiseSupReNameNoise">
<property name="toolTip">
<string>Use the noise suppression algorithm provided by RNNoise.</string>
</property>

View File

@ -21,8 +21,8 @@ option(translations "Include languages other than English." ON)
option(bundle-qt-translations "Bundle Qt's translations as well" ${static})
option(bundled-speex "Build the included version of Speex instead of looking for one on the system." ON)
option(rnnoise "Use RNNoise for machine learning noise reduction." OFF)
option(bundled-rnnoise "Build the included version of RNNoise instead of looking for one on the system." ${rnnoise})
option(renamenoise "Use ReNameNoise for machine learning noise reduction." ON)
option(bundled-renamenoise "Build the included version of ReNameNoise instead of looking for one on the system." ${renamenoise})
option(bundled-json "Build the included version of nlohmann_json instead of looking for one on the system" ON)
option(manual-plugin "Include the built-in \"manual\" positional audio plugin." ON)
@ -738,31 +738,32 @@ else()
)
endif()
if(rnnoise)
message(WARNING "Using RNNoise is discouraged and can lead to unforeseen behavior, including crashes at runtime due to the RNNoise library exposing Opus/CELT symbols")
target_compile_definitions(mumble_client_object_lib PRIVATE "USE_RNNOISE")
if(renamenoise)
target_compile_definitions(mumble_client_object_lib PRIVATE "USE_RENAMENOISE")
if(bundled-rnnoise)
add_subdirectory("${3RDPARTY_DIR}/rnnoise-build" "${CMAKE_CURRENT_BINARY_DIR}/rnnoise" EXCLUDE_FROM_ALL)
if(bundled-renamenoise)
set(RENAMENOISE_DEMO_EXECUTABLE OFF CACHE INTERNAL "")
# Disable all warnings that the RNNoise code may emit
disable_warnings_for_all_targets_in("${3RDPARTY_DIR}/rnnoise-build")
add_subdirectory("${3RDPARTY_DIR}/renamenoise" "${CMAKE_CURRENT_BINARY_DIR}/renamenoise" EXCLUDE_FROM_ALL)
target_link_libraries(mumble_client_object_lib PRIVATE rnnoise)
# Disable all warnings that the ReNameNoise code may emit
disable_warnings_for_all_targets_in("${3RDPARTY_DIR}/renamenoise")
target_link_libraries(mumble_client_object_lib PRIVATE renamenoise)
if(WIN32)
# Shared library on Windows (e.g. ".dll")
set_target_properties(rnnoise PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set_target_properties(renamenoise PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
else()
# Shared library on UNIX (e.g. ".so")
set_target_properties(rnnoise PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set_target_properties(renamenoise PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
endif()
install_library(rnnoise mumble_client)
install_library(renamenoise mumble_client)
else()
find_pkg(rnnoise REQUIRED)
find_pkg(renamenoise REQUIRED)
target_link_libraries(mumble_client_object_lib PRIVATE ${rnnoise_LIBRARIES})
target_link_libraries(mumble_client_object_lib PRIVATE ${renamenoise_LIBRARIES})
endif()
endif()
@ -1179,12 +1180,6 @@ if(packaging AND WIN32)
)
endif()
if(rnnoise)
list(APPEND installer_vars
"--rnnoise"
)
endif()
file(COPY
${CMAKE_SOURCE_DIR}/installer/MumbleInstall.cs
${CMAKE_SOURCE_DIR}/installer/ClientInstaller.cs

View File

@ -217,9 +217,9 @@ void from_json(const nlohmann::json &j, Settings &settings) {
settings.mumbleQuitNormally = json.at(SettingsKeys::MUMBLE_QUIT_NORMALLY_KEY);
}
#ifndef USE_RNNOISE
#ifndef USE_RENAMENOISE
if (settings.noiseCancelMode == Settings::NoiseCancelRNN || settings.noiseCancelMode == Settings::NoiseCancelBoth) {
// Use Speex instead as this Mumble build was built without support for RNNoise
// Use Speex instead as this Mumble build was built without support for ReNameNoise
settings.noiseCancelMode = Settings::NoiseCancelSpeex;
}
#endif

View File

@ -816,9 +816,9 @@ void Settings::legacyLoad(const QString &path) {
LOADENUM(noiseCancelMode, "audio/noiseCancelMode");
#ifndef USE_RNNOISE
#ifndef USE_RENAMENOISE
if (noiseCancelMode == NoiseCancelRNN || noiseCancelMode == NoiseCancelBoth) {
// Use Speex instead as this Mumble build was built without support for RNNoise
// Use Speex instead as this Mumble build was built without support for ReNameNoise
noiseCancelMode = NoiseCancelSpeex;
}
#endif

View File

@ -139,7 +139,7 @@ def getDefaultValueForType(dataType):
elif dataType in ["IdleAction"]:
return "Settings::Deafen"
elif dataType in ["NoiseCancel"]:
return "Settings::NoiseCancelOff"
return "Settings::NoiseCancelBoth"
elif dataType in ["EchoCancelOptionID"]:
return "EchoCancelOptionID::SPEEX_MULTICHANNEL"
elif dataType in ["QuitBehavior"]: