📄 noise_gate.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 + -