mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-12-19 14:32:34 +00:00
Merge branch 'master' into 'more-flip-fixes'
# Conflicts: # src/g_demo.cpp
This commit is contained in:
commit
237b72ea3e
69 changed files with 7488 additions and 66 deletions
19
.gitlab/issue_templates/Default.md
Normal file
19
.gitlab/issue_templates/Default.md
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# What version of Ring Racers are you playing?
|
||||||
|
|
||||||
|
(Replace this text with the version number. You can see this on the title screen at the bottom-left corner.)
|
||||||
|
|
||||||
|
# What is the fastest way to trigger the bug?
|
||||||
|
|
||||||
|
(Bugs that can't be reproduced are extremely hard to fix. If you can't make it happen on demand, try and describe the circumstances where it triggers.)
|
||||||
|
|
||||||
|
# What is the bugged behavior?
|
||||||
|
|
||||||
|
(Describe what happens when you encounter the bug.)
|
||||||
|
|
||||||
|
# What do you expect to happen instead?
|
||||||
|
|
||||||
|
(Describe what should be happening instead of the bugged behavior.)
|
||||||
|
|
||||||
|
# Logs, videos, or screenshots that showcase the issue
|
||||||
|
|
||||||
|
(For crash bugs, look for an .RPT file, or your `latest-log.txt`. You can drag it directly into this window.)
|
||||||
|
|
@ -20,6 +20,14 @@
|
||||||
- libvorbis + libvorbisenc
|
- libvorbis + libvorbisenc
|
||||||
Copyright (c) 2002-2020 Xiph.org Foundation
|
Copyright (c) 2002-2020 Xiph.org Foundation
|
||||||
https://github.com/xiph/vorbis
|
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
|
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 PNG::PNG)
|
||||||
target_link_libraries(SRB2SDL2 PRIVATE CURL::libcurl)
|
target_link_libraries(SRB2SDL2 PRIVATE CURL::libcurl)
|
||||||
target_link_libraries(SRB2SDL2 PRIVATE Opus::opus)
|
target_link_libraries(SRB2SDL2 PRIVATE Opus::opus)
|
||||||
|
target_link_libraries(SRB2SDL2 PRIVATE ReNameNoise::renamenoise)
|
||||||
if("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD")
|
if("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD")
|
||||||
target_link_libraries(SRB2SDL2 PRIVATE -lexecinfo)
|
target_link_libraries(SRB2SDL2 PRIVATE -lexecinfo)
|
||||||
target_link_libraries(SRB2SDL2 PRIVATE -lpthread)
|
target_link_libraries(SRB2SDL2 PRIVATE -lpthread)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
@ -89,8 +90,12 @@ int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
|
||||||
|
|
||||||
int luaO_str2d (const char *s, lua_Number *result) {
|
int luaO_str2d (const char *s, lua_Number *result) {
|
||||||
char *endptr;
|
char *endptr;
|
||||||
double r = lua_str2number(s, &endptr);
|
long r = lua_str2number(s, &endptr);
|
||||||
*result = (lua_Number)r;
|
if (r > INT32_MAX)
|
||||||
|
r = INT32_MAX;
|
||||||
|
else if (r < INT32_MIN)
|
||||||
|
r = INT32_MIN;
|
||||||
|
*result = (lua_Number)r;
|
||||||
if (endptr == s) return 0; /* conversion failed */
|
if (endptr == s) return 0; /* conversion failed */
|
||||||
if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
|
if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
|
||||||
*result = cast_num(strtoul(s, &endptr, 16));
|
*result = cast_num(strtoul(s, &endptr, 16));
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@ CV_PossibleValue_t descriptiveinput_cons_t[] = {
|
||||||
{6, "6Bt. (C)"},
|
{6, "6Bt. (C)"},
|
||||||
{7, "6Bt. (D)"},
|
{7, "6Bt. (D)"},
|
||||||
{8, "6Bt. (E)"},
|
{8, "6Bt. (E)"},
|
||||||
|
{9, "6Bt. (F)"},
|
||||||
{0, NULL}
|
{0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include "../cxxutil.hpp"
|
#include "../cxxutil.hpp"
|
||||||
#include "../z_zone.h"
|
#include "../z_zone.h"
|
||||||
|
#include "../lua_script.h"
|
||||||
|
|
||||||
using namespace srb2;
|
using namespace srb2;
|
||||||
|
|
||||||
|
|
@ -117,6 +118,9 @@ void* PoolAllocator::allocate()
|
||||||
|
|
||||||
void PoolAllocator::deallocate(void* p)
|
void PoolAllocator::deallocate(void* p)
|
||||||
{
|
{
|
||||||
|
// Required in case this block is reused
|
||||||
|
LUA_InvalidateUserdata(p);
|
||||||
|
|
||||||
FreeBlock* block = reinterpret_cast<FreeBlock*>(p);
|
FreeBlock* block = reinterpret_cast<FreeBlock*>(p);
|
||||||
block->next = head_;
|
block->next = head_;
|
||||||
head_ = block;
|
head_ = block;
|
||||||
|
|
@ -127,6 +131,12 @@ void PoolAllocator::release()
|
||||||
ChunkFooter* next = nullptr;
|
ChunkFooter* next = nullptr;
|
||||||
for (ChunkFooter* i = first_chunk_; i != nullptr; i = next)
|
for (ChunkFooter* i = first_chunk_; i != nullptr; i = next)
|
||||||
{
|
{
|
||||||
|
uint8_t *chunk = (uint8_t*)i->start;
|
||||||
|
for (size_t j = 0; j < blocks_; j++)
|
||||||
|
{
|
||||||
|
// Invalidate all blocks that possibly weren't passed to deallocate
|
||||||
|
LUA_InvalidateUserdata(chunk + (j * block_size_));
|
||||||
|
}
|
||||||
next = i->next;
|
next = i->next;
|
||||||
Z_Free(i->start);
|
Z_Free(i->start);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -622,7 +622,7 @@ void Lagless_OnChange(void);
|
||||||
consvar_t cv_lagless = NetVar("lagless", "Off").on_off().onchange(Lagless_OnChange);
|
consvar_t cv_lagless = NetVar("lagless", "Off").on_off().onchange(Lagless_OnChange);
|
||||||
|
|
||||||
// max file size to send to a player (in kilobytes)
|
// max file size to send to a player (in kilobytes)
|
||||||
consvar_t cv_maxsend = NetVar("maxsend", "51200").min_max(0, 51200);
|
consvar_t cv_maxsend = NetVar("maxsend", "204800").min_max(-1, 999999999);
|
||||||
|
|
||||||
consvar_t cv_noticedownload = NetVar("noticedownload", "Off").on_off();
|
consvar_t cv_noticedownload = NetVar("noticedownload", "Off").on_off();
|
||||||
consvar_t cv_pingtimeout = NetVar("maxdelaytimeout", "10").min_max(8, 120);
|
consvar_t cv_pingtimeout = NetVar("maxdelaytimeout", "10").min_max(8, 120);
|
||||||
|
|
@ -1410,6 +1410,10 @@ consvar_t cv_voice_loopback = Player("voice_loopback", "Off")
|
||||||
.dont_save()
|
.dont_save()
|
||||||
.description("When on, plays the local player's voice");
|
.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")
|
consvar_t cv_voice_proximity = NetVar("voice_proximity", "On")
|
||||||
.on_off()
|
.on_off()
|
||||||
.description("Whether proximity effects for voice chat are enabled on the server.");
|
.description("Whether proximity effects for voice chat are enabled on the server.");
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <opus.h>
|
#include <opus.h>
|
||||||
|
#include <renamenoise.h>
|
||||||
|
|
||||||
#include "i_time.h"
|
#include "i_time.h"
|
||||||
#include "i_net.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];
|
static UINT32 g_player_voice_frames_this_tic[MAXPLAYERS];
|
||||||
#define MAX_PLAYER_VOICE_FRAMES_PER_TIC 3
|
#define MAX_PLAYER_VOICE_FRAMES_PER_TIC 3
|
||||||
static OpusEncoder *g_local_opus_encoder;
|
static OpusEncoder *g_local_opus_encoder;
|
||||||
|
static ReNameNoiseDenoiseState *g_local_renamenoise_state;
|
||||||
static UINT64 g_local_opus_frame = 0;
|
static UINT64 g_local_opus_frame = 0;
|
||||||
#define SRB2_VOICE_OPUS_FRAME_SIZE 960
|
#define SRB2_VOICE_OPUS_FRAME_SIZE 960
|
||||||
static float g_local_voice_buffer[SRB2_VOICE_OPUS_FRAME_SIZE];
|
static float g_local_voice_buffer[SRB2_VOICE_OPUS_FRAME_SIZE];
|
||||||
|
|
@ -1585,6 +1587,7 @@ static void SendAskInfo(INT32 node)
|
||||||
serverelem_t serverlist[MAXSERVERLIST];
|
serverelem_t serverlist[MAXSERVERLIST];
|
||||||
UINT32 serverlistcount = 0;
|
UINT32 serverlistcount = 0;
|
||||||
UINT32 serverlistultimatecount = 0;
|
UINT32 serverlistultimatecount = 0;
|
||||||
|
boolean serverlistmode = false;
|
||||||
|
|
||||||
static boolean resendserverlistnode[MAXNETNODES];
|
static boolean resendserverlistnode[MAXNETNODES];
|
||||||
static tic_t serverlistepoch;
|
static tic_t serverlistepoch;
|
||||||
|
|
@ -1655,7 +1658,7 @@ static boolean SL_InsertServer(serverinfo_pak* info, SINT8 node)
|
||||||
if (i == UINT32_MAX)
|
if (i == UINT32_MAX)
|
||||||
{
|
{
|
||||||
// Still not added to list... check for modifiedgame rejections
|
// Still not added to list... check for modifiedgame rejections
|
||||||
if (serverlistultimatecount)
|
if (serverlistmode)
|
||||||
{
|
{
|
||||||
// We're on the server browser page. We can reject based on our room.
|
// We're on the server browser page. We can reject based on our room.
|
||||||
if (
|
if (
|
||||||
|
|
@ -2573,6 +2576,25 @@ static void Command_connect(void)
|
||||||
|
|
||||||
static void ResetNode(INT32 node);
|
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
|
// CL_ClearPlayer
|
||||||
//
|
//
|
||||||
|
|
@ -2648,23 +2670,7 @@ void CL_ClearPlayer(INT32 playernum)
|
||||||
// Clear voice chat data
|
// Clear voice chat data
|
||||||
S_ResetVoiceQueue(playernum);
|
S_ResetVoiceQueue(playernum);
|
||||||
|
|
||||||
{
|
RecreatePlayerOpusDecoder(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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -3709,6 +3715,17 @@ void D_QuitNetGame(void)
|
||||||
#endif
|
#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)
|
static void InitializeLocalVoiceEncoder(void)
|
||||||
{
|
{
|
||||||
// Reset voice opus encoder for local "player 1"
|
// Reset voice opus encoder for local "player 1"
|
||||||
|
|
@ -3815,6 +3832,7 @@ static void Got_AddPlayer(const UINT8 **p, INT32 playernum)
|
||||||
}
|
}
|
||||||
DEBFILE("spawning me\n");
|
DEBFILE("spawning me\n");
|
||||||
|
|
||||||
|
InitializeLocalVoiceDenoiser();
|
||||||
InitializeLocalVoiceEncoder();
|
InitializeLocalVoiceEncoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7592,6 +7610,28 @@ void NetVoiceUpdate(void)
|
||||||
g_local_voice_buffer[i] *= ampfactor;
|
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;
|
float softmem = 0.f;
|
||||||
opus_pcm_soft_clip(g_local_voice_buffer, SRB2_VOICE_OPUS_FRAME_SIZE, 1, &softmem);
|
opus_pcm_soft_clip(g_local_voice_buffer, SRB2_VOICE_OPUS_FRAME_SIZE, 1, &softmem);
|
||||||
|
|
||||||
|
|
@ -7670,6 +7710,10 @@ void NetVoiceUpdate(void)
|
||||||
|
|
||||||
if (cv_voice_loopback.value)
|
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);
|
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);
|
S_QueueVoiceFrameFromPlayer(consoleplayer, g_local_voice_buffer, result * sizeof(float), false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -508,6 +508,7 @@ struct serverelem_t
|
||||||
|
|
||||||
extern serverelem_t serverlist[MAXSERVERLIST];
|
extern serverelem_t serverlist[MAXSERVERLIST];
|
||||||
extern UINT32 serverlistcount, serverlistultimatecount;
|
extern UINT32 serverlistcount, serverlistultimatecount;
|
||||||
|
extern boolean serverlistmode;
|
||||||
extern INT32 mapchangepending;
|
extern INT32 mapchangepending;
|
||||||
|
|
||||||
// Points inside doomcom
|
// Points inside doomcom
|
||||||
|
|
|
||||||
|
|
@ -1209,6 +1209,7 @@ void D_ClearState(void)
|
||||||
SV_StopServer();
|
SV_StopServer();
|
||||||
SV_ResetServer();
|
SV_ResetServer();
|
||||||
serverlistultimatecount = 0;
|
serverlistultimatecount = 0;
|
||||||
|
serverlistmode = false;
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
CL_ClearPlayer(i);
|
CL_ClearPlayer(i);
|
||||||
|
|
|
||||||
|
|
@ -204,7 +204,7 @@ UINT8 *PutFileNeeded(UINT16 firstfile)
|
||||||
// Store in the upper four bits
|
// Store in the upper four bits
|
||||||
if (!cv_downloading.value)
|
if (!cv_downloading.value)
|
||||||
filestatus += (2 << 4); // Won't send
|
filestatus += (2 << 4); // Won't send
|
||||||
else if ((wadfiles[i]->filesize <= (UINT32)cv_maxsend.value * 1024))
|
else if (cv_maxsend.value == -1 || wadfiles[i]->filesize <= (UINT32)cv_maxsend.value * 1024)
|
||||||
filestatus += (1 << 4); // Will send if requested
|
filestatus += (1 << 4); // Will send if requested
|
||||||
// else
|
// else
|
||||||
// filestatus += (0 << 4); -- Won't send, too big
|
// filestatus += (0 << 4); -- Won't send, too big
|
||||||
|
|
@ -964,7 +964,7 @@ static boolean AddFileToSendQueue(INT32 node, const char *filename, UINT8 fileid
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle huge file requests (i.e. bigger than cv_maxsend.value KB)
|
// Handle huge file requests (i.e. bigger than cv_maxsend.value KB)
|
||||||
if (wadfiles[i]->filesize > (UINT32)cv_maxsend.value * 1024)
|
if (cv_maxsend.value != -1 && wadfiles[i]->filesize > (UINT32)cv_maxsend.value * 1024)
|
||||||
{
|
{
|
||||||
// Too big
|
// Too big
|
||||||
// Don't inform client (client sucks, man)
|
// Don't inform client (client sucks, man)
|
||||||
|
|
|
||||||
|
|
@ -754,6 +754,7 @@ struct player_t
|
||||||
UINT16 bigwaypointgap; // timer counts down if finish line distance gap is too big to update waypoint
|
UINT16 bigwaypointgap; // timer counts down if finish line distance gap is too big to update waypoint
|
||||||
UINT8 startboost; // (0 to 125) - Boost you get from start of race
|
UINT8 startboost; // (0 to 125) - Boost you get from start of race
|
||||||
UINT8 dropdashboost; // Boost you get when holding A while respawning
|
UINT8 dropdashboost; // Boost you get when holding A while respawning
|
||||||
|
UINT8 aciddropdashboost; // acid dropdash
|
||||||
|
|
||||||
UINT16 flashing;
|
UINT16 flashing;
|
||||||
UINT16 spinouttimer; // Spin-out from a banana peel or oil slick (was "pw_bananacam")
|
UINT16 spinouttimer; // Spin-out from a banana peel or oil slick (was "pw_bananacam")
|
||||||
|
|
@ -1131,6 +1132,7 @@ struct player_t
|
||||||
UINT32 lastringboost; // What was our accumulated boost when locking the award?
|
UINT32 lastringboost; // What was our accumulated boost when locking the award?
|
||||||
|
|
||||||
UINT8 amps;
|
UINT8 amps;
|
||||||
|
UINT8 recentamps;
|
||||||
UINT8 amppickup;
|
UINT8 amppickup;
|
||||||
UINT8 ampspending;
|
UINT8 ampspending;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1506,6 +1506,13 @@ void readlevelheader(MYFILE *f, char * name)
|
||||||
|
|
||||||
mapheaderinfo[num]->cameraHeight = camheight;;
|
mapheaderinfo[num]->cameraHeight = camheight;;
|
||||||
}
|
}
|
||||||
|
else if (fastcmp(word, "NOCOMMS") || fastcmp(word, "NOCOMM"))
|
||||||
|
{
|
||||||
|
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||||
|
mapheaderinfo[num]->levelflags |= LF_NOCOMMS;
|
||||||
|
else
|
||||||
|
mapheaderinfo[num]->levelflags &= ~LF_NOCOMMS;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
deh_warning("Level header %d: unknown word '%s'", num, word);
|
deh_warning("Level header %d: unknown word '%s'", num, word);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4747,6 +4747,7 @@ struct int_const_s const INT_CONST[] = {
|
||||||
{"LF_NOZONE",LF_NOZONE},
|
{"LF_NOZONE",LF_NOZONE},
|
||||||
{"LF_SECTIONRACE",LF_SECTIONRACE},
|
{"LF_SECTIONRACE",LF_SECTIONRACE},
|
||||||
{"LF_SUBTRACTNUM",LF_SUBTRACTNUM},
|
{"LF_SUBTRACTNUM",LF_SUBTRACTNUM},
|
||||||
|
{"LF_NOCOMMS",LF_NOCOMMS},
|
||||||
// And map flags
|
// And map flags
|
||||||
{"LF2_HIDEINMENU",LF2_HIDEINMENU},
|
{"LF2_HIDEINMENU",LF2_HIDEINMENU},
|
||||||
{"LF2_NOTIMEATTACK",LF2_NOTIMEATTACK},
|
{"LF2_NOTIMEATTACK",LF2_NOTIMEATTACK},
|
||||||
|
|
|
||||||
|
|
@ -605,6 +605,7 @@ struct mapheader_t
|
||||||
#define LF_NOZONE (1<<1) ///< Don't include "ZONE" on level title
|
#define LF_NOZONE (1<<1) ///< Don't include "ZONE" on level title
|
||||||
#define LF_SECTIONRACE (1<<2) ///< Section race level
|
#define LF_SECTIONRACE (1<<2) ///< Section race level
|
||||||
#define LF_SUBTRACTNUM (1<<3) ///< Use subtractive position number (for bright levels)
|
#define LF_SUBTRACTNUM (1<<3) ///< Use subtractive position number (for bright levels)
|
||||||
|
#define LF_NOCOMMS (1<<4) ///< Disable dialogue "communications in progress" graphic
|
||||||
|
|
||||||
#define LF2_HIDEINMENU (1<<0) ///< Hide in the multiplayer menu
|
#define LF2_HIDEINMENU (1<<0) ///< Hide in the multiplayer menu
|
||||||
#define LF2_NOTIMEATTACK (1<<1) ///< Hide this map in Time Attack modes
|
#define LF2_NOTIMEATTACK (1<<1) ///< Hide this map in Time Attack modes
|
||||||
|
|
|
||||||
|
|
@ -2241,7 +2241,7 @@ void G_BeginRecording(void)
|
||||||
// Save follower's colour
|
// Save follower's colour
|
||||||
for (j = (numskincolors+2)-1; j > 0; j--)
|
for (j = (numskincolors+2)-1; j > 0; j--)
|
||||||
{
|
{
|
||||||
if (Followercolor_cons_t[j].value == players[i].followercolor)
|
if (Followercolor_cons_t[j].value == player->followercolor)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
demobuf.p += copy_fixed_buf(demobuf.p, Followercolor_cons_t[j].strvalue, g_buffer_sizes.color_name); // Not KartColor_Names because followercolor has extra values such as "Match"
|
demobuf.p += copy_fixed_buf(demobuf.p, Followercolor_cons_t[j].strvalue, g_buffer_sizes.color_name); // Not KartColor_Names because followercolor has extra values such as "Match"
|
||||||
|
|
|
||||||
|
|
@ -3415,6 +3415,11 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
||||||
return; // cap
|
return; // cap
|
||||||
|
|
||||||
blend = HWR_SurfaceBlend(blendmode, trans, &Surf);
|
blend = HWR_SurfaceBlend(blendmode, trans, &Surf);
|
||||||
|
|
||||||
|
// if sprite has PF_ALWAYSONTOP, draw on top of everything.
|
||||||
|
if (cv_debugrender_spriteclip.value || spr->mobj->renderflags & RF_ALWAYSONTOP)
|
||||||
|
blend |= PF_NoDepthTest;
|
||||||
|
|
||||||
if (!trans && !blendmode)
|
if (!trans && !blendmode)
|
||||||
{
|
{
|
||||||
// BP: i agree that is little better in environement but it don't
|
// BP: i agree that is little better in environement but it don't
|
||||||
|
|
@ -3896,6 +3901,11 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
||||||
return; // cap
|
return; // cap
|
||||||
|
|
||||||
blend = HWR_SurfaceBlend(blendmode, trans, &Surf);
|
blend = HWR_SurfaceBlend(blendmode, trans, &Surf);
|
||||||
|
|
||||||
|
// if sprite has PF_ALWAYSONTOP, draw on top of everything.
|
||||||
|
if (cv_debugrender_spriteclip.value || spr->mobj->renderflags & RF_ALWAYSONTOP)
|
||||||
|
blend |= PF_NoDepthTest;
|
||||||
|
|
||||||
if (!trans && !blendmode)
|
if (!trans && !blendmode)
|
||||||
{
|
{
|
||||||
// BP: i agree that is little better in environement but it don't
|
// BP: i agree that is little better in environement but it don't
|
||||||
|
|
@ -3921,7 +3931,10 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
||||||
|
|
||||||
if (HWR_UseShader())
|
if (HWR_UseShader())
|
||||||
{
|
{
|
||||||
shader = (R_ThingIsPaperSprite(spr->mobj) || R_ThingIsFloorSprite(spr->mobj)) ? SHADER_SPRITE : SHADER_SPRITECLIPHACK;;
|
shader = (R_ThingIsPaperSprite(spr->mobj)
|
||||||
|
|| R_ThingIsFloorSprite(spr->mobj)
|
||||||
|
|| (spr->mobj->terrain && spr->mobj->terrain->floorClip)
|
||||||
|
) ? SHADER_SPRITE : SHADER_SPRITECLIPHACK;
|
||||||
blend |= PF_ColorMapped;
|
blend |= PF_ColorMapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5007,6 +5020,9 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
x1 = tr_x + x1 * rightcos;
|
x1 = tr_x + x1 * rightcos;
|
||||||
x2 = tr_x - x2 * rightcos;
|
x2 = tr_x - x2 * rightcos;
|
||||||
|
|
||||||
|
if (thing->terrain && thing->terrain->floorClip)
|
||||||
|
spr_topoffset -= thing->terrain->floorClip;
|
||||||
|
|
||||||
if (vflip)
|
if (vflip)
|
||||||
{
|
{
|
||||||
gz = FIXED_TO_FLOAT(interp.z + thing->height) - (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
|
gz = FIXED_TO_FLOAT(interp.z + thing->height) - (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
|
||||||
|
|
|
||||||
|
|
@ -1723,6 +1723,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
||||||
HWD.pfnSetShader(SHADER_MODEL); // model shader
|
HWD.pfnSetShader(SHADER_MODEL); // model shader
|
||||||
{
|
{
|
||||||
float this_scale = FIXED_TO_FLOAT(spr->mobj->scale);
|
float this_scale = FIXED_TO_FLOAT(spr->mobj->scale);
|
||||||
|
fixed_t floorClip = spr->mobj->terrain ? spr->mobj->terrain->floorClip : 0;
|
||||||
|
float finalfloorClip = FIXED_TO_FLOAT(FixedMul(floorClip, mapobjectscale)*P_MobjFlip(spr->mobj));
|
||||||
|
|
||||||
float xs = this_scale * FIXED_TO_FLOAT(spr->mobj->spritexscale);
|
float xs = this_scale * FIXED_TO_FLOAT(spr->mobj->spritexscale);
|
||||||
float ys = this_scale * FIXED_TO_FLOAT(spr->mobj->spriteyscale);
|
float ys = this_scale * FIXED_TO_FLOAT(spr->mobj->spriteyscale);
|
||||||
|
|
@ -1733,7 +1735,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
||||||
// offset perpendicular to the camera angle
|
// offset perpendicular to the camera angle
|
||||||
p.x -= ox * gl_viewsin;
|
p.x -= ox * gl_viewsin;
|
||||||
p.y += ox * gl_viewcos;
|
p.y += ox * gl_viewcos;
|
||||||
p.z += oy;
|
p.z += oy - finalfloorClip;
|
||||||
|
|
||||||
if (R_ThingIsUsingBakedOffsets(spr->mobj))
|
if (R_ThingIsUsingBakedOffsets(spr->mobj))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@
|
||||||
--------------------------------------------------*/
|
--------------------------------------------------*/
|
||||||
static inline boolean K_ItemButtonWasDown(const player_t *player)
|
static inline boolean K_ItemButtonWasDown(const player_t *player)
|
||||||
{
|
{
|
||||||
return (player->oldcmd.buttons & BT_ATTACK);
|
return !!(player->oldcmd.buttons & BT_ATTACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
|
|
@ -950,7 +950,7 @@ static void K_BotItemOrbinaut(const player_t *player, ticcmd_t *cmd)
|
||||||
cmd->buttons |= BT_LOOKBACK;
|
cmd->buttons |= BT_LOOKBACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player->botvars.itemconfirm > 25*TICRATE)
|
if (player->botvars.itemconfirm > 10*TICRATE)
|
||||||
{
|
{
|
||||||
K_BotGenericPressItem(player, cmd, throwdir);
|
K_BotGenericPressItem(player, cmd, throwdir);
|
||||||
}
|
}
|
||||||
|
|
@ -1178,7 +1178,7 @@ static void K_BotItemJawz(const player_t *player, ticcmd_t *cmd)
|
||||||
cmd->buttons |= BT_LOOKBACK;
|
cmd->buttons |= BT_LOOKBACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player->botvars.itemconfirm > 25*TICRATE)
|
if (player->botvars.itemconfirm > 10*TICRATE)
|
||||||
{
|
{
|
||||||
K_BotGenericPressItem(player, cmd, throwdir);
|
K_BotGenericPressItem(player, cmd, throwdir);
|
||||||
}
|
}
|
||||||
|
|
@ -1234,6 +1234,9 @@ static void K_BotItemBubble(const player_t *player, ticcmd_t *cmd)
|
||||||
|
|
||||||
boolean hold = false;
|
boolean hold = false;
|
||||||
|
|
||||||
|
if (player->botvars.itemconfirm > 10*TICRATE)
|
||||||
|
hold = true;
|
||||||
|
|
||||||
if (player->bubbleblowup <= 0)
|
if (player->bubbleblowup <= 0)
|
||||||
{
|
{
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
|
|
|
||||||
|
|
@ -316,7 +316,7 @@ void K_InitGrandPrixBots(void)
|
||||||
// Intentionally referenced before (currently dummied out) unlock check. Such a tease!
|
// Intentionally referenced before (currently dummied out) unlock check. Such a tease!
|
||||||
if (rivalnum != -1 && grabskins[(UINT16)rivalnum] != MAXSKINS)
|
if (rivalnum != -1 && grabskins[(UINT16)rivalnum] != MAXSKINS)
|
||||||
{
|
{
|
||||||
botskinlist[botskinlistpos++] = (UINT8)rivalnum;
|
botskinlist[botskinlistpos++] = (UINT16)rivalnum;
|
||||||
grabskins[(UINT16)rivalnum] = MAXSKINS;
|
grabskins[(UINT16)rivalnum] = MAXSKINS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4320,7 +4320,7 @@ static void K_drawRingCounter(boolean gametypeinfoshown)
|
||||||
if (stplyr->hudrings <= 0 && stplyr->ringvisualwarning > 1)
|
if (stplyr->hudrings <= 0 && stplyr->ringvisualwarning > 1)
|
||||||
{
|
{
|
||||||
colorring = true;
|
colorring = true;
|
||||||
if ((leveltime/2 & 1))
|
if ((leveltime/2 & 1) || (cv_reducevfx.value))
|
||||||
{
|
{
|
||||||
ringmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_CRIMSON, GTC_CACHE);
|
ringmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_CRIMSON, GTC_CACHE);
|
||||||
}
|
}
|
||||||
|
|
@ -4329,7 +4329,7 @@ static void K_drawRingCounter(boolean gametypeinfoshown)
|
||||||
ringmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_WHITE, GTC_CACHE);
|
ringmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_WHITE, GTC_CACHE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (stplyr->hudrings <= 0 && (leveltime/5 & 1)) // In debt
|
else if (stplyr->hudrings <= 0 && ((leveltime/5 & 1) || (cv_reducevfx.value))) // In debt
|
||||||
{
|
{
|
||||||
ringmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_CRIMSON, GTC_CACHE);
|
ringmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_CRIMSON, GTC_CACHE);
|
||||||
colorring = true;
|
colorring = true;
|
||||||
|
|
@ -7466,6 +7466,7 @@ static void K_DrawBotDebugger(void)
|
||||||
|
|
||||||
V_DrawSmallString(8, 76, 0, va("Prediction error: %.2fdeg", FIXED_TO_FLOAT(FixedDiv(bot->botvars.predictionError, ANG1))));
|
V_DrawSmallString(8, 76, 0, va("Prediction error: %.2fdeg", FIXED_TO_FLOAT(FixedDiv(bot->botvars.predictionError, ANG1))));
|
||||||
V_DrawSmallString(8, 80, 0, va("Recent deflection: %.2fdeg", FIXED_TO_FLOAT(FixedDiv(bot->botvars.recentDeflection, ANG1))));
|
V_DrawSmallString(8, 80, 0, va("Recent deflection: %.2fdeg", FIXED_TO_FLOAT(FixedDiv(bot->botvars.recentDeflection, ANG1))));
|
||||||
|
V_DrawSmallString(8, 84, 0, va("Bumpslow: %d", bot->botvars.bumpslow));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void K_DrawGPRankDebugger(void)
|
static void K_DrawGPRankDebugger(void)
|
||||||
|
|
@ -7803,7 +7804,7 @@ void K_drawKartHUD(void)
|
||||||
|
|
||||||
// Tacitcal Normie Countermeasure
|
// Tacitcal Normie Countermeasure
|
||||||
INT32 dfade = K_GetDialogueFade();
|
INT32 dfade = K_GetDialogueFade();
|
||||||
if (dfade)
|
if (dfade && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOCOMMS))
|
||||||
{
|
{
|
||||||
V_DrawFadeScreen(31, dfade); // Fade out
|
V_DrawFadeScreen(31, dfade); // Fade out
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -292,6 +292,22 @@ private:
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cv_reducevfx.value)
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
{ // Near
|
||||||
|
{8, 2, {kp_capsuletarget_near[0]}}, // 1P
|
||||||
|
{{8, 2, {kp_capsuletarget_near[1]}}}, // 4P
|
||||||
|
},
|
||||||
|
{{ // Far
|
||||||
|
{2, 16, foreground ?
|
||||||
|
layers {kp_capsuletarget_far[0], kp_capsuletarget_far_text} :
|
||||||
|
layers {kp_capsuletarget_far[0]}}, // 1P
|
||||||
|
{{2, 16, {kp_capsuletarget_far[1]}}}, // 4P
|
||||||
|
}},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
{ // Near
|
{ // Near
|
||||||
{8, 2, {kp_capsuletarget_near[0]}}, // 1P
|
{8, 2, {kp_capsuletarget_near[0]}}, // 1P
|
||||||
|
|
@ -681,13 +697,19 @@ void K_DrawTargetTracking(const TargetTracking& target)
|
||||||
if (target.mobj->type == MT_BATTLECAPSULE
|
if (target.mobj->type == MT_BATTLECAPSULE
|
||||||
|| target.mobj->type == MT_CDUFO)
|
|| target.mobj->type == MT_CDUFO)
|
||||||
{
|
{
|
||||||
targetPatch = kp_capsuletarget_icon[timer & 1];
|
if (cv_reducevfx.value)
|
||||||
|
targetPatch = kp_capsuletarget_icon[(timer/6) & 1];
|
||||||
|
else
|
||||||
|
targetPatch = kp_capsuletarget_icon[timer & 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abs(borderDir.x) > abs(borderDir.y))
|
if (abs(borderDir.x) > abs(borderDir.y))
|
||||||
{
|
{
|
||||||
// Horizontal arrow
|
// Horizontal arrow
|
||||||
arrowPatch = kp_capsuletarget_arrow[1][timer & 1];
|
if (cv_reducevfx.value)
|
||||||
|
arrowPatch = kp_capsuletarget_arrow[1][(timer/6) & 1];
|
||||||
|
else
|
||||||
|
arrowPatch = kp_capsuletarget_arrow[1][timer & 1];
|
||||||
arrowDir.y = 0;
|
arrowDir.y = 0;
|
||||||
|
|
||||||
if (borderDir.x < 0)
|
if (borderDir.x < 0)
|
||||||
|
|
@ -704,7 +726,10 @@ void K_DrawTargetTracking(const TargetTracking& target)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Vertical arrow
|
// Vertical arrow
|
||||||
arrowPatch = kp_capsuletarget_arrow[0][timer & 1];
|
if (cv_reducevfx.value)
|
||||||
|
arrowPatch = kp_capsuletarget_arrow[0][(timer/6) & 1];
|
||||||
|
else
|
||||||
|
arrowPatch = kp_capsuletarget_arrow[0][timer & 1];
|
||||||
arrowDir.x = 0;
|
arrowDir.x = 0;
|
||||||
|
|
||||||
if (borderDir.y < 0)
|
if (borderDir.y < 0)
|
||||||
|
|
|
||||||
81
src/k_kart.c
81
src/k_kart.c
|
|
@ -1937,7 +1937,7 @@ void K_SpawnDashDustRelease(player_t *player)
|
||||||
if (!P_IsObjectOnGround(player->mo))
|
if (!P_IsObjectOnGround(player->mo))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!player->speed && !player->startboost && !player->spindash && !player->dropdashboost)
|
if (!player->speed && !player->startboost && !player->spindash && !player->dropdashboost && !player->aciddropdashboost)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
travelangle = player->mo->angle;
|
travelangle = player->mo->angle;
|
||||||
|
|
@ -3802,6 +3802,11 @@ static void K_GetKartBoostPower(player_t *player)
|
||||||
ADDBOOST(FRACUNIT/3, 4*FRACUNIT, HANDLESCALING); // + 33% top speed, + 400% acceleration, +50% handling
|
ADDBOOST(FRACUNIT/3, 4*FRACUNIT, HANDLESCALING); // + 33% top speed, + 400% acceleration, +50% handling
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (player->aciddropdashboost) // Great value Drop dash
|
||||||
|
{
|
||||||
|
ADDBOOST(FRACUNIT/3, 4*FRACUNIT, HANDLESCALING/3); // + 33% top speed, + 400% acceleration, +33% handling, No sliptides here
|
||||||
|
}
|
||||||
|
|
||||||
if (player->driftboost) // Drift Boost
|
if (player->driftboost) // Drift Boost
|
||||||
{
|
{
|
||||||
// Rebuff Eggman's stat block corner
|
// Rebuff Eggman's stat block corner
|
||||||
|
|
@ -4452,6 +4457,22 @@ void K_SpawnAmps(player_t *player, UINT8 amps, mobj_t *impact)
|
||||||
// FixedMul(scaledamps<<FRACBITS, itemdistmult)>>FRACBITS);
|
// FixedMul(scaledamps<<FRACBITS, itemdistmult)>>FRACBITS);
|
||||||
scaledamps = FixedMul(scaledamps<<FRACBITS, itemdistmult)>>FRACBITS;
|
scaledamps = FixedMul(scaledamps<<FRACBITS, itemdistmult)>>FRACBITS;
|
||||||
|
|
||||||
|
//CONS_Printf("SA=%d ", scaledamps);
|
||||||
|
|
||||||
|
// Arbitrary tuning constants.
|
||||||
|
// Reduce amp payouts by 1/40th for each 2 amps obtained recently
|
||||||
|
UINT8 num = 40;
|
||||||
|
UINT8 div = 40;
|
||||||
|
UINT8 reduction = min(30, player->recentamps);
|
||||||
|
|
||||||
|
num -= reduction;
|
||||||
|
|
||||||
|
//CONS_Printf("N=%d D=%d RA=%d ", num, div, player->recentamps);
|
||||||
|
|
||||||
|
scaledamps = num * scaledamps / div;
|
||||||
|
|
||||||
|
//CONS_Printf("SA2=%d\n", scaledamps);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (player->position <= 1)
|
if (player->position <= 1)
|
||||||
scaledamps /= 2;
|
scaledamps /= 2;
|
||||||
|
|
@ -4468,6 +4489,7 @@ void K_SpawnAmps(player_t *player, UINT8 amps, mobj_t *impact)
|
||||||
pickup->color = player->skincolor;
|
pickup->color = player->skincolor;
|
||||||
P_SetTarget(&pickup->target, player->mo);
|
P_SetTarget(&pickup->target, player->mo);
|
||||||
player->ampspending++;
|
player->ampspending++;
|
||||||
|
player->recentamps++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -10012,6 +10034,20 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||||
|
|
||||||
if (onground && player->transfer)
|
if (onground && player->transfer)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (G_CompatLevel(0x0010))
|
||||||
|
{
|
||||||
|
// Ghosts prior to 2.4 RC2 don't get this
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (player->fastfall) // If you elected to acid drop, you get a small dropdash boost on landing
|
||||||
|
{
|
||||||
|
S_StartSound(player->mo, sfx_s23c);
|
||||||
|
player->aciddropdashboost = max(player->aciddropdashboost, 35);
|
||||||
|
K_SpawnDashDustRelease(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
player->fastfall = 0;
|
player->fastfall = 0;
|
||||||
player->transfer = 0;
|
player->transfer = 0;
|
||||||
player->pflags2 &= ~PF2_SUPERTRANSFERVFX;
|
player->pflags2 &= ~PF2_SUPERTRANSFERVFX;
|
||||||
|
|
@ -10022,6 +10058,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||||
K_DropItems(player);
|
K_DropItems(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (K_InRaceDuel() && D_NumPlayersInRace() < 2)
|
||||||
|
P_DoPlayerExit(player, 0);
|
||||||
|
|
||||||
if (G_TimeAttackStart() && !attacktimingstarted && player->speed && leveltime > introtime)
|
if (G_TimeAttackStart() && !attacktimingstarted && player->speed && leveltime > introtime)
|
||||||
{
|
{
|
||||||
attacktimingstarted = leveltime;
|
attacktimingstarted = leveltime;
|
||||||
|
|
@ -10468,8 +10507,22 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||||
if (player->trickboost)
|
if (player->trickboost)
|
||||||
player->trickboost--;
|
player->trickboost--;
|
||||||
|
|
||||||
if (K_PlayerUsesBotMovement(players) && player->botvars.bumpslow && player->incontrol)
|
/*
|
||||||
|
if (K_PlayerUsesBotMovement(player) && player->botvars.bumpslow && player->incontrol)
|
||||||
player->botvars.bumpslow--;
|
player->botvars.bumpslow--;
|
||||||
|
*/
|
||||||
|
|
||||||
|
// WHOOPS! 2.4 bots were tuned around a bugged version of bumpslow that NEVER decayed
|
||||||
|
// if the player in slot 0 was a human. People seem to like this tuning, but the dampened
|
||||||
|
// rubberbanding only started applying after a bot wallbonked or got hit, which is
|
||||||
|
// probably why people report weird runaways.
|
||||||
|
//
|
||||||
|
// I'd like to retune this later, but for now, just set bumpslow on every bot, as if they all
|
||||||
|
// contact a wall instantly—consistently giving them the softer rubberband advancement.
|
||||||
|
// What the fuck making games is hard.
|
||||||
|
if (K_PlayerUsesBotMovement(player))
|
||||||
|
player->botvars.bumpslow = TICRATE*2;
|
||||||
|
|
||||||
|
|
||||||
if (player->flamedash)
|
if (player->flamedash)
|
||||||
{
|
{
|
||||||
|
|
@ -10532,6 +10585,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||||
if (player->dropdashboost)
|
if (player->dropdashboost)
|
||||||
player->dropdashboost--;
|
player->dropdashboost--;
|
||||||
|
|
||||||
|
if (player->aciddropdashboost)
|
||||||
|
player->aciddropdashboost--;
|
||||||
|
|
||||||
if (player->wavedashboost > 0 && onground == true)
|
if (player->wavedashboost > 0 && onground == true)
|
||||||
{
|
{
|
||||||
player->wavedashboost--;
|
player->wavedashboost--;
|
||||||
|
|
@ -10614,6 +10670,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (player->recentamps && (leveltime%TICRATE == 0))
|
||||||
|
player->recentamps--;
|
||||||
|
|
||||||
if (player->invincibilitytimer && (player->ignoreAirtimeLeniency > 0 || onground == true || K_PowerUpRemaining(player, POWERUP_SMONITOR)))
|
if (player->invincibilitytimer && (player->ignoreAirtimeLeniency > 0 || onground == true || K_PowerUpRemaining(player, POWERUP_SMONITOR)))
|
||||||
{
|
{
|
||||||
player->invincibilitytimer--;
|
player->invincibilitytimer--;
|
||||||
|
|
@ -12759,7 +12818,7 @@ static void K_KartDrift(player_t *player, boolean onground)
|
||||||
|
|
||||||
// Airtime means we're not gaining speed. Get grounded!
|
// Airtime means we're not gaining speed. Get grounded!
|
||||||
if (!onground)
|
if (!onground)
|
||||||
player->mo->momz -= player->speed/2;
|
player->mo->momz -= (player->mo->eflags & MFE_VERTICALFLIP ? -1 : 1) * player->speed/2;
|
||||||
|
|
||||||
if (player->driftcharge < 0)
|
if (player->driftcharge < 0)
|
||||||
{
|
{
|
||||||
|
|
@ -13977,6 +14036,22 @@ static void K_KartSpindash(player_t *player)
|
||||||
player->transfer = 0;
|
player->transfer = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!G_CompatLevel(0x0010))
|
||||||
|
{
|
||||||
|
boolean ebrakelasttic = ((player->oldcmd.buttons & BT_EBRAKEMASK) == BT_EBRAKEMASK);
|
||||||
|
if (player->pflags2 & PF2_STRICTFASTFALL)
|
||||||
|
ebrakelasttic = (player->oldcmd.buttons & BT_SPINDASH);
|
||||||
|
|
||||||
|
boolean ebrakenow = K_PressingEBrake(player);
|
||||||
|
if (player->pflags2 & PF2_STRICTFASTFALL && !(player->cmd.buttons & BT_SPINDASH))
|
||||||
|
ebrakenow = false;
|
||||||
|
|
||||||
|
if (!ebrakelasttic && ebrakenow && player->fastfall && player->transfer)
|
||||||
|
{
|
||||||
|
player->transfer = 0;
|
||||||
|
S_StartSound(player->mo, sfx_s3k7d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update fastfall.
|
// Update fastfall.
|
||||||
player->fastfall = player->mo->momz;
|
player->fastfall = player->mo->momz;
|
||||||
|
|
|
||||||
|
|
@ -5673,6 +5673,9 @@ void M_DrawProfileControls(void)
|
||||||
case 8:
|
case 8:
|
||||||
help = va("6Bt. (E): Saturn buttons, Hori/M30X layout. (LB/LT = LS/RS)");
|
help = va("6Bt. (E): Saturn buttons, Hori/M30X layout. (LB/LT = LS/RS)");
|
||||||
break;
|
break;
|
||||||
|
case 9:
|
||||||
|
help = va("6Bt. (F): Saturn buttons, Mayflash layout. (C/Z = RS/LS)");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
V_DrawThinString(12, ypos, V_YELLOWMAP, help);
|
V_DrawThinString(12, ypos, V_YELLOWMAP, help);
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,7 @@ void M_ChangeCvarDirect(INT32 choice, consvar_t *cv)
|
||||||
if (cv == &cv_nettimeout || cv == &cv_jointimeout)
|
if (cv == &cv_nettimeout || cv == &cv_jointimeout)
|
||||||
choice *= (TICRATE/7);
|
choice *= (TICRATE/7);
|
||||||
else if (cv == &cv_maxsend)
|
else if (cv == &cv_maxsend)
|
||||||
choice *= 512;
|
choice *= 1024;
|
||||||
|
|
||||||
CV_AddValue(cv, choice);
|
CV_AddValue(cv, choice);
|
||||||
}
|
}
|
||||||
|
|
@ -548,9 +548,6 @@ void M_PlayMenuJam(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (soundtest.playing)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const boolean trulystarted = M_GameTrulyStarted();
|
const boolean trulystarted = M_GameTrulyStarted();
|
||||||
const boolean profilemode = (
|
const boolean profilemode = (
|
||||||
optionsmenu.profilemenu
|
optionsmenu.profilemenu
|
||||||
|
|
|
||||||
|
|
@ -350,9 +350,6 @@ botItemPriority_e K_GetBotItemPriority(kartitems_t result)
|
||||||
case KITEM_INVINCIBILITY:
|
case KITEM_INVINCIBILITY:
|
||||||
case KITEM_GROW:
|
case KITEM_GROW:
|
||||||
case KITEM_SHRINK:
|
case KITEM_SHRINK:
|
||||||
case KITEM_LIGHTNINGSHIELD:
|
|
||||||
case KITEM_BUBBLESHIELD:
|
|
||||||
case KITEM_FLAMESHIELD:
|
|
||||||
{
|
{
|
||||||
// Items that drastically improve your own defense and/or speed.
|
// Items that drastically improve your own defense and/or speed.
|
||||||
return BOT_ITEM_PR_POWER;
|
return BOT_ITEM_PR_POWER;
|
||||||
|
|
@ -389,6 +386,9 @@ botItemPriority_e K_GetBotItemPriority(kartitems_t result)
|
||||||
case KITEM_JAWZ:
|
case KITEM_JAWZ:
|
||||||
case KITEM_BANANA:
|
case KITEM_BANANA:
|
||||||
case KITEM_MINE:
|
case KITEM_MINE:
|
||||||
|
case KITEM_LIGHTNINGSHIELD:
|
||||||
|
case KITEM_BUBBLESHIELD:
|
||||||
|
case KITEM_FLAMESHIELD:
|
||||||
{
|
{
|
||||||
// Used in all other instances (close to other players, no priority override)
|
// Used in all other instances (close to other players, no priority override)
|
||||||
// Typically attack items that give you protection.
|
// Typically attack items that give you protection.
|
||||||
|
|
|
||||||
|
|
@ -295,6 +295,8 @@ static int player_get(lua_State *L)
|
||||||
lua_pushinteger(L, plr->lastringboost);
|
lua_pushinteger(L, plr->lastringboost);
|
||||||
else if (fastcmp(field,"amps"))
|
else if (fastcmp(field,"amps"))
|
||||||
lua_pushinteger(L, plr->amps);
|
lua_pushinteger(L, plr->amps);
|
||||||
|
else if (fastcmp(field,"recentamps"))
|
||||||
|
lua_pushinteger(L, plr->recentamps);
|
||||||
else if (fastcmp(field,"amppickup"))
|
else if (fastcmp(field,"amppickup"))
|
||||||
lua_pushinteger(L, plr->amppickup);
|
lua_pushinteger(L, plr->amppickup);
|
||||||
else if (fastcmp(field,"ampspending"))
|
else if (fastcmp(field,"ampspending"))
|
||||||
|
|
@ -319,6 +321,8 @@ static int player_get(lua_State *L)
|
||||||
lua_pushinteger(L, plr->startboost);
|
lua_pushinteger(L, plr->startboost);
|
||||||
else if (fastcmp(field,"dropdashboost"))
|
else if (fastcmp(field,"dropdashboost"))
|
||||||
lua_pushinteger(L, plr->dropdashboost);
|
lua_pushinteger(L, plr->dropdashboost);
|
||||||
|
else if (fastcmp(field,"aciddropdashboost"))
|
||||||
|
lua_pushinteger(L, plr->aciddropdashboost);
|
||||||
else if (fastcmp(field,"aizdriftstrat"))
|
else if (fastcmp(field,"aizdriftstrat"))
|
||||||
lua_pushinteger(L, plr->aizdriftstrat);
|
lua_pushinteger(L, plr->aizdriftstrat);
|
||||||
else if (fastcmp(field,"aizdriftextend"))
|
else if (fastcmp(field,"aizdriftextend"))
|
||||||
|
|
@ -958,6 +962,8 @@ static int player_set(lua_State *L)
|
||||||
plr->lastringboost = luaL_checkinteger(L, 3);
|
plr->lastringboost = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"amps"))
|
else if (fastcmp(field,"amps"))
|
||||||
plr->amps = luaL_checkinteger(L, 3);
|
plr->amps = luaL_checkinteger(L, 3);
|
||||||
|
else if (fastcmp(field,"recentamps"))
|
||||||
|
plr->recentamps = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"amppickup"))
|
else if (fastcmp(field,"amppickup"))
|
||||||
plr->amppickup = luaL_checkinteger(L, 3);
|
plr->amppickup = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"ampspending"))
|
else if (fastcmp(field,"ampspending"))
|
||||||
|
|
@ -982,6 +988,8 @@ static int player_set(lua_State *L)
|
||||||
plr->startboost = luaL_checkinteger(L, 3);
|
plr->startboost = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"dropdashboost"))
|
else if (fastcmp(field,"dropdashboost"))
|
||||||
plr->dropdashboost = luaL_checkinteger(L, 3);
|
plr->dropdashboost = luaL_checkinteger(L, 3);
|
||||||
|
else if (fastcmp(field,"aciddropdashboost"))
|
||||||
|
plr->aciddropdashboost = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"aizdriftstrat"))
|
else if (fastcmp(field,"aizdriftstrat"))
|
||||||
plr->aizdriftstrat = luaL_checkinteger(L, 3);
|
plr->aizdriftstrat = luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"aizdrifttilt"))
|
else if (fastcmp(field,"aizdrifttilt"))
|
||||||
|
|
|
||||||
|
|
@ -533,7 +533,7 @@ static void M_ChallengesTutorial(UINT8 option)
|
||||||
{
|
{
|
||||||
M_StartMessage("Big Challenges & Chao Keys",
|
M_StartMessage("Big Challenges & Chao Keys",
|
||||||
M_GetText(
|
M_GetText(
|
||||||
"Watch out! You need 10 Chao Keys.\n"
|
"Watch out! You need 10 Chao Keys\n"
|
||||||
"to break open Big Challenge tiles.\n"
|
"to break open Big Challenge tiles.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"You'll also need to unlock\n"
|
"You'll also need to unlock\n"
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,8 @@ void M_ResetOptions(void)
|
||||||
// For profiles:
|
// For profiles:
|
||||||
memset(setup_player, 0, sizeof(setup_player));
|
memset(setup_player, 0, sizeof(setup_player));
|
||||||
optionsmenu.profile = NULL;
|
optionsmenu.profile = NULL;
|
||||||
|
optionsmenu.profilemenu = false;
|
||||||
|
optionsmenu.resetprofilemenu = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void M_InitOptions(INT32 choice)
|
void M_InitOptions(INT32 choice)
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,7 @@ void M_FirstPickProfile(INT32 c)
|
||||||
{
|
{
|
||||||
if (c == MA_YES)
|
if (c == MA_YES)
|
||||||
{
|
{
|
||||||
M_ResetOptions(); // Reset all options variables otherwise things are gonna go reaaal bad lol.
|
M_ResetOptions(); // Reset all options variables otherwise things are gonna go reaaal bad lol.
|
||||||
optionsmenu.profile = NULL; // Make sure to get rid of that, too.
|
|
||||||
|
|
||||||
PR_ApplyProfile(optionsmenu.profilen, 0);
|
PR_ApplyProfile(optionsmenu.profilen, 0);
|
||||||
|
|
||||||
|
|
@ -162,7 +161,7 @@ void M_HandleProfileSelect(INT32 ch)
|
||||||
|
|
||||||
if (menutransition.tics == 0 && optionsmenu.resetprofile)
|
if (menutransition.tics == 0 && optionsmenu.resetprofile)
|
||||||
{
|
{
|
||||||
optionsmenu.profile = NULL; // Make sure to reset that when transitions are done.'
|
optionsmenu.profile = NULL; // Make sure to reset that when transitions are done.
|
||||||
optionsmenu.resetprofile = false;
|
optionsmenu.resetprofile = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -135,8 +135,7 @@ static void M_ProfileEditExit(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
M_ResetOptions(); // Reset all options variables otherwise things are gonna go reaaal bad lol.
|
M_ResetOptions(); // Reset all options variables otherwise things are gonna go reaaal bad lol.
|
||||||
optionsmenu.profile = NULL; // Make sure to get rid of that, too.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PR_SaveProfiles(); // save profiles after we do that.
|
PR_SaveProfiles(); // save profiles after we do that.
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,9 @@ menuitem_t OPTIONS_Voice[] =
|
||||||
{IT_STRING | IT_CVAR, "Input Amplifier", "Amplify your voice, in decibels. Negative values are quieter.",
|
{IT_STRING | IT_CVAR, "Input Amplifier", "Amplify your voice, in decibels. Negative values are quieter.",
|
||||||
NULL, {.cvar = &cv_voice_inputamp}, 0, 0},
|
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.",
|
{IT_STRING | IT_CVAR, "Input Sensitivity", "Voice higher than this threshold will transmit, in decibels.",
|
||||||
NULL, {.cvar = &cv_voice_activationthreshold}, 0, 0},
|
NULL, {.cvar = &cv_voice_activationthreshold}, 0, 0},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ void M_ServerListFillDebug(void);
|
||||||
static boolean M_ServerBrowserQuit(void)
|
static boolean M_ServerBrowserQuit(void)
|
||||||
{
|
{
|
||||||
serverlistultimatecount = 0;
|
serverlistultimatecount = 0;
|
||||||
|
serverlistmode = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -240,6 +241,8 @@ void M_ServersMenu(INT32 choice)
|
||||||
// modified game check: no longer handled
|
// modified game check: no longer handled
|
||||||
// we don't request a restart unless the filelist differs
|
// we don't request a restart unless the filelist differs
|
||||||
|
|
||||||
|
serverlistmode = true;
|
||||||
|
|
||||||
CL_UpdateServerList();
|
CL_UpdateServerList();
|
||||||
|
|
||||||
mpmenu.ticker = 0;
|
mpmenu.ticker = 0;
|
||||||
|
|
|
||||||
|
|
@ -660,9 +660,12 @@ void M_LevelSelectInit(INT32 choice)
|
||||||
levellist.levelsearch.timeattack = false;
|
levellist.levelsearch.timeattack = false;
|
||||||
levellist.canqueue = true;
|
levellist.canqueue = true;
|
||||||
|
|
||||||
CV_StealthSet(&cv_kartbot, cv_dummymatchbots.string);
|
if (gamestate == GS_MENU)
|
||||||
CV_StealthSet(&cv_kartencore, (cv_dummygpencore.value == 1) ? "On" : "Auto");
|
{
|
||||||
CV_StealthSet(&cv_kartspeed, (cv_dummykartspeed.value == KARTSPEED_NORMAL) ? "Auto Gear" : cv_dummykartspeed.string);
|
CV_StealthSet(&cv_kartbot, cv_dummymatchbots.string);
|
||||||
|
CV_StealthSet(&cv_kartencore, (cv_dummygpencore.value == 1) ? "On" : "Auto");
|
||||||
|
CV_StealthSet(&cv_kartspeed, (cv_dummykartspeed.value == KARTSPEED_NORMAL) ? "Auto Gear" : cv_dummykartspeed.string);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ struct Particle : Mobj
|
||||||
skins[pskinn]->sprites[states[spr2state].frame].numframes > 0)
|
skins[pskinn]->sprites[states[spr2state].frame].numframes > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
x->skin = (void*)(&skins[pskinn]);
|
x->skin = (void*)(skins[pskinn]);
|
||||||
x->state(spr2state);
|
x->state(spr2state);
|
||||||
//frame will be set by state()
|
//frame will be set by state()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3510,9 +3510,20 @@ void A_AttractChase(mobj_t *actor)
|
||||||
|
|
||||||
if (actor->extravalue1 && actor->type != MT_EMERALD) // SRB2Kart
|
if (actor->extravalue1 && actor->type != MT_EMERALD) // SRB2Kart
|
||||||
{
|
{
|
||||||
if (!actor->target || P_MobjWasRemoved(actor->target) || !actor->target->player
|
// Screwed this up for staffghosts, so have a mess.
|
||||||
|| actor->target->player->baildrop || actor->target->player->bailcharge || actor->target->player->defenseLockout > PUNISHWINDOW)
|
// 1. Insta-Whip's extended punish window used to delete flingrings off you while they were attracting
|
||||||
|
// 2. ALL conditions that deleted flingrings off you didn't decrement pickuprings, desyncing your ring count
|
||||||
|
boolean stale = (!actor->target || P_MobjWasRemoved(actor->target) || !actor->target->player);
|
||||||
|
|
||||||
|
boolean blocked = (actor->target->player->baildrop || actor->target->player->bailcharge);
|
||||||
|
if (G_CompatLevel(0x0010))
|
||||||
|
blocked |= (actor->target->player->defenseLockout > PUNISHWINDOW);
|
||||||
|
|
||||||
|
if (stale || blocked)
|
||||||
{
|
{
|
||||||
|
if (!G_CompatLevel(0x0010) && !stale)
|
||||||
|
actor->target->player->pickuprings--;
|
||||||
|
|
||||||
P_RemoveMobj(actor);
|
P_RemoveMobj(actor);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -489,9 +489,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||||
if (special->fuse) // This box is respawning, but was broken very recently (see P_FuseThink)
|
if (special->fuse) // This box is respawning, but was broken very recently (see P_FuseThink)
|
||||||
{
|
{
|
||||||
// What was this box broken as?
|
// What was this box broken as?
|
||||||
if (cv_thunderdome.value)
|
if (!K_ThunderDome() && special->cvmem && !(special->flags2 & MF2_BOSSDEAD))
|
||||||
K_StartItemRoulette(player, true);
|
|
||||||
else if (special->cvmem && !(special->flags2 & MF2_BOSSDEAD))
|
|
||||||
K_StartItemRoulette(player, false);
|
K_StartItemRoulette(player, false);
|
||||||
else
|
else
|
||||||
K_StartItemRoulette(player, true);
|
K_StartItemRoulette(player, true);
|
||||||
|
|
|
||||||
|
|
@ -15569,7 +15569,7 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai
|
||||||
//
|
//
|
||||||
void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration)
|
void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration)
|
||||||
{
|
{
|
||||||
if (!pl)
|
if (!pl || cv_reducevfx.value)
|
||||||
return;
|
return;
|
||||||
pl->flashcount = duration;
|
pl->flashcount = duration;
|
||||||
pl->flashpal = type;
|
pl->flashpal = type;
|
||||||
|
|
|
||||||
|
|
@ -468,6 +468,7 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
||||||
WRITEUINT16(save->p, players[i].bigwaypointgap);
|
WRITEUINT16(save->p, players[i].bigwaypointgap);
|
||||||
WRITEUINT8(save->p, players[i].startboost);
|
WRITEUINT8(save->p, players[i].startboost);
|
||||||
WRITEUINT8(save->p, players[i].dropdashboost);
|
WRITEUINT8(save->p, players[i].dropdashboost);
|
||||||
|
WRITEUINT8(save->p, players[i].aciddropdashboost);
|
||||||
|
|
||||||
WRITEUINT16(save->p, players[i].flashing);
|
WRITEUINT16(save->p, players[i].flashing);
|
||||||
WRITEUINT16(save->p, players[i].spinouttimer);
|
WRITEUINT16(save->p, players[i].spinouttimer);
|
||||||
|
|
@ -708,6 +709,7 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
||||||
WRITEUINT32(save->p, players[i].lastringboost);
|
WRITEUINT32(save->p, players[i].lastringboost);
|
||||||
|
|
||||||
WRITEUINT8(save->p, players[i].amps);
|
WRITEUINT8(save->p, players[i].amps);
|
||||||
|
WRITEUINT8(save->p, players[i].recentamps);
|
||||||
WRITEUINT8(save->p, players[i].amppickup);
|
WRITEUINT8(save->p, players[i].amppickup);
|
||||||
WRITEUINT8(save->p, players[i].ampspending);
|
WRITEUINT8(save->p, players[i].ampspending);
|
||||||
|
|
||||||
|
|
@ -1145,6 +1147,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
||||||
players[i].bigwaypointgap = READUINT16(save->p);
|
players[i].bigwaypointgap = READUINT16(save->p);
|
||||||
players[i].startboost = READUINT8(save->p);
|
players[i].startboost = READUINT8(save->p);
|
||||||
players[i].dropdashboost = READUINT8(save->p);
|
players[i].dropdashboost = READUINT8(save->p);
|
||||||
|
players[i].aciddropdashboost = READUINT8(save->p);
|
||||||
|
|
||||||
players[i].flashing = READUINT16(save->p);
|
players[i].flashing = READUINT16(save->p);
|
||||||
players[i].spinouttimer = READUINT16(save->p);
|
players[i].spinouttimer = READUINT16(save->p);
|
||||||
|
|
@ -1383,6 +1386,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
||||||
players[i].lastringboost = READUINT32(save->p);
|
players[i].lastringboost = READUINT32(save->p);
|
||||||
|
|
||||||
players[i].amps =READUINT8(save->p);
|
players[i].amps =READUINT8(save->p);
|
||||||
|
players[i].recentamps =READUINT8(save->p);
|
||||||
players[i].amppickup =READUINT8(save->p);
|
players[i].amppickup =READUINT8(save->p);
|
||||||
players[i].ampspending =READUINT8(save->p);
|
players[i].ampspending =READUINT8(save->p);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2071,8 +2071,6 @@ static void K_HandleLapIncrement(player_t *player)
|
||||||
{
|
{
|
||||||
S_StartSound(player->mo, sfx_s23c);
|
S_StartSound(player->mo, sfx_s23c);
|
||||||
player->startboost = 125;
|
player->startboost = 125;
|
||||||
if (!K_PlayerUsesBotMovement(player) && grandprixinfo.gp)
|
|
||||||
player->startboost /= 2;
|
|
||||||
|
|
||||||
K_SpawnDriftBoostExplosion(player, 4);
|
K_SpawnDriftBoostExplosion(player, 4);
|
||||||
K_SpawnDriftElectricSparks(player, SKINCOLOR_SILVER, false);
|
K_SpawnDriftElectricSparks(player, SKINCOLOR_SILVER, false);
|
||||||
|
|
|
||||||
|
|
@ -1011,7 +1011,11 @@ void S_UpdateVoicePositionalProperties(void)
|
||||||
float pdirx = px / p2ddistance;
|
float pdirx = px / p2ddistance;
|
||||||
float pdiry = py / p2ddistance;
|
float pdiry = py / p2ddistance;
|
||||||
float angle = acosf(pdirx * ldirx + pdiry * ldiry);
|
float angle = acosf(pdirx * ldirx + pdiry * ldiry);
|
||||||
angle = PointIsLeft(ldirx, ldiry, pdirx, pdiry) ? -angle : angle;
|
angle = (
|
||||||
|
PointIsLeft(ldirx, ldiry, pdirx, pdiry)
|
||||||
|
^ stereoreverse.value
|
||||||
|
^ encoremode
|
||||||
|
) ? -angle : angle;
|
||||||
|
|
||||||
float plrvolume = 1.0f;
|
float plrvolume = 1.0f;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ extern consvar_t cv_voice_selfdeafen;
|
||||||
extern consvar_t cv_voice_mode;
|
extern consvar_t cv_voice_mode;
|
||||||
extern consvar_t cv_voice_selfmute;
|
extern consvar_t cv_voice_selfmute;
|
||||||
extern consvar_t cv_voice_loopback;
|
extern consvar_t cv_voice_loopback;
|
||||||
|
extern consvar_t cv_voice_denoise;
|
||||||
extern consvar_t cv_voice_inputamp;
|
extern consvar_t cv_voice_inputamp;
|
||||||
extern consvar_t cv_voice_activationthreshold;
|
extern consvar_t cv_voice_activationthreshold;
|
||||||
extern consvar_t cv_voice_proximity;
|
extern consvar_t cv_voice_proximity;
|
||||||
|
|
|
||||||
|
|
@ -263,6 +263,9 @@ Draw::TextElement& Draw::TextElement::parse(std::string_view raw)
|
||||||
case 8:
|
case 8:
|
||||||
padconfig = saturntypeE;
|
padconfig = saturntypeE;
|
||||||
break;
|
break;
|
||||||
|
case 9:
|
||||||
|
padconfig = saturntypeF;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto pretty = prettyinputs.find(bind); pretty != prettyinputs.end()) // Gamepad direction or keyboard arrow, use something nice-looking
|
if (auto pretty = prettyinputs.find(bind); pretty != prettyinputs.end()) // Gamepad direction or keyboard arrow, use something nice-looking
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,23 @@ static const srb2::HashMap<INT32, char> saturntypeE = {
|
||||||
{nc_back, gb_back},
|
{nc_back, gb_back},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Saturn Type F - Mayflash XInput Saturn adapter, CZ = RS LS
|
||||||
|
// Cannot be disambiguated. GEE I SURE WISH THERE WERE A STANDARD
|
||||||
|
static const srb2::HashMap<INT32, char> saturntypeF = {
|
||||||
|
{nc_a, sb_a},
|
||||||
|
{nc_b, sb_b},
|
||||||
|
{nc_x, sb_x},
|
||||||
|
{nc_y, sb_y},
|
||||||
|
{nc_rt, gb_rt},
|
||||||
|
{nc_rb, gb_rb},
|
||||||
|
{nc_lb, gb_lb},
|
||||||
|
{nc_lt, gb_lt},
|
||||||
|
{nc_ls, sb_z},
|
||||||
|
{nc_rs, sb_c},
|
||||||
|
{nc_start, gb_start},
|
||||||
|
{nc_back, gb_back},
|
||||||
|
};
|
||||||
|
|
||||||
namespace srb2
|
namespace srb2
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
||||||
2
thirdparty/CMakeLists.txt
vendored
2
thirdparty/CMakeLists.txt
vendored
|
|
@ -19,3 +19,5 @@ add_subdirectory(fmt)
|
||||||
add_subdirectory(vulkan-headers)
|
add_subdirectory(vulkan-headers)
|
||||||
add_subdirectory(volk)
|
add_subdirectory(volk)
|
||||||
add_subdirectory(vma)
|
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