diff options
author | Yann Herklotz <ymherklotz@gmail.com> | 2018-03-18 10:19:58 +0000 |
---|---|---|
committer | Yann Herklotz <ymherklotz@gmail.com> | 2018-03-18 10:19:58 +0000 |
commit | 8cafd3deee9e424857c361362352f563367489eb (patch) | |
tree | 4177cf0c50d898856dd106ed88ab6f9fd01d3502 /Project/RTDSP | |
parent | d11bcd43595b5c3591e80b7557e5ebb5eb1412b7 (diff) | |
download | NoiseSilencer-8cafd3deee9e424857c361362352f563367489eb.tar.gz NoiseSilencer-8cafd3deee9e424857c361362352f563367489eb.zip |
[Clean] Cleaning whitespace...
Diffstat (limited to 'Project/RTDSP')
-rw-r--r-- | Project/RTDSP/enhance.c | 487 |
1 files changed, 244 insertions, 243 deletions
diff --git a/Project/RTDSP/enhance.c b/Project/RTDSP/enhance.c index d4b8ce3..09b78d6 100644 --- a/Project/RTDSP/enhance.c +++ b/Project/RTDSP/enhance.c @@ -1,33 +1,33 @@ /************************************************************************************* - DEPARTMENT OF ELECTRICAL AND ELECTRONIC ENGINEERING - IMPERIAL COLLEGE LONDON + DEPARTMENT OF ELECTRICAL AND ELECTRONIC ENGINEERING + IMPERIAL COLLEGE LONDON - EE 3.19: Real Time Digital Signal Processing - Dr Paul Mitcheson and Daniel Harvey + EE 3.19: Real Time Digital Signal Processing + Dr Paul Mitcheson and Daniel Harvey - PROJECT: Frame Processing + PROJECT: Frame Processing - ********* ENHANCE. C ********** - Shell for speech enhancement + ********* ENHANCE. C ********** + Shell for speech enhancement - Demonstrates overlap-add frame processing (interrupt driven) on the DSK. + Demonstrates overlap-add frame processing (interrupt driven) on the DSK. ************************************************************************************* - By Danny Harvey: 21 July 2006 - Updated for use on CCS v4 Sept 2010 + By Danny Harvey: 21 July 2006 + Updated for use on CCS v4 Sept 2010 ************************************************************************************/ /* - * You should modify the code so that a speech enhancement project is built + * You should modify the code so that a speech enhancement project is built * on top of this template. */ /**************************** Pre-processor statements ******************************/ // library required when using calloc #include <stdlib.h> -// Included so program can make use of DSP/BIOS configuration tool. +// Included so program can make use of DSP/BIOS configuration tool. #include "dsp_bios_cfg.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 +/* 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" @@ -36,8 +36,8 @@ #include <math.h> /* Some functions to help with Complex algebra and FFT. */ -#include "cmplx.h" -#include "fft_functions.h" +#include "cmplx.h" +#include "fft_functions.h" // Some functions to help with writing/reading the audio ports when using interrupts. #include <helper_functions_ISR.h> @@ -46,7 +46,7 @@ #define FSAMP 8000.0 /* sample frequency, ensure this matches Config for AIC */ #define FFTLEN 256 /* fft length = frame length 256/8000 = 32 ms*/ #define NFREQ (1+FFTLEN/2) /* number of frequency bins from a real FFT */ -#define OVERSAMP 4 /* oversampling ratio (2 or 4) */ +#define OVERSAMP 4 /* oversampling ratio (2 or 4) */ #define FRAMEINC (FFTLEN/OVERSAMP) /* Frame increment */ #define CIRCBUF (FFTLEN+FRAMEINC) /* length of I/O buffers */ #define FRAME_TIME 2.5 @@ -56,18 +56,18 @@ #define INGAIN (1.0/16000.0) /* Input gain for ADC */ #define NUM_M 4 #define NUM_ALPHA 4 -// PI defined here for use in your code +// PI defined here for use in your code #define PI 3.141592653589793 #define TFRAME FRAMEINC/FSAMP /* time between calculation of each frame */ /******************************* Global declarations ********************************/ -/* Audio port configuration settings: these values set registers in the AIC23 audio +/* 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 */ - /**********************************************************************/\ + /**********************************************************************/ + /* 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 */\ @@ -78,17 +78,17 @@ DSK6713_AIC23_Config Config = { \ 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 +// Codec handle:- a variable used to identify audio interface DSK6713_AIC23_CodecHandle H_Codec; -float *inbuffer, *outbuffer; /* Input/output circular buffers */ +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 */ +float ingain, outgain; /* ADC and DAC gains */ +float cpufrac; /* Fraction of CPU time used */ complex *fft_out; /* FFT output */ float *noise; float *power_in; @@ -112,277 +112,278 @@ float K; float time_constant = 40e-3; /* Time constant in ms */ int started = 0; /******************************* Function prototypes *******************************/ -void init_hardware(void); /* Initialize codec */ +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 */ void write_spectrum(void); void get_noise(void); -void low_pass_filter(float* current, float* next); -void overestimation(void); +void low_pass_filter(float* current, float* next); +void overestimation(void); /********************************** Main routine ************************************/ void main() -{ +{ - int k; // used in various for loops - int counter = 1; -/* Initialize and zero fill arrays */ + int k; // used in various for loops + int counter = 1; +/* Initialize and zero fill arrays */ - inbuffer = (float *) calloc(CIRCBUF, sizeof(float)); /* Input array */ + 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*/ + 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 */ fft_out = (complex *) calloc(FFTLEN, sizeof(complex)); /* FFT Output */ power_in = (float *) calloc(FFTLEN, sizeof(float)); /* Output window */ - p_w = (float *) calloc(FFTLEN, sizeof(float)); /* Output window */ + p_w = (float *) calloc(FFTLEN, sizeof(float)); /* Output window */ mag_in = (float *) calloc(FFTLEN, sizeof(float)); /* Output window */ noise = (float *) calloc(FFTLEN, sizeof(float)); /* Output window */ - prev_noise = (float *) calloc(FFTLEN, sizeof(float)); /* Output window */ - SNR = (float *) calloc(FFTLEN, sizeof(float)); /* Output window */ - for(k = 0; k < FFTLEN; ++k) { - SNR[k] = 0; - } - /* initialize board and the audio port */ - init_hardware(); - - /* initialize hardware interrupts */ - init_HWI(); - -/* 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; - - for (k = 0; k < NUM_M; ++k) { - M[k] = (float *) calloc(FFTLEN, sizeof(float)); - } - - K = exp(-TFRAME/time_constant); - /* main loop, wait for interrupt */ - while(1) { - process_frame(); - counter++; - snr_val = total_snr / counter; - } + prev_noise = (float *) calloc(FFTLEN, sizeof(float)); /* Output window */ + SNR = (float *) calloc(FFTLEN, sizeof(float)); /* Output window */ + for(k = 0; k < FFTLEN; ++k) { + SNR[k] = 0; + } + /* initialize board and the audio port */ + init_hardware(); + + /* initialize hardware interrupts */ + init_HWI(); + +/* 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; + + for (k = 0; k < NUM_M; ++k) { + M[k] = (float *) calloc(FFTLEN, sizeof(float)); + } + + K = exp(-TFRAME/time_constant); + /* main loop, wait for interrupt */ + while(1) { + process_frame(); + counter++; + snr_val = total_snr / counter; + } } - -/********************************** init_hardware() *********************************/ + +/********************************** init_hardware() *********************************/ void init_hardware() { - // Initialize the board support library, must be called first + // Initialize the board support library, must be called first DSK6713_init(); - - // Start the AIC23 codec using the settings defined above in config + + // 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); + /* 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); - /* 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); - /* 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() **************************************/ +/********************************** 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 + 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 } // Spectrum calculations for the new values void write_spectrum(void) { - unsigned int k; - for(k = 0; k < FFTLEN; ++k) { - if(power_in[k] < M[m_ptr][k] || M[m_ptr][k] == 0) { - M[m_ptr][k] = power_in[k]; - } - } + unsigned int k; + for(k = 0; k < FFTLEN; ++k) { + if(power_in[k] < M[m_ptr][k] || M[m_ptr][k] == 0) { + M[m_ptr][k] = power_in[k]; + } + } } // Noise estimataion void get_noise(void) { - int k, i, min_i; - float min_val; - - for(k = 0; k < FFTLEN; ++k) { - min_i = 0; - min_val = M[0][k]; - for(i = 1; i < NUM_M; ++i) { - if (M[i][k] < min_val && M[i][k]!= 0) { - min_val = M[i][k]; - min_i = i; - } - } - noise[k] = M[min_i][k]; - } - - overestimation(); + int k, i, min_i; + float min_val; + + for(k = 0; k < FFTLEN; ++k) { + min_i = 0; + min_val = M[0][k]; + for(i = 1; i < NUM_M; ++i) { + if (M[i][k] < min_val && M[i][k]!= 0) { + min_val = M[i][k]; + min_i = i; + } + } + noise[k] = M[min_i][k]; + } + + overestimation(); } void overestimation(void) { - int i; - sum = 0; - // Calcualte |signal^2/noise^2| for all k - for (i = 0; i < FFTLEN; ++i) { - if(noise[i] != 0) { - SNR[i] = power_in[i] / noise[i]; - sum += SNR[i]; - } - } - - // Calculate average - sum /= FFTLEN; - total_snr += sum; - // Use SNRs to divide - for (i = 0; i < FFTLEN; ++i) { - // Normalising - SNR[i] /= 2*sum; - SNR[i] = SNR[i] > 1 ? 1 : SNR[i]; - noise[i] *= alpha[(int)(SNR[i] * (NUM_ALPHA-1))]; - } + int i; + sum = 0; + // Calcualte |signal^2/noise^2| for all k + for (i = 0; i < FFTLEN; ++i) { + if(noise[i] != 0) { + SNR[i] = power_in[i] / noise[i]; + sum += SNR[i]; + } + } + + // Calculate average + sum /= FFTLEN; + total_snr += sum; + // Use SNRs to divide + for (i = 0; i < FFTLEN; ++i) { + // Normalising + SNR[i] /= 2*sum; + SNR[i] = SNR[i] > 1 ? 1 : SNR[i]; + noise[i] *= alpha[(int)(SNR[i] * (NUM_ALPHA-1))]; + } } // Low pass filter X(w) void low_pass_filter(float* current, float* next) { - int w; - float temp; - for (w = 0; w < FFTLEN; ++w) { - current[w] = (1-K)*current[w] + K*next[w]; - next[w] = current[w]; - } + int w; + float temp; + for (w = 0; w < FFTLEN; ++w) { + current[w] = (1-K)*current[w] + K*next[w]; + next[w] = current[w]; + } } - -/******************************** process_frame() ***********************************/ + +/******************************** process_frame() ***********************************/ void process_frame(void) { - int k, m; - int io_ptr0; - /* work out fraction of available CPU time used by algorithm */ - cpufrac = ((float) (io_ptr & (FRAMEINC - 1)))/FRAMEINC; - - /* wait until io_ptr is at the start of the current frame */ - while((io_ptr/FRAMEINC) != frame_ptr); - - /* then increment the framecount (wrapping if required) */ - if (++frame_ptr >= (CIRCBUF/FRAMEINC)) frame_ptr=0; - - /* save a pointer to the position in the I/O buffers (inbuffer/outbuffer) where the - data should be read (inbuffer) and saved (outbuffer) for the purpose of processing */ - io_ptr0=frame_ptr * FRAMEINC; - - /* copy input data from inbuffer into inframe (starting from the pointer position) */ - - m=io_ptr0; + int k, m; + int io_ptr0; + /* work out fraction of available CPU time used by algorithm */ + cpufrac = ((float) (io_ptr & (FRAMEINC - 1)))/FRAMEINC; + + /* wait until io_ptr is at the start of the current frame */ + while((io_ptr/FRAMEINC) != frame_ptr); + + /* then increment the framecount (wrapping if required) */ + if (++frame_ptr >= (CIRCBUF/FRAMEINC)) frame_ptr=0; + + /* save a pointer to the position in the I/O buffers (inbuffer/outbuffer) where the + data should be read (inbuffer) and saved (outbuffer) for the purpose of processing */ + io_ptr0=frame_ptr * FRAMEINC; + + /* copy input data from inbuffer into inframe (starting from the pointer position) */ + + m=io_ptr0; for (k=0;k<FFTLEN;k++) - { - inframe[k] = inbuffer[m] * inwin[k]; - if (++m >= CIRCBUF) m=0; /* wrap if required */ - } - - /************************* DO PROCESSING OF FRAME HERE **************************/ - - // Initialise the array fft_out for FFT - for (k = 0; k < FFTLEN; ++k) { - fft_out[k] = cmplx(inframe[k], 0.0); - } - - // Perform the FFT - fft(FFTLEN, fft_out); - - // calculate the power spectrum - for (k = 0; k < FFTLEN; ++k) { - power_in[k] = fft_out[k].r * fft_out[k].r + fft_out[k].i * fft_out[k].i; - } - - low_pass_filter(power_in, p_w); - low_pass_filter(noise, prev_noise); - - // Get average of fft_out and write to Spectrum - write_spectrum(); - - // Set the noise - get_noise(); - - if(frame_ctr > MAX_COUNT-1) { - int i; - frame_ctr = 0; - if(++m_ptr == NUM_M) m_ptr = 0; - for(i = 0; i < FFTLEN; ++i) { - M[m_ptr][i] = power_in[i]; - } - } - - // max(lambda, |N(w)/g(w)| - for (k = 0; k < FFTLEN; ++k) { - float g; - mag_N_X = sqrt(1 - noise[k]/power_in[k]); - g = mag_N_X > lambda ? mag_N_X : lambda; - fft_out[k] = rmul(g, fft_out[k]); - } - - // Back into time domain - ifft(FFTLEN, fft_out); - - for (k = 0; k < FFTLEN; ++k) { - outframe[k] = fft_out[k].r; - } - /********************************************************************************/ - - /* multiply outframe by output window and overlap-add into output buffer */ - - m=io_ptr0; - - for (k=0;k<(FFTLEN-FRAMEINC);k++) - { /* this loop adds into outbuffer */ - outbuffer[m] = outbuffer[m]+outframe[k]*outwin[k]; - if (++m >= CIRCBUF) m=0; /* wrap if required */ - } - for (;k<FFTLEN;k++) - { - outbuffer[m] = outframe[k]*outwin[k]; /* this loop over-writes outbuffer */ - m++; - } -} + { + inframe[k] = inbuffer[m] * inwin[k]; + if (++m >= CIRCBUF) m=0; /* wrap if required */ + } + + /************************* DO PROCESSING OF FRAME HERE **************************/ + + // Initialise the array fft_out for FFT + for (k = 0; k < FFTLEN; ++k) { + fft_out[k] = cmplx(inframe[k], 0.0); + } + + // Perform the FFT + fft(FFTLEN, fft_out); + + // calculate the power spectrum + for (k = 0; k < FFTLEN; ++k) { + power_in[k] = fft_out[k].r * fft_out[k].r + fft_out[k].i * fft_out[k].i; + } + + low_pass_filter(power_in, p_w); + low_pass_filter(noise, prev_noise); + + // Get average of fft_out and write to Spectrum + write_spectrum(); + + // Set the noise + get_noise(); + + if(frame_ctr > MAX_COUNT-1) { + int i; + frame_ctr = 0; + if(++m_ptr == NUM_M) m_ptr = 0; + for(i = 0; i < FFTLEN; ++i) { + M[m_ptr][i] = power_in[i]; + } + } + + // max(lambda, |N(w)/g(w)| + for (k = 0; k < FFTLEN; ++k) { + float g; + mag_N_X = sqrt(1 - noise[k]/power_in[k]); + g = mag_N_X > lambda ? mag_N_X : lambda; + fft_out[k] = rmul(g, fft_out[k]); + } + + // Back into time domain + ifft(FFTLEN, fft_out); + + for (k = 0; k < FFTLEN; ++k) { + outframe[k] = fft_out[k].r; + } + /********************************************************************************/ + + /* multiply outframe by output window and overlap-add into output buffer */ + + m=io_ptr0; + + for (k=0;k<(FFTLEN-FRAMEINC);k++) + { /* this loop adds into outbuffer */ + outbuffer[m] = outbuffer[m]+outframe[k]*outwin[k]; + if (++m >= CIRCBUF) m=0; /* wrap if required */ + } + + for (;k<FFTLEN;k++) + { + outbuffer[m] = outframe[k]*outwin[k]; /* this loop over-writes outbuffer */ + m++; + } +} /*************************** INTERRUPT SERVICE ROUTINE *****************************/ // Map this to the appropriate interrupt in the CDB file - + void ISR_AIC(void) -{ - short sample; - /* Read and write the ADC and DAC using inbuffer and outbuffer */ - sample = mono_read_16Bit(); - inbuffer[io_ptr] = ((float)sample)*ingain; - /* write new output data */ - mono_write_16Bit((int)(outbuffer[io_ptr]*outgain)); - - /* update io_ptr and check for buffer wraparound */ - - if (++io_ptr >= CIRCBUF) io_ptr=0; - frame_ctr++; - started = 1; +{ + short sample; + /* Read and write the ADC and DAC using inbuffer and outbuffer */ + sample = mono_read_16Bit(); + inbuffer[io_ptr] = ((float)sample)*ingain; + /* write new output data */ + mono_write_16Bit((int)(outbuffer[io_ptr]*outgain)); + + /* update io_ptr and check for buffer wraparound */ + + if (++io_ptr >= CIRCBUF) io_ptr=0; + frame_ctr++; + started = 1; } /************************************************************************************/ |