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

📄 noise_gate.asm

📁 adsp21065例程代码 音频处理及其他 adsp2XXX源代码 在Vdsp++下应用
💻 ASM
字号:
/***   NOISE_GATE.ASM   *****************************************************************
*                                                                                       *
*   ADSP-21065L EZLAB  Noise Gate Effect Program                                        *
*   Developed using ADSP-21065L EZ-LAB Evaluation Platform                              *
*                                                                                       *
*                                                                                       *
*   What the noise gate does?                                                           *
*   -------------------------                                                           *
*   Reduces the amound of gain below a certan threshold to reduce or eliminiate         *
*   noise produced when no audio signal is present, while still allowing the            *
*   signal to pass thru.  This is useful after processing multiple audio effects        *
*   that can introduce noise above the noise floor of the AD1819a DACs.                 *
*                                                                                       *
*   Parameters:                                                                         *
*   ----------                                                                          *
*   Threshold:  The level at which the noise gate processor begins decreasing the       *
*   volume of the signal.                                                               *
*   NOTE: Threshold values are in RMS.  This routine calculates the RMS of the          *
*   audio signal in determining if low level noise should be removed.  A running        *
*   average is not sufficent otherwise the audio signal will be severely distorted      *
*                                                                                       *
*   Future Parameters that will be added in Rev 2.0:                                    *
*   -----------------------------------------------                                     *
*   Attack Time:  The amount of time it takes once the input signal has passed the      *
*   threshold for the dynamics processor to begin attenuating the signal.               *
*   Release Time:  The amount of time it takes once the input signal has passed         *
*   below the threshold for the dynamics processor to stop attenuating the signal       *	
*                                                                                       *
*   The audio data is sent out to the AD1819A Line Outputs                              *
*                                                                                       *
*                                                                                       *
*                                                           John Tomarakos              *
*                                                           ADI DSP Applications Group  *
*                                                           Revision 1.0                *
*                                                           11/19/98                    *
*                                                                                       *
*****************************************************************************************/

/* ADSP-21065L System Register bit definitions */
#include 	"def21065l.h"
#include 	"new65Ldefs.h"

.EXTERN 	Left_Channel_In;
.EXTERN 	Right_Channel_In;
.EXTERN 	Left_Channel_Out;
.EXTERN 	Right_Channel_Out;
.GLOBAL		Noise_Gate;
.GLOBAL		select_threshold;
.GLOBAL		init_averaging_buffers;


.segment /dm    noisegt;

.var	IRQ1_counter = 0x00000003;		
.var	threshold = 0.04;
.var	Left_RMS_Result;
.var	Right_RMS_Result;
.var	left_float;
.var	right_float;
.var	left_RMS_squared = 0.0;
.var	right_RMS_squared = 0.0;
.var	left_RMS_line[500];			/* used to detect the RMS value of the left channel audio signal */
.var	right_RMS_line[500];     	/* used to detect the RMS value of the right channel audio signal */

.endseg;


.segment /pm pm_code;

init_averaging_buffers:
	B6 = left_RMS_line;  
	L6 = @left_RMS_line;        	/* delay-line buffer pointer and length */
	m6 = 1;

	LCNTR = L6; 					/* clear delay line buffer to zero */
    DO clrDlineL UNTIL LCE;
clrDlineL:         dm(i6, m6) = 0;

	B7 = right_RMS_line;  
	L7 = @right_RMS_line;       	/* delay-line buffer pointer and length */
	m7 = 1;

	LCNTR = L7; 					/* clear delay line buffer to zero */
    DO clrDlineR UNTIL LCE;
clrDlineR:         dm(i7, m7) = 0;

	RTS;


/* //////////////////////////////////////////////////////////////////////////// *
 *                                                                              *
 *                            STEREO NOISE GATE ROUTINE                         *
 *                                                                              *
 *		inputs:                                                                 *
 *		f2 = left channel data                                                  *
 *		f3 = right channel data                                                 *
 *                                                                              *
 *		outputs:                                                                *
 *		f2 = compressed left channel data                                       *
 *		f3 = compressed right channel data                                      *
 *                                                                              *
 * //////////////////////////////////////////////////////////////////////////// */


Noise_Gate:
	r2 = DM(Left_Channel_In);		/* left input sample */
	r3 = DM(Right_Channel_In);		/* right input sample */

	r1 = -31;     					/* scale the sample to the range of +/-1.0 */									
   	f2 = float r2 by r1; 			/* convert left fixed point sample to floating point */							
	f3 = float r3 by r1; 			/* convert right fixed point sample to floating point */

	DM(left_float) = f2;			/* save floating point samples temporarily */
	DM(right_float) = f3;

	f15 = 0.002;					/* 1/500 = 0.002*/
	f5 = DM(threshold);				/* f1 = Threshold = 0.1	*/

RMS_left_value:
	f0 = abs f2;					/* take absolute value of incoming left sample */
	f1 = f0;						/* get ready to square the input */
	f0 = f0 * f1;					/* f0 = square(abs(x)) */
	f0 = f0 * f15;					/* divide incoming squared sample by length of RMS line */
	f1 = dm(i6,0);					/* fetch oldest value in RMS line */
	f10 = DM(left_RMS_squared);		/* get previous running average of the squares of the input */
	f10 = f10 + f0;					/* add scaled squared input to the running average value */
	f10 = f10 - f1;					/* subtract oldest squared sample from running average */
	DM(left_RMS_squared) = f10;     /* save new running average of the square of the inputs samples */
	dm(i6,1) = f0;					/* store new scaled squared sample over old sample in RMS line */

	/* calculate square root of new average in f10 based on the Newton-Raphson iteration algorithm */
	f8 = 3.0;
	f2 = 0.5;
	f4 = RSQRTS f10; 				/* Fetch seed */
	f1 = f4;
	f12 = f4 * f1;					/* F12=X0^2 */
	f12 = f12 * f0;					/* F12=C*X0^2 */
	f4 = f2 * f4, f12 = f8 - f12;	/* F4=.5*X0, F10=3-C*X0^2 */
	f4 = f4 * f12;					/* F4=X1=.5*X0(3-C*X0^2) */
	f1 = f4;
	f12 = f4 * f1;					/* F12=X1^2 */
	f12 = f12 * f0;					/* F12=C*X1^2 */
	f4 = f2 * f4, f12 = f8 - f12;	/* F4=.5*X1, F10=3-C*X1^2 */
	f4 = f4 * f12;					/* F4=X2=.5*X1(3-C*X1^2) */
	f1 = f4;
	f12 = f4 * f1;					/* F12=X2^2 */
	f12 = f12 * f0;					/* F12=C*X2^2 */
	f4 = f2 * f4, f12 = f8 - f12;	/* F4=.5*X2, F10=3-C*X2^2 */
	f4 = f4 * f12;					/* F4=X3=.5*X2(3-C*X2^2) */
	f10 = f4 * f10;					/* X=sqrt(Y)=Y/sqrt(Y) */
	DM(Left_RMS_Result) = f10;

gate_left:
	f2 = DM(left_float);
	f10 = abs f10;					/* get absolute value of running average */			
	comp(f10,f5);					/* compare to desired threshold */
	if LT f2 = f2 - f2; 			/* if left channel < threshold, left channel = 0.0 */

	/* send gated results to left DAC channel */
	r1 = 31;     					/* scale the result back up to MSBs */			   
	r2 = fix f2 by r1;				/* convert back to fixed point number */			
	DM(Left_Channel_Out) = r2;

RMS_right_value:
	f0 = abs f3;					/* take absolute value of incoming right sample */
	f1 = f0;						/* get ready to square the input */
	f0 = f0 * f1;					/* f0 = square(abs(x)) */
	f0 = f0 * f15;					/* divide incoming squared sample by length of RMS line */
	f1 = dm(i7,0);					/* fetch oldest value in RMS line */
	f10 = DM(right_RMS_squared);	/* get previous running average of the squares of the input */
	f10 = f10 + f0;					/* add scaled squared input to the running average value */
	f10 = f10 - f1;					/* subtract oldest squared sample from running average */
	DM(right_RMS_squared) = f10;    /* save new running average of the square of the inputs samples */
	dm(i7,1) = f0;					/* store new scaled squared sample over old sample in RMS line */

	/* caclulate square root of new average in f10 based on the Newton-Raphson iteration algorithm */
	f8 = 3.0;
	f2 = 0.5;	
	f4 = RSQRTS f10; 				/* Fetch seed */
	f1 = f4;
	f12 = f4 * f1;					/* F12=X0^2 */
	f12 = f12 * f0;					/* F12=C*X0^2 */
	f4 = f2 * f4, f12 = f8 - f12;	/* F4=.5*X0, F10=3-C*X0^2 */
	f4 = f4 * f12;					/* F4=X1=.5*X0(3-C*X0^2) */
	f1 = f4;
	f12 = f4 * f1;					/* F12=X1^2 */
	f12 = f12 * f0;					/* F12=C*X1^2 */
	f4 = f2 * f4, f12 = f8 - f12;	/* F4=.5*X1, F10=3-C*X1^2 */
	f4 = f4 * f12;					/* F4=X2=.5*X1(3-C*X1^2) */
	f1 = f4;
	f12 = f4 * f1;					/* F12=X2^2 */
	f12 = f12 * f0;					/* F12=C*X2^2 */
	f4 = f2 * f4, f12 = f8 - f12;	/* F4=.5*X2, F10=3-C*X2^2 */
	f4 = f4 * f12;					/* F4=X3=.5*X2(3-C*X2^2) */
	f10 = f4 * f10;					/* X=sqrt(Y)=Y/sqrt(Y) */
	DM(Right_RMS_Result) = f10;
					      	
gate_right:
	f3 = DM(right_float);
	f10 = abs f10;					
	comp(f10,f5);
	if LT f3 = f3 - f3; 			/* if right channel < threshold, right channel = 0 */

	/* send gated results to right DAC channel */
	r1 = 31;     					/* scale the result back up to MSBs */			   
	r3 = fix f3 by r1;				/* convert back to fixed point number */			
	DM(Right_Channel_Out) = r3;

	rts;

	
/* ------------------------------------------------------------------------------------ */
/*                                                                                      */
/*                       IRQ1 Pushbutton Interrupt Service Routine                      */
/*                                                                                      */
/*      This routine selects the noise gate threshhold, which is the level at which     */
/*      removal of the input signal occurs.                                             */
/*                                                                                      */
/*      The threshold can range from 0.0 to 0.5                                         */
/*                                                                                      */
/*      Default before 1st IRQ push: 0.05                                               */
/*      1st Pushbutton Press:	0.05                                                    */
/*      2nd Pushbutton Press:	0.1                                                     */
/*      3rd Pushbutton Press:	0.2                                                     */
/*      4th Pushbutton Press:	0.25                                                    */
/*      5th Pushbutton Press:	0.3                                                     */
/*      6th Pushbutton Press:	Reverts back to 1st Pushbutton Press                    */
/*                                                                                      */
/*      The pushbutton setting is shown by the active LED setting, all others are off   */
/*      FLAG 4 LEDis set, indicating the user is modifying ratio settings.              */	
/* ------------------------------------------------------------------------------------ */
						  
select_threshold:
    bit set mode1 SRRFH;				/* enable background register file */
	NOP; 								/* 1 CYCLE LATENCY FOR WRITING TO MODE1 REGISER!!   */

	r13 = 5;							/* number of presets */	
	r15 = DM(IRQ1_counter);				/* get preset count */
	r15 = r15 + 1;						/* increment preset */
	comp (r15, r13);
	if ge r15 = r15 - r15;				/* reset to zero */
	DM(IRQ1_counter) = r15;				/* save preset count */

	r10 = pass r15;						/* get preset mode */
	if eq jump threshold_2;				/* check for count == 0 */	
	r10 = r10 - 1;						/* get preset mode */
	if eq jump threshold_3;				/* check for count == 1 */	
	r10 = r10 - 1;						/* get preset mode */
	if eq jump threshold_4;				/* check for count == 2 */	
	r10 = r10 - 1;						/* get preset mode */
	if eq jump threshold_5;				/* check for count == 3 */

threshold_1:							/* count therefore, is == 4 if you are here */
	f14 = 0.1;			
	DM(threshold) = f14;
	bit set ustat1 0x2C;		
	bit clr ustat1 0x02;				/* turn on Flag4 & Flag5 LEDs */
	dm(IOSTAT)=ustat1;
     	jump exit;

threshold_2:
	f14 = 0.08;	
	DM(threshold) = f14;
	bit set ustat1 0x2A;		
	bit clr ustat1 0x05;				/* turn on Flag4 & Flag6 LEDs */
	dm(IOSTAT)=ustat1;
	jump exit;
	
threshold_3:							/* count therefore, is == 4 if you are here */
	f14 = 0.06;	
	DM(threshold) = f14;
	bit set ustat1 0x26;		
	bit clr ustat1 0x09;				/* turn on Flag4 & Flag7 LEDs */
	dm(IOSTAT)=ustat1;
     	jump exit;

threshold_4:							/* count therefore, is == 4 if you are here */
	f14 = 0.035;	
	DM(threshold) = f14;
	bit set ustat1 0x2E;		
	bit clr ustat1 0x11;				/* turn on Flag4 & Flag8 LEDs */
	dm(IOSTAT)=ustat1;
     	jump exit;

threshold_5:							/* count therefore, is == 4 if you are here */
	f14 = 0.01;	
	DM(threshold) = f14;
	bit set ustat1 0x1E;		
	bit clr ustat1 0x21;				/* turn on Flag4 & Flag9 LEDs */
	dm(IOSTAT)=ustat1;

exit:	
	rti(db);
	bit clr mode1 SRRFH;				/* switch back to primary register set */
	nop;

.endseg;









⌨️ 快捷键说明

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