📄 amf_agclimitercoretable.c
字号:
// Copyright(c) 2005 Analog Devices, Inc. All Rights Reserved.
// This software is proprietary and confidential to Analog Devices, Inc. and its licensors.
// File : $Id: //depot/development/visualaudio/modules/2.5.0/SHARC/Source/AMF_AGCLimiterCore.c#3 $
// Part of : VisualAudio V2.5.0
// Updated : $Date: 2007-08-08 12:37:19 +0530 (Wed, 08 Aug 2007) $ by $Author: kdasari2 $
#include "AMF_AGCLimiterCoreTable.h"
#include "math.h"
void AMF_AGCLimiterCoreTable_Render(AMF_AGCLimiterCoreTable * restrict instance,float * restrict * buffers, int tickSize);
// NOTE: The C version of this function is for reference only (it is
// intended just to show the general algorithm that the module
// uses), and it may not have been fully tested
#if 0
void AMF_AGCLimiterCoreTable_Render(AMF_AGCLimiterCoreTable * restrict instance,float * restrict * buffers, int tickSize) {
int i,j,index,num_points;
float *in = buffers[0];
float *out = buffers[1];
float envState = instance->envState;
float envCoef;
float attackCoef = instance->attackCoef;
float decayCoef = instance->decayCoef;
float *input_levels = instance->inputTable;
float *output_levels = instance->outputTable;
float temp,slope,signal;
num_points = instance->Table_points;
/*********************************************************
*envelope follower, where filtering coefficient depends on
*whether input is increasing or decreasing in amplitude
*********************************************************/
for(i=0;i<tickSize;i++)
{
signal = in[i];
/*************************************************
* Check if attck or decay
**************************************************/
if(envState < signal)
{
envCoef = attackCoef;
}
else
{
envCoef = decayCoef;
}
/*************************************************
* one pole filter for envelope detector
**************************************************/
signal = envCoef*signal + (1.0-envCoef)*envState;
envState = signal;
/*************************************************
* convert env output to log
**************************************************/
signal = AMF_TranslateVeryFastAmpToDB(signal);
/*******************************************************
* Check in which range input gain falls in given table
********************************************************/
index = 0;
for(j = 0;j< num_points;j++) // num_point is array size of input and output levels
{
if(signal > input_levels[j])
index++;
}
/* slope for signal which is <= minimum level of the input table */
if(index == 0)
{
if(signal < input_levels[0])
{
temp = input_levels[1] - input_levels[0];
if(temp == 0.0)
{
slope = 0.0;
}
else
{
slope = (output_levels[1] - output_levels[0]) / (input_levels[1] - input_levels[0]);
}
index = 1;
}
}
/* slope for signal which is >= max level of the input table */
else if( index == num_points)
{
temp = input_levels[num_points -1 ] - input_levels[num_points -2];
if(temp == 0.0)
{
slope = 0.0;
}
else
{
slope = (output_levels[num_points -1] - output_levels[num_points -2]) / (input_levels[num_points -1] - input_levels[num_points -2]);
}
}
/* falls under given range of input table, slope = (y2 - y1)/ (x2 - x1) */
else
{
temp = input_levels[index] - input_levels[index - 1];
if(temp == 0.0)
{
slope = 0.0;
}
else
{
slope = (output_levels[index] - output_levels[index-1])/ (input_levels[index ] - input_levels[index - 1]);
}
}
/*************************************************************************
* Calculate thereshold delta depending on given input range
**************************************************************************/
temp = output_levels[index-1] + slope*(signal - input_levels[index-1]);
temp = temp - signal;
signal = temp + instance->gain;
/*******************************************************************************
* Make linear and write in output
********************************************************************************/
out[i] = AMF_TranslateVeryFastDBToAmp(signal);
}
instance->envState = envState;
}
#endif
const AMF_ModuleClass AMFClassAGCLimiterCoreTable = {
/* Flags */
0,
/* Render function */
(AMF_RenderFunction) AMF_AGCLimiterCoreTable_Render, // render function
/* Default bypass */
(void *)0,
/* Input descriptor - 1 input, and it is mono. */
1, 0,
/* Output descriptor - 1 output, and it is mono. */
1, 0,
};
// Class-specific helper functions
#pragma optimize_for_space
float AMF_AGCLimiterCoreTable_TranslateEnvFollowerTimeConst(float timeConstMilliseconds, float samplingRate)
{
return 1.0-exp(-1.0 / (samplingRate * (0.001*timeConstMilliseconds)));
}
#pragma optimize_for_space
float AMF_AGCLimiterCoreTable_TranslateEnvFollowerT60(float T60Milliseconds, float samplingRate)
{
return 1.0-pow(10.0, -3.0/(0.001*T60Milliseconds*samplingRate));
}
#pragma optimize_for_space
float AMF_AGCLimiterCoreTable_TranslateSlope(float ratio)
{
return 1.0 - (1.0 / ratio);
}
#pragma optimize_for_space
float AMF_AGCLimiterCoreTable_TranslateSharpnessFactor (float kneeDepth)
{
return 1.0 / kneeDepth;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -