⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 amf_agccompressorcoretable.c

📁 ADI SHARC DSP 音频算法标准模块库
💻 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_AGCCompressorCore.c#3 $ 
// Part of : VisualAudio V2.5.0 
// Updated : $Date: 2006/10/12 $ by $Author: Fernando $



#include "AMF_AGCCompressorCoreTable.h"
#include "math.h"

void AMF_AGCCompressorCoreTable_Render(AMF_AGCCompressorCoreTable * 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_AGCCompressorCoreTable_Render(AMF_AGCCompressorCoreTable * restrict instance,float * restrict * buffers,int tickSize) {
    int i;
    float *in = buffers[0]; 
    float *out = buffers[1];
    float envState = instance->envState;
    float attackCoef = instance->attackCoef;
    float decayCoef = instance->decayCoef;
    float envCoef;
    float smoothingState = instance->smoothingState;
    float attackCoefSmoothing = instance->attackCoefSmoothing;
    float decayCoefSmoothing = instance->decayCoefSmoothing;
    float coefSmoothing,slope;
    float maxInput;
    float signal_ths,temp;
	float *input_levels = instance->inputTable;
	float *output_levels = instance->outputTable;
	int num_points = instance->Table_points;
	int index=0;
	
	
	envCoef = attackCoef;	
    coefSmoothing = attackCoefSmoothing;
	
    maxInput = in[0];
    
	/**********************************************
	* Find the max value in the tick
	***********************************************/
	for(i=1;i<tickSize;i++)
	{
    	maxInput = fmaxf(maxInput,in[i]);
    } 
    
   /*************************************************
   * update envelop coeff depending attack or decay
   **************************************************/
    if(envState < maxInput) 
    {
        envCoef = attackCoef;
        coefSmoothing = attackCoefSmoothing;
        instance->Statecount = instance->Hold;
        
		/*To hold that many states before changing to decay.(i.e)When it changes 
		from attak to decay it will still retain attack coefficient for 'hold' 
		number of samples. So to change to decay coefficient the maxInput 
		has to be decreasing in amplitude for atleast hold number of samples*/ 
    }
    else 
    {
        if(instance->Statecount <= 0)
        {
        	envCoef = decayCoef;
        	coefSmoothing = decayCoefSmoothing;
        }
     }
	   
   /*************************************************
   * one pole filter for envelope detector
   **************************************************/
	signal_ths = envCoef*maxInput + (1.0-envCoef)*envState;
    instance->envState = signal_ths;
    
   /*************************************************
   * Convert to dB scale
   **************************************************/
    signal_ths = AMF_TranslateVeryFastAmpToDB(signal_ths);


	/************************************************
	* Find out where signal falls in the given 
	* input table.
	*************************************************/
	index = 0;
	for(i = 0;i< num_points;i++)  // num_point is array size of input and output levels
	{
		if(signal_ths > input_levels[i])
			index++;
	}
	
	/*********************************************
	* Look for slope in the lookup table
	* if signal is out of bounds extend linearly
	**********************************************/
	/* slope for signal which is <= minimum level of the input table */
	if(index == 0)
	{
		if(signal_ths < 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 the gain depending on input level
   *	if the input level falls out of the table 
   *	Linearly extend the line segments.
   *************************************************/

	temp = output_levels[index-1] + slope*(signal_ths - input_levels[index-1]);
	temp = temp - signal_ths;

    /******************************************************
	* Apply compressor gain on post gain
	******************************************************/
    signal_ths = temp + instance->gain;
    
	/******************************************************
	* Translate from dB to normal scale
	******************************************************/
    signal_ths = AMF_TranslateVeryFastDBToAmp(signal_ths);
      
    /*************************************************************
	* filter output with one pole filter running at sampling rate 
	**************************************************************/
	for (i=0; i<tickSize; i++)
	{
    	out[i] = coefSmoothing*signal_ths + (1.0-coefSmoothing)*smoothingState;
    	smoothingState = out[i];
	}
       
    instance->smoothingState = smoothingState;
    instance->Statecount = instance->Statecount - tickSize;
}
#endif

#if 1

SEG_MOD_SLOW_CONST const AMF_ModuleClass AMFClassAGCCompressorCoreTable = {
    
    /* Flags */
    0,
     
    /* Render function */
    (AMF_RenderFunction)AMF_AGCCompressorCoreTable_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,
};

#endif

// Class-specific helper functions
 float AMF_AGCCompressorCoreTable_TranslateEnvFollowerT60(float T60, int tickSize, float samplingRate)
{
    return 1.0-exp(-1.0 * tickSize / (samplingRate * (0.001*T60)));
}

float AMF_AGCCompressorCoreTable_TranslateSmoothingFilterT60(float T60, int tickSize, float samplingRate)
{
    return 1.0-exp(-1.0 / (samplingRate * (0.001*T60)));
}

float AMF_AGCCompressorCoreTable_TranslateSlope(float ratio)
{
    return 1.0 - (1.0 / ratio);
}






⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -