mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'eid-rnnoise' into 'master'
Add rnnoise denoiser See merge request kart-krew-dev/ring-racers-internal!2861
This commit is contained in:
commit
6eae1715a0
31 changed files with 7219 additions and 17 deletions
|
|
@ -20,6 +20,14 @@
|
|||
- libvorbis + libvorbisenc
|
||||
Copyright (c) 2002-2020 Xiph.org Foundation
|
||||
https://github.com/xiph/vorbis
|
||||
- ReNameNoise + rnnoise
|
||||
Copyright (c) 2024 The Mumble Developers
|
||||
Copyright (c) 2017 Mozilla
|
||||
Copyright (c) 2007-2017 Jean-Marc Valin
|
||||
Copyright (c) 2005-2017 Xiph.Org Foundation
|
||||
Copyright (c) 2003-2004 Mark Borgerding
|
||||
https://github.com/mumble-voip/ReNameNoise
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
|||
|
|
@ -279,6 +279,7 @@ target_link_libraries(SRB2SDL2 PRIVATE ZLIB::ZLIB)
|
|||
target_link_libraries(SRB2SDL2 PRIVATE PNG::PNG)
|
||||
target_link_libraries(SRB2SDL2 PRIVATE CURL::libcurl)
|
||||
target_link_libraries(SRB2SDL2 PRIVATE Opus::opus)
|
||||
target_link_libraries(SRB2SDL2 PRIVATE ReNameNoise::renamenoise)
|
||||
if("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD")
|
||||
target_link_libraries(SRB2SDL2 PRIVATE -lexecinfo)
|
||||
target_link_libraries(SRB2SDL2 PRIVATE -lpthread)
|
||||
|
|
|
|||
|
|
@ -1410,6 +1410,10 @@ consvar_t cv_voice_loopback = Player("voice_loopback", "Off")
|
|||
.dont_save()
|
||||
.description("When on, plays the local player's voice");
|
||||
|
||||
consvar_t cv_voice_denoise = Player("voice_denoise", "On")
|
||||
.on_off()
|
||||
.description("When on, denoises the voice microphone signal");
|
||||
|
||||
consvar_t cv_voice_proximity = NetVar("voice_proximity", "On")
|
||||
.on_off()
|
||||
.description("Whether proximity effects for voice chat are enabled on the server.");
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#endif
|
||||
|
||||
#include <opus.h>
|
||||
#include <renamenoise.h>
|
||||
|
||||
#include "i_time.h"
|
||||
#include "i_net.h"
|
||||
|
|
@ -203,6 +204,7 @@ static UINT64 g_player_opus_lastframe[MAXPLAYERS];
|
|||
static UINT32 g_player_voice_frames_this_tic[MAXPLAYERS];
|
||||
#define MAX_PLAYER_VOICE_FRAMES_PER_TIC 3
|
||||
static OpusEncoder *g_local_opus_encoder;
|
||||
static ReNameNoiseDenoiseState *g_local_renamenoise_state;
|
||||
static UINT64 g_local_opus_frame = 0;
|
||||
#define SRB2_VOICE_OPUS_FRAME_SIZE 960
|
||||
static float g_local_voice_buffer[SRB2_VOICE_OPUS_FRAME_SIZE];
|
||||
|
|
@ -2573,6 +2575,25 @@ static void Command_connect(void)
|
|||
|
||||
static void ResetNode(INT32 node);
|
||||
|
||||
static void RecreatePlayerOpusDecoder(INT32 playernum)
|
||||
{
|
||||
// Destroy and recreate the opus decoder for this playernum
|
||||
OpusDecoder *opusdecoder = g_player_opus_decoders[playernum];
|
||||
if (opusdecoder)
|
||||
{
|
||||
opus_decoder_destroy(opusdecoder);
|
||||
opusdecoder = NULL;
|
||||
}
|
||||
int error;
|
||||
opusdecoder = opus_decoder_create(48000, 1, &error);
|
||||
if (error != OPUS_OK)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Failed to create Opus decoder for player %d: opus error %d\n", playernum, error);
|
||||
opusdecoder = NULL;
|
||||
}
|
||||
g_player_opus_decoders[playernum] = opusdecoder;
|
||||
}
|
||||
|
||||
//
|
||||
// CL_ClearPlayer
|
||||
//
|
||||
|
|
@ -2648,23 +2669,7 @@ void CL_ClearPlayer(INT32 playernum)
|
|||
// Clear voice chat data
|
||||
S_ResetVoiceQueue(playernum);
|
||||
|
||||
{
|
||||
// Destroy and recreate the opus decoder for this playernum
|
||||
OpusDecoder *opusdecoder = g_player_opus_decoders[playernum];
|
||||
if (opusdecoder)
|
||||
{
|
||||
opus_decoder_destroy(opusdecoder);
|
||||
opusdecoder = NULL;
|
||||
}
|
||||
int error;
|
||||
opusdecoder = opus_decoder_create(48000, 1, &error);
|
||||
if (error != OPUS_OK)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Failed to create Opus decoder for player %d: opus error %d\n", playernum, error);
|
||||
opusdecoder = NULL;
|
||||
}
|
||||
g_player_opus_decoders[playernum] = opusdecoder;
|
||||
}
|
||||
RecreatePlayerOpusDecoder(playernum);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -3709,6 +3714,17 @@ void D_QuitNetGame(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void InitializeLocalVoiceDenoiser(void)
|
||||
{
|
||||
if (g_local_renamenoise_state != NULL)
|
||||
{
|
||||
renamenoise_destroy(g_local_renamenoise_state);
|
||||
g_local_renamenoise_state = NULL;
|
||||
}
|
||||
|
||||
g_local_renamenoise_state = renamenoise_create(NULL);
|
||||
}
|
||||
|
||||
static void InitializeLocalVoiceEncoder(void)
|
||||
{
|
||||
// Reset voice opus encoder for local "player 1"
|
||||
|
|
@ -3815,6 +3831,7 @@ static void Got_AddPlayer(const UINT8 **p, INT32 playernum)
|
|||
}
|
||||
DEBFILE("spawning me\n");
|
||||
|
||||
InitializeLocalVoiceDenoiser();
|
||||
InitializeLocalVoiceEncoder();
|
||||
}
|
||||
|
||||
|
|
@ -7592,6 +7609,28 @@ void NetVoiceUpdate(void)
|
|||
g_local_voice_buffer[i] *= ampfactor;
|
||||
}
|
||||
|
||||
if (cv_voice_denoise.value)
|
||||
{
|
||||
if (g_local_renamenoise_state == NULL)
|
||||
{
|
||||
InitializeLocalVoiceDenoiser();
|
||||
}
|
||||
int rnnoise_size = renamenoise_get_frame_size();
|
||||
float *subframe_buffer = (float*) Z_Malloc(rnnoise_size * sizeof(float), PU_STATIC, NULL);
|
||||
float *denoise_buffer = (float*) Z_Malloc(rnnoise_size * sizeof(float), PU_STATIC, NULL);
|
||||
|
||||
// rnnoise frames are smaller than opus, but we should not expect the opus frame to be an exact multiple of rnnoise
|
||||
for (int denoise_position = 0; denoise_position < SRB2_VOICE_OPUS_FRAME_SIZE; denoise_position += rnnoise_size)
|
||||
{
|
||||
memset(subframe_buffer, 0, rnnoise_size * sizeof(float));
|
||||
memcpy(subframe_buffer, g_local_voice_buffer + denoise_position, min(rnnoise_size * sizeof(float), (SRB2_VOICE_OPUS_FRAME_SIZE - denoise_position) * sizeof(float)));
|
||||
renamenoise_process_frame(g_local_renamenoise_state, denoise_buffer, subframe_buffer);
|
||||
memcpy(g_local_voice_buffer + denoise_position, denoise_buffer, min(rnnoise_size * sizeof(float), (SRB2_VOICE_OPUS_FRAME_SIZE - denoise_position) * sizeof(float)));
|
||||
}
|
||||
Z_Free(denoise_buffer);
|
||||
Z_Free(subframe_buffer);
|
||||
}
|
||||
|
||||
float softmem = 0.f;
|
||||
opus_pcm_soft_clip(g_local_voice_buffer, SRB2_VOICE_OPUS_FRAME_SIZE, 1, &softmem);
|
||||
|
||||
|
|
@ -7670,6 +7709,10 @@ void NetVoiceUpdate(void)
|
|||
|
||||
if (cv_voice_loopback.value)
|
||||
{
|
||||
if (g_player_opus_decoders[consoleplayer] == NULL && !netgame)
|
||||
{
|
||||
RecreatePlayerOpusDecoder(consoleplayer);
|
||||
}
|
||||
result = opus_decode_float(g_player_opus_decoders[consoleplayer], encoded, result, g_local_voice_buffer, SRB2_VOICE_OPUS_FRAME_SIZE, 0);
|
||||
S_QueueVoiceFrameFromPlayer(consoleplayer, g_local_voice_buffer, result * sizeof(float), false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ menuitem_t OPTIONS_Voice[] =
|
|||
{IT_STRING | IT_CVAR, "Input Amplifier", "Amplify your voice, in decibels. Negative values are quieter.",
|
||||
NULL, {.cvar = &cv_voice_inputamp}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR, "Input Noise Suppression", "Suppress background noise from your voice.",
|
||||
NULL, {.cvar = &cv_voice_denoise}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR, "Input Sensitivity", "Voice higher than this threshold will transmit, in decibels.",
|
||||
NULL, {.cvar = &cv_voice_activationthreshold}, 0, 0},
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ extern consvar_t cv_voice_selfdeafen;
|
|||
extern consvar_t cv_voice_mode;
|
||||
extern consvar_t cv_voice_selfmute;
|
||||
extern consvar_t cv_voice_loopback;
|
||||
extern consvar_t cv_voice_denoise;
|
||||
extern consvar_t cv_voice_inputamp;
|
||||
extern consvar_t cv_voice_activationthreshold;
|
||||
extern consvar_t cv_voice_proximity;
|
||||
|
|
|
|||
2
thirdparty/CMakeLists.txt
vendored
2
thirdparty/CMakeLists.txt
vendored
|
|
@ -19,3 +19,5 @@ add_subdirectory(fmt)
|
|||
add_subdirectory(vulkan-headers)
|
||||
add_subdirectory(volk)
|
||||
add_subdirectory(vma)
|
||||
|
||||
add_subdirectory(renamenoise)
|
||||
|
|
|
|||
1
thirdparty/renamenoise/AUTHORS
vendored
Normal file
1
thirdparty/renamenoise/AUTHORS
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
Jean-Marc Valin <jmvalin@jmvalin.ca>
|
||||
17
thirdparty/renamenoise/CMakeLists.txt
vendored
Normal file
17
thirdparty/renamenoise/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# Update from https://github.com/mumble-voip/ReNameNoise
|
||||
# ReNameNoise unversioned
|
||||
# License: BSD-3
|
||||
|
||||
add_library(renamenoise STATIC)
|
||||
target_sources(renamenoise PRIVATE
|
||||
"src/rnn_data.c"
|
||||
"src/rnn.c"
|
||||
"src/pitch.c"
|
||||
"src/renamenoise_fft.c"
|
||||
"src/denoise.c"
|
||||
"src/renamenoise_lpc.c"
|
||||
)
|
||||
target_include_directories(renamenoise PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
target_compile_definitions(renamenoise PRIVATE "RENAMENOISE_BUILD")
|
||||
target_compile_definitions(renamenoise PRIVATE "ENABLE_ASSERTIONS")
|
||||
add_library(ReNameNoise::renamenoise ALIAS renamenoise)
|
||||
32
thirdparty/renamenoise/COPYING
vendored
Normal file
32
thirdparty/renamenoise/COPYING
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
Copyright (c) 2024, The Mumble Developers
|
||||
Copyright (c) 2017, Mozilla
|
||||
Copyright (c) 2007-2017, Jean-Marc Valin
|
||||
Copyright (c) 2005-2017, Xiph.Org Foundation
|
||||
Copyright (c) 2003-2004, Mark Borgerding
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.Org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
67
thirdparty/renamenoise/README.md
vendored
Normal file
67
thirdparty/renamenoise/README.md
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
# ReNameNoise
|
||||
|
||||
ReNameNoise - a fork of [RNNoise](https://gitlab.xiph.org/xiph/rnnoise) - is a noise suppression library based on a recurrent neural network.
|
||||
|
||||
A description of the algorithm is provided in the following paper:
|
||||
|
||||
```
|
||||
J.-M. Valin, A Hybrid DSP/Deep Learning Approach to Real-Time Full-Band Speech
|
||||
Enhancement, Proceedings of IEEE Multimedia Signal Processing (MMSP) Workshop,
|
||||
arXiv:1709.08243, 2018.
|
||||
https://arxiv.org/pdf/1709.08243.pdf
|
||||
```
|
||||
|
||||
An interactive demo is available at: https://jmvalin.ca/demo/rnnoise/
|
||||
|
||||
## Prerequisites
|
||||
|
||||
To build the library with the existing, pre-trained network data you will need to install the following packages:
|
||||
|
||||
* build-essential
|
||||
* cmake
|
||||
|
||||
## Build
|
||||
|
||||
To compile, open a terminal in the repository root directory and type:
|
||||
|
||||
```bash
|
||||
cmake .
|
||||
make
|
||||
```
|
||||
|
||||
To compile the library only, without the demo executable:
|
||||
|
||||
```bash
|
||||
cmake -DRENAMENOISE_DEMO_EXECUTABLE=OFF .
|
||||
make
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
While it is meant to be used as a library, a simple command-line tool is
|
||||
provided as an example. It operates on RAW 16-bit (machine endian) mono
|
||||
PCM files sampled at 48 kHz. It can be used as:
|
||||
|
||||
``./examples/renamenoise_demo <noisy speech> <output denoised>``
|
||||
|
||||
The output is also a 16-bit raw PCM file.d
|
||||
|
||||
## Training
|
||||
|
||||
Training is not necessary to use the library as presented in this repository.
|
||||
|
||||
However, if you want to train the network on your own samples you need to follow these steps:
|
||||
|
||||
```bash
|
||||
cd src ; ./compile.sh
|
||||
|
||||
./denoise_training signal.raw noise.raw count > training.f32
|
||||
|
||||
# (note the matrix size and replace 500000 87 below)
|
||||
|
||||
cd training ; ./bin2hdf5.py ../src/training.f32 500000 87 training.h5
|
||||
|
||||
./rnn_train.py
|
||||
|
||||
./dump_rnn.py weights.hdf5 ../src/rnn_data.c ../src/rnn_data.h
|
||||
```
|
||||
125
thirdparty/renamenoise/include/renamenoise.h
vendored
Normal file
125
thirdparty/renamenoise/include/renamenoise.h
vendored
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
Copyright (c) 2024, The Mumble Developers
|
||||
Copyright (c) 2018, Gregor Richards
|
||||
Copyright (c) 2017, Mozilla
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef RENAMENOISE_H
|
||||
#define RENAMENOISE_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef RENAMENOISE_EXPORT
|
||||
# if defined(WIN32)
|
||||
# if defined(RENAMENOISE_BUILD) && defined(DLL_EXPORT)
|
||||
# define RENAMENOISE_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define RENAMENOISE_EXPORT
|
||||
# endif
|
||||
# elif defined(__GNUC__) && defined(RENAMENOISE_BUILD)
|
||||
# define RENAMENOISE_EXPORT __attribute__((visibility("default")))
|
||||
# else
|
||||
# define RENAMENOISE_EXPORT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef struct ReNameNoiseDenoiseState ReNameNoiseDenoiseState;
|
||||
typedef struct ReNameNoiseModel ReNameNoiseModel;
|
||||
|
||||
/**
|
||||
* Return the size of ReNameNoiseDenoiseState
|
||||
*/
|
||||
RENAMENOISE_EXPORT int renamenoise_get_size(void);
|
||||
|
||||
/**
|
||||
* Return the number of samples processed by renamenoise_process_frame at a time
|
||||
*/
|
||||
RENAMENOISE_EXPORT int renamenoise_get_frame_size(void);
|
||||
|
||||
/**
|
||||
* Initializes a pre-allocated ReNameNoiseDenoiseState
|
||||
*
|
||||
* If model is NULL the default model is used.
|
||||
*
|
||||
* See: renamenoise_create() and renamenoise_model_from_file()
|
||||
*/
|
||||
RENAMENOISE_EXPORT int renamenoise_init(ReNameNoiseDenoiseState *st, ReNameNoiseModel *model);
|
||||
|
||||
/**
|
||||
* Allocate and initialize a ReNameNoiseDenoiseState
|
||||
*
|
||||
* If model is NULL the default model is used.
|
||||
*
|
||||
* The returned pointer MUST be freed with renamenoise_destroy().
|
||||
*/
|
||||
RENAMENOISE_EXPORT ReNameNoiseDenoiseState *renamenoise_create(ReNameNoiseModel *model);
|
||||
|
||||
/**
|
||||
* Free a ReNameNoiseDenoiseState produced by renamenoise_create.
|
||||
*
|
||||
* The optional custom model must be freed by renamenoise_model_free() after.
|
||||
*/
|
||||
RENAMENOISE_EXPORT void renamenoise_destroy(ReNameNoiseDenoiseState *st);
|
||||
|
||||
/**
|
||||
* Denoise a frame of samples
|
||||
*
|
||||
* in and out must be at least renamenoise_get_frame_size() large.
|
||||
*/
|
||||
RENAMENOISE_EXPORT float renamenoise_process_frame(ReNameNoiseDenoiseState *st, float *out, const float *in);
|
||||
|
||||
/**
|
||||
* Denoise a frame of samples, but clamp the output to fit into a 16 bit signed short
|
||||
*
|
||||
* in and out must be at least renamenoise_get_frame_size() large.
|
||||
*/
|
||||
RENAMENOISE_EXPORT float renamenoise_process_frame_clamped(ReNameNoiseDenoiseState *st, short *out, const float *in);
|
||||
|
||||
/**
|
||||
* Load a model from a file
|
||||
*
|
||||
* It must be deallocated with renamenoise_model_free()
|
||||
*/
|
||||
RENAMENOISE_EXPORT ReNameNoiseModel *renamenoise_model_from_file(FILE *f);
|
||||
|
||||
/**
|
||||
* Free a custom model
|
||||
*
|
||||
* It must be called after all the ReNameNoiseDenoiseStates referring to it are freed.
|
||||
*/
|
||||
RENAMENOISE_EXPORT void renamenoise_model_free(ReNameNoiseModel *model);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* RENAMENOISE_H */
|
||||
111
thirdparty/renamenoise/src/_renamenoise_fft_guts.h
vendored
Normal file
111
thirdparty/renamenoise/src/_renamenoise_fft_guts.h
vendored
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
Copyright (c) 2024, The Mumble Developers
|
||||
Copyright (c) 2003-2004, Mark Borgerding
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef RENAMENOISE_FFT_GUTS_H
|
||||
#define RENAMENOISE_FFT_GUTS_H
|
||||
|
||||
/**
|
||||
renamenoise_fft.h
|
||||
Defines renamenoise_fft_scalar as either short or a float type
|
||||
and defines
|
||||
typedef struct {
|
||||
renamenoise_fft_scalar r;
|
||||
renamenoise_fft_scalar i;
|
||||
} renamenoise_fft_cpx;
|
||||
**/
|
||||
#include "renamenoise_fft.h"
|
||||
|
||||
/*
|
||||
Explanation of macros dealing with complex math:
|
||||
|
||||
C_MUL(m,a,b) : m = a*b
|
||||
C_SUB( res, a,b) : res = a - b
|
||||
C_SUBFROM( res , a) : res -= a
|
||||
C_ADDTO( res , a) : res += a
|
||||
*/
|
||||
|
||||
#define RENAMENOISE_S_MUL(a, b) ((a) * (b))
|
||||
|
||||
#define RENAMENOISE_C_MUL(m, a, b) \
|
||||
do { \
|
||||
(m).r = (a).r * (b).r - (a).i * (b).i; \
|
||||
(m).i = (a).r * (b).i + (a).i * (b).r; \
|
||||
} while (0)
|
||||
|
||||
#define RENAMENOISE_C_MULC(m, a, b) \
|
||||
do { \
|
||||
(m).r = (a).r * (b).r + (a).i * (b).i; \
|
||||
(m).i = (a).i * (b).r - (a).r * (b).i; \
|
||||
} while (0)
|
||||
|
||||
#define RENAMENOISE_C_MUL4(m, a, b) RENAMENOISE_C_MUL(m, a, b)
|
||||
|
||||
#define RENAMENOISE_C_MULBYSCALAR(c, s) \
|
||||
do { \
|
||||
(c).r *= (s); \
|
||||
(c).i *= (s); \
|
||||
} while (0)
|
||||
|
||||
#ifndef RENAMENOISE_C_ADD
|
||||
# define RENAMENOISE_C_ADD(res, a, b) \
|
||||
do { \
|
||||
(res).r = (a).r + (b).r; \
|
||||
(res).i = (a).i + (b).i; \
|
||||
} while (0)
|
||||
|
||||
# define RENAMENOISE_C_SUB(res, a, b) \
|
||||
do { \
|
||||
(res).r = (a).r - (b).r; \
|
||||
(res).i = (a).i - (b).i; \
|
||||
} while (0)
|
||||
|
||||
# define RENAMENOISE_C_ADDTO(res, a) \
|
||||
do { \
|
||||
(res).r += (a).r; \
|
||||
(res).i += (a).i; \
|
||||
} while (0)
|
||||
|
||||
# define RENAMENOISE_C_SUBFROM(res, a) \
|
||||
do { \
|
||||
(res).r -= (a).r; \
|
||||
(res).i -= (a).i; \
|
||||
} while (0)
|
||||
#endif /* !RENAMENOISE_C_ADD defined */
|
||||
|
||||
#define RENAMENOISE_FFT_COS(phase) (renamenoise_fft_scalar) cos(phase)
|
||||
#define RENAMENOISE_FFT_SIN(phase) (renamenoise_fft_scalar) sin(phase)
|
||||
|
||||
#define renamenoise_kf_cexp(x, phase) \
|
||||
do { \
|
||||
(x)->r = RENAMENOISE_FFT_COS(phase); \
|
||||
(x)->i = RENAMENOISE_FFT_SIN(phase); \
|
||||
} while (0)
|
||||
|
||||
#endif /* RENAMENOISE_FFT_GUTS_H */
|
||||
165
thirdparty/renamenoise/src/arch.h
vendored
Normal file
165
thirdparty/renamenoise/src/arch.h
vendored
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
Copyright (c) 2024, The Mumble Developers
|
||||
Copyright (c) 2007-2009, Xiph.Org Foundation
|
||||
Copyright (c) 2007-2008, CSIRO
|
||||
Copyright (c) 2003-2008, Jean-Marc Valin
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
@file arch.h
|
||||
@brief Various architecture definitions for ReNameNoise
|
||||
*/
|
||||
|
||||
#ifndef ARCH_H
|
||||
#define ARCH_H
|
||||
|
||||
#include "common.h"
|
||||
#include "renamenoise_types.h"
|
||||
|
||||
#if !defined(__GNUC_PREREQ)
|
||||
# if defined(__GNUC__) && defined(__GNUC_MINOR__)
|
||||
# define __GNUC_PREREQ(_maj, _min) ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((_maj) << 16) + (_min))
|
||||
# else
|
||||
# define __GNUC_PREREQ(_maj, _min) 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
# define M_PI (3.14159265358979323846)
|
||||
#endif
|
||||
|
||||
#define renamenoise_fatal(str) _renamenoise_fatal(str, __FILE__, __LINE__);
|
||||
|
||||
#ifdef ENABLE_ASSERTIONS
|
||||
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
|
||||
# ifdef __GNUC__
|
||||
__attribute__((noreturn))
|
||||
# endif
|
||||
|
||||
static RENAMENOISE_INLINE void
|
||||
_renamenoise_fatal(const char *str, const char *file, int line) {
|
||||
fprintf(stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
|
||||
abort();
|
||||
}
|
||||
|
||||
# define renamenoise_assert(cond) \
|
||||
{ \
|
||||
if (!(cond)) { \
|
||||
renamenoise_fatal("assertion failed: " #cond); \
|
||||
} \
|
||||
}
|
||||
|
||||
# define renamenoise_assert2(cond, message) \
|
||||
{ \
|
||||
if (!(cond)) { \
|
||||
renamenoise_fatal("assertion failed: " #cond "\n" message); \
|
||||
} \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
# define renamenoise_assert(cond)
|
||||
|
||||
# define renamenoise_assert2(cond, message)
|
||||
|
||||
#endif /* !ENABLE_ASSERTIONS defined */
|
||||
|
||||
#define RENAMENOISE_MIN16(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
#define RENAMENOISE_MAX16(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
#define RENAMENOISE_MIN32(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
#define RENAMENOISE_MAX32(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
typedef float renamenoise_val16;
|
||||
typedef float renamenoise_val32;
|
||||
|
||||
typedef float renamenoise_sig;
|
||||
|
||||
#ifdef RENAMENOISE_FLOAT_APPROX
|
||||
// This code should reliably detect NaN/inf even when -ffast-math is used.
|
||||
// Assumes IEEE 754 format.
|
||||
static RENAMENOISE_INLINE int renamenoise_isnan(float x) {
|
||||
union {
|
||||
float f;
|
||||
renamenoise_uint32 i;
|
||||
} in;
|
||||
in.f = x;
|
||||
return ((in.i >> 23) & 0xFF) == 0xFF && (in.i & 0x007FFFFF) != 0;
|
||||
}
|
||||
#else
|
||||
# ifdef __FAST_MATH__
|
||||
# error Cannot build renamenoise with -ffast-math unless RENAMENOISE_FLOAT_APPROX is defined. This could result in crashes on extreme (e.g. NaN) input
|
||||
# endif
|
||||
# define renamenoise_isnan(x) ((x) != (x))
|
||||
#endif
|
||||
|
||||
#define RENAMENOISE_Q15ONE 1.0f
|
||||
|
||||
#define RENAMENOISE_EPSILON 1e-15f
|
||||
#define RENAMENOISE_VERY_SMALL 1e-30f
|
||||
#define RENAMENOISE_VERY_LARGE16 1e15f
|
||||
|
||||
#define RENAMENOISE_HALF(x) (.5f * (x))
|
||||
|
||||
#define RENAMENOISE_ADD(a, b) ((a) + (b))
|
||||
#define RENAMENOISE_SUB(a, b) ((a) - (b))
|
||||
|
||||
#define RENAMENOISE_MAC(c, a, b) ((c) + (renamenoise_val32) (a) * (renamenoise_val32) (b))
|
||||
|
||||
#define RENAMENOISE_MULT(a, b) ((a) * (b))
|
||||
|
||||
#if __STDC_VERSION__ < 199901L || (__STDC_VERSION__ > 201000L && __STDC_NO_VLA__ == 1)
|
||||
# define RENAMENOISE_NO_VLA
|
||||
#endif
|
||||
|
||||
#ifdef RENAMENOISE_NO_VLA
|
||||
# include <malloc.h>
|
||||
# define renamenoise_stackalloc(type, id, len) type *id = alloca((len) * sizeof(type))
|
||||
#else
|
||||
# define renamenoise_stackalloc(type, id, len) type id[len]
|
||||
#endif
|
||||
|
||||
// Portable macros for denoting unreachable code.
|
||||
// In such a scenario, perform an early exit ('panic')
|
||||
|
||||
#if _MSC_VER // MSVC
|
||||
# define renamenoise_unreachable() __assume(0)
|
||||
#elif __GNUC__ || __clang__ || __MINGW32__
|
||||
# define renamenoise_unreachable() __builtin_unreachable()
|
||||
// #elif __BORLANDC__
|
||||
// #define renamenoise_unreachable() __builtin_unreachable() // unknown. needs investigation
|
||||
#else
|
||||
# define renamenoise_unreachable()
|
||||
#endif
|
||||
|
||||
#endif /* ARCH_H */
|
||||
54
thirdparty/renamenoise/src/common.h
vendored
Normal file
54
thirdparty/renamenoise/src/common.h
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
Copyright (c) 2024, The Mumble Developers
|
||||
Copyright (c) 2017, Jean-Marc Valin
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
|
||||
#define RENAMENOISE_INLINE inline
|
||||
|
||||
/** Copy n elements from src to dst. The 0* term provides compile-time type checking */
|
||||
#ifndef OVERRIDE_RENAMENOISE_COPY
|
||||
# define RENAMENOISE_COPY(dst, src, n) (memcpy((dst), (src), (n) * sizeof(*(dst)) + 0 * ((dst) - (src))))
|
||||
#endif
|
||||
|
||||
/** Copy n elements from src to dst, allowing overlapping regions. The 0* term provides compile-time type checking */
|
||||
#ifndef OVERRIDE_RENAMENOISE_MOVE
|
||||
# define RENAMENOISE_MOVE(dst, src, n) (memmove((dst), (src), (n) * sizeof(*(dst)) + 0 * ((dst) - (src))))
|
||||
#endif
|
||||
|
||||
/** Set n elements of dst to zero */
|
||||
#ifndef OVERRIDE_RENAMENOISE_CLEAR
|
||||
# define RENAMENOISE_CLEAR(dst, n) (memset((dst), 0, (n) * sizeof(*(dst))))
|
||||
#endif
|
||||
|
||||
#endif /* COMMON_H */
|
||||
3
thirdparty/renamenoise/src/compile.sh
vendored
Executable file
3
thirdparty/renamenoise/src/compile.sh
vendored
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
gcc -DRENAMENOISE_TRAINING=1 -Wall -W -O3 -g -I../include denoise.c renamenoise_fft.c pitch.c renamenoise_lpc.c rnn.c rnn_data.c -o denoise_training -lm
|
||||
692
thirdparty/renamenoise/src/denoise.c
vendored
Normal file
692
thirdparty/renamenoise/src/denoise.c
vendored
Normal file
|
|
@ -0,0 +1,692 @@
|
|||
/*
|
||||
Copyright (c) 2024, The Mumble Developers
|
||||
Copyright (c) 2018, Gregor Richards
|
||||
Copyright (c) 2017, Mozilla
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "arch.h"
|
||||
#include "common.h"
|
||||
#include "pitch.h"
|
||||
#include "renamenoise.h"
|
||||
#include "renamenoise_fft.h"
|
||||
#include "rnn.h"
|
||||
#include "rnn_data.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define RENAMENOISE_FRAME_SIZE_SHIFT 2
|
||||
#define RENAMENOISE_FRAME_SIZE (120 << RENAMENOISE_FRAME_SIZE_SHIFT)
|
||||
#define RENAMENOISE_WINDOW_SIZE (2 * RENAMENOISE_FRAME_SIZE)
|
||||
#define RENAMENOISE_FREQ_SIZE (RENAMENOISE_FRAME_SIZE + 1)
|
||||
|
||||
#define RENAMENOISE_PITCH_MIN_PERIOD 60
|
||||
#define RENAMENOISE_PITCH_MAX_PERIOD 768
|
||||
#define RENAMENOISE_PITCH_FRAME_SIZE 960
|
||||
#define RENAMENOISE_PITCH_BUF_SIZE (RENAMENOISE_PITCH_MAX_PERIOD + RENAMENOISE_PITCH_FRAME_SIZE)
|
||||
|
||||
#define RENAMENOISE_SQUARE(x) ((x) * (x))
|
||||
|
||||
#define RENAMENOISE_NB_BANDS 22
|
||||
|
||||
#define RENAMENOISE_CEPS_MEM 8
|
||||
#define RENAMENOISE_NB_DELTA_CEPS 6
|
||||
|
||||
#define RENAMENOISE_NB_FEATURES (RENAMENOISE_NB_BANDS + 3 * RENAMENOISE_NB_DELTA_CEPS + 2)
|
||||
|
||||
#ifndef RENAMENOISE_TRAINING
|
||||
# define RENAMENOISE_TRAINING 0
|
||||
#endif
|
||||
|
||||
/* The built-in model, used if no file is given as input */
|
||||
extern const struct ReNameNoiseModel renamenoise_model_orig;
|
||||
|
||||
static const renamenoise_int16 renamenoise_eband5ms[] = {
|
||||
// 0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12,
|
||||
// 2.8 3.2 4k 4.8 5.6 6.8 8k 9.6 12k 15.6 20k
|
||||
14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100};
|
||||
|
||||
typedef struct {
|
||||
int init;
|
||||
renamenoise_fft_state *kfft;
|
||||
float half_window[RENAMENOISE_FRAME_SIZE];
|
||||
float dct_table[RENAMENOISE_NB_BANDS * RENAMENOISE_NB_BANDS];
|
||||
} ReNameNoiseCommonState;
|
||||
|
||||
struct ReNameNoiseDenoiseState {
|
||||
float analysis_mem[RENAMENOISE_FRAME_SIZE];
|
||||
float cepstral_mem[RENAMENOISE_CEPS_MEM][RENAMENOISE_NB_BANDS];
|
||||
int memid;
|
||||
float synthesis_mem[RENAMENOISE_FRAME_SIZE];
|
||||
float pitch_buf[RENAMENOISE_PITCH_BUF_SIZE];
|
||||
float pitch_enh_buf[RENAMENOISE_PITCH_BUF_SIZE];
|
||||
float last_gain;
|
||||
int last_period;
|
||||
float mem_hp_x[2];
|
||||
float lastg[RENAMENOISE_NB_BANDS];
|
||||
ReNameNoiseRNNState rnn;
|
||||
};
|
||||
|
||||
void renamenoise_compute_band_energy(float *bandE, const renamenoise_fft_cpx *X) {
|
||||
int i;
|
||||
float sum[RENAMENOISE_NB_BANDS] = {0};
|
||||
for (i = 0; i < RENAMENOISE_NB_BANDS - 1; i++) {
|
||||
int j;
|
||||
int band_size;
|
||||
band_size = (renamenoise_eband5ms[i + 1] - renamenoise_eband5ms[i]) << RENAMENOISE_FRAME_SIZE_SHIFT;
|
||||
for (j = 0; j < band_size; j++) {
|
||||
float tmp;
|
||||
float frac = (float) j / band_size;
|
||||
tmp = RENAMENOISE_SQUARE(X[(renamenoise_eband5ms[i] << RENAMENOISE_FRAME_SIZE_SHIFT) + j].r);
|
||||
tmp += RENAMENOISE_SQUARE(X[(renamenoise_eband5ms[i] << RENAMENOISE_FRAME_SIZE_SHIFT) + j].i);
|
||||
sum[i] = sum[i] + (1 - frac) * tmp;
|
||||
sum[i + 1] = sum[i + 1] + frac * tmp;
|
||||
}
|
||||
}
|
||||
sum[0] *= 2;
|
||||
sum[RENAMENOISE_NB_BANDS - 1] *= 2;
|
||||
for (i = 0; i < RENAMENOISE_NB_BANDS; i++) {
|
||||
bandE[i] = sum[i];
|
||||
}
|
||||
}
|
||||
|
||||
void renamenoise_compute_band_corr(float *bandE, const renamenoise_fft_cpx *X, const renamenoise_fft_cpx *P) {
|
||||
int i;
|
||||
float sum[RENAMENOISE_NB_BANDS] = {0};
|
||||
for (i = 0; i < RENAMENOISE_NB_BANDS - 1; i++) {
|
||||
int j;
|
||||
int band_size;
|
||||
band_size = (renamenoise_eband5ms[i + 1] - renamenoise_eband5ms[i]) << RENAMENOISE_FRAME_SIZE_SHIFT;
|
||||
for (j = 0; j < band_size; j++) {
|
||||
float tmp;
|
||||
float frac = (float) j / band_size;
|
||||
tmp = X[(renamenoise_eband5ms[i] << RENAMENOISE_FRAME_SIZE_SHIFT) + j].r
|
||||
* P[(renamenoise_eband5ms[i] << RENAMENOISE_FRAME_SIZE_SHIFT) + j].r;
|
||||
tmp += X[(renamenoise_eband5ms[i] << RENAMENOISE_FRAME_SIZE_SHIFT) + j].i
|
||||
* P[(renamenoise_eband5ms[i] << RENAMENOISE_FRAME_SIZE_SHIFT) + j].i;
|
||||
sum[i] += (1 - frac) * tmp;
|
||||
sum[i + 1] += frac * tmp;
|
||||
}
|
||||
}
|
||||
sum[0] *= 2;
|
||||
sum[RENAMENOISE_NB_BANDS - 1] *= 2;
|
||||
for (i = 0; i < RENAMENOISE_NB_BANDS; i++) {
|
||||
bandE[i] = sum[i];
|
||||
}
|
||||
}
|
||||
|
||||
void renamenoise_interp_band_gain(float *g, const float *bandE) {
|
||||
int i;
|
||||
memset(g, 0, RENAMENOISE_FREQ_SIZE);
|
||||
for (i = 0; i < RENAMENOISE_NB_BANDS - 1; i++) {
|
||||
int j;
|
||||
int band_size;
|
||||
band_size = (renamenoise_eband5ms[i + 1] - renamenoise_eband5ms[i]) << RENAMENOISE_FRAME_SIZE_SHIFT;
|
||||
for (j = 0; j < band_size; j++) {
|
||||
float frac = (float) j / band_size;
|
||||
g[(renamenoise_eband5ms[i] << RENAMENOISE_FRAME_SIZE_SHIFT) + j] = (1 - frac) * bandE[i] + frac * bandE[i + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReNameNoiseCommonState renamenoise_common;
|
||||
|
||||
static void renamenoise_check_init(void) {
|
||||
int i;
|
||||
if (renamenoise_common.init) {
|
||||
return;
|
||||
}
|
||||
renamenoise_common.kfft = renamenoise_fft_alloc_twiddles(2 * RENAMENOISE_FRAME_SIZE, NULL, NULL, NULL, 0);
|
||||
for (i = 0; i < RENAMENOISE_FRAME_SIZE; i++) {
|
||||
renamenoise_common.half_window[i] =
|
||||
sin(.5 * M_PI * sin(.5 * M_PI * (i + .5) / RENAMENOISE_FRAME_SIZE) * sin(.5 * M_PI * (i + .5) / RENAMENOISE_FRAME_SIZE));
|
||||
}
|
||||
for (i = 0; i < RENAMENOISE_NB_BANDS; i++) {
|
||||
int j;
|
||||
for (j = 0; j < RENAMENOISE_NB_BANDS; j++) {
|
||||
renamenoise_common.dct_table[i * RENAMENOISE_NB_BANDS + j] = cos((i + .5) * j * M_PI / RENAMENOISE_NB_BANDS);
|
||||
if (j == 0) {
|
||||
renamenoise_common.dct_table[i * RENAMENOISE_NB_BANDS + j] *= sqrt(.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
renamenoise_common.init = 1;
|
||||
}
|
||||
|
||||
static void renamenoise_dct(float *out, const float *in) {
|
||||
int i;
|
||||
renamenoise_check_init();
|
||||
for (i = 0; i < RENAMENOISE_NB_BANDS; i++) {
|
||||
int j;
|
||||
float sum = 0;
|
||||
for (j = 0; j < RENAMENOISE_NB_BANDS; j++) {
|
||||
sum += in[j] * renamenoise_common.dct_table[j * RENAMENOISE_NB_BANDS + i];
|
||||
}
|
||||
out[i] = sum * sqrt(2. / 22);
|
||||
}
|
||||
}
|
||||
|
||||
static void renamenoise_forward_transform(renamenoise_fft_cpx *out, const float *in) {
|
||||
int i;
|
||||
renamenoise_fft_cpx x[RENAMENOISE_WINDOW_SIZE];
|
||||
renamenoise_fft_cpx y[RENAMENOISE_WINDOW_SIZE];
|
||||
renamenoise_check_init();
|
||||
for (i = 0; i < RENAMENOISE_WINDOW_SIZE; i++) {
|
||||
x[i].r = in[i];
|
||||
x[i].i = 0;
|
||||
}
|
||||
renamenoise_fft(renamenoise_common.kfft, x, y, 0);
|
||||
for (i = 0; i < RENAMENOISE_FREQ_SIZE; i++) {
|
||||
out[i] = y[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void renamenoise_inverse_transform(float *out, const renamenoise_fft_cpx *in) {
|
||||
int i;
|
||||
renamenoise_fft_cpx x[RENAMENOISE_WINDOW_SIZE];
|
||||
renamenoise_fft_cpx y[RENAMENOISE_WINDOW_SIZE];
|
||||
renamenoise_check_init();
|
||||
for (i = 0; i < RENAMENOISE_FREQ_SIZE; i++) {
|
||||
x[i] = in[i];
|
||||
}
|
||||
for (; i < RENAMENOISE_WINDOW_SIZE; i++) {
|
||||
x[i].r = x[RENAMENOISE_WINDOW_SIZE - i].r;
|
||||
x[i].i = -x[RENAMENOISE_WINDOW_SIZE - i].i;
|
||||
}
|
||||
renamenoise_fft(renamenoise_common.kfft, x, y, 0);
|
||||
// output in reverse order for IFFT.
|
||||
out[0] = RENAMENOISE_WINDOW_SIZE * y[0].r;
|
||||
for (i = 1; i < RENAMENOISE_WINDOW_SIZE; i++) {
|
||||
out[i] = RENAMENOISE_WINDOW_SIZE * y[RENAMENOISE_WINDOW_SIZE - i].r;
|
||||
}
|
||||
}
|
||||
|
||||
static void renamenoise_apply_window(float *x) {
|
||||
int i;
|
||||
renamenoise_check_init();
|
||||
for (i = 0; i < RENAMENOISE_FRAME_SIZE; i++) {
|
||||
x[i] *= renamenoise_common.half_window[i];
|
||||
x[RENAMENOISE_WINDOW_SIZE - 1 - i] *= renamenoise_common.half_window[i];
|
||||
}
|
||||
}
|
||||
|
||||
int renamenoise_get_size(void) {
|
||||
return sizeof(ReNameNoiseDenoiseState);
|
||||
}
|
||||
|
||||
int renamenoise_get_frame_size(void) {
|
||||
return RENAMENOISE_FRAME_SIZE;
|
||||
}
|
||||
|
||||
int renamenoise_init(ReNameNoiseDenoiseState *st, ReNameNoiseModel *model) {
|
||||
memset(st, 0, sizeof(*st));
|
||||
if (model) {
|
||||
st->rnn.model = model;
|
||||
} else {
|
||||
st->rnn.model = &renamenoise_model_orig;
|
||||
}
|
||||
st->rnn.vad_gru_state = calloc(sizeof(float), st->rnn.model->vad_gru_size);
|
||||
st->rnn.noise_gru_state = calloc(sizeof(float), st->rnn.model->noise_gru_size);
|
||||
st->rnn.denoise_gru_state = calloc(sizeof(float), st->rnn.model->denoise_gru_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ReNameNoiseDenoiseState *renamenoise_create(ReNameNoiseModel *model) {
|
||||
ReNameNoiseDenoiseState *st;
|
||||
st = malloc(renamenoise_get_size());
|
||||
renamenoise_init(st, model);
|
||||
return st;
|
||||
}
|
||||
|
||||
void renamenoise_destroy(ReNameNoiseDenoiseState *st) {
|
||||
free(st->rnn.vad_gru_state);
|
||||
free(st->rnn.noise_gru_state);
|
||||
free(st->rnn.denoise_gru_state);
|
||||
free(st);
|
||||
}
|
||||
|
||||
#if RENAMENOISE_TRAINING
|
||||
int lowpass = RENAMENOISE_FREQ_SIZE;
|
||||
int band_lp = RENAMENOISE_NB_BANDS;
|
||||
#endif
|
||||
|
||||
static void renamenoise_frame_analysis(ReNameNoiseDenoiseState *st, renamenoise_fft_cpx *X, float *Ex, const float *in) {
|
||||
int i;
|
||||
float x[RENAMENOISE_WINDOW_SIZE];
|
||||
RENAMENOISE_COPY(x, st->analysis_mem, RENAMENOISE_FRAME_SIZE);
|
||||
for (i = 0; i < RENAMENOISE_FRAME_SIZE; i++) {
|
||||
x[RENAMENOISE_FRAME_SIZE + i] = in[i];
|
||||
}
|
||||
RENAMENOISE_COPY(st->analysis_mem, in, RENAMENOISE_FRAME_SIZE);
|
||||
renamenoise_apply_window(x);
|
||||
renamenoise_forward_transform(X, x);
|
||||
#if RENAMENOISE_TRAINING
|
||||
for (i = lowpass; i < RENAMENOISE_FREQ_SIZE; i++) {
|
||||
X[i].r = X[i].i = 0;
|
||||
}
|
||||
#endif
|
||||
renamenoise_compute_band_energy(Ex, X);
|
||||
}
|
||||
|
||||
static int renamenoise_compute_frame_features(ReNameNoiseDenoiseState *st, renamenoise_fft_cpx *X, renamenoise_fft_cpx *P, float *Ex, float *Ep,
|
||||
float *Exp, float *features, const float *in) {
|
||||
int i;
|
||||
float E = 0;
|
||||
float *ceps_0, *ceps_1, *ceps_2;
|
||||
float spec_variability = 0;
|
||||
float Ly[RENAMENOISE_NB_BANDS];
|
||||
float p[RENAMENOISE_WINDOW_SIZE];
|
||||
float pitch_buf[RENAMENOISE_PITCH_BUF_SIZE >> 1];
|
||||
int pitch_index;
|
||||
float gain;
|
||||
float *(pre[1]);
|
||||
float tmp[RENAMENOISE_NB_BANDS];
|
||||
float follow, logMax;
|
||||
renamenoise_frame_analysis(st, X, Ex, in);
|
||||
RENAMENOISE_MOVE(st->pitch_buf, &st->pitch_buf[RENAMENOISE_FRAME_SIZE], RENAMENOISE_PITCH_BUF_SIZE - RENAMENOISE_FRAME_SIZE);
|
||||
RENAMENOISE_COPY(&st->pitch_buf[RENAMENOISE_PITCH_BUF_SIZE - RENAMENOISE_FRAME_SIZE], in, RENAMENOISE_FRAME_SIZE);
|
||||
pre[0] = &st->pitch_buf[0];
|
||||
renamenoise_pitch_downsample(pre, pitch_buf, RENAMENOISE_PITCH_BUF_SIZE, 1);
|
||||
renamenoise_pitch_search(pitch_buf + (RENAMENOISE_PITCH_MAX_PERIOD >> 1), pitch_buf, RENAMENOISE_PITCH_FRAME_SIZE,
|
||||
RENAMENOISE_PITCH_MAX_PERIOD - 3 * RENAMENOISE_PITCH_MIN_PERIOD, &pitch_index);
|
||||
pitch_index = RENAMENOISE_PITCH_MAX_PERIOD - pitch_index;
|
||||
|
||||
gain = renamenoise_remove_doubling(pitch_buf, RENAMENOISE_PITCH_MAX_PERIOD, RENAMENOISE_PITCH_MIN_PERIOD, RENAMENOISE_PITCH_FRAME_SIZE,
|
||||
&pitch_index, st->last_period, st->last_gain);
|
||||
st->last_period = pitch_index;
|
||||
st->last_gain = gain;
|
||||
for (i = 0; i < RENAMENOISE_WINDOW_SIZE; i++) {
|
||||
p[i] = st->pitch_buf[RENAMENOISE_PITCH_BUF_SIZE - RENAMENOISE_WINDOW_SIZE - pitch_index + i];
|
||||
}
|
||||
renamenoise_apply_window(p);
|
||||
renamenoise_forward_transform(P, p);
|
||||
renamenoise_compute_band_energy(Ep, P);
|
||||
renamenoise_compute_band_corr(Exp, X, P);
|
||||
for (i = 0; i < RENAMENOISE_NB_BANDS; i++) {
|
||||
Exp[i] = Exp[i] / sqrt(.001 + Ex[i] * Ep[i]);
|
||||
}
|
||||
renamenoise_dct(tmp, Exp);
|
||||
for (i = 0; i < RENAMENOISE_NB_DELTA_CEPS; i++) {
|
||||
features[RENAMENOISE_NB_BANDS + 2 * RENAMENOISE_NB_DELTA_CEPS + i] = tmp[i];
|
||||
}
|
||||
features[RENAMENOISE_NB_BANDS + 2 * RENAMENOISE_NB_DELTA_CEPS] -= 1.3;
|
||||
features[RENAMENOISE_NB_BANDS + 2 * RENAMENOISE_NB_DELTA_CEPS + 1] -= 0.9;
|
||||
features[RENAMENOISE_NB_BANDS + 3 * RENAMENOISE_NB_DELTA_CEPS] = .01 * (pitch_index - 300);
|
||||
logMax = -2;
|
||||
follow = -2;
|
||||
for (i = 0; i < RENAMENOISE_NB_BANDS; i++) {
|
||||
Ly[i] = log10(1e-2 + Ex[i]);
|
||||
Ly[i] = RENAMENOISE_MAX16(logMax - 7, RENAMENOISE_MAX16(follow - 1.5, Ly[i]));
|
||||
logMax = RENAMENOISE_MAX16(logMax, Ly[i]);
|
||||
follow = RENAMENOISE_MAX16(follow - 1.5, Ly[i]);
|
||||
E += Ex[i];
|
||||
}
|
||||
if (!RENAMENOISE_TRAINING && E < 0.04) {
|
||||
// If there's no audio, avoid messing up the state.
|
||||
RENAMENOISE_CLEAR(features, RENAMENOISE_NB_FEATURES);
|
||||
return 1;
|
||||
}
|
||||
renamenoise_dct(features, Ly);
|
||||
features[0] -= 12;
|
||||
features[1] -= 4;
|
||||
ceps_0 = st->cepstral_mem[st->memid];
|
||||
ceps_1 = (st->memid < 1) ? st->cepstral_mem[RENAMENOISE_CEPS_MEM + st->memid - 1] : st->cepstral_mem[st->memid - 1];
|
||||
ceps_2 = (st->memid < 2) ? st->cepstral_mem[RENAMENOISE_CEPS_MEM + st->memid - 2] : st->cepstral_mem[st->memid - 2];
|
||||
for (i = 0; i < RENAMENOISE_NB_BANDS; i++) {
|
||||
ceps_0[i] = features[i];
|
||||
}
|
||||
st->memid++;
|
||||
for (i = 0; i < RENAMENOISE_NB_DELTA_CEPS; i++) {
|
||||
features[i] = ceps_0[i] + ceps_1[i] + ceps_2[i];
|
||||
features[RENAMENOISE_NB_BANDS + i] = ceps_0[i] - ceps_2[i];
|
||||
features[RENAMENOISE_NB_BANDS + RENAMENOISE_NB_DELTA_CEPS + i] = ceps_0[i] - 2 * ceps_1[i] + ceps_2[i];
|
||||
}
|
||||
// Spectral variability features.
|
||||
if (st->memid == RENAMENOISE_CEPS_MEM) {
|
||||
st->memid = 0;
|
||||
}
|
||||
for (i = 0; i < RENAMENOISE_CEPS_MEM; i++) {
|
||||
int j;
|
||||
float mindist = 1e15f;
|
||||
for (j = 0; j < RENAMENOISE_CEPS_MEM; j++) {
|
||||
int k;
|
||||
float dist = 0;
|
||||
for (k = 0; k < RENAMENOISE_NB_BANDS; k++) {
|
||||
float tmp;
|
||||
tmp = st->cepstral_mem[i][k] - st->cepstral_mem[j][k];
|
||||
dist += tmp * tmp;
|
||||
}
|
||||
if (j != i) {
|
||||
mindist = RENAMENOISE_MIN32(mindist, dist);
|
||||
}
|
||||
}
|
||||
spec_variability += mindist;
|
||||
}
|
||||
features[RENAMENOISE_NB_BANDS + 3 * RENAMENOISE_NB_DELTA_CEPS + 1] = spec_variability / RENAMENOISE_CEPS_MEM - 2.1;
|
||||
return RENAMENOISE_TRAINING && E < 0.1;
|
||||
}
|
||||
|
||||
static void renamenoise_frame_synthesis(ReNameNoiseDenoiseState *st, float *out, const renamenoise_fft_cpx *y) {
|
||||
float x[RENAMENOISE_WINDOW_SIZE];
|
||||
int i;
|
||||
renamenoise_inverse_transform(x, y);
|
||||
renamenoise_apply_window(x);
|
||||
for (i = 0; i < RENAMENOISE_FRAME_SIZE; i++) {
|
||||
out[i] = x[i] + st->synthesis_mem[i];
|
||||
}
|
||||
RENAMENOISE_COPY(st->synthesis_mem, &x[RENAMENOISE_FRAME_SIZE], RENAMENOISE_FRAME_SIZE);
|
||||
}
|
||||
|
||||
static void renamenoise_biquad(float *y, float mem[2], const float *x, const float *b, const float *a, int N) {
|
||||
int i;
|
||||
for (i = 0; i < N; i++) {
|
||||
float xi, yi;
|
||||
xi = x[i];
|
||||
yi = x[i] + mem[0];
|
||||
mem[0] = mem[1] + (b[0] * (double) xi - a[0] * (double) yi);
|
||||
mem[1] = (b[1] * (double) xi - a[1] * (double) yi);
|
||||
y[i] = yi;
|
||||
}
|
||||
}
|
||||
|
||||
void renamenoise_pitch_filter(renamenoise_fft_cpx *X, const renamenoise_fft_cpx *P, const float *Ex, const float *Ep, const float *Exp,
|
||||
const float *g) {
|
||||
int i;
|
||||
float r[RENAMENOISE_NB_BANDS];
|
||||
float rf[RENAMENOISE_FREQ_SIZE] = {0};
|
||||
for (i = 0; i < RENAMENOISE_NB_BANDS; i++) {
|
||||
if (Exp[i] > g[i]) {
|
||||
r[i] = 1;
|
||||
} else {
|
||||
r[i] = RENAMENOISE_SQUARE(Exp[i]) * (1 - RENAMENOISE_SQUARE(g[i])) / (.001 + RENAMENOISE_SQUARE(g[i]) * (1 - RENAMENOISE_SQUARE(Exp[i])));
|
||||
}
|
||||
r[i] = sqrt(RENAMENOISE_MIN16(1, RENAMENOISE_MAX16(0, r[i])));
|
||||
r[i] *= sqrt(Ex[i] / (1e-8 + Ep[i]));
|
||||
}
|
||||
renamenoise_interp_band_gain(rf, r);
|
||||
for (i = 0; i < RENAMENOISE_FREQ_SIZE; i++) {
|
||||
X[i].r += rf[i] * P[i].r;
|
||||
X[i].i += rf[i] * P[i].i;
|
||||
}
|
||||
float newE[RENAMENOISE_NB_BANDS];
|
||||
renamenoise_compute_band_energy(newE, X);
|
||||
float norm[RENAMENOISE_NB_BANDS];
|
||||
float normf[RENAMENOISE_FREQ_SIZE] = {0};
|
||||
for (i = 0; i < RENAMENOISE_NB_BANDS; i++) {
|
||||
norm[i] = sqrt(Ex[i] / (1e-8 + newE[i]));
|
||||
}
|
||||
renamenoise_interp_band_gain(normf, norm);
|
||||
for (i = 0; i < RENAMENOISE_FREQ_SIZE; i++) {
|
||||
X[i].r *= normf[i];
|
||||
X[i].i *= normf[i];
|
||||
}
|
||||
}
|
||||
|
||||
float renamenoise_process_frame(ReNameNoiseDenoiseState *st, float *out, const float *in) {
|
||||
int i;
|
||||
renamenoise_fft_cpx X[RENAMENOISE_FREQ_SIZE];
|
||||
renamenoise_fft_cpx P[RENAMENOISE_WINDOW_SIZE];
|
||||
float x[RENAMENOISE_FRAME_SIZE];
|
||||
float Ex[RENAMENOISE_NB_BANDS], Ep[RENAMENOISE_NB_BANDS];
|
||||
float Exp[RENAMENOISE_NB_BANDS];
|
||||
float features[RENAMENOISE_NB_FEATURES];
|
||||
float g[RENAMENOISE_NB_BANDS];
|
||||
float gf[RENAMENOISE_FREQ_SIZE] = {1};
|
||||
float vad_prob = 0;
|
||||
int silence;
|
||||
static const float a_hp[2] = {-1.99599, 0.99600};
|
||||
static const float b_hp[2] = {-2, 1};
|
||||
renamenoise_biquad(x, st->mem_hp_x, in, b_hp, a_hp, RENAMENOISE_FRAME_SIZE);
|
||||
silence = renamenoise_compute_frame_features(st, X, P, Ex, Ep, Exp, features, x);
|
||||
|
||||
if (!silence) {
|
||||
renamenoise_compute_rnn(&st->rnn, g, &vad_prob, features);
|
||||
renamenoise_pitch_filter(X, P, Ex, Ep, Exp, g);
|
||||
for (i = 0; i < RENAMENOISE_NB_BANDS; i++) {
|
||||
float alpha = .6f;
|
||||
g[i] = RENAMENOISE_MAX16(g[i], alpha * st->lastg[i]);
|
||||
st->lastg[i] = g[i];
|
||||
}
|
||||
renamenoise_interp_band_gain(gf, g);
|
||||
for (i = 0; i < RENAMENOISE_FREQ_SIZE; i++) {
|
||||
X[i].r *= gf[i];
|
||||
X[i].i *= gf[i];
|
||||
}
|
||||
}
|
||||
|
||||
renamenoise_frame_synthesis(st, out, X);
|
||||
return vad_prob;
|
||||
}
|
||||
|
||||
float renamenoise_process_frame_clamped(ReNameNoiseDenoiseState *st, short *out, const float *in) {
|
||||
float denoise_frames[RENAMENOISE_FRAME_SIZE];
|
||||
|
||||
float vad_prob = renamenoise_process_frame(st, denoise_frames, in);
|
||||
|
||||
for (unsigned int i = 0; i < RENAMENOISE_FRAME_SIZE; i++) {
|
||||
out[i] = (short) RENAMENOISE_MIN16(RENAMENOISE_MAX16(denoise_frames[i], SHRT_MIN), SHRT_MAX);
|
||||
}
|
||||
|
||||
return vad_prob;
|
||||
}
|
||||
|
||||
#if RENAMENOISE_TRAINING
|
||||
|
||||
static float renamenoise_uni_rand() {
|
||||
return rand() / (double) RAND_MAX - .5;
|
||||
}
|
||||
|
||||
static void renamenoise_rand_resp(float *a, float *b) {
|
||||
a[0] = .75 * renamenoise_uni_rand();
|
||||
a[1] = .75 * renamenoise_uni_rand();
|
||||
b[0] = .75 * renamenoise_uni_rand();
|
||||
b[1] = .75 * renamenoise_uni_rand();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int i;
|
||||
int count = 0;
|
||||
static const float a_hp[2] = {-1.99599, 0.99600};
|
||||
static const float b_hp[2] = {-2, 1};
|
||||
float a_noise[2] = {0};
|
||||
float b_noise[2] = {0};
|
||||
float a_sig[2] = {0};
|
||||
float b_sig[2] = {0};
|
||||
float mem_hp_x[2] = {0};
|
||||
float mem_hp_n[2] = {0};
|
||||
float mem_resp_x[2] = {0};
|
||||
float mem_resp_n[2] = {0};
|
||||
float x[RENAMENOISE_FRAME_SIZE];
|
||||
float n[RENAMENOISE_FRAME_SIZE];
|
||||
float xn[RENAMENOISE_FRAME_SIZE];
|
||||
int vad_cnt = 0;
|
||||
int gain_change_count = 0;
|
||||
float speech_gain = 1, noise_gain = 1;
|
||||
FILE *f1, *f2;
|
||||
int maxCount;
|
||||
ReNameNoiseDenoiseState *st;
|
||||
ReNameNoiseDenoiseState *noise_state;
|
||||
ReNameNoiseDenoiseState *noisy;
|
||||
st = renamenoise_create(NULL);
|
||||
noise_state = renamenoise_create(NULL);
|
||||
noisy = renamenoise_create(NULL);
|
||||
if (argc != 4) {
|
||||
fprintf(stderr, "usage: %s <speech> <noise> <count>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
f1 = fopen(argv[1], "r");
|
||||
f2 = fopen(argv[2], "r");
|
||||
maxCount = atoi(argv[3]);
|
||||
for (i = 0; i < 150; i++) {
|
||||
short tmp[RENAMENOISE_FRAME_SIZE];
|
||||
fread(tmp, sizeof(short), RENAMENOISE_FRAME_SIZE, f2);
|
||||
}
|
||||
while (1) {
|
||||
renamenoise_fft_cpx X[RENAMENOISE_FREQ_SIZE], Y[RENAMENOISE_FREQ_SIZE], N[RENAMENOISE_FREQ_SIZE], P[RENAMENOISE_WINDOW_SIZE];
|
||||
float Ex[RENAMENOISE_NB_BANDS], Ey[RENAMENOISE_NB_BANDS], En[RENAMENOISE_NB_BANDS], Ep[RENAMENOISE_NB_BANDS];
|
||||
float Exp[RENAMENOISE_NB_BANDS];
|
||||
float Ln[RENAMENOISE_NB_BANDS];
|
||||
float features[RENAMENOISE_NB_FEATURES];
|
||||
float g[RENAMENOISE_NB_BANDS];
|
||||
short tmp[RENAMENOISE_FRAME_SIZE];
|
||||
float vad = 0;
|
||||
float E = 0;
|
||||
if (count == maxCount) {
|
||||
break;
|
||||
}
|
||||
if ((count % 1000) == 0) {
|
||||
fprintf(stderr, "%d\r", count);
|
||||
}
|
||||
if (++gain_change_count > 2821) {
|
||||
speech_gain = pow(10., (-40 + (rand() % 60)) / 20.);
|
||||
noise_gain = pow(10., (-30 + (rand() % 50)) / 20.);
|
||||
if (rand() % 10 == 0) {
|
||||
noise_gain = 0;
|
||||
}
|
||||
noise_gain *= speech_gain;
|
||||
if (rand() % 10 == 0) {
|
||||
speech_gain = 0;
|
||||
}
|
||||
gain_change_count = 0;
|
||||
renamenoise_rand_resp(a_noise, b_noise);
|
||||
renamenoise_rand_resp(a_sig, b_sig);
|
||||
lowpass = RENAMENOISE_FREQ_SIZE * 3000. / 24000. * pow(50., rand() / (double) RAND_MAX);
|
||||
for (i = 0; i < RENAMENOISE_NB_BANDS; i++) {
|
||||
if (renamenoise_eband5ms[i] << RENAMENOISE_FRAME_SIZE_SHIFT > lowpass) {
|
||||
band_lp = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (speech_gain != 0) {
|
||||
fread(tmp, sizeof(short), RENAMENOISE_FRAME_SIZE, f1);
|
||||
if (feof(f1)) {
|
||||
rewind(f1);
|
||||
fread(tmp, sizeof(short), RENAMENOISE_FRAME_SIZE, f1);
|
||||
}
|
||||
for (i = 0; i < RENAMENOISE_FRAME_SIZE; i++) {
|
||||
x[i] = speech_gain * tmp[i];
|
||||
}
|
||||
for (i = 0; i < RENAMENOISE_FRAME_SIZE; i++) {
|
||||
E += tmp[i] * (float) tmp[i];
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < RENAMENOISE_FRAME_SIZE; i++) {
|
||||
x[i] = 0;
|
||||
}
|
||||
E = 0;
|
||||
}
|
||||
if (noise_gain != 0) {
|
||||
fread(tmp, sizeof(short), RENAMENOISE_FRAME_SIZE, f2);
|
||||
if (feof(f2)) {
|
||||
rewind(f2);
|
||||
fread(tmp, sizeof(short), RENAMENOISE_FRAME_SIZE, f2);
|
||||
}
|
||||
for (i = 0; i < RENAMENOISE_FRAME_SIZE; i++) {
|
||||
n[i] = noise_gain * tmp[i];
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < RENAMENOISE_FRAME_SIZE; i++) {
|
||||
n[i] = 0;
|
||||
}
|
||||
}
|
||||
renamenoise_biquad(x, mem_hp_x, x, b_hp, a_hp, RENAMENOISE_FRAME_SIZE);
|
||||
renamenoise_biquad(x, mem_resp_x, x, b_sig, a_sig, RENAMENOISE_FRAME_SIZE);
|
||||
renamenoise_biquad(n, mem_hp_n, n, b_hp, a_hp, RENAMENOISE_FRAME_SIZE);
|
||||
renamenoise_biquad(n, mem_resp_n, n, b_noise, a_noise, RENAMENOISE_FRAME_SIZE);
|
||||
for (i = 0; i < RENAMENOISE_FRAME_SIZE; i++) {
|
||||
xn[i] = x[i] + n[i];
|
||||
}
|
||||
if (E > 1e9f) {
|
||||
vad_cnt = 0;
|
||||
} else if (E > 1e8f) {
|
||||
vad_cnt -= 5;
|
||||
} else if (E > 1e7f) {
|
||||
vad_cnt++;
|
||||
} else {
|
||||
vad_cnt += 2;
|
||||
}
|
||||
if (vad_cnt < 0) {
|
||||
vad_cnt = 0;
|
||||
}
|
||||
if (vad_cnt > 15) {
|
||||
vad_cnt = 15;
|
||||
}
|
||||
|
||||
if (vad_cnt >= 10) {
|
||||
vad = 0;
|
||||
} else if (vad_cnt > 0) {
|
||||
vad = 0.5f;
|
||||
} else {
|
||||
vad = 1.f;
|
||||
}
|
||||
|
||||
renamenoise_frame_analysis(st, Y, Ey, x);
|
||||
renamenoise_frame_analysis(noise_state, N, En, n);
|
||||
for (i = 0; i < RENAMENOISE_NB_BANDS; i++) {
|
||||
Ln[i] = log10(1e-2 + En[i]);
|
||||
}
|
||||
int silence = renamenoise_compute_frame_features(noisy, X, P, Ex, Ep, Exp, features, xn);
|
||||
renamenoise_pitch_filter(X, P, Ex, Ep, Exp, g);
|
||||
// printf("%f %d\n", noisy->last_gain, noisy->last_period);
|
||||
for (i = 0; i < RENAMENOISE_NB_BANDS; i++) {
|
||||
g[i] = sqrt((Ey[i] + 1e-3) / (Ex[i] + 1e-3));
|
||||
if (g[i] > 1) {
|
||||
g[i] = 1;
|
||||
}
|
||||
if (silence || i > band_lp) {
|
||||
g[i] = -1;
|
||||
}
|
||||
if (Ey[i] < 5e-2 && Ex[i] < 5e-2) {
|
||||
g[i] = -1;
|
||||
}
|
||||
if (vad == 0 && noise_gain == 0) {
|
||||
g[i] = -1;
|
||||
}
|
||||
}
|
||||
count++;
|
||||
fwrite(features, sizeof(float), RENAMENOISE_NB_FEATURES, stdout);
|
||||
fwrite(g, sizeof(float), RENAMENOISE_NB_BANDS, stdout);
|
||||
fwrite(Ln, sizeof(float), RENAMENOISE_NB_BANDS, stdout);
|
||||
fwrite(&vad, sizeof(float), 1, stdout);
|
||||
}
|
||||
fprintf(stderr, "matrix size: %d x %d\n", count, RENAMENOISE_NB_FEATURES + 2 * RENAMENOISE_NB_BANDS + 1);
|
||||
fclose(f1);
|
||||
fclose(f2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
363
thirdparty/renamenoise/src/pitch.c
vendored
Normal file
363
thirdparty/renamenoise/src/pitch.c
vendored
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
/*
|
||||
Copyright (c) 2024, The Mumble Developers
|
||||
Copyright (c) 2007-2009, Xiph.Org Foundation
|
||||
Copyright (c) 2007-2008, CSIRO
|
||||
Copyright (c) 2003-2008, Jean-Marc Valin
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
@file pitch.c
|
||||
@brief Pitch analysis
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "pitch.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "math.h"
|
||||
#include "renamenoise_lpc.h"
|
||||
|
||||
static void renamenoise_find_best_pitch(renamenoise_val32 *xcorr, renamenoise_val16 *y, int len, int max_pitch, int *best_pitch) {
|
||||
int i, j;
|
||||
renamenoise_val32 Syy = 1;
|
||||
renamenoise_val16 best_num[2];
|
||||
renamenoise_val32 best_den[2];
|
||||
|
||||
best_num[0] = -1;
|
||||
best_num[1] = -1;
|
||||
best_den[0] = 0;
|
||||
best_den[1] = 0;
|
||||
best_pitch[0] = 0;
|
||||
best_pitch[1] = 1;
|
||||
for (j = 0; j < len; j++) {
|
||||
Syy = RENAMENOISE_ADD(Syy, RENAMENOISE_MULT(y[j], y[j]));
|
||||
}
|
||||
for (i = 0; i < max_pitch; i++) {
|
||||
if (xcorr[i] > 0) {
|
||||
renamenoise_val16 num;
|
||||
renamenoise_val32 xcorr16;
|
||||
xcorr16 = xcorr[i];
|
||||
// Considering the range of xcorr16, this should avoid both underflows and overflows (inf) when squaring xcorr16
|
||||
xcorr16 *= 1e-12f;
|
||||
num = RENAMENOISE_MULT(xcorr16, xcorr16);
|
||||
if (RENAMENOISE_MULT(num, best_den[1]) > RENAMENOISE_MULT(best_num[1], Syy)) {
|
||||
if (RENAMENOISE_MULT(num, best_den[0]) > RENAMENOISE_MULT(best_num[0], Syy)) {
|
||||
best_num[1] = best_num[0];
|
||||
best_den[1] = best_den[0];
|
||||
best_pitch[1] = best_pitch[0];
|
||||
best_num[0] = num;
|
||||
best_den[0] = Syy;
|
||||
best_pitch[0] = i;
|
||||
} else {
|
||||
best_num[1] = num;
|
||||
best_den[1] = Syy;
|
||||
best_pitch[1] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
Syy += RENAMENOISE_MULT(y[i + len], y[i + len]) - RENAMENOISE_MULT(y[i], y[i]);
|
||||
Syy = RENAMENOISE_MAX32(1, Syy);
|
||||
}
|
||||
}
|
||||
|
||||
static void renamenoise_fir5(const renamenoise_val16 *x, const renamenoise_val16 *num, renamenoise_val16 *y, int N, renamenoise_val16 *mem) {
|
||||
int i;
|
||||
renamenoise_val16 num0, num1, num2, num3, num4;
|
||||
renamenoise_val32 mem0, mem1, mem2, mem3, mem4;
|
||||
num0 = num[0];
|
||||
num1 = num[1];
|
||||
num2 = num[2];
|
||||
num3 = num[3];
|
||||
num4 = num[4];
|
||||
mem0 = mem[0];
|
||||
mem1 = mem[1];
|
||||
mem2 = mem[2];
|
||||
mem3 = mem[3];
|
||||
mem4 = mem[4];
|
||||
for (i = 0; i < N; i++) {
|
||||
renamenoise_val32 sum = x[i];
|
||||
sum = RENAMENOISE_MAC(sum, num0, mem0);
|
||||
sum = RENAMENOISE_MAC(sum, num1, mem1);
|
||||
sum = RENAMENOISE_MAC(sum, num2, mem2);
|
||||
sum = RENAMENOISE_MAC(sum, num3, mem3);
|
||||
sum = RENAMENOISE_MAC(sum, num4, mem4);
|
||||
mem4 = mem3;
|
||||
mem3 = mem2;
|
||||
mem2 = mem1;
|
||||
mem1 = mem0;
|
||||
mem0 = x[i];
|
||||
y[i] = sum;
|
||||
}
|
||||
mem[0] = mem0;
|
||||
mem[1] = mem1;
|
||||
mem[2] = mem2;
|
||||
mem[3] = mem3;
|
||||
mem[4] = mem4;
|
||||
}
|
||||
|
||||
void renamenoise_pitch_downsample(renamenoise_sig *x[], renamenoise_val16 *x_lp, int len, int C) {
|
||||
int i;
|
||||
renamenoise_val32 ac[5];
|
||||
renamenoise_val16 tmp = RENAMENOISE_Q15ONE;
|
||||
renamenoise_val16 lpc[4], mem[5] = {0, 0, 0, 0, 0};
|
||||
renamenoise_val16 lpc2[5];
|
||||
renamenoise_val16 c1 = .8f;
|
||||
for (i = 1; i < (len >> 1); i++) {
|
||||
x_lp[i] = RENAMENOISE_HALF(RENAMENOISE_HALF(x[0][(2 * i - 1)] + x[0][(2 * i + 1)]) + x[0][2 * i]);
|
||||
}
|
||||
x_lp[0] = RENAMENOISE_HALF(RENAMENOISE_HALF(x[0][1]) + x[0][0]);
|
||||
if (C == 2) {
|
||||
for (i = 1; i < (len >> 1); i++) {
|
||||
x_lp[i] += RENAMENOISE_HALF(RENAMENOISE_HALF(x[1][(2 * i - 1)] + x[1][(2 * i + 1)]) + x[1][2 * i]);
|
||||
}
|
||||
x_lp[0] += RENAMENOISE_HALF(RENAMENOISE_HALF(x[1][1]) + x[1][0]);
|
||||
}
|
||||
|
||||
_renamenoise_autocorr(x_lp, ac, NULL, 0, 4, len >> 1);
|
||||
|
||||
// Noise floor -40 dB
|
||||
ac[0] *= 1.0001f;
|
||||
// Lag windowing
|
||||
for (i = 1; i <= 4; i++) {
|
||||
// ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));
|
||||
ac[i] -= ac[i] * (.008f * i) * (.008f * i);
|
||||
}
|
||||
|
||||
_renamenoise_lpc(lpc, ac, 4);
|
||||
for (i = 0; i < 4; i++) {
|
||||
tmp = RENAMENOISE_MULT(.9f, tmp);
|
||||
lpc[i] = RENAMENOISE_MULT(lpc[i], tmp);
|
||||
}
|
||||
// Add a zero
|
||||
lpc2[0] = lpc[0] + .8f;
|
||||
lpc2[1] = lpc[1] + RENAMENOISE_MULT(c1, lpc[0]);
|
||||
lpc2[2] = lpc[2] + RENAMENOISE_MULT(c1, lpc[1]);
|
||||
lpc2[3] = lpc[3] + RENAMENOISE_MULT(c1, lpc[2]);
|
||||
lpc2[4] = RENAMENOISE_MULT(c1, lpc[3]);
|
||||
renamenoise_fir5(x_lp, lpc2, x_lp, len >> 1, mem);
|
||||
}
|
||||
|
||||
void renamenoise_pitch_xcorr(const renamenoise_val16 *_x, const renamenoise_val16 *_y, renamenoise_val32 *xcorr, int len, int max_pitch) {
|
||||
// Unrolled version of the pitch correlation -- runs faster on x86 and ARM
|
||||
|
||||
int i;
|
||||
// The EDSP version requires that max_pitch is at least 1,
|
||||
// and that _x is 32-bit aligned.
|
||||
// Since it's hard to put asserts in assembly, put them here.
|
||||
renamenoise_assert(max_pitch > 0);
|
||||
renamenoise_assert((((unsigned char *) _x - (unsigned char *) NULL) & 3) == 0);
|
||||
for (i = 0; i < max_pitch - 3; i += 4) {
|
||||
renamenoise_val32 sum[4] = {0, 0, 0, 0};
|
||||
renamenoise_xcorr_kernel(_x, _y + i, sum, len);
|
||||
xcorr[i] = sum[0];
|
||||
xcorr[i + 1] = sum[1];
|
||||
xcorr[i + 2] = sum[2];
|
||||
xcorr[i + 3] = sum[3];
|
||||
}
|
||||
// In case max_pitch isn't a multiple of 4, do non-unrolled version.
|
||||
for (; i < max_pitch; i++) {
|
||||
renamenoise_val32 sum;
|
||||
sum = renamenoise_inner_prod(_x, _y + i, len);
|
||||
xcorr[i] = sum;
|
||||
}
|
||||
}
|
||||
|
||||
void renamenoise_pitch_search(const renamenoise_val16 *x_lp, renamenoise_val16 *y, int len, int max_pitch, int *pitch) {
|
||||
int i, j;
|
||||
int lag;
|
||||
int best_pitch[2] = {0, 0};
|
||||
int offset;
|
||||
|
||||
renamenoise_assert(len > 0);
|
||||
renamenoise_assert(max_pitch > 0);
|
||||
lag = len + max_pitch;
|
||||
|
||||
renamenoise_stackalloc(renamenoise_val16, x_lp4, len >> 2);
|
||||
renamenoise_stackalloc(renamenoise_val16, y_lp4, lag >> 2);
|
||||
renamenoise_stackalloc(renamenoise_val32, xcorr, max_pitch >> 1);
|
||||
|
||||
// Downsample by 2 again
|
||||
for (j = 0; j < (len >> 2); j++) {
|
||||
x_lp4[j] = x_lp[2 * j];
|
||||
}
|
||||
for (j = 0; j < (lag >> 2); j++) {
|
||||
y_lp4[j] = y[2 * j];
|
||||
}
|
||||
|
||||
// Coarse search with 4x decimation
|
||||
|
||||
renamenoise_pitch_xcorr(x_lp4, y_lp4, xcorr, len >> 2, max_pitch >> 2);
|
||||
|
||||
renamenoise_find_best_pitch(xcorr, y_lp4, len >> 2, max_pitch >> 2, best_pitch);
|
||||
|
||||
// Finer search with 2x decimation
|
||||
for (i = 0; i < (max_pitch >> 1); i++) {
|
||||
renamenoise_val32 sum;
|
||||
xcorr[i] = 0;
|
||||
if (abs(i - 2 * best_pitch[0]) > 2 && abs(i - 2 * best_pitch[1]) > 2) {
|
||||
continue;
|
||||
}
|
||||
sum = renamenoise_inner_prod(x_lp, y + i, len >> 1);
|
||||
xcorr[i] = RENAMENOISE_MAX32(-1, sum);
|
||||
}
|
||||
renamenoise_find_best_pitch(xcorr, y, len >> 1, max_pitch >> 1, best_pitch);
|
||||
|
||||
// Refine by pseudo-interpolation
|
||||
if (best_pitch[0] > 0 && best_pitch[0] < (max_pitch >> 1) - 1) {
|
||||
renamenoise_val32 a, b, c;
|
||||
a = xcorr[best_pitch[0] - 1];
|
||||
b = xcorr[best_pitch[0]];
|
||||
c = xcorr[best_pitch[0] + 1];
|
||||
if ((c - a) > RENAMENOISE_MULT(.7f, b - a)) {
|
||||
offset = 1;
|
||||
} else if ((a - c) > RENAMENOISE_MULT(.7f, b - c)) {
|
||||
offset = -1;
|
||||
} else {
|
||||
offset = 0;
|
||||
}
|
||||
} else {
|
||||
offset = 0;
|
||||
}
|
||||
*pitch = 2 * best_pitch[0] - offset;
|
||||
}
|
||||
|
||||
static renamenoise_val16 renamenoise_compute_pitch_gain(renamenoise_val32 xy, renamenoise_val32 xx, renamenoise_val32 yy) {
|
||||
return xy / sqrt(1 + xx * yy);
|
||||
}
|
||||
|
||||
static const int renamenoise_second_check[16] = {0, 0, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2};
|
||||
renamenoise_val16 renamenoise_remove_doubling(renamenoise_val16 *x, int maxperiod, int minperiod, int N, int *T0_, int prev_period,
|
||||
renamenoise_val16 prev_gain) {
|
||||
int k, i, T, T0;
|
||||
renamenoise_val16 g, g0;
|
||||
renamenoise_val16 pg;
|
||||
renamenoise_val32 xy, xx, yy, xy2;
|
||||
renamenoise_val32 xcorr[3];
|
||||
renamenoise_val32 best_xy, best_yy;
|
||||
int offset;
|
||||
int minperiod0;
|
||||
|
||||
minperiod0 = minperiod;
|
||||
maxperiod /= 2;
|
||||
minperiod /= 2;
|
||||
*T0_ /= 2;
|
||||
prev_period /= 2;
|
||||
N /= 2;
|
||||
x += maxperiod;
|
||||
if (*T0_ >= maxperiod) {
|
||||
*T0_ = maxperiod - 1;
|
||||
}
|
||||
|
||||
T = T0 = *T0_;
|
||||
renamenoise_stackalloc(renamenoise_val32, yy_lookup, maxperiod + 1);
|
||||
renamenoise_dual_inner_prod(x, x, x - T0, N, &xx, &xy);
|
||||
yy_lookup[0] = xx;
|
||||
yy = xx;
|
||||
for (i = 1; i <= maxperiod; i++) {
|
||||
yy = yy + RENAMENOISE_MULT(x[-i], x[-i]) - RENAMENOISE_MULT(x[N - i], x[N - i]);
|
||||
yy_lookup[i] = RENAMENOISE_MAX32(0, yy);
|
||||
}
|
||||
yy = yy_lookup[T0];
|
||||
best_xy = xy;
|
||||
best_yy = yy;
|
||||
g = g0 = renamenoise_compute_pitch_gain(xy, xx, yy);
|
||||
// Look for any pitch at T/k
|
||||
for (k = 2; k <= 15; k++) {
|
||||
int T1, T1b;
|
||||
renamenoise_val16 g1;
|
||||
renamenoise_val16 cont = 0;
|
||||
renamenoise_val16 thresh;
|
||||
T1 = (2 * T0 + k) / (2 * k);
|
||||
if (T1 < minperiod) {
|
||||
break;
|
||||
}
|
||||
// Look for another strong correlation at T1b
|
||||
if (k == 2) {
|
||||
if (T1 + T0 > maxperiod) {
|
||||
T1b = T0;
|
||||
} else {
|
||||
T1b = T0 + T1;
|
||||
}
|
||||
} else {
|
||||
T1b = (2 * renamenoise_second_check[k] * T0 + k) / (2 * k);
|
||||
}
|
||||
renamenoise_dual_inner_prod(x, &x[-T1], &x[-T1b], N, &xy, &xy2);
|
||||
xy = RENAMENOISE_HALF(xy + xy2);
|
||||
yy = RENAMENOISE_HALF(yy_lookup[T1] + yy_lookup[T1b]);
|
||||
g1 = renamenoise_compute_pitch_gain(xy, xx, yy);
|
||||
if (abs(T1 - prev_period) <= 1) {
|
||||
cont = prev_gain;
|
||||
} else if (abs(T1 - prev_period) <= 2 && 5 * k * k < T0) {
|
||||
cont = RENAMENOISE_HALF(prev_gain);
|
||||
} else {
|
||||
cont = 0;
|
||||
}
|
||||
thresh = RENAMENOISE_MAX16(.3f, RENAMENOISE_MULT(.7f, g0) - cont);
|
||||
// Bias against very high pitch (very short period) to avoid false-positives due to short-term correlation
|
||||
if (T1 < 3 * minperiod) {
|
||||
thresh = RENAMENOISE_MAX16(.4f, RENAMENOISE_MULT(.85f, g0) - cont);
|
||||
} else if (T1 < 2 * minperiod) {
|
||||
thresh = RENAMENOISE_MAX16(.5f, RENAMENOISE_MULT(.9f, g0) - cont);
|
||||
}
|
||||
if (g1 > thresh) {
|
||||
best_xy = xy;
|
||||
best_yy = yy;
|
||||
T = T1;
|
||||
g = g1;
|
||||
}
|
||||
}
|
||||
best_xy = RENAMENOISE_MAX32(0, best_xy);
|
||||
if (best_yy <= best_xy) {
|
||||
pg = RENAMENOISE_Q15ONE;
|
||||
} else {
|
||||
pg = best_xy / (best_yy + 1);
|
||||
}
|
||||
|
||||
for (k = 0; k < 3; k++) {
|
||||
xcorr[k] = renamenoise_inner_prod(x, x - (T + k - 1), N);
|
||||
}
|
||||
if ((xcorr[2] - xcorr[0]) > RENAMENOISE_MULT(.7f, xcorr[1] - xcorr[0])) {
|
||||
offset = 1;
|
||||
} else if ((xcorr[0] - xcorr[2]) > RENAMENOISE_MULT(.7f, xcorr[1] - xcorr[2])) {
|
||||
offset = -1;
|
||||
} else {
|
||||
offset = 0;
|
||||
}
|
||||
if (pg > g) {
|
||||
pg = g;
|
||||
}
|
||||
*T0_ = 2 * T + offset;
|
||||
|
||||
if (*T0_ < minperiod0) {
|
||||
*T0_ = minperiod0;
|
||||
}
|
||||
return pg;
|
||||
}
|
||||
137
thirdparty/renamenoise/src/pitch.h
vendored
Normal file
137
thirdparty/renamenoise/src/pitch.h
vendored
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
Copyright (c) 2024, The Mumble Developers
|
||||
Copyright (c) 2007-2009, Xiph.Org Foundation
|
||||
Copyright (c) 2007-2008, CSIRO
|
||||
Copyright (c) 2003-2008, Jean-Marc Valin
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
@file pitch.h
|
||||
@brief Pitch analysis
|
||||
*/
|
||||
|
||||
#ifndef PITCH_H
|
||||
#define PITCH_H
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
void renamenoise_pitch_downsample(renamenoise_sig *x[], renamenoise_val16 *x_lp, int len, int C);
|
||||
|
||||
void renamenoise_pitch_search(const renamenoise_val16 *x_lp, renamenoise_val16 *y, int len, int max_pitch, int *pitch);
|
||||
|
||||
renamenoise_val16 renamenoise_remove_doubling(renamenoise_val16 *x, int maxperiod, int minperiod, int N, int *T0, int prev_period,
|
||||
renamenoise_val16 prev_gain);
|
||||
|
||||
// OPT: This is the kernel you really want to optimize. It gets used a lot by the prefilter and by the PLC.
|
||||
static RENAMENOISE_INLINE void renamenoise_xcorr_kernel(const renamenoise_val16 *x, const renamenoise_val16 *y, renamenoise_val32 sum[4], int len) {
|
||||
int j;
|
||||
renamenoise_val16 y_0, y_1, y_2, y_3;
|
||||
renamenoise_assert(len >= 3);
|
||||
y_3 = 0; /* gcc doesn't realize that y_3 can't be used uninitialized */
|
||||
y_0 = *y++;
|
||||
y_1 = *y++;
|
||||
y_2 = *y++;
|
||||
for (j = 0; j < len - 3; j += 4) {
|
||||
renamenoise_val16 tmp;
|
||||
tmp = *x++;
|
||||
y_3 = *y++;
|
||||
sum[0] = RENAMENOISE_MAC(sum[0], tmp, y_0);
|
||||
sum[1] = RENAMENOISE_MAC(sum[1], tmp, y_1);
|
||||
sum[2] = RENAMENOISE_MAC(sum[2], tmp, y_2);
|
||||
sum[3] = RENAMENOISE_MAC(sum[3], tmp, y_3);
|
||||
tmp = *x++;
|
||||
y_0 = *y++;
|
||||
sum[0] = RENAMENOISE_MAC(sum[0], tmp, y_1);
|
||||
sum[1] = RENAMENOISE_MAC(sum[1], tmp, y_2);
|
||||
sum[2] = RENAMENOISE_MAC(sum[2], tmp, y_3);
|
||||
sum[3] = RENAMENOISE_MAC(sum[3], tmp, y_0);
|
||||
tmp = *x++;
|
||||
y_1 = *y++;
|
||||
sum[0] = RENAMENOISE_MAC(sum[0], tmp, y_2);
|
||||
sum[1] = RENAMENOISE_MAC(sum[1], tmp, y_3);
|
||||
sum[2] = RENAMENOISE_MAC(sum[2], tmp, y_0);
|
||||
sum[3] = RENAMENOISE_MAC(sum[3], tmp, y_1);
|
||||
tmp = *x++;
|
||||
y_2 = *y++;
|
||||
sum[0] = RENAMENOISE_MAC(sum[0], tmp, y_3);
|
||||
sum[1] = RENAMENOISE_MAC(sum[1], tmp, y_0);
|
||||
sum[2] = RENAMENOISE_MAC(sum[2], tmp, y_1);
|
||||
sum[3] = RENAMENOISE_MAC(sum[3], tmp, y_2);
|
||||
}
|
||||
if (j++ < len) {
|
||||
renamenoise_val16 tmp = *x++;
|
||||
y_3 = *y++;
|
||||
sum[0] = RENAMENOISE_MAC(sum[0], tmp, y_0);
|
||||
sum[1] = RENAMENOISE_MAC(sum[1], tmp, y_1);
|
||||
sum[2] = RENAMENOISE_MAC(sum[2], tmp, y_2);
|
||||
sum[3] = RENAMENOISE_MAC(sum[3], tmp, y_3);
|
||||
}
|
||||
if (j++ < len) {
|
||||
renamenoise_val16 tmp = *x++;
|
||||
y_0 = *y++;
|
||||
sum[0] = RENAMENOISE_MAC(sum[0], tmp, y_1);
|
||||
sum[1] = RENAMENOISE_MAC(sum[1], tmp, y_2);
|
||||
sum[2] = RENAMENOISE_MAC(sum[2], tmp, y_3);
|
||||
sum[3] = RENAMENOISE_MAC(sum[3], tmp, y_0);
|
||||
}
|
||||
if (j < len) {
|
||||
renamenoise_val16 tmp = *x++;
|
||||
y_1 = *y++;
|
||||
sum[0] = RENAMENOISE_MAC(sum[0], tmp, y_2);
|
||||
sum[1] = RENAMENOISE_MAC(sum[1], tmp, y_3);
|
||||
sum[2] = RENAMENOISE_MAC(sum[2], tmp, y_0);
|
||||
sum[3] = RENAMENOISE_MAC(sum[3], tmp, y_1);
|
||||
}
|
||||
}
|
||||
|
||||
static RENAMENOISE_INLINE void renamenoise_dual_inner_prod(const renamenoise_val16 *x, const renamenoise_val16 *y01, const renamenoise_val16 *y02,
|
||||
int N, renamenoise_val32 *xy1, renamenoise_val32 *xy2) {
|
||||
int i;
|
||||
renamenoise_val32 xy01 = 0;
|
||||
renamenoise_val32 xy02 = 0;
|
||||
for (i = 0; i < N; i++) {
|
||||
xy01 = RENAMENOISE_MAC(xy01, x[i], y01[i]);
|
||||
xy02 = RENAMENOISE_MAC(xy02, x[i], y02[i]);
|
||||
}
|
||||
*xy1 = xy01;
|
||||
*xy2 = xy02;
|
||||
}
|
||||
|
||||
// We make sure a C version is always available for cases where the overhead of vectorization and passing around an arch flag aren't worth it.
|
||||
static RENAMENOISE_INLINE renamenoise_val32 renamenoise_inner_prod(const renamenoise_val16 *x, const renamenoise_val16 *y, int N) {
|
||||
int i;
|
||||
renamenoise_val32 xy = 0;
|
||||
for (i = 0; i < N; i++) {
|
||||
xy = RENAMENOISE_MAC(xy, x[i], y[i]);
|
||||
}
|
||||
return xy;
|
||||
}
|
||||
|
||||
void renamenoise_pitch_xcorr(const renamenoise_val16 *_x, const renamenoise_val16 *_y, renamenoise_val32 *xcorr, int len, int max_pitch);
|
||||
|
||||
#endif /* PITCH_H */
|
||||
471
thirdparty/renamenoise/src/renamenoise_fft.c
vendored
Normal file
471
thirdparty/renamenoise/src/renamenoise_fft.c
vendored
Normal file
|
|
@ -0,0 +1,471 @@
|
|||
/*
|
||||
Copyright (c) 2024, The Mumble Developers
|
||||
Copyright (c) 2008, Xiph.Org Foundation, CSIRO
|
||||
Copyright (c) 2005-2007, Xiph.Org Foundation
|
||||
Lots of modifications by Jean-Marc Valin
|
||||
Copyright (c) 2003-2004, Mark Borgerding
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// Lots of modifications by Jean-Marc Valin. This code is originally from Mark
|
||||
// Borgerding's KISS-FFT but has been heavily modified to better suit Opus and
|
||||
// was subsequently refactored for ReNameNoise
|
||||
|
||||
#ifndef SKIP_CONFIG_H
|
||||
# ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "_renamenoise_fft_guts.h"
|
||||
|
||||
// The guts header contains all the multiplication and addition macros that are
|
||||
// defined for complex numbers. It also declares the kf_ internal functions.
|
||||
|
||||
static void renamenoise_kf_bfly2(renamenoise_fft_cpx *Fout, int m, int N) {
|
||||
renamenoise_fft_cpx *Fout2;
|
||||
int i;
|
||||
(void) m;
|
||||
if (m == 1) {
|
||||
renamenoise_assert(m == 1);
|
||||
for (i = 0; i < N; i++) {
|
||||
renamenoise_fft_cpx t;
|
||||
Fout2 = Fout + 1;
|
||||
t = *Fout2;
|
||||
RENAMENOISE_C_SUB(*Fout2, *Fout, t);
|
||||
RENAMENOISE_C_ADDTO(*Fout, t);
|
||||
Fout += 2;
|
||||
}
|
||||
} else {
|
||||
renamenoise_val16 tw;
|
||||
tw = 0.7071067812f;
|
||||
// We know that m==4 here because the radix-2 is just after a radix-4
|
||||
renamenoise_assert(m == 4);
|
||||
for (i = 0; i < N; i++) {
|
||||
renamenoise_fft_cpx t;
|
||||
Fout2 = Fout + 4;
|
||||
t = Fout2[0];
|
||||
RENAMENOISE_C_SUB(Fout2[0], Fout[0], t);
|
||||
RENAMENOISE_C_ADDTO(Fout[0], t);
|
||||
|
||||
t.r = RENAMENOISE_S_MUL(RENAMENOISE_ADD(Fout2[1].r, Fout2[1].i), tw);
|
||||
t.i = RENAMENOISE_S_MUL(RENAMENOISE_SUB(Fout2[1].i, Fout2[1].r), tw);
|
||||
RENAMENOISE_C_SUB(Fout2[1], Fout[1], t);
|
||||
RENAMENOISE_C_ADDTO(Fout[1], t);
|
||||
|
||||
t.r = Fout2[2].i;
|
||||
t.i = -Fout2[2].r;
|
||||
RENAMENOISE_C_SUB(Fout2[2], Fout[2], t);
|
||||
RENAMENOISE_C_ADDTO(Fout[2], t);
|
||||
|
||||
t.r = RENAMENOISE_S_MUL(RENAMENOISE_SUB(Fout2[3].i, Fout2[3].r), tw);
|
||||
t.i = RENAMENOISE_S_MUL(-RENAMENOISE_ADD(Fout2[3].i, Fout2[3].r), tw);
|
||||
RENAMENOISE_C_SUB(Fout2[3], Fout[3], t);
|
||||
RENAMENOISE_C_ADDTO(Fout[3], t);
|
||||
Fout += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void renamenoise_kf_bfly4(renamenoise_fft_cpx *Fout, const size_t fstride, const renamenoise_fft_state *st, int m, int N, int mm) {
|
||||
int i;
|
||||
|
||||
if (m == 1) {
|
||||
// Degenerate case where all the twiddles are 1.
|
||||
for (i = 0; i < N; i++) {
|
||||
renamenoise_fft_cpx scratch0, scratch1;
|
||||
|
||||
RENAMENOISE_C_SUB(scratch0, *Fout, Fout[2]);
|
||||
RENAMENOISE_C_ADDTO(*Fout, Fout[2]);
|
||||
RENAMENOISE_C_ADD(scratch1, Fout[1], Fout[3]);
|
||||
RENAMENOISE_C_SUB(Fout[2], *Fout, scratch1);
|
||||
RENAMENOISE_C_ADDTO(*Fout, scratch1);
|
||||
RENAMENOISE_C_SUB(scratch1, Fout[1], Fout[3]);
|
||||
|
||||
Fout[1].r = RENAMENOISE_ADD(scratch0.r, scratch1.i);
|
||||
Fout[1].i = RENAMENOISE_SUB(scratch0.i, scratch1.r);
|
||||
Fout[3].r = RENAMENOISE_SUB(scratch0.r, scratch1.i);
|
||||
Fout[3].i = RENAMENOISE_ADD(scratch0.i, scratch1.r);
|
||||
Fout += 4;
|
||||
}
|
||||
} else {
|
||||
int j;
|
||||
renamenoise_fft_cpx scratch[6];
|
||||
const renamenoise_twiddle_cpx *tw1, *tw2, *tw3;
|
||||
const int m2 = 2 * m;
|
||||
const int m3 = 3 * m;
|
||||
renamenoise_fft_cpx *Fout_beg = Fout;
|
||||
for (i = 0; i < N; i++) {
|
||||
Fout = Fout_beg + i * mm;
|
||||
tw3 = tw2 = tw1 = st->twiddles;
|
||||
// m is guaranteed to be a multiple of 4.
|
||||
for (j = 0; j < m; j++) {
|
||||
RENAMENOISE_C_MUL(scratch[0], Fout[m], *tw1);
|
||||
RENAMENOISE_C_MUL(scratch[1], Fout[m2], *tw2);
|
||||
RENAMENOISE_C_MUL(scratch[2], Fout[m3], *tw3);
|
||||
|
||||
RENAMENOISE_C_SUB(scratch[5], *Fout, scratch[1]);
|
||||
RENAMENOISE_C_ADDTO(*Fout, scratch[1]);
|
||||
RENAMENOISE_C_ADD(scratch[3], scratch[0], scratch[2]);
|
||||
RENAMENOISE_C_SUB(scratch[4], scratch[0], scratch[2]);
|
||||
RENAMENOISE_C_SUB(Fout[m2], *Fout, scratch[3]);
|
||||
tw1 += fstride;
|
||||
tw2 += fstride * 2;
|
||||
tw3 += fstride * 3;
|
||||
RENAMENOISE_C_ADDTO(*Fout, scratch[3]);
|
||||
|
||||
Fout[m].r = RENAMENOISE_ADD(scratch[5].r, scratch[4].i);
|
||||
Fout[m].i = RENAMENOISE_SUB(scratch[5].i, scratch[4].r);
|
||||
Fout[m3].r = RENAMENOISE_SUB(scratch[5].r, scratch[4].i);
|
||||
Fout[m3].i = RENAMENOISE_ADD(scratch[5].i, scratch[4].r);
|
||||
++Fout;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void renamenoise_kf_bfly3(renamenoise_fft_cpx *Fout, const size_t fstride, const renamenoise_fft_state *st, int m, int N, int mm) {
|
||||
int i;
|
||||
size_t k;
|
||||
const size_t m2 = 2 * m;
|
||||
const renamenoise_twiddle_cpx *tw1, *tw2;
|
||||
renamenoise_fft_cpx scratch[5];
|
||||
renamenoise_twiddle_cpx epi3;
|
||||
|
||||
renamenoise_fft_cpx *Fout_beg = Fout;
|
||||
epi3 = st->twiddles[fstride * m];
|
||||
for (i = 0; i < N; i++) {
|
||||
Fout = Fout_beg + i * mm;
|
||||
tw1 = tw2 = st->twiddles;
|
||||
// For non-custom modes, m is guaranteed to be a multiple of 4.
|
||||
k = m;
|
||||
do {
|
||||
RENAMENOISE_C_MUL(scratch[1], Fout[m], *tw1);
|
||||
RENAMENOISE_C_MUL(scratch[2], Fout[m2], *tw2);
|
||||
|
||||
RENAMENOISE_C_ADD(scratch[3], scratch[1], scratch[2]);
|
||||
RENAMENOISE_C_SUB(scratch[0], scratch[1], scratch[2]);
|
||||
tw1 += fstride;
|
||||
tw2 += fstride * 2;
|
||||
|
||||
Fout[m].r = RENAMENOISE_SUB(Fout->r, RENAMENOISE_HALF(scratch[3].r));
|
||||
Fout[m].i = RENAMENOISE_SUB(Fout->i, RENAMENOISE_HALF(scratch[3].i));
|
||||
|
||||
RENAMENOISE_C_MULBYSCALAR(scratch[0], epi3.i);
|
||||
|
||||
RENAMENOISE_C_ADDTO(*Fout, scratch[3]);
|
||||
|
||||
Fout[m2].r = RENAMENOISE_ADD(Fout[m].r, scratch[0].i);
|
||||
Fout[m2].i = RENAMENOISE_SUB(Fout[m].i, scratch[0].r);
|
||||
|
||||
Fout[m].r = RENAMENOISE_SUB(Fout[m].r, scratch[0].i);
|
||||
Fout[m].i = RENAMENOISE_ADD(Fout[m].i, scratch[0].r);
|
||||
|
||||
++Fout;
|
||||
} while (--k);
|
||||
}
|
||||
}
|
||||
|
||||
static void renamenoise_kf_bfly5(renamenoise_fft_cpx *Fout, const size_t fstride, const renamenoise_fft_state *st, int m, int N, int mm) {
|
||||
renamenoise_fft_cpx *Fout0, *Fout1, *Fout2, *Fout3, *Fout4;
|
||||
int i, u;
|
||||
renamenoise_fft_cpx scratch[13];
|
||||
const renamenoise_twiddle_cpx *tw;
|
||||
renamenoise_twiddle_cpx ya, yb;
|
||||
renamenoise_fft_cpx *Fout_beg = Fout;
|
||||
|
||||
ya = st->twiddles[fstride * m];
|
||||
yb = st->twiddles[fstride * 2 * m];
|
||||
tw = st->twiddles;
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
Fout = Fout_beg + i * mm;
|
||||
Fout0 = Fout;
|
||||
Fout1 = Fout0 + m;
|
||||
Fout2 = Fout0 + 2 * m;
|
||||
Fout3 = Fout0 + 3 * m;
|
||||
Fout4 = Fout0 + 4 * m;
|
||||
|
||||
// For non-custom modes, m is guaranteed to be a multiple of 4.
|
||||
for (u = 0; u < m; ++u) {
|
||||
scratch[0] = *Fout0;
|
||||
|
||||
RENAMENOISE_C_MUL(scratch[1], *Fout1, tw[u * fstride]);
|
||||
RENAMENOISE_C_MUL(scratch[2], *Fout2, tw[2 * u * fstride]);
|
||||
RENAMENOISE_C_MUL(scratch[3], *Fout3, tw[3 * u * fstride]);
|
||||
RENAMENOISE_C_MUL(scratch[4], *Fout4, tw[4 * u * fstride]);
|
||||
|
||||
RENAMENOISE_C_ADD(scratch[7], scratch[1], scratch[4]);
|
||||
RENAMENOISE_C_SUB(scratch[10], scratch[1], scratch[4]);
|
||||
RENAMENOISE_C_ADD(scratch[8], scratch[2], scratch[3]);
|
||||
RENAMENOISE_C_SUB(scratch[9], scratch[2], scratch[3]);
|
||||
|
||||
Fout0->r = RENAMENOISE_ADD(Fout0->r, RENAMENOISE_ADD(scratch[7].r, scratch[8].r));
|
||||
Fout0->i = RENAMENOISE_ADD(Fout0->i, RENAMENOISE_ADD(scratch[7].i, scratch[8].i));
|
||||
|
||||
scratch[5].r =
|
||||
RENAMENOISE_ADD(scratch[0].r, RENAMENOISE_ADD(RENAMENOISE_S_MUL(scratch[7].r, ya.r), RENAMENOISE_S_MUL(scratch[8].r, yb.r)));
|
||||
scratch[5].i =
|
||||
RENAMENOISE_ADD(scratch[0].i, RENAMENOISE_ADD(RENAMENOISE_S_MUL(scratch[7].i, ya.r), RENAMENOISE_S_MUL(scratch[8].i, yb.r)));
|
||||
|
||||
scratch[6].r = RENAMENOISE_ADD(RENAMENOISE_S_MUL(scratch[10].i, ya.i), RENAMENOISE_S_MUL(scratch[9].i, yb.i));
|
||||
scratch[6].i = -RENAMENOISE_ADD(RENAMENOISE_S_MUL(scratch[10].r, ya.i), RENAMENOISE_S_MUL(scratch[9].r, yb.i));
|
||||
|
||||
RENAMENOISE_C_SUB(*Fout1, scratch[5], scratch[6]);
|
||||
RENAMENOISE_C_ADD(*Fout4, scratch[5], scratch[6]);
|
||||
|
||||
scratch[11].r =
|
||||
RENAMENOISE_ADD(scratch[0].r, RENAMENOISE_ADD(RENAMENOISE_S_MUL(scratch[7].r, yb.r), RENAMENOISE_S_MUL(scratch[8].r, ya.r)));
|
||||
scratch[11].i =
|
||||
RENAMENOISE_ADD(scratch[0].i, RENAMENOISE_ADD(RENAMENOISE_S_MUL(scratch[7].i, yb.r), RENAMENOISE_S_MUL(scratch[8].i, ya.r)));
|
||||
scratch[12].r = RENAMENOISE_SUB(RENAMENOISE_S_MUL(scratch[9].i, ya.i), RENAMENOISE_S_MUL(scratch[10].i, yb.i));
|
||||
scratch[12].i = RENAMENOISE_SUB(RENAMENOISE_S_MUL(scratch[10].r, yb.i), RENAMENOISE_S_MUL(scratch[9].r, ya.i));
|
||||
|
||||
RENAMENOISE_C_ADD(*Fout2, scratch[11], scratch[12]);
|
||||
RENAMENOISE_C_SUB(*Fout3, scratch[11], scratch[12]);
|
||||
|
||||
++Fout0;
|
||||
++Fout1;
|
||||
++Fout2;
|
||||
++Fout3;
|
||||
++Fout4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void renamenoise_compute_bitrev_table(int Fout, renamenoise_int16 *f, const size_t fstride, int in_stride, renamenoise_int16 *factors,
|
||||
const renamenoise_fft_state *st) {
|
||||
const int p = *factors++; // the radix
|
||||
const int m = *factors++; // stage's fft length/p
|
||||
|
||||
if (m == 1) {
|
||||
int j;
|
||||
for (j = 0; j < p; j++) {
|
||||
*f = Fout + j;
|
||||
f += fstride * in_stride;
|
||||
}
|
||||
} else {
|
||||
int j;
|
||||
for (j = 0; j < p; j++) {
|
||||
renamenoise_compute_bitrev_table(Fout, f, fstride * p, in_stride, factors, st);
|
||||
f += fstride * in_stride;
|
||||
Fout += m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// facbuf is populated by p1,m1,p2,m2, ...
|
||||
// where
|
||||
// p[i] * m[i] = m[i-1]
|
||||
// m0 = n
|
||||
static int renamenoise_kf_factor(int n, renamenoise_int16 *facbuf) {
|
||||
int p = 4;
|
||||
int i;
|
||||
int stages = 0;
|
||||
int nbak = n;
|
||||
|
||||
// factor out powers of 4, powers of 2, then any remaining primes
|
||||
do {
|
||||
while (n % p) {
|
||||
switch (p) {
|
||||
case 4: p = 2; break;
|
||||
case 2: p = 3; break;
|
||||
default: p += 2; break;
|
||||
}
|
||||
if (p > 32000 || (renamenoise_int32) p * (renamenoise_int32) p > n) {
|
||||
p = n; // no more factors, skip to end
|
||||
}
|
||||
}
|
||||
n /= p;
|
||||
if (p > 5) {
|
||||
return 0;
|
||||
}
|
||||
facbuf[2 * stages] = p;
|
||||
if (p == 2 && stages > 1) {
|
||||
facbuf[2 * stages] = 4;
|
||||
facbuf[2] = 2;
|
||||
}
|
||||
stages++;
|
||||
} while (n > 1);
|
||||
n = nbak;
|
||||
// Reverse the order to get the radix 4 at the end, so we can use the
|
||||
// fast degenerate case. It turns out that reversing the order also
|
||||
// improves the noise behaviour.
|
||||
for (i = 0; i < stages / 2; i++) {
|
||||
int tmp;
|
||||
tmp = facbuf[2 * i];
|
||||
facbuf[2 * i] = facbuf[2 * (stages - i - 1)];
|
||||
facbuf[2 * (stages - i - 1)] = tmp;
|
||||
}
|
||||
for (i = 0; i < stages; i++) {
|
||||
n /= facbuf[2 * i];
|
||||
facbuf[2 * i + 1] = n;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void renamenoise_compute_twiddles(renamenoise_twiddle_cpx *twiddles, int nfft) {
|
||||
int i;
|
||||
for (i = 0; i < nfft; ++i) {
|
||||
double phase = (-2 * M_PI / nfft) * i;
|
||||
renamenoise_kf_cexp(twiddles + i, phase);
|
||||
}
|
||||
}
|
||||
|
||||
int renamenoise_fft_alloc_arch_c(renamenoise_fft_state *st) {
|
||||
(void) st;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates all necessary storage space for the fft and ifft.
|
||||
* The return value is a contiguous block of memory. As such,
|
||||
* It can be freed with free().
|
||||
*/
|
||||
renamenoise_fft_state *renamenoise_fft_alloc_twiddles(int nfft, void *mem, size_t *lenmem, const renamenoise_fft_state *base, int arch) {
|
||||
renamenoise_fft_state *st = NULL;
|
||||
size_t memneeded = sizeof(struct renamenoise_fft_state); // twiddle factors
|
||||
|
||||
if (lenmem == NULL) {
|
||||
st = (renamenoise_fft_state *) RENAMENOISE_FFT_MALLOC(memneeded);
|
||||
} else {
|
||||
if (mem != NULL && *lenmem >= memneeded) {
|
||||
st = (renamenoise_fft_state *) mem;
|
||||
}
|
||||
*lenmem = memneeded;
|
||||
}
|
||||
if (st) {
|
||||
renamenoise_int16 *bitrev;
|
||||
renamenoise_twiddle_cpx *twiddles;
|
||||
|
||||
st->nfft = nfft;
|
||||
st->scale = 1.f / nfft;
|
||||
if (base != NULL) {
|
||||
st->twiddles = base->twiddles;
|
||||
st->shift = 0;
|
||||
while (st->shift < 32 && nfft << st->shift != base->nfft) {
|
||||
st->shift++;
|
||||
}
|
||||
if (st->shift >= 32) {
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
st->twiddles = twiddles = (renamenoise_twiddle_cpx *) RENAMENOISE_FFT_MALLOC(sizeof(renamenoise_twiddle_cpx) * nfft);
|
||||
renamenoise_compute_twiddles(twiddles, nfft);
|
||||
st->shift = -1;
|
||||
}
|
||||
if (!renamenoise_kf_factor(nfft, st->factors)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// bitrev
|
||||
st->bitrev = bitrev = (renamenoise_int16 *) RENAMENOISE_FFT_MALLOC(sizeof(renamenoise_int16) * nfft);
|
||||
if (st->bitrev == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
renamenoise_compute_bitrev_table(0, bitrev, 1, 1, st->factors, st);
|
||||
|
||||
// Initialize architecture specific fft parameters
|
||||
if (renamenoise_fft_alloc_arch(st, arch)) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
return st;
|
||||
fail:
|
||||
renamenoise_fft_free(st, arch);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
renamenoise_fft_state *renamenoise_fft_alloc(int nfft, void *mem, size_t *lenmem, int arch) {
|
||||
return renamenoise_fft_alloc_twiddles(nfft, mem, lenmem, NULL, arch);
|
||||
}
|
||||
|
||||
void renamenoise_fft_free_arch_c(renamenoise_fft_state *st) {
|
||||
(void) st;
|
||||
}
|
||||
|
||||
void renamenoise_fft_free(const renamenoise_fft_state *cfg, int arch) {
|
||||
if (cfg) {
|
||||
renamenoise_fft_free_arch((renamenoise_fft_state *) cfg, arch);
|
||||
renamenoise_free2((renamenoise_int16 *) cfg->bitrev);
|
||||
if (cfg->shift < 0) {
|
||||
renamenoise_free2((renamenoise_twiddle_cpx *) cfg->twiddles);
|
||||
}
|
||||
renamenoise_free2((renamenoise_fft_state *) cfg);
|
||||
}
|
||||
}
|
||||
|
||||
void renamenoise_fft_impl(const renamenoise_fft_state *st, renamenoise_fft_cpx *fout) {
|
||||
int m2, m;
|
||||
int p;
|
||||
int L;
|
||||
int fstride[RENAMENOISE_MAXFACTORS];
|
||||
int i;
|
||||
int shift;
|
||||
|
||||
// st->shift can be -1
|
||||
shift = st->shift > 0 ? st->shift : 0;
|
||||
|
||||
fstride[0] = 1;
|
||||
L = 0;
|
||||
do {
|
||||
p = st->factors[2 * L];
|
||||
m = st->factors[2 * L + 1];
|
||||
fstride[L + 1] = fstride[L] * p;
|
||||
L++;
|
||||
} while (m != 1);
|
||||
m = st->factors[2 * L - 1];
|
||||
for (i = L - 1; i >= 0; i--) {
|
||||
if (i != 0) {
|
||||
m2 = st->factors[2 * i - 1];
|
||||
} else {
|
||||
m2 = 1;
|
||||
}
|
||||
switch (st->factors[2 * i]) {
|
||||
case 2: renamenoise_kf_bfly2(fout, m, fstride[i]); break;
|
||||
case 4: renamenoise_kf_bfly4(fout, fstride[i] << shift, st, m, fstride[i], m2); break;
|
||||
case 3: renamenoise_kf_bfly3(fout, fstride[i] << shift, st, m, fstride[i], m2); break;
|
||||
case 5: renamenoise_kf_bfly5(fout, fstride[i] << shift, st, m, fstride[i], m2); break;
|
||||
}
|
||||
m = m2;
|
||||
}
|
||||
}
|
||||
|
||||
void renamenoise_fft_c(const renamenoise_fft_state *st, const renamenoise_fft_cpx *fin, renamenoise_fft_cpx *fout) {
|
||||
int i;
|
||||
renamenoise_val16 scale;
|
||||
scale = st->scale;
|
||||
|
||||
renamenoise_assert2(fin != fout, "In-place FFT not supported");
|
||||
// Bit-reverse the input
|
||||
for (i = 0; i < st->nfft; i++) {
|
||||
renamenoise_fft_cpx x = fin[i];
|
||||
fout[st->bitrev[i]].r = RENAMENOISE_MULT(scale, x.r);
|
||||
fout[st->bitrev[i]].i = RENAMENOISE_MULT(scale, x.i);
|
||||
}
|
||||
renamenoise_fft_impl(st, fout);
|
||||
}
|
||||
150
thirdparty/renamenoise/src/renamenoise_fft.h
vendored
Normal file
150
thirdparty/renamenoise/src/renamenoise_fft.h
vendored
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
Copyright (c) 2024, The Mumble Developers
|
||||
Copyright (c) 2008, Xiph.Org Foundation, CSIRO
|
||||
Copyright (c) 2005-2007, Xiph.Org Foundation
|
||||
Lots of modifications by Jean-Marc Valin
|
||||
Copyright (c) 2003-2004, Mark Borgerding
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef RENAMENOISE_FFT_H
|
||||
#define RENAMENOISE_FFT_H
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#define renamenoise_alloc2(x) malloc(x)
|
||||
#define renamenoise_free2(x) free(x)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RENAMENOISE_FFT_MALLOC renamenoise_alloc2
|
||||
|
||||
#ifndef renamenoise_fft_scalar
|
||||
// default is float
|
||||
# define renamenoise_fft_scalar float
|
||||
# define renamenoise_twiddle_scalar float
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
renamenoise_fft_scalar r;
|
||||
renamenoise_fft_scalar i;
|
||||
} renamenoise_fft_cpx;
|
||||
|
||||
typedef struct {
|
||||
renamenoise_twiddle_scalar r;
|
||||
renamenoise_twiddle_scalar i;
|
||||
} renamenoise_twiddle_cpx;
|
||||
|
||||
#define RENAMENOISE_MAXFACTORS 8
|
||||
// e.g. an fft of length 128 has 4 factors
|
||||
// as far as renamenoisefft is concerned
|
||||
// 4*4*4*2
|
||||
|
||||
typedef struct renamenoise_arch_fft_state {
|
||||
int is_supported;
|
||||
void *priv;
|
||||
} renamenoise_arch_fft_state;
|
||||
|
||||
typedef struct renamenoise_fft_state {
|
||||
int nfft;
|
||||
renamenoise_val16 scale;
|
||||
int shift;
|
||||
renamenoise_int16 factors[2 * RENAMENOISE_MAXFACTORS];
|
||||
const renamenoise_int16 *bitrev;
|
||||
const renamenoise_twiddle_cpx *twiddles;
|
||||
renamenoise_arch_fft_state *arch_fft;
|
||||
} renamenoise_fft_state;
|
||||
|
||||
// typedef struct renamenoise_fft_state* renamenoise_fft_cfg;
|
||||
|
||||
/**
|
||||
* renamenoise_fft_alloc
|
||||
*
|
||||
* Initialize a FFT (or IFFT) algorithm's cfg/state buffer.
|
||||
*
|
||||
* typical usage: renamenoise_fft_cfg
|
||||
* mycfg=renamenoise_fft_alloc(1024,0,NULL,NULL);
|
||||
*
|
||||
* The return value from fft_alloc is a cfg buffer used internally
|
||||
* by the fft routine or NULL.
|
||||
*
|
||||
* If lenmem is NULL, then renamenoise_fft_alloc will allocate a cfg buffer
|
||||
* using malloc. The returned value should be free()d when done to avoid memory
|
||||
* leaks.
|
||||
*
|
||||
* The state can be placed in a user supplied buffer 'mem':
|
||||
* If lenmem is not NULL and mem is not NULL and *lenmem is large enough,
|
||||
* then the function places the cfg in mem and the size used in *lenmem
|
||||
* and returns mem.
|
||||
*
|
||||
* If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough),
|
||||
* then the function returns NULL and places the minimum cfg
|
||||
* buffer size in *lenmem.
|
||||
*/
|
||||
|
||||
renamenoise_fft_state *renamenoise_fft_alloc_twiddles(int nfft, void *mem, size_t *lenmem, const renamenoise_fft_state *base, int arch);
|
||||
|
||||
renamenoise_fft_state *renamenoise_fft_alloc(int nfft, void *mem, size_t *lenmem, int arch);
|
||||
|
||||
/**
|
||||
* renamenoise_fft(cfg,in_out_buf)
|
||||
*
|
||||
* Perform an FFT on a complex input buffer.
|
||||
* for a forward FFT,
|
||||
* fin should be f[0] , f[1] , ... ,f[nfft-1]
|
||||
* fout will be F[0] , F[1] , ... ,F[nfft-1]
|
||||
* Note that each element is complex and can be accessed like
|
||||
* f[k].r and f[k].i
|
||||
*/
|
||||
void renamenoise_fft_c(const renamenoise_fft_state *cfg, const renamenoise_fft_cpx *fin, renamenoise_fft_cpx *fout);
|
||||
|
||||
void renamenoise_fft_impl(const renamenoise_fft_state *st, renamenoise_fft_cpx *fout);
|
||||
|
||||
void renamenoise_fft_free(const renamenoise_fft_state *cfg, int arch);
|
||||
|
||||
void renamenoise_fft_free_arch_c(renamenoise_fft_state *st);
|
||||
int renamenoise_fft_alloc_arch_c(renamenoise_fft_state *st);
|
||||
|
||||
#if !defined(OVERRIDE_RENAMENOISE_FFT)
|
||||
|
||||
# define renamenoise_fft_alloc_arch(_st, arch) ((void) (arch), renamenoise_fft_alloc_arch_c(_st))
|
||||
|
||||
# define renamenoise_fft_free_arch(_st, arch) ((void) (arch), renamenoise_fft_free_arch_c(_st))
|
||||
|
||||
# define renamenoise_fft(_cfg, _fin, _fout, arch) ((void) (arch), renamenoise_fft_c(_cfg, _fin, _fout))
|
||||
|
||||
#endif /* end if !defined(OVERRIDE_RENAMENOISE_FFT) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* RENAMENOISE_FFT_H */
|
||||
111
thirdparty/renamenoise/src/renamenoise_lpc.c
vendored
Normal file
111
thirdparty/renamenoise/src/renamenoise_lpc.c
vendored
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
Copyright (c) 2024, The Mumble Developers
|
||||
Copyright (c) 2009-2010, Xiph.Org Foundation, Written by Jean-Marc Valin
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "renamenoise_lpc.h"
|
||||
|
||||
#include "arch.h"
|
||||
#include "common.h"
|
||||
#include "pitch.h"
|
||||
|
||||
void _renamenoise_lpc(renamenoise_val16 *_lpc, // out: [0...p-1] LPC coefficients
|
||||
const renamenoise_val32 *ac, // in: [0...p] autocorrelation values
|
||||
int p) {
|
||||
int i, j;
|
||||
renamenoise_val32 r;
|
||||
renamenoise_val32 error = ac[0];
|
||||
float *lpc = _lpc;
|
||||
|
||||
RENAMENOISE_CLEAR(lpc, p);
|
||||
if (ac[0] != 0) {
|
||||
for (i = 0; i < p; i++) {
|
||||
// Sum up this iteration's reflection coefficient
|
||||
renamenoise_val32 rr = 0;
|
||||
for (j = 0; j < i; j++) {
|
||||
rr += RENAMENOISE_MULT(lpc[j], ac[i - j]);
|
||||
}
|
||||
rr += ac[i + 1];
|
||||
r = -rr / error;
|
||||
// Update LPC coefficients and total error
|
||||
lpc[i] = r;
|
||||
for (j = 0; j < ((i + 1) >> 1); j++) {
|
||||
renamenoise_val32 tmp1, tmp2;
|
||||
tmp1 = lpc[j];
|
||||
tmp2 = lpc[i - 1 - j];
|
||||
lpc[j] = tmp1 + RENAMENOISE_MULT(r, tmp2);
|
||||
lpc[i - 1 - j] = tmp2 + RENAMENOISE_MULT(r, tmp1);
|
||||
}
|
||||
|
||||
error = error - RENAMENOISE_MULT(RENAMENOISE_MULT(r, r), error);
|
||||
// Bail out once we get 30 dB gain
|
||||
if (error < .001f * ac[0]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int _renamenoise_autocorr(const renamenoise_val16 *x, // in: [0...n-1] samples x
|
||||
renamenoise_val32 *ac, // out: [0...lag-1] ac values
|
||||
const renamenoise_val16 *window, int overlap, int lag, int n) {
|
||||
renamenoise_val32 d;
|
||||
int i, k;
|
||||
int fastN = n - lag;
|
||||
int shift;
|
||||
const renamenoise_val16 *xptr;
|
||||
renamenoise_stackalloc(renamenoise_val16, xx, n);
|
||||
renamenoise_assert(n > 0);
|
||||
renamenoise_assert(overlap >= 0);
|
||||
if (overlap == 0) {
|
||||
xptr = x;
|
||||
} else {
|
||||
for (i = 0; i < n; i++) {
|
||||
xx[i] = x[i];
|
||||
}
|
||||
for (i = 0; i < overlap; i++) {
|
||||
xx[i] = RENAMENOISE_MULT(x[i], window[i]);
|
||||
xx[n - i - 1] = RENAMENOISE_MULT(x[n - i - 1], window[i]);
|
||||
}
|
||||
xptr = xx;
|
||||
}
|
||||
shift = 0;
|
||||
renamenoise_pitch_xcorr(xptr, xptr, ac, fastN, lag + 1);
|
||||
for (k = 0; k <= lag; k++) {
|
||||
for (i = k + fastN, d = 0; i < n; i++) {
|
||||
d = RENAMENOISE_MAC(d, xptr[i], xptr[i - k]);
|
||||
}
|
||||
ac[k] += d;
|
||||
}
|
||||
|
||||
return shift;
|
||||
}
|
||||
41
thirdparty/renamenoise/src/renamenoise_lpc.h
vendored
Normal file
41
thirdparty/renamenoise/src/renamenoise_lpc.h
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
Copyright (c) 2024, The Mumble Developers
|
||||
Copyright (c) 2009-2010, Xiph.Org Foundation, Written by Jean-Marc Valin
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef RENAMENOISE_LPC_H
|
||||
#define RENAMENOISE_LPC_H
|
||||
|
||||
#include "arch.h"
|
||||
#include "common.h"
|
||||
|
||||
void _renamenoise_lpc(renamenoise_val16 *_lpc, const renamenoise_val32 *ac, int p);
|
||||
|
||||
int _renamenoise_autocorr(const renamenoise_val16 *x, renamenoise_val32 *ac, const renamenoise_val16 *window, int overlap, int lag, int n);
|
||||
|
||||
#endif /* RENAMENOISE_LPC_H */
|
||||
164
thirdparty/renamenoise/src/renamenoise_types.h
vendored
Normal file
164
thirdparty/renamenoise/src/renamenoise_types.h
vendored
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
Copyright (c) 2024, The Mumble Developers
|
||||
Copyright (c) 1994-2002, Xiph.Org Foundation, Modified by Jean-Marc Valin
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// renamenoise_types.h based on opus_types.h based on ogg_types.h from libogg
|
||||
|
||||
/**
|
||||
@file renamenoise_types.h
|
||||
@brief Reference implementation types
|
||||
*/
|
||||
#ifndef RENAMENOISE_TYPES_H
|
||||
#define RENAMENOISE_TYPES_H
|
||||
|
||||
// Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.h)
|
||||
#if (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) \
|
||||
|| (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined(HAVE_STDINT_H))
|
||||
# include <stdint.h>
|
||||
|
||||
typedef int16_t renamenoise_int16;
|
||||
typedef uint16_t renamenoise_uint16;
|
||||
typedef int32_t renamenoise_int32;
|
||||
typedef uint32_t renamenoise_uint32;
|
||||
#elif defined(_WIN32)
|
||||
|
||||
# if defined(__CYGWIN__)
|
||||
# include <_G_config.h>
|
||||
typedef _G_int32_t renamenoise_int32;
|
||||
typedef _G_uint32_t renamenoise_uint32;
|
||||
typedef _G_int16 renamenoise_int16;
|
||||
typedef _G_uint16 renamenoise_uint16;
|
||||
# elif defined(__MINGW32__)
|
||||
typedef short renamenoise_int16;
|
||||
typedef unsigned short renamenoise_uint16;
|
||||
typedef int renamenoise_int32;
|
||||
typedef unsigned int renamenoise_uint32;
|
||||
# elif defined(__MWERKS__)
|
||||
typedef int renamenoise_int32;
|
||||
typedef unsigned int renamenoise_uint32;
|
||||
typedef short renamenoise_int16;
|
||||
typedef unsigned short renamenoise_uint16;
|
||||
# else
|
||||
// MSVC/Borland
|
||||
typedef __int32 renamenoise_int32;
|
||||
typedef unsigned __int32 renamenoise_uint32;
|
||||
typedef __int16 renamenoise_int16;
|
||||
typedef unsigned __int16 renamenoise_uint16;
|
||||
# endif
|
||||
|
||||
#elif defined(__MACOS__)
|
||||
|
||||
# include <sys/types.h>
|
||||
typedef SInt16 renamenoise_int16;
|
||||
typedef UInt16 renamenoise_uint16;
|
||||
typedef SInt32 renamenoise_int32;
|
||||
typedef UInt32 renamenoise_uint32;
|
||||
|
||||
#elif (defined(__APPLE__) && defined(__MACH__)) // MacOS X Framework build
|
||||
|
||||
# include <sys/types.h>
|
||||
typedef int16_t renamenoise_int16;
|
||||
typedef u_int16_t renamenoise_uint16;
|
||||
typedef int32_t renamenoise_int32;
|
||||
typedef u_int32_t renamenoise_uint32;
|
||||
|
||||
#elif defined(__BEOS__)
|
||||
|
||||
// Be
|
||||
# include <inttypes.h>
|
||||
typedef int16 renamenoise_int16;
|
||||
typedef u_int16 renamenoise_uint16;
|
||||
typedef int32_t renamenoise_int32;
|
||||
typedef u_int32_t renamenoise_uint32;
|
||||
|
||||
#elif defined(__EMX__)
|
||||
|
||||
// OS/2 GCC
|
||||
typedef short renamenoise_int16;
|
||||
typedef unsigned short renamenoise_uint16;
|
||||
typedef int renamenoise_int32;
|
||||
typedef unsigned int renamenoise_uint32;
|
||||
|
||||
#elif defined(DJGPP)
|
||||
|
||||
// DJGPP
|
||||
typedef short renamenoise_int16;
|
||||
typedef unsigned short renamenoise_uint16;
|
||||
typedef int renamenoise_int32;
|
||||
typedef unsigned int renamenoise_uint32;
|
||||
|
||||
#elif defined(R5900)
|
||||
|
||||
// PS2 EE
|
||||
typedef int renamenoise_int32;
|
||||
typedef unsigned renamenoise_uint32;
|
||||
typedef short renamenoise_int16;
|
||||
typedef unsigned short renamenoise_uint16;
|
||||
|
||||
#elif defined(__SYMBIAN32__)
|
||||
|
||||
// Symbian GCC
|
||||
typedef signed short renamenoise_int16;
|
||||
typedef unsigned short renamenoise_uint16;
|
||||
typedef signed int renamenoise_int32;
|
||||
typedef unsigned int renamenoise_uint32;
|
||||
|
||||
#elif defined(CONFIG_TI_C54X) || defined(CONFIG_TI_C55X)
|
||||
|
||||
typedef short renamenoise_int16;
|
||||
typedef unsigned short renamenoise_uint16;
|
||||
typedef long renamenoise_int32;
|
||||
typedef unsigned long renamenoise_uint32;
|
||||
|
||||
#elif defined(CONFIG_TI_C6X)
|
||||
|
||||
typedef short renamenoise_int16;
|
||||
typedef unsigned short renamenoise_uint16;
|
||||
typedef int renamenoise_int32;
|
||||
typedef unsigned int renamenoise_uint32;
|
||||
|
||||
#else
|
||||
|
||||
// Give up, take a reasonable guess
|
||||
typedef short renamenoise_int16;
|
||||
typedef unsigned short renamenoise_uint16;
|
||||
typedef int renamenoise_int32;
|
||||
typedef unsigned int renamenoise_uint32;
|
||||
|
||||
#endif
|
||||
|
||||
#define renamenoise_int int // used for counters etc; at least 16 bits
|
||||
#define renamenoise_int64 long long
|
||||
#define renamenoise_int8 signed char
|
||||
|
||||
#define renamenoise_uint unsigned int // used for counters etc; at least 16 bits
|
||||
#define renamenoise_uint64 unsigned long long
|
||||
#define renamenoise_uint8 unsigned char
|
||||
|
||||
#endif /* RENAMENOISE_TYPES_H */
|
||||
238
thirdparty/renamenoise/src/rnn.c
vendored
Normal file
238
thirdparty/renamenoise/src/rnn.c
vendored
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
Copyright (c) 2024, The Mumble Developers
|
||||
Copyright (c) 2012-2017, Jean-Marc Valin
|
||||
Copyright (c) 2008-2011, Octasic Inc
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "rnn.h"
|
||||
|
||||
#include "arch.h"
|
||||
#include "common.h"
|
||||
#include "renamenoise_types.h"
|
||||
#include "rnn_data.h"
|
||||
#include "tansig_table.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static RENAMENOISE_INLINE float renamenoise_tansig_approx(float x) {
|
||||
int i;
|
||||
float y, dy;
|
||||
float sign = 1;
|
||||
// Tests are reversed to catch NaNs
|
||||
if (!(x < 8)) {
|
||||
return 1;
|
||||
}
|
||||
if (!(x > -8)) {
|
||||
return -1;
|
||||
}
|
||||
// Another check in case of -ffast-math
|
||||
if (renamenoise_isnan(x)) {
|
||||
return 0;
|
||||
}
|
||||
if (x < 0) {
|
||||
x = -x;
|
||||
sign = -1;
|
||||
}
|
||||
i = (int) floor(.5f + 25 * x);
|
||||
x -= .04f * i;
|
||||
y = renamenoise_tansig_table[i];
|
||||
dy = 1 - y * y;
|
||||
y = y + x * dy * (1 - y * x);
|
||||
return sign * y;
|
||||
}
|
||||
|
||||
static RENAMENOISE_INLINE float renamenoise_sigmoid_approx(float x) {
|
||||
return .5 + .5 * renamenoise_tansig_approx(.5 * x);
|
||||
}
|
||||
|
||||
static RENAMENOISE_INLINE float renamenoise_relu(float x) {
|
||||
return x < 0 ? 0 : x;
|
||||
}
|
||||
|
||||
static void renamenoise_faxpy(float *restrict a, const renamenoise_rnn_weight *restrict b, const int k, const float u) {
|
||||
if (u == 0.0) {
|
||||
return;
|
||||
}
|
||||
for (int idx = 0; idx < k; idx++) {
|
||||
a[idx] += b[idx] * u;
|
||||
}
|
||||
}
|
||||
|
||||
static void renamenoise_faxpy2(float *restrict a, const renamenoise_rnn_weight *restrict b, const int k, const float u, const float u2) {
|
||||
if (u == 0.0 || u2 == 0.0) {
|
||||
return;
|
||||
}
|
||||
for (int idx = 0; idx < k; idx++) {
|
||||
a[idx] += (b[idx] * u) * u2;
|
||||
}
|
||||
}
|
||||
|
||||
void renamenoise_compute_dense(const ReNameNoiseDenseLayer *layer, float *output, const float *input) {
|
||||
int i, j;
|
||||
int N, M;
|
||||
M = layer->nb_inputs;
|
||||
N = layer->nb_neurons;
|
||||
const renamenoise_rnn_weight *ip = layer->input_weights;
|
||||
|
||||
// Compute update gate.
|
||||
for (i = 0; i < N; i++) {
|
||||
output[i] = layer->bias[i];
|
||||
}
|
||||
for (j = 0; j < M; j++, ip += N) {
|
||||
renamenoise_faxpy(output, ip, N, input[j]);
|
||||
}
|
||||
if (layer->activation == RENAMENOISE_ACTIVATION_SIGMOID) {
|
||||
for (i = 0; i < N; i++) {
|
||||
output[i] = renamenoise_sigmoid_approx(RENAMENOISE_WEIGHTS_SCALE * output[i]);
|
||||
}
|
||||
} else if (layer->activation == RENAMENOISE_ACTIVATION_TANH) {
|
||||
for (i = 0; i < N; i++) {
|
||||
output[i] = renamenoise_tansig_approx(RENAMENOISE_WEIGHTS_SCALE * output[i]);
|
||||
}
|
||||
} else if (layer->activation == RENAMENOISE_ACTIVATION_RELU) {
|
||||
for (i = 0; i < N; i++) {
|
||||
output[i] = renamenoise_relu(RENAMENOISE_WEIGHTS_SCALE * output[i]);
|
||||
}
|
||||
} else {
|
||||
renamenoise_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
void renamenoise_compute_gru(const ReNameNoiseGRULayer *gru, float *state, const float *input) {
|
||||
int i, j;
|
||||
int N, M;
|
||||
int stride;
|
||||
float z[RENAMENOISE_MAX_NEURONS];
|
||||
float r[RENAMENOISE_MAX_NEURONS];
|
||||
float h[RENAMENOISE_MAX_NEURONS];
|
||||
M = gru->nb_inputs;
|
||||
N = gru->nb_neurons;
|
||||
stride = 3 * N;
|
||||
const renamenoise_rnn_weight *ip = gru->input_weights;
|
||||
const renamenoise_rnn_weight *rp = gru->recurrent_weights;
|
||||
|
||||
// Compute update gate.
|
||||
for (i = 0; i < N; i++) {
|
||||
z[i] = gru->bias[i];
|
||||
}
|
||||
for (j = 0; j < M; j++, ip += stride) {
|
||||
renamenoise_faxpy(z, ip, N, input[j]);
|
||||
}
|
||||
for (j = 0; j < N; j++, rp += stride) {
|
||||
renamenoise_faxpy(z, rp, N, state[j]);
|
||||
}
|
||||
for (i = 0; i < N; i++) {
|
||||
z[i] = renamenoise_sigmoid_approx(RENAMENOISE_WEIGHTS_SCALE * z[i]);
|
||||
}
|
||||
|
||||
// Compute reset gate.
|
||||
for (i = 0; i < N; i++) {
|
||||
r[i] = gru->bias[N + i];
|
||||
}
|
||||
ip = gru->input_weights + N;
|
||||
rp = gru->recurrent_weights + N;
|
||||
for (j = 0; j < M; j++, ip += stride) {
|
||||
renamenoise_faxpy(r, ip, N, input[j]);
|
||||
}
|
||||
for (j = 0; j < N; j++, rp += stride) {
|
||||
renamenoise_faxpy(r, rp, N, state[j]);
|
||||
}
|
||||
for (i = 0; i < N; i++) {
|
||||
r[i] = renamenoise_sigmoid_approx(RENAMENOISE_WEIGHTS_SCALE * r[i]);
|
||||
}
|
||||
|
||||
// Compute output.
|
||||
for (i = 0; i < N; i++) {
|
||||
h[i] = gru->bias[2 * N + i];
|
||||
}
|
||||
|
||||
ip = gru->input_weights + 2 * N;
|
||||
rp = gru->recurrent_weights + 2 * N;
|
||||
|
||||
for (j = 0; j < M; j++, ip += stride) {
|
||||
renamenoise_faxpy(h, ip, N, input[j]);
|
||||
}
|
||||
|
||||
for (j = 0; j < N; j++, rp += stride) {
|
||||
renamenoise_faxpy2(h, rp, N, state[j], r[j]);
|
||||
}
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
if (gru->activation == RENAMENOISE_ACTIVATION_SIGMOID) {
|
||||
h[i] = renamenoise_sigmoid_approx(RENAMENOISE_WEIGHTS_SCALE * h[i]);
|
||||
} else if (gru->activation == RENAMENOISE_ACTIVATION_TANH) {
|
||||
h[i] = renamenoise_tansig_approx(RENAMENOISE_WEIGHTS_SCALE * h[i]);
|
||||
} else if (gru->activation == RENAMENOISE_ACTIVATION_RELU) {
|
||||
h[i] = renamenoise_relu(RENAMENOISE_WEIGHTS_SCALE * h[i]);
|
||||
} else {
|
||||
renamenoise_unreachable();
|
||||
}
|
||||
h[i] = z[i] * state[i] + (1 - z[i]) * h[i];
|
||||
}
|
||||
|
||||
memcpy((void *) state, (void *) h, N * sizeof(float));
|
||||
}
|
||||
|
||||
#define RENAMENOISE_INPUT_SIZE 42
|
||||
|
||||
void renamenoise_compute_rnn(ReNameNoiseRNNState *rnn, float *gains, float *vad, const float *input) {
|
||||
int i;
|
||||
float dense_out[RENAMENOISE_MAX_NEURONS];
|
||||
float noise_input[RENAMENOISE_MAX_NEURONS * 3];
|
||||
float denoise_input[RENAMENOISE_MAX_NEURONS * 3];
|
||||
renamenoise_compute_dense(rnn->model->input_dense, dense_out, input);
|
||||
renamenoise_compute_gru(rnn->model->vad_gru, rnn->vad_gru_state, dense_out);
|
||||
renamenoise_compute_dense(rnn->model->vad_output, vad, rnn->vad_gru_state);
|
||||
for (i = 0; i < rnn->model->input_dense_size; i++) {
|
||||
noise_input[i] = dense_out[i];
|
||||
}
|
||||
for (i = 0; i < rnn->model->vad_gru_size; i++) {
|
||||
noise_input[i + rnn->model->input_dense_size] = rnn->vad_gru_state[i];
|
||||
}
|
||||
for (i = 0; i < RENAMENOISE_INPUT_SIZE; i++) {
|
||||
noise_input[i + rnn->model->input_dense_size + rnn->model->vad_gru_size] = input[i];
|
||||
}
|
||||
renamenoise_compute_gru(rnn->model->noise_gru, rnn->noise_gru_state, noise_input);
|
||||
|
||||
for (i = 0; i < rnn->model->vad_gru_size; i++) {
|
||||
denoise_input[i] = rnn->vad_gru_state[i];
|
||||
}
|
||||
for (i = 0; i < rnn->model->noise_gru_size; i++) {
|
||||
denoise_input[i + rnn->model->vad_gru_size] = rnn->noise_gru_state[i];
|
||||
}
|
||||
for (i = 0; i < RENAMENOISE_INPUT_SIZE; i++) {
|
||||
denoise_input[i + rnn->model->vad_gru_size + rnn->model->noise_gru_size] = input[i];
|
||||
}
|
||||
renamenoise_compute_gru(rnn->model->denoise_gru, rnn->denoise_gru_state, denoise_input);
|
||||
renamenoise_compute_dense(rnn->model->denoise_output, gains, rnn->denoise_gru_state);
|
||||
}
|
||||
72
thirdparty/renamenoise/src/rnn.h
vendored
Normal file
72
thirdparty/renamenoise/src/rnn.h
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
Copyright (c) 2024, The Mumble Developers
|
||||
Copyright (c) 2017, Jean-Marc Valin
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef RNN_H_
|
||||
#define RNN_H_
|
||||
|
||||
#include "renamenoise.h"
|
||||
#include "renamenoise_types.h"
|
||||
|
||||
#define RENAMENOISE_WEIGHTS_SCALE (1.f / 256)
|
||||
|
||||
#define RENAMENOISE_MAX_NEURONS 128
|
||||
|
||||
#define RENAMENOISE_ACTIVATION_TANH 0
|
||||
#define RENAMENOISE_ACTIVATION_SIGMOID 1
|
||||
#define RENAMENOISE_ACTIVATION_RELU 2
|
||||
|
||||
typedef signed char renamenoise_rnn_weight;
|
||||
|
||||
typedef struct {
|
||||
const renamenoise_rnn_weight *bias;
|
||||
const renamenoise_rnn_weight *input_weights;
|
||||
int nb_inputs;
|
||||
int nb_neurons;
|
||||
int activation;
|
||||
} ReNameNoiseDenseLayer;
|
||||
|
||||
typedef struct {
|
||||
const renamenoise_rnn_weight *bias;
|
||||
const renamenoise_rnn_weight *input_weights;
|
||||
const renamenoise_rnn_weight *recurrent_weights;
|
||||
int nb_inputs;
|
||||
int nb_neurons;
|
||||
int activation;
|
||||
} ReNameNoiseGRULayer;
|
||||
|
||||
typedef struct ReNameNoiseRNNState ReNameNoiseRNNState;
|
||||
|
||||
void renamenoise_compute_dense(const ReNameNoiseDenseLayer *layer, float *output, const float *input);
|
||||
|
||||
void renamenoise_compute_gru(const ReNameNoiseGRULayer *gru, float *state, const float *input);
|
||||
|
||||
void renamenoise_compute_rnn(ReNameNoiseRNNState *rnn, float *gains, float *vad, const float *input);
|
||||
|
||||
#endif /* RNN_H_ */
|
||||
3735
thirdparty/renamenoise/src/rnn_data.c
vendored
Normal file
3735
thirdparty/renamenoise/src/rnn_data.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
63
thirdparty/renamenoise/src/rnn_data.h
vendored
Normal file
63
thirdparty/renamenoise/src/rnn_data.h
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
Copyright (c) 2024, The Mumble Developers
|
||||
Copyright (c) 2017, Xiph.Org Foundation, Jean-Marc Valin
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef RNN_DATA_H
|
||||
#define RNN_DATA_H
|
||||
|
||||
#include "rnn.h"
|
||||
|
||||
struct ReNameNoiseModel {
|
||||
int input_dense_size;
|
||||
const ReNameNoiseDenseLayer *input_dense;
|
||||
|
||||
int vad_gru_size;
|
||||
const ReNameNoiseGRULayer *vad_gru;
|
||||
|
||||
int noise_gru_size;
|
||||
const ReNameNoiseGRULayer *noise_gru;
|
||||
|
||||
int denoise_gru_size;
|
||||
const ReNameNoiseGRULayer *denoise_gru;
|
||||
|
||||
int denoise_output_size;
|
||||
const ReNameNoiseDenseLayer *denoise_output;
|
||||
|
||||
int vad_output_size;
|
||||
const ReNameNoiseDenseLayer *vad_output;
|
||||
};
|
||||
|
||||
struct ReNameNoiseRNNState {
|
||||
const ReNameNoiseModel *model;
|
||||
float *vad_gru_state;
|
||||
float *noise_gru_state;
|
||||
float *denoise_gru_state;
|
||||
};
|
||||
|
||||
#endif /* RNN_DATA_H */
|
||||
179
thirdparty/renamenoise/src/rnn_reader.c
vendored
Normal file
179
thirdparty/renamenoise/src/rnn_reader.c
vendored
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
Copyright (c) 2024, The Mumble Developers
|
||||
Copyright (c) 2018, Gregor Richards
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "renamenoise.h"
|
||||
#include "rnn.h"
|
||||
#include "rnn_data.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
// Although these values are the same as in rnn.h, we make them separate to
|
||||
// avoid accidentally burning internal values into a file format
|
||||
#define F_RENAMENOISE_ACTIVATION_TANH 0
|
||||
#define F_RENAMENOISE_ACTIVATION_SIGMOID 1
|
||||
#define F_RENAMENOISE_ACTIVATION_RELU 2
|
||||
|
||||
ReNameNoiseModel *renamenoise_model_from_file(FILE *f) {
|
||||
int i, in;
|
||||
|
||||
if (fscanf(f, "renamenoise-nu model file version %d\n", &in) != 1 || in != 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ReNameNoiseModel *ret = calloc(1, sizeof(ReNameNoiseModel));
|
||||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define RENAMENOISE_ALLOC_LAYER(type, name) \
|
||||
type *name; \
|
||||
name = calloc(1, sizeof(type)); \
|
||||
if (!name) { \
|
||||
renamenoise_model_free(ret); \
|
||||
return NULL; \
|
||||
} \
|
||||
ret->name = name
|
||||
|
||||
RENAMENOISE_ALLOC_LAYER(ReNameNoiseDenseLayer, input_dense);
|
||||
RENAMENOISE_ALLOC_LAYER(ReNameNoiseGRULayer, vad_gru);
|
||||
RENAMENOISE_ALLOC_LAYER(ReNameNoiseGRULayer, noise_gru);
|
||||
RENAMENOISE_ALLOC_LAYER(ReNameNoiseGRULayer, denoise_gru);
|
||||
RENAMENOISE_ALLOC_LAYER(ReNameNoiseDenseLayer, denoise_output);
|
||||
RENAMENOISE_ALLOC_LAYER(ReNameNoiseDenseLayer, vad_output);
|
||||
|
||||
#define RENAMENOISE_INPUT_VAL(name) \
|
||||
do { \
|
||||
if (fscanf(f, "%d", &in) != 1 || in < 0 || in > 128) { \
|
||||
renamenoise_model_free(ret); \
|
||||
return NULL; \
|
||||
} \
|
||||
name = in; \
|
||||
} while (0)
|
||||
|
||||
#define RENAMENOISE_INPUT_ACTIVATION(name) \
|
||||
do { \
|
||||
int activation; \
|
||||
RENAMENOISE_INPUT_VAL(activation); \
|
||||
switch (activation) { \
|
||||
case F_RENAMENOISE_ACTIVATION_SIGMOID: name = RENAMENOISE_ACTIVATION_SIGMOID; break; \
|
||||
case F_RENAMENOISE_ACTIVATION_RELU: name = RENAMENOISE_ACTIVATION_RELU; break; \
|
||||
default: name = RENAMENOISE_ACTIVATION_TANH; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define RENAMENOISE_INPUT_ARRAY(name, len) \
|
||||
do { \
|
||||
renamenoise_rnn_weight *values = malloc((len) * sizeof(renamenoise_rnn_weight)); \
|
||||
if (!values) { \
|
||||
renamenoise_model_free(ret); \
|
||||
return NULL; \
|
||||
} \
|
||||
name = values; \
|
||||
for (i = 0; i < (len); i++) { \
|
||||
if (fscanf(f, "%d", &in) != 1) { \
|
||||
renamenoise_model_free(ret); \
|
||||
return NULL; \
|
||||
} \
|
||||
values[i] = in; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define RENAMENOISE_INPUT_DENSE(name) \
|
||||
do { \
|
||||
RENAMENOISE_INPUT_VAL(name->nb_inputs); \
|
||||
RENAMENOISE_INPUT_VAL(name->nb_neurons); \
|
||||
ret->name##_size = name->nb_neurons; \
|
||||
RENAMENOISE_INPUT_ACTIVATION(name->activation); \
|
||||
RENAMENOISE_INPUT_ARRAY(name->input_weights, name->nb_inputs * name->nb_neurons); \
|
||||
RENAMENOISE_INPUT_ARRAY(name->bias, name->nb_neurons); \
|
||||
} while (0)
|
||||
|
||||
#define RENAMENOISE_INPUT_GRU(name) \
|
||||
do { \
|
||||
RENAMENOISE_INPUT_VAL(name->nb_inputs); \
|
||||
RENAMENOISE_INPUT_VAL(name->nb_neurons); \
|
||||
ret->name##_size = name->nb_neurons; \
|
||||
RENAMENOISE_INPUT_ACTIVATION(name->activation); \
|
||||
RENAMENOISE_INPUT_ARRAY(name->input_weights, name->nb_inputs * name->nb_neurons * 3); \
|
||||
RENAMENOISE_INPUT_ARRAY(name->recurrent_weights, name->nb_neurons * name->nb_neurons * 3); \
|
||||
RENAMENOISE_INPUT_ARRAY(name->bias, name->nb_neurons * 3); \
|
||||
} while (0)
|
||||
|
||||
RENAMENOISE_INPUT_DENSE(input_dense);
|
||||
RENAMENOISE_INPUT_GRU(vad_gru);
|
||||
RENAMENOISE_INPUT_GRU(noise_gru);
|
||||
RENAMENOISE_INPUT_GRU(denoise_gru);
|
||||
RENAMENOISE_INPUT_DENSE(denoise_output);
|
||||
RENAMENOISE_INPUT_DENSE(vad_output);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void renamenoise_model_free(ReNameNoiseModel *model) {
|
||||
#define RENAMENOISE_FREE_MAYBE(ptr) \
|
||||
do { \
|
||||
if (ptr) \
|
||||
free(ptr); \
|
||||
} while (0)
|
||||
#define RENAMENOISE_FREE_DENSE(name) \
|
||||
do { \
|
||||
if (model->name) { \
|
||||
free((void *) model->name->input_weights); \
|
||||
free((void *) model->name->bias); \
|
||||
free((void *) model->name); \
|
||||
} \
|
||||
} while (0)
|
||||
#define RENAMENOISE_FREE_GRU(name) \
|
||||
do { \
|
||||
if (model->name) { \
|
||||
free((void *) model->name->input_weights); \
|
||||
free((void *) model->name->recurrent_weights); \
|
||||
free((void *) model->name->bias); \
|
||||
free((void *) model->name); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
if (!model) {
|
||||
return;
|
||||
}
|
||||
RENAMENOISE_FREE_DENSE(input_dense);
|
||||
RENAMENOISE_FREE_GRU(vad_gru);
|
||||
RENAMENOISE_FREE_GRU(noise_gru);
|
||||
RENAMENOISE_FREE_GRU(denoise_gru);
|
||||
RENAMENOISE_FREE_DENSE(denoise_output);
|
||||
RENAMENOISE_FREE_DENSE(vad_output);
|
||||
free(model);
|
||||
}
|
||||
94
thirdparty/renamenoise/src/rnn_train.py
vendored
Executable file
94
thirdparty/renamenoise/src/rnn_train.py
vendored
Executable file
|
|
@ -0,0 +1,94 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
#
|
||||
# Copyright (c) 2017, Jean-Marc Valin
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# - Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# - Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from keras.models import Sequential
|
||||
from keras.models import Model
|
||||
from keras.layers import Input
|
||||
from keras.layers import Dense
|
||||
from keras.layers import LSTM
|
||||
from keras.layers import GRU
|
||||
from keras.layers import SimpleRNN
|
||||
from keras.layers import Dropout
|
||||
from keras import losses
|
||||
import h5py
|
||||
|
||||
from keras import backend as K
|
||||
import numpy as np
|
||||
|
||||
print('Build model...')
|
||||
main_input = Input(shape=(None, 22), name='main_input')
|
||||
#x = Dense(44, activation='relu')(main_input)
|
||||
#x = GRU(44, dropout=0.0, recurrent_dropout=0.0, activation='tanh', recurrent_activation='sigmoid', return_sequences=True)(x)
|
||||
x=main_input
|
||||
x = GRU(128, activation='tanh', recurrent_activation='sigmoid', return_sequences=True)(x)
|
||||
#x = GRU(128, return_sequences=True)(x)
|
||||
#x = GRU(22, activation='relu', return_sequences=True)(x)
|
||||
x = Dense(22, activation='sigmoid')(x)
|
||||
#x = Dense(22, activation='softplus')(x)
|
||||
model = Model(inputs=main_input, outputs=x)
|
||||
|
||||
batch_size = 32
|
||||
|
||||
print('Loading data...')
|
||||
with h5py.File('denoise_data.h5', 'r') as hf:
|
||||
all_data = hf['denoise_data'][:]
|
||||
print('done.')
|
||||
|
||||
window_size = 500
|
||||
|
||||
nb_sequences = len(all_data)//window_size
|
||||
print(nb_sequences, ' sequences')
|
||||
x_train = all_data[:nb_sequences*window_size, :-22]
|
||||
x_train = np.reshape(x_train, (nb_sequences, window_size, 22))
|
||||
|
||||
y_train = np.copy(all_data[:nb_sequences*window_size, -22:])
|
||||
y_train = np.reshape(y_train, (nb_sequences, window_size, 22))
|
||||
|
||||
#y_train = -20*np.log10(np.add(y_train, .03));
|
||||
|
||||
all_data = 0;
|
||||
x_train = x_train.astype('float32')
|
||||
y_train = y_train.astype('float32')
|
||||
|
||||
print(len(x_train), 'train sequences. x shape =', x_train.shape, 'y shape = ', y_train.shape)
|
||||
|
||||
# try using different optimizers and different optimizer configs
|
||||
model.compile(loss='mean_squared_error',
|
||||
optimizer='adam',
|
||||
metrics=['binary_accuracy'])
|
||||
|
||||
print('Train...')
|
||||
model.fit(x_train, y_train,
|
||||
batch_size=batch_size,
|
||||
epochs=200,
|
||||
validation_data=(x_train, y_train))
|
||||
model.save("newweights.hdf5")
|
||||
55
thirdparty/renamenoise/src/tansig_table.h
vendored
Normal file
55
thirdparty/renamenoise/src/tansig_table.h
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
Copyright (c) 2024, The Mumble Developers
|
||||
Copyright (c) 2017, Jean-Marc Valin
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* This file is auto-generated by gen_tables */
|
||||
|
||||
#ifndef TANSIG_TABLE_H
|
||||
#define TANSIG_TABLE_H
|
||||
|
||||
static const float renamenoise_tansig_table[201] = {
|
||||
0.000000f, 0.039979f, 0.079830f, 0.119427f, 0.158649f, 0.197375f, 0.235496f, 0.272905f, 0.309507f, 0.345214f, 0.379949f, 0.413644f, 0.446244f,
|
||||
0.477700f, 0.507977f, 0.537050f, 0.564900f, 0.591519f, 0.616909f, 0.641077f, 0.664037f, 0.685809f, 0.706419f, 0.725897f, 0.744277f, 0.761594f,
|
||||
0.777888f, 0.793199f, 0.807569f, 0.821040f, 0.833655f, 0.845456f, 0.856485f, 0.866784f, 0.876393f, 0.885352f, 0.893698f, 0.901468f, 0.908698f,
|
||||
0.915420f, 0.921669f, 0.927473f, 0.932862f, 0.937863f, 0.942503f, 0.946806f, 0.950795f, 0.954492f, 0.957917f, 0.961090f, 0.964028f, 0.966747f,
|
||||
0.969265f, 0.971594f, 0.973749f, 0.975743f, 0.977587f, 0.979293f, 0.980869f, 0.982327f, 0.983675f, 0.984921f, 0.986072f, 0.987136f, 0.988119f,
|
||||
0.989027f, 0.989867f, 0.990642f, 0.991359f, 0.992020f, 0.992631f, 0.993196f, 0.993718f, 0.994199f, 0.994644f, 0.995055f, 0.995434f, 0.995784f,
|
||||
0.996108f, 0.996407f, 0.996682f, 0.996937f, 0.997172f, 0.997389f, 0.997590f, 0.997775f, 0.997946f, 0.998104f, 0.998249f, 0.998384f, 0.998508f,
|
||||
0.998623f, 0.998728f, 0.998826f, 0.998916f, 0.999000f, 0.999076f, 0.999147f, 0.999213f, 0.999273f, 0.999329f, 0.999381f, 0.999428f, 0.999472f,
|
||||
0.999513f, 0.999550f, 0.999585f, 0.999617f, 0.999646f, 0.999673f, 0.999699f, 0.999722f, 0.999743f, 0.999763f, 0.999781f, 0.999798f, 0.999813f,
|
||||
0.999828f, 0.999841f, 0.999853f, 0.999865f, 0.999875f, 0.999885f, 0.999893f, 0.999902f, 0.999909f, 0.999916f, 0.999923f, 0.999929f, 0.999934f,
|
||||
0.999939f, 0.999944f, 0.999948f, 0.999952f, 0.999956f, 0.999959f, 0.999962f, 0.999965f, 0.999968f, 0.999970f, 0.999973f, 0.999975f, 0.999977f,
|
||||
0.999978f, 0.999980f, 0.999982f, 0.999983f, 0.999984f, 0.999986f, 0.999987f, 0.999988f, 0.999989f, 0.999990f, 0.999990f, 0.999991f, 0.999992f,
|
||||
0.999992f, 0.999993f, 0.999994f, 0.999994f, 0.999994f, 0.999995f, 0.999995f, 0.999996f, 0.999996f, 0.999996f, 0.999997f, 0.999997f, 0.999997f,
|
||||
0.999997f, 0.999997f, 0.999998f, 0.999998f, 0.999998f, 0.999998f, 0.999998f, 0.999998f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f,
|
||||
0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||
1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
|
||||
};
|
||||
|
||||
#endif /* TANSIG_TABLE_H */
|
||||
Loading…
Add table
Reference in a new issue