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

📄 amf_agccompressorcoretable_render.asm

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




//    Module Name     : AMF_AGCCompressorCore_Render.asm 
//    DSP Processor   : ADSP21161
//    Original Author : Tim Stilson 
//    Date            : 8/28/03
//====================================================================================
// Processor resources used:
//  79 words pmem 
// 273 cycles, tickSize=128, (145 + 2*(tickSize/2))
// (SIMD used)
//====================================================================================

#if 1

    ////////////////////////////////////////////////////////////////////////////////
    //
    // History:
    //
    // 8/28/03 Kishore Dasari: 
    //
    ////////////////////////////////////////////////////////////////////////////////

#include "processor.h"
#include "AMF_AGCCompressorCoreTable.h"
#include <asm_sprt.h>

// global routines
.global _AMF_AGCCompressorCoreTable_Render;

.segment /pm SEG_MOD_FAST_CODE;

////////////////////////////////////////////////////////////////////////////////
// AGCCompressorCore filter
//
_AMF_AGCCompressorCoreTable_Render:
    
 // push context on stack
    puts = mode1;
    puts = r10;
 	r0 = i3; puts = r0;
 	r0=i0; puts=r0;
    r0=i1; puts=r0;
    puts=r3;
    puts=r5;
    puts=r9;
    puts=r13;
    puts=r14;
    puts=r15;
	puts=r6;
	
    i1=r8;                  // i1->*buffers
    r10 = r12;              //block size
   	m4 = 1;
	m12 = 1;
 
	// initialize input and output samples pointers
    i0=dm(0,i1);            // i0->buffers[0], input
    i4=dm(1,i1);            // i4->buffers[1], output
	i3 = i4;                // i3->buffers[1], output
    i1=r4;                  //i1->testModuleInstance[0]
    
    /**********************************************
	* Find the max value in the tick
	***********************************************/
    f1 = f1 - f1,f0 = dm(i0,m4); 
	
    lcntr = r10, do (pc,1) until lce;
    f1 = max(f0,f1), f0 = dm(i0,m4);
       	
	/*************************************************
   * update envelop coeff depending attack or decay
   * and one pole filter for envelope detector
   **************************************************/
	f0 = dm(AMF_AGCCompressorCoreTable_EnvState,i1); 
    r8=dm(AMF_AGCCompressorCoreTable_AttackCoef,i1);          
    f5=dm(AMF_AGCCompressorCoreTable_DecayCoefSmoothing,i1);     // the smoothing coefs will be used by the smoother at the end,
    f4=dm(AMF_AGCCompressorCoreTable_AttackCoefSmoothing,i1);    //   we decide here which one to use
	
    r3=dm(AMF_AGCCompressorCoreTable_Hold,i1);
	r13=dm(AMF_AGCCompressorCoreTable_Statecount,i1);
	
    f2=f1-f0,  f9=dm(AMF_AGCCompressorCoreTable_DecayCoef,i1); // r2=in-state (also does the comparison), f9 = decay coef
   /* if LT f2=f9*f2;                     // if in<state, r2=decaycoef*(in-state), since this is a multiply, the alu condition isn't affected
    if GE f2=f8*f2, f5=f4;  */            // "else" r2=attackcoef*(in-state), and choose/remember the corresponding smoothing coef
    
    if GT f2 = f8 * f2, f5 = f4;
    if GT dm(AMF_AGCCompressorCoreTable_Statecount,i1) = r3;
    
    /*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*/ 
   		
    if GT jump Calculate_signal;
    r3 = 0;
    comp(r13,r3);
    if LE f2=f9*f2;
    if GT f2=f8*f2;
    
Calculate_signal:f0=f2+f0;                           // state = r0 = state+coef*(in-state)

    dm(AMF_AGCCompressorCoreTable_EnvState,i1)=f0;         

  	
    /**********************************************************
    *		Convert to dB 
    ***********************************************************/
        // using lower-accuracy approximation to dB... using straight-line interp instread of table lookup to handle mantissa part:
        //      6.0206*(exponent + mantissa - 1) rather than 6.0206*(exponent + log2table(mantissa)) 
        //  this is quicker and didn't seem to have terrible effect on quality
 

    // basic assumption: float mantissa = scalb x by (-logb x) gives a value in the range 1 -> 2 (verified)
    // instead of doing out=6.0206*(exp + (mant-1)), we're doing 6.0206*exp - 6.0206 + 6.0206*mant
    // (this, by giving us an extra independent multiply, allows us to overlap the conversion of the exp into float)

    f4=6.0206;
    
    r14=r14-r14;                 // clear r14/s14, put smoother coef in PEy side too
    r8=logb f0,  f15=f4;                // r8/s8 = exponent(tmp), copy f4 into higher reg for parallel op below
    r3=-r8;
    f2=scalb f0 by r3;                  // f2/s2 = mantissa(tmp) (in range 1-2)
    f8=f2*f4, f1=float r8 by r14;       // f8/s2=6.*mant, convert exponent to float
    f1=f1*f4, f8=f8-f15;                // f1/s1=6.*exp, f8/s8=6.*mant - 6.
    f15=f1+f8,r2 = dm(AMF_AGCCompressorCoreTable_TablePoints,i1);  // f8/s8=6.*exp + 6.*mant - 6. , this is the result
   
 	/******************************************************
	* Find out where signal falls in the given input table
	******************************************************/
    
	i4 = dm(AMF_AGCCompressorCoreTable_InputTable,i1);
	r13 = 0;
	f1 = dm(i4,m4);
	
	lcntr = r2, do Check_InputLevel_Table_Loopend until lce;
	comp(f15,f1), f1 = dm(i4,m4);
Check_InputLevel_Table_Loopend:if gt r13 =r13 + 1;    //r13->index
		        
			
	r2 = 0;
	f3 = 0.0;
	i12 = dm(AMF_AGCCompressorCoreTable_OutputTable,i1);
	i4 = dm(AMF_AGCCompressorCoreTable_InputTable,i1);
	/*********************************************
	* 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 */
	comp(r13,r2), r2 = dm(AMF_AGCCompressorCoreTable_TablePoints,i1); 
	if ne jump Check_BeyondgivenThreshold;
	
	f1 = dm(i4,m4),f6 = pm(i12,m12);
	f2 = f15 - f1,f8 = dm(i4,m4), f4 = pm(i12,m12);
	f8 = f8 - f1; // denominator
	f4 = f4 - f6; // numerator
	f0 = 0.0;
	comp(f3,f8);
	if ne call _CompressedCore_devide_func;
	f3 = f0;  // slope
	jump SlopeCalculationComplete;
	
	/* slope for signal which is >= max level of the input table */			
Check_BeyondgivenThreshold:
	comp(r13,r2), r0 = dm(AMF_AGCCompressorCoreTable_InputTable,i1);
	if ne jump Check_GivenTable;
	r1 = 2;
	r2 = r2 - r1, r1 = dm(AMF_AGCCompressorCoreTable_OutputTable,i1);
	r0 = r0 + r2;
	r1 = r1 + r2, i4 = r0;
	i12 = r1;
	f1 = dm(i4,m4),f6 = pm(i12,m12);
	f2 = f15 - f1,f8 = dm(i4,m4), f4 = pm(i12,m12);
	f8 = f8 - f1; // denominator
	f4 = f4 - f6; // numarator
	comp(f3,f8);
	if ne call _CompressedCore_devide_func;
	f3 = f0;  // slope
	jump SlopeCalculationComplete;
				
	/*  falls under given range of input table, slope = (y2 - y1)/ (x2 - x1) */
Check_GivenTable:
	r0 = dm(AMF_AGCCompressorCoreTable_InputTable,i1);
	r13 = r13 - 1;
	r0 = r0 + r13, r1 = dm(AMF_AGCCompressorCoreTable_OutputTable,i1);
	r1 = r1 + r13, i4 = r0;
	i12 = r1;
	f1 = dm(i4,m4),f6 = pm(i12,m12);
	f2 = f15 - f1,f8 = dm(i4,m4), f4 = pm(i12,m12); // sig_ths - inputlvel[index-1]
	f8 = f8 - f1; // denominator
	f4 = f4 - f6; // numerator
	comp(f3,f8);
	if ne call _CompressedCore_devide_func;
	f3 = f0;  // slope
		
SlopeCalculationComplete:
		
	/*************************************************
   	*	Calculate the gain depending on input level
   	*	if the input level falls out of the table 
  	*	Linearly extend the line segments.
   	*************************************************/
	f8 = f3 * f2; 
	f8 = f8 + f6;  // temp = output_levels[index-1] + slope*(signal_ths - input_levels[index-1]);		
	f8 = f8 - f15, f4 = dm(AMF_AGCCompressorCoreTable_Gain,i1);
	
	/******************************************************
	* Apply compressor gain on post gain
	******************************************************/
	f0 = f8 + f4;
	
		
	/*********************************************************
	*	Convert from dB back to linear
	***********************************************************/
   	f1=0.166096;                            // this is the input scale of the dB->lin conversion
   	f0=f0*f1;                               // f0/s0=tmp[i/i+1]*0.166096, 0.166096 = log2(10)/20;
   	bit set mode1 TRUNCATE;                 // round to -inf for the fp->int conversion (the fix operation)
   	f9=1.0;
   	r1=fix f0;                          // r1=(int)floor(tmp);
   	f2=float r1;                        // back to float to get fractional part
   	f2=f0-f2;                           // f2=fractional part, read next in 
   	f2=f2+f9, f3 = dm(AMF_AGCCompressorCoreTable_SmoothingState,i1);                           // f2 = frac + 1;
   	f8=scalb f2 by r1;                  // f8 = (frac + 1)*2^floor(tmp) (this will be the target for the smoother below)
   	bit clr mode1 TRUNCATE;                 // reset rounding mode
	
    /*************************************************************
	* filter output with one pole filter running at sampling rate 
	**************************************************************/
         
    f0 = 1.0;
    f4 = f0 - f5;    //(1-coefsmoothing)
    f8 = f5 * f8;    //coefsmoothing*signal_ths
    f12 = f4 * f3;   //(1-coefsmoothing) * smoothingstate
    r13 = r10-1;
    f0 = f8 + f12;
           
    lcntr = r13, do output_write until lce;
    f12 = f4 * f0,dm(i3,m4) = f0;
output_write:f0 = f8 + f12;
  
  	dm(i3,m4) = f0;
	dm(AMF_AGCCompressorCoreTable_SmoothingState,i1) = f0;
	
 	r13=dm(AMF_AGCCompressorCoreTable_Statecount,i1);
	r13 = r13 - r10; 		//statecount - = ticksize
 	dm(AMF_AGCCompressorCoreTable_Statecount,i1)=r13;
 		
 // pop context off stack
    r6=gets(1);
 	r15=gets(2);
    r14=gets(3);
    r13=gets(4);
    r9=gets(5);
    r5=gets(6);
    r3=gets(7);
    i1=gets(8);
    i0=gets(9);
    i3=gets(10);
    r10 = gets(11);
    mode1 =gets(12);
   
    alter(12);
	
//------------------------------------------------------------------------------------
_AMF_AGCCompressorCoreTable_Render.END:
nop;nop;
leaf_exit; // C-rth requires this instead of rts
//------------------------------------------------------------------------------------
    
.endseg;
#endif


/**************************************************************************
*   Devide(x/y) function
**************************************************************************/

.global _CompressedCore_devide_func;
.segment SEG_MOD_FAST_CODE;

_CompressedCore_devide_func:

leaf_entry;

	f12 = f8;
	f8 = 2.0;
	
	f0  = recips f12; //{get 8 bit seed r0=1/d} 

	f12 = f0*f12; //{d' = d*r0} 

	f4  = f0*f4, f0 = f8-f12; //{f0=r1=2-d', f7=n*r0} 

	f12 = f0*f12; //{f12=d'-d'*r1} 

	f4  = f0*f4, f0 = f8-f12; //{f7=n*r0*r1, f0=r2=2-d'} 

	f12 = f0*f12; //{f12=d'=d'*r2} 

	f4  = f0*f4, f0 = f8-f12; //{f7=n*r0*r1*r2, f0=r3=2-d'} 

	f0  = f0*f4; //{f7=n*r0*r1*r2*r3} 
	
rts;	
_CompressedCore_devide_func.end: //rts(db);



⌨️ 快捷键说明

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