📄 enhance.c
字号:
/*************************************************************************************
DEPARTMENT OF ELECTRICAL AND ELECTRONIC ENGINEERING
IMPERIAL COLLEGE LONDON
EE 3.19: Real Time Digital Signal Processing
Dr Paul Mitcheson and Daniel Harvey
PROJECT: Frame Processing
********* ENHANCE. C **********
Shell for speech enhancement
Demonstrates overlap-add frame processing (interrupt driven) on the DSK.
*************************************************************************************
By Danny Harvey: 21 July 2006
************************************************************************************/
/*
* You should modify the code so that a speech enhancement project is built
* on top of this template.
*/
/**************************** Pre-processor statements ******************************/
// Included so program can make use of DSP/BIOS configuration tool.
#include "enhancecfg.h"
/* The file dsk6713.h must be included in every program that uses the BSL. This
example also includes dsk6713_aic23.h because it uses the
AIC23 codec module (audio interface). */
#include "dsk6713.h"
#include "dsk6713_aic23.h"
// math library (trig functions)
#include <math.h>
/* Some functions to help with Complex algebra and FFT. */
#include "cmplx.h"
#include "fft_functions.h"
// Some functions to help with writing/reading the audio ports when using interrupts.
#include "helper_functions_ISR.c"
#define WINCONST 0.85185 /* 0.46/0.54 for Hamming window */
#define FSAMP 8000.0 /* sample frequency, ensure this matches Config for AIC */
#define NFREQ (1+FFTLEN/2) /* number of frequency bins from a real FFT */
#define FFTLEN 256 /* fft length = frame length 256/8000 = 32 ms*/
#define OVERSAMP 4 /* oversampling ratio (2 or 4) */
#define FRAMEINC (FFTLEN/OVERSAMP) /* Frame increment */
#define CIRCBUF (FFTLEN+FRAMEINC) /* length of I/O buffers */
#define OUTGAIN 16000.0 /* Output gain for DAC */
#define INGAIN (1.0/16000.0) /* Input gain for ADC */
// PI defined here for use in your code
#define PI 3.141592653589793
#define TFRAME FRAMEINC/FSAMP /* time between calculation of each frame */
#define NFRAME 312 /* number of frames processed within 2.5sec */
/******************************* Global declarations ********************************/
/* Audio port configuration settings: these values set registers in the AIC23 audio
interface to configure it. See TI doc SLWS106D 3-3 to 3-10 for more info. */
DSK6713_AIC23_Config Config = { \
/**********************************************************************/
/* REGISTER FUNCTION SETTINGS */
/**********************************************************************/\
0x0017, /* 0 LEFTINVOL Left line input channel volume 0dB */\
0x0017, /* 1 RIGHTINVOL Right line input channel volume 0dB */\
0x01f9, /* 2 LEFTHPVOL Left channel headphone volume 0dB */\
0x01f9, /* 3 RIGHTHPVOL Right channel headphone volume 0dB */\
0x0011, /* 4 ANAPATH Analog audio path control DAC on, Mic boost 20dB*/\
0x0000, /* 5 DIGPATH Digital audio path control All Filters off */\
0x0000, /* 6 DPOWERDOWN Power down control All Hardware on */\
0x0043, /* 7 DIGIF Digital audio interface format 16 bit */\
0x008d, /* 8 SAMPLERATE Sample rate control 8 KHZ-ensure matches FSAMP */\
0x0001 /* 9 DIGACT Digital interface activation On */\
/**********************************************************************/
};
// Codec handle:- a variable used to identify audio interface
DSK6713_AIC23_CodecHandle H_Codec;
float *inbuffer, *outbuffer; /* Input/output circular buffers */
float *inframe, *outframe; /* Input and output frames */
float *inwin, *outwin; /* Input and output windows */
float ingain, outgain; /* ADC and DAC gains */
float cpufrac; /* Fraction of CPU time used */
int io_ptr=0; /* Input/ouput pointer for circular buffers */
int frame_ptr=0; /* Frame pointer */
float *M1, *M2, *M3, *M4; /* minimum noise value in each 2.5 sec */
float *M_min; /* minimum magnitude of noise spectrum in M2[]~M4[] */
int num=0; /* number of frames having been processed within each 2.5 sec */
float *Px; /* Px=|X(w)|or low pass versioin of |X(w)| or |X(w)|^2 */
float *Pn; /* Pn=|N(w)|or low pass versioin of |N(w)| or |N(w)|^2 */
float *Px1; /* previous X|w| (will be used in "enhancement 8") */
float *Pn1; /* previous N|w| (will be used in "enhancement 8") */
float *LPx; /* Low pass version of |X(w)| */
float *inframe_mag; /* magnitude of spectrum,i.e.|X(w)| */
complex *Y1, *Y2, *Y3; /* used in "enhancement 8" to store the prvious,current and
furture value of prcessed Y(w) seperately */
complex *inframe_copy; /* copy data to inframe[] and do processing here */
float *G; /* will be used in noise substraction */
float *noise; /* |N(w)|, noise spectrum estimation value */
float K_lowpass; /* parameter of Low pass filter */
float *SNR; /* SNR (will be used in enhancement 6) */
float *a_SNR; /* parameter a_SNR[k] varies with SNR[k]
(will be used in enhancement 6)*/
float a=2.0; /* factor to correct underestimation of noise*/
float LAMDA=0.08; /* used when set the minimum allowed value for G[k] */
float threshold=0.8; /* threshold for |N(w)|/|X(w)|*/
float TAO=0.05;
/* These variables are used to switch and combine different enhancement methods */
int N_opt=0; /* option of |N(w)| version (enhancement 1;2) */
int X_opt=2; /* option of |X(w)| version (enhancement 3)*/
int G_opt=0; /* option of G(w) version (enhancement 4;5)*/
int a_opt=1; /* option of a (enhancement 6) */
int Y_opt=1; /* option of Y(w) (enhancement 8) */
/******************************* Function prototypes *******************************/
void init_hardware(void); /* Initialize codec */
void init_HWI(void); /* Initialize hardware interrupts */
void ISR_AIC(void); /* Interrupt service routine for codec */
void process_frame(void); /* Frame processing routine */
float min(float x, float y); /* find minimum value between x and y */
float max(float a, float b); /* find maximum value between x and y */
/********************************** Main routine ************************************/
void main()
{
int k; // used in various for loops
/* initialize board and the audio port */
init_hardware();
/* initialize hardware interrupts */
init_HWI();
/* Initialize and zero fill arrays */
inbuffer = (float *) calloc(CIRCBUF, sizeof(float)); /* Input array */
outbuffer = (float *) calloc(CIRCBUF, sizeof(float)); /* Output array */
inframe = (float *) calloc(FFTLEN, sizeof(float)); /* Array for processing*/
outframe = (float *) calloc(FFTLEN, sizeof(float)); /* Array for processing*/
inwin = (float *) calloc(FFTLEN, sizeof(float)); /* Input window */
outwin = (float *) calloc(FFTLEN, sizeof(float)); /* Output window */
inframe_copy= (complex *)calloc(FFTLEN,sizeof(complex));/* do frame process in inframe_copy */
/* M1[]~M4[]array to store the minimum values in each 2.5 sec*/
M1 = (float *) calloc(FFTLEN, sizeof(float));
M2 = (float *) calloc(FFTLEN, sizeof(float));
M3 = (float *) calloc(FFTLEN, sizeof(float));
M4 = (float *) calloc(FFTLEN, sizeof(float));
/* minimum magnitude of Noise spectrum in M2[]~M4[] */
M_min = (float *) calloc(FFTLEN, sizeof(float));
inframe_mag = (float *) calloc(FFTLEN, sizeof(float)); /* |X(w)|, magnitude of spectrum*/
G = (float *) calloc(FFTLEN, sizeof(float)); /* will be used in noise substraction */
noise = (float *) calloc(FFTLEN, sizeof(float)); /* |N(w)|, noise spectrum estimation value */
a_SNR = (float *) calloc(FFTLEN, sizeof(float)); /* signal to noise ratio */
SNR = (float *) calloc(FFTLEN, sizeof(float)); /* parameter a_SNR[k] varies with SNR[k] */
Px = (float *) calloc(FFTLEN, sizeof(float)); /* version |X(w)| */
Pn = (float *) calloc(FFTLEN, sizeof(float)); /* version |N(w)| */
Px1 = (float *) calloc(FFTLEN, sizeof(float)); /* previous |X(w)| */
Pn1 = (float *) calloc(FFTLEN, sizeof(float)); /* previous |N(w)| */
LPx = (float *) calloc(FFTLEN, sizeof(float)); /* low_pass version |X(w)| */
/* the prvious,current and furture value of prcessed Y(w) seperately */
Y1 = (complex *) calloc(FFTLEN, sizeof(complex));
Y2 = (complex *) calloc(FFTLEN, sizeof(complex));
Y3 = (complex *) calloc(FFTLEN, sizeof(complex));
for(k=0;k<FFTLEN;k++)
Px1[k]=0.0001; // fill Px1[] with 0.0001 (since Pn[k]/Px[k] will be used in enhancement 6)
/* calculate parameters which will be used in low-pass version */
K_lowpass=exp(-TFRAME/TAO);
/* initialize algorithm constants */
for (k=0;k<FFTLEN;k++)
{
inwin[k] = sqrt((1.0-WINCONST*cos(PI*(2*k+1)/FFTLEN))/OVERSAMP);
outwin[k] = inwin[k];
}
ingain=INGAIN;
outgain=OUTGAIN;
/* main loop, wait for interrupt */
while(1) process_frame();
}
/********************************** init_hardware() *********************************/
void init_hardware()
{
// Initialize the board support library, must be called first
DSK6713_init();
// Start the AIC23 codec using the settings defined above in config
H_Codec = DSK6713_AIC23_openCodec(0, &Config);
/* Function below sets the number of bits in word used by MSBSP (serial port) for
receives from AIC23 (audio port). We are using a 32 bit packet containing two
16 bit numbers hence 32BIT is set for receive */
MCBSP_FSETS(RCR1, RWDLEN1, 32BIT);
/* Configures interrupt to activate on each consecutive available 32 bits
from Audio port hence an interrupt is generated for each L & R sample pair */
MCBSP_FSETS(SPCR1, RINTM, FRM);
/* These commands do the same thing as above but applied to data transfers to the
audio port */
MCBSP_FSETS(XCR1, XWDLEN1, 32BIT);
MCBSP_FSETS(SPCR1, XINTM, FRM);
}
/********************************** init_HWI() **************************************/
void init_HWI(void)
{
IRQ_globalDisable(); // Globally disables interrupts
IRQ_nmiEnable(); // Enables the NMI interrupt (used by the debugger)
IRQ_map(IRQ_EVT_RINT1,4); // Maps an event to a physical interrupt
IRQ_enable(IRQ_EVT_RINT1); // Enables the event
IRQ_globalEnable(); // Globally enables interrupts
}
/**********************************min() *******************************************/
/* find and return the minimum value */
float min(float x, float y)
{
if (x<y)
return x;
else
return y;
}
/**********************************max() *******************************************/
/* find and return maximum value */
float max(float a, float b)
{
if (a>b)
return a;
else
return b;
}
/******************************** process_frame() ***********************************/
void process_frame(void)
{
int k, m;
int io_ptr0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -