📄 amf_agclimitercore.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: 2006/10/12 $ by $Author: Fernando $
#include "AMF_AGCLimiterCore.h"
#include "math.h"
void AMF_AGCLimiterCore_Render(AMF_AGCLimiterCore * 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
SEG_MOD_FAST_CODE void AMF_AGCLimiterCore_Render(AMF_AGCLimiterCore * restrict instance,float * restrict * buffers, int tickSize) {
int i;
float *in = buffers[0];
float *out = buffers[1];
float *tmp = buffers[2];
float envState = instance->envState;
float envCoef;
float attackCoef = instance->attackCoef;
float decayCoef = instance->decayCoef;
/* envelope follower, where filtering coefficient depends on
whether input is increasing or decreasing in amplitude
*/
for(i=0;i<tickSize;i++) {
if(envState < in[i])
envCoef = attackCoef;
else
envCoef = decayCoef;
// one pole filter for envelope detector, where filter coef is determined above
tmp[i] = envCoef*in[i] + (1.0-envCoef)*envState;
envState = tmp[i];
}
instance->envState = envState;
// convert env output to log
for(i=0;i<tickSize;i++)
tmp[i] = AMF_TranslateVeryFastAmpToDB(tmp[i]);
// subtract compression threshold from logEnv
for(i=0;i<tickSize;i++)
tmp[i] -= instance->threshold;
// scale into range for parabolic soft knee
for(i=0;i<tickSize;i++)
tmp[i] = tmp[i] * instance->sharpnessFactor;
// soft knee
for(i=0;i<tickSize;i++) {
if(tmp[i] < -1.0)
tmp[i] = 0.0;
else if(tmp[i] > 1.0)
tmp[i] = tmp[i] * instance->slope;
else
tmp[i] = instance->slope * (0.25 + 0.5*tmp[i] + 0.25*tmp[i]*tmp[i]);
}
// convert from knee range into normal range, and add gain offset
for(i=0;i<tickSize;i++)
tmp[i] = -tmp[i]*instance->kneeDepth + instance->gain;
// convert log values into linear amplitude control, and send to output
for(i=0;i<tickSize;i++)
out[i] = AMF_TranslateVeryFastDBToAmp(tmp[i]);
}
#endif
SEG_MOD_SLOW_CONST const AMF_ModuleClass AMFClassAGCLimiterCore = {
/* Flags */
0,
/* Render function */
(AMF_RenderFunction) AMF_AGCLimiterCore_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
SEG_MOD_SLOW_CODE float AMF_AGCLimiterCore_TranslateEnvFollowerTimeConst(float timeConstMilliseconds, float samplingRate)
{
return 1.0-exp(-1.0 / (samplingRate * (0.001*timeConstMilliseconds)));
}
#pragma optimize_for_space
SEG_MOD_SLOW_CODE float AMF_AGCLimiterCore_TranslateEnvFollowerT60(float T60Milliseconds, float samplingRate)
{
return 1.0-pow(10.0, -3.0/(0.001*T60Milliseconds*samplingRate));
}
#pragma optimize_for_space
SEG_MOD_SLOW_CODE float AMF_AGCLimiterCore_TranslateSlope(float ratio)
{
return 1.0 - (1.0 / ratio);
}
#pragma optimize_for_space
SEG_MOD_SLOW_CODE float AMF_AGCLimiterCore_TranslateSharpnessFactor (float kneeDepth)
{
return 1.0 / kneeDepth;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -