📄 gain.c
字号:
/* gain.c -- Gain control routines Copyright (C) 2001-2003 Shane Wegner This file is part of Intercom. Intercom is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. Intercom is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of version 2 of the GNU General Public License along with Intercom; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA To contact the author, please send email to shane@cm.nu. *//* $Id: gain.c,v 1.2 2003/02/13 20:22:49 shane Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdlib.h>#include <math.h>#include <gain.h>#ifndef ROUND# define ROUND(x) floor((x) + 0.5)#endif#define DBTOFRAC(x) pow(10,(x)/20.0)static double lmtr_lvl = 0.5;/* * Limiter function: * * / tanh((x + lev) / (1-lev)) * (1-lev) - lev (for x < -lev) * | * x' = | x (for |x| <= lev) * | * \ tanh((x - lev) / (1-lev)) * (1-lev) + lev (for x > lev) * * With limiter level = 0, this is equivalent to a tanh() function; * with limiter level = 1, this is equivalent to clipping. */static double limiter(double x){double xp; if (x < -lmtr_lvl) xp = tanh((x + lmtr_lvl) / (1-lmtr_lvl)) * (1-lmtr_lvl) - lmtr_lvl; else if (x <= lmtr_lvl) xp = x; else xp = tanh((x - lmtr_lvl) / (1-lmtr_lvl)) * (1-lmtr_lvl) + lmtr_lvl; return xp;}static void gain_buildtable(struct gain *handle){#define SAMPLEMIN -32768#define SAMPLEMAX 32767int i;if (handle->gain > 1.0) { /* gain with limiter */for (i = SAMPLEMIN; i < 0; i++)handle->tblp[i] = ROUND(-SAMPLEMIN * limiter(i * handle->gain / (double)-SAMPLEMIN));for (; i <= SAMPLEMAX; i++)handle->tblp[i] = ROUND(SAMPLEMAX * limiter(i * handle->gain / (double)SAMPLEMAX));} else { /* no limiter if gain is negative */for (i = SAMPLEMIN; i <= SAMPLEMAX; i++)handle->tblp[i] = i * handle->gain;}}struct gain *gain_init(double gain){struct gain *g = malloc(sizeof(struct gain));g->gain = DBTOFRAC(gain);g->gain_db = gain;g->tbl = malloc(sizeof(short) * 65536);g->tblp = g->tbl + 32768;gain_buildtable(g);return g;}void gain_update(struct gain *handle, double gain){handle->gain = DBTOFRAC(gain);handle->gain_db = gain;gain_buildtable(handle);}void gain_apply(struct gain *handle, short *buff, size_t samples){size_t i;for (i = 0; i < samples; i++)buff[i] = handle->tblp[buff[i]];}void gain_free(struct gain *handle){free(handle->tbl);free(handle);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -