1.       Write a program (in C/C++) to design a FIR low pass filter. The program should ask for the number of taps, sampling frequency, the cut-off frequency and whether windowing is to be used. Choose a suitable window.

The C++ programming language was chosen to complete the objectives outlined for this assignment. The FIR low pass filter was created through research of similar implementations in books, notes and web based examples. The program was compiled using Visual Studio.

F.I.R. filters (Finite Impulse Response) are implemented using a finite number “n” delay taps on a delay line and “n” computation coefficients to compute the algorithm (filter) function.  They can offer shape, factor accuracy and stability equivalent to very high-order linear active filters that cannot be achieved in the analogue domain.

FIR filters can create transfer functions that have no equivalent in linear circuit technology. FIR filters are formed with only the equivalent of zeros in the linear domain. This means that the taps depress or push down the amplitude of the transfer function. The amount of depression for each tap depends upon the value of the multiplier coefficient. Hence, the total number of taps determines the “steepness” of the slope. More taps increase the steepness of the filter roll-off while increasing calculation time (delay) and for high order filters, limiting bandwidth. There is tradeoff between phase delay and filter precision when designing FIR filters.

Filter Design:

For my filter, I have utilized the Windowing and the Hanning Technique.

Windowed Filter:

The simplest technique is known as “Windowed” filters. This technique is based on designing a filter using well-known frequency domain transition functions called “windows”. The use of windows often involves a choice of the lesser of two evils. Some windows, such as the Rectangular, yield fast roll-off in the frequency domain, but have limited attenuation in the stop-band along with poor group delay characteristics. Other windows like the Blackman, have better stop-band attenuation and group delay, but have a wide transition-band (the band-width between the corner frequency and the frequency attenuation floor). Windowed filters are easy to use, are scalable (give the same results no matter what the corner frequency is) and can be computed on-the-fly by the DSP.

Rectangular and Hanning Windowing

Rectangular windowing is a simple multiplication by 0 or 1, the impulse response is cut to zero at the point the window stops. In this example the window is the size of the entire filter effectively making no difference to the output.

w(n) = 1

Hanning Window:

The “Raised Cosine” window uses a similar technique although the coefficient is calculated differently.

Calculate Coeefficient

To determine the coefficients and fill the coefficients array, requires the “Nyquist Frequency” of the filter.

nyquist frequency

H(Θ) is the frequency response as a function of the Nyquist frequency. Using a discrete inverse Fourier transform the coefficients for a low pass filter can be described as:

Low Pass Filter Coefficients

The code for my filter is contained in Appendix A.

filter.cpp is the main application source file.

filter.h is the header file.

main.cpp has the entry point for the program. In that object of filter, a class is created

and filtering is called to start the filtering.

2.       Use your program to design a filter (i)with and (ii)without windowing, whose number of taps is equal to the last two digits of your id number. The sampling frequency is to be 8000Hz and cut off frequency is 200Hz.

For this part, I used 101 as my number of taps, my id ends in 00 so I added 101.The graphs are plotted using Microsoft Excel. The function CalCoeff(), calculates the coefficients and these are displayed using the display() function. The code for my filter is contained in Appendix A.

(i) With Hanning Window

Phase Response:

Phase Response with windowing

Figure 1 – Phase Response with windowing

Appendix B gives the values used to calculate this graph.

Amplitude Response:

Purple indicates the use of Hanning windowing.

Blue indicates without the use of windowing.

Amplitude Response with and without windowing

Figure 2 – Amplitude Response with and without windowing

Appendix B gives the values used to calculate this graph.

(ii) Without Windowing:

Phase Response:

Phase Response without Windowing

Figure 3 – Phase Response without Windowing

Appendix B gives the values used to calculate this graph.

Amplitude Response:

Please see Figure 2.

Appendix B gives the values used to calculate this graph.

3.       Write a program (in C/C++) to calculate the frequency response (Amplitude & Phase) of a digital filter and use it to plot the frequency response of the filters you designed in 2. Compare the responses (Amplitude & Phase).

For this part, I added FreqResponse() function to the program which calculates the Amplitude & Phase response. The calculated phase response and amplitude response values are stored in phase.txt and amp.txt respectively. The code for my filter is contained in Appendix A.

Phase Response of Filter designed in Part 2

Figure 4 – Phase Response of Filter designed in Part 2

Amplitude Response of Filter designed in Part 2

Figure 5 – Amplitude Response of Filter designed in Part 2

4.       Make a file of about 400 samples [at 8kHz] of your own speech waveform.[try to get the transition between a fricative (like "sh") and a vowel (like "a")]. Plot the original waveform, process it through your filter and plot the resultant output. Compare the input and output signals. What is the time shift between the input and output? Why?

I created a file at 8kHz using the word “shark” to create the waveform beneath. The results used to calculate Figure 6 and 7 are contained in Appendix C. There is a time shift between input & output signal, as the speech signal passes through the filter. The filtered output is longer than the input signal by no of taps chosen – in our case 100 (101 – 1). So, time shift = 100.

I changed the CalCoeff() function of my previous program to write coefficients to a file.

void Filter::CalCoeff()

{

//Allocate memory for coefficients

p_mcoeff = new double[m_tap];

ofstream coeffFile;

coeffFile.open (“C:\coeff.txt”);

int i=1,count;

//To keep our filter causal, shift the centre of it to the middle of taps.

if(m_tap%2 == 0)

{

count = (m_tap – 1)>>1;

}

else

{

count = m_tap >> 1;

}

//Calculate centre value of coefficient.

p_mcoeff[count] = m_nqFreq/PI;

//Calculate remaining values of coefficient.

while(i<=count)

{

p_mcoeff[count-i]=sin(i*m_nqFreq)/PI/i;

p_mcoeff[count+i]=p_mcoeff[count-i];

i++;

}

coeffFile<<m_tap<<” “;

for(i=0;i<m_tap;i++)

{

Then I processed the coefficients of my filter and my waveform through the new filter. This is contained in Appendix B. The same coefficients are used in Part 5. It utilizes the same header file. I edited the main file to prompt the user to input files. This is contained in Appendix B. This filter performs 4 main tasks:

1.         Reads the coefficients of filter from the specified .txt file.

2.         Reads the samples of the speech signal from the specified .wav file.

3.         Convolution of coefficients & samples.

4.         Writes the output of the filtered signal in a file.

Speech Waveform

Figure 6 –  Speech Waveform

Output Waveform

Figure 7 –  Output Waveform

5.       Using Matlab, plot the spectrum of the input and output [of the vowel part of the] speech signals. Comment.

From the graphs, it can be seen that both signals have different levels of power. The filtered output can be seen in Figure 8.

The Matlab code used to complete this:

sound_data = wavread(‘C:\temp\part_4_voice.wav’);

filter_coeff = [0.00636938;0.00641538;0.00630221;0.00602589;0.00558612;0.00498633;0.00423384;0.00333978;0.00231904;0.00119006;-2.53607e-005;-0.00130248;-0.00261392;-0.00393023;-0.00522029;-0.006452;-0.00759278;-0.00861027;-0.00947294;-0.0101507;-0.0106157;-0.0108426;-0.0108094;-0.0104981;-0.00989464;-0.00898978;-0.00777917;-0.00626361;-0.00444919;-0.00234732;2.53607e-005;0.00264715;0.00549151;0.00852747;0.0117201;0.0150308;0.0184184;0.0218392;0.0252482;0.0285994;0.0318471;0.0349461;0.0378527;0.0405256;0.0429265;0.0450207;0.0467777;0.0481717;0.0491824;0.0497948;0.05;0.0497948;0.0491824;0.0481717;0.0467777;0.0450207;0.0429265;0.0405256;0.0378527;0.0349461;0.0318471;0.0285994;0.0252482;0.0218392;0.0184184;0.0150308;0.0117201;0.00852747;0.00549151;0.00264715;2.53607e-005;-0.00234732;-0.00444919;-0.00626361;-0.00777917;-0.00898978;-0.00989464;-0.0104981;-0.0108094;-0.0108426;-0.0106157;-0.0101507;-0.00947294;-0.00861027;-0.00759278;-0.006452;-0.00522029;-0.00393023;-0.00261392;-0.00130248;-2.53607e-005;0.00119006;0.00231904;0.00333978;0.00423384;0.00498633;0.00558612;0.00602589;0.00630221;0.00641538;0.00636938;];

filtered_output = conv(filter_coeff,sound_data);

fft_output = abs(fft(filtered_output));

fft_input = abs(fft(sound_data));

subplot(2,1,1), plot(fft_input,’red’);

xlabel(‘frequency’);

ylabel(‘Amplitude’);

title(‘Specturm of input speech signal’);

subplot(2,1,2),plot(fft_output,’blue’);

xlabel(‘frequency’);

ylabel(‘Amplitude’);

title(‘Specturm of output speech signal’);

Input and Output Waveform

Figure 8 –  Input and Output Waveform

6.       Construct a real – time implementation of your filter on the C31 DSK. Record a few seconds o your speech.

To complete this part, I had to write a C31 Assembler version of my filter. I used RFIR.ASM as a guide.

There were 3 main changes I made to this:

  • TA        .set     48.828

This had to be changed to 48.828 as the original sampling frequency was set too high.

  • The Data buffer was changed to 128 bits(2^8) as I used 101 taps for my filter.
  • The coefficients were changed to the values of my filter.

;———————————————————

; FIR.ASM

; Keith Larson

; TMS320 DSP Applications

; (C) Copyright 1995,1996

; Texas Instruments Incorporated

;

; This is unsupported freeware with no implied warranties or

; liabilities.  See the disclaimer document for details

;

; The FIR filter code used in this example is taken

; from the TMS320C3x Users Guide.  The AIC setup and

; control is designed to work with the TMS320C31 DSK

;

; This example can either be loaded and run from the debugger

; or by directly loading and running from DSK3LOAD

;———————————————————

;

;     How to change the sampling frequency.

;

;     [Ronan Scaife, DCU, October 17th 2001]

;

;     By changing either TA/TB and RA/RB in the AIC,

;     OR by changing the figures for the C31 timer

;     see the section of code labelled “ST-STUB”

;     below, you can change the sampling frequency.

;     The default settings in Keith Larsen’s

;     original version give fS ~ 48,828 s/s.

;     For more interesting effects, I have modified

;     TA and RA to 16 to reduce fS to 24,414 s/s.

;

;     Edited By Sameer Kumar

;———————————————————

;

; Define constants used by program    ;

;TA        .set     8                  ; AIC timing register values

TA        .set     48.828                 ; AIC timing register values/this value must be changed as the original sampling frequency is too high

TB      .set         16             ;

;RA        .set     8                  ;

RA        .set     16                  ;

RB      .set         16             ;

GIE       .set     0×2000             ; This bit in ST turns on interrupts

.include “C3XMMRS.ASM”      ;

;

;     change start addr for WinDSK [RS 8-x-01]

;

;          .start   “AICTEST”,0×809820 ; Start assembling here

.start   “AICTEST”,0×809900 ; Start assembling here

.sect    “AICTEST”          ;

;- – - – - – - – - – - – - – - – - – - – - – - – - – - – - – -

; 128 bit float data buffer of incoming data from the AIC

; The location in memory must be on a 2^N boundary and the

; size of the coefficeint table must be the same as the data

; Taps for my filter = 101, therefore 128 bit data buffer must be utilised

;- – - – - – - – - – - – - – - – - – - – - – - – - – - – - – -

ADC_recv     .float    0.0          ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0           ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0           ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

.float    0.0            ;

;- – - – - – - – - – - – - – - – - – - – - – - – -

; FIR filter coefficients

;- – - – - – - – - – - – - – - – - – - – - – - – -

FIR_coef    .float    0.00636938

.float       0.00641538

.float       0.00630221

.float       0.00602589

.float       0.00558612

.float      0.00498633

.float       0.00423384

.float       0.00333978

.float       0.00231904

.float       0.00119006

.float       -2.53607e-005

.float       -0.00130248

.float       -0.00261392

.float       -0.00393023

.float       -0.00522029

.float       -0.006452

.float       -0.00759278

.float       -0.00861027

.float       -0.00947294

.float       -0.0101507

.float       -0.0106157

.float       -0.0108426

.float       -0.0108094

.float       -0.0104981

.float       -0.00989464

.float       -0.00898978

.float       -0.00777917

.float       -0.00626361

.float       -0.00444919

.float       -0.00234732

.float       2.53607e-005

.float       0.00264715

.float       0.00549151

.float       0.00852747

.float       0.0117201

.float       0.0150308

.float       0.0184184

.float       0.0218392

.float       0.0252482

.float       0.0285994

.float       0.0318471

.float       0.0349461

.float       0.0378527

.float       0.0405256

.float       0.0429265

.float       0.0450207

.float       0.0467777

.float       0.0481717

.float       0.0491824

.float      0.0497948

.float      0.05

.float      0.0497948

.float      0.0491824

.float      0.0481717

.float      0.0467777

.float      0.0450207

.float      0.0429265

.float      0.0405256

.float      0.0378527

.float      0.0349461

.float      0.0318471

.float      0.0285994

.float      0.0252482

.float      0.0218392

.float      0.0184184

.float      0.0150308

.float      0.0117201

.float      0.00852747

.float      0.00549151

.float      0.00264715

.float      2.53607e-005

.float      -0.00234732

.float      -0.00444919

.float      -0.00626361

.float      -0.00777917

.float      -0.00898978

.float      -0.00989464

.float      -0.0104981

.float      -0.0108094

.float      -0.0108426

.float      -0.0106157

.float      -0.0101507

.float      -0.00947294

.float      -0.00861027

.float      -0.00759278

.float      -0.006452

.float      -0.00522029

.float      -0.00393023

.float      -0.00261392

.float      -0.00130248

.float      -2.53607e-005

.float      0.00119006

.float      0.00231904

.float      0.00333978

.float      0.00423384

.float      0.00498633

.float      0.00558612

.float      0.00602589

.float      0.00630221

.float      0.00641538

.float      0.00636938       ;  FIR filter coefficients

END_coef

;- – - – - – - – - – - – - – - – - – -

BufSz      .set      END_coef – FIR_coef

;- – - – - – - – - – - – - – - – - – -

SIZE         .word    BufSz           ; Size of filter

ADC_first    .word    ADC_recv

ADC_end      .word    FIR_coef

ADC_last     .word    ADC_recv

FIR_coefx    .word    FIR_coef

;————————————

; Define some constant storage data

;————————————

A_REG        .word  (TA<<9)+(RA<<2)+0 ; A registers

B_REG        .word  (TB<<9)+(RB<<2)+2 ; B registers

C_REG      .word  00000011b         ; control

S0_gctrl_val .word  0x0E970300        ; Serial port control register values

S0_xctrl_val .word  0×00000111        ;

S0_rctrl_val .word  0×00000111        ;

;****************************************************

; Begin main code loop here

;****************************************************

main      or    GIE,ST          ; Turn on INTS

ldi   0xF4,IE         ; Enable XINT/RINT/INT2

b     main            ; Do it again!

;——————————-

DAC2      push  ST              ; DAC Interrupt service routine

push  R0              ;

pushf R0              ;

push  R2              ;

pushf R2              ;

push  AR0             ;

push  AR1             ;

ldi   @ADC_last,AR1   ;

ldi   @FIR_coefx,AR0  ;

ldi   @SIZE,BK

FIR       mpyf3 *AR0++,*AR1++(1)%,R0

ldf   0.0,R2

ldi   @SIZE,RC

subi  2,RC

rptb  FIR2

mpyf3 *AR0++,*AR1++(1)%,R0

FIR2  ||  addf3 R0,R2,R2

addf  R2,R0

fix   R0,R0

andn  3,R0            ;

sti   R0,@S0_xdata    ; Output the new DAC value

pop   AR1             ;

pop   AR0             ;

popf  R2              ;

pop   R2              ;

popf  R0              ;

pop   R0              ;

pop   ST              ;

reti                  ;

;——————————-

ADC2      push  ST              ;

push  R3              ;

pushf R3              ;

push  AR0             ;

ldi   @S0_rdata,R3    ;

lsh   16,R3

ash   -16,R3

ldi   @ADC_last,AR0

float R3,R3

stf   R3,*AR0++

cmpi  @ADC_end,AR0

ldige @ADC_first,AR0

sti   AR0,@ADC_last

pop   AR0

popf  R3              ;

pop   R3              ;

pop   ST              ;

reti                  ;

;*****************************************************;

; The startup stub is used during initialization only ;

; and can be safely overwritten by the stack or data  ;

;*****************************************************;

.entry   ST_STUB      ; Debugger starts here

ST_STUB   ldp   T0_ctrl         ; Use kernel data page and stack

ldi   @stack,SP

ldi   0,R0            ; Halt TIM0 & TIM1

sti   R0,@T0_ctrl     ;

sti   R0,@T0_count    ; Set counts to 0

ldi   1,R0            ; Set periods to 1

sti   R0,@T0_prd      ;

ldi   0x2C1,R0        ; Restart both timers

sti   R0,@T0_ctrl     ;

;———————

ldi   @S0_xctrl_val,R0;

sti   R0,@S0_xctrl    ; transmit control

ldi   @S0_rctrl_val,R0;

sti   R0,@S0_rctrl    ; receive control

ldi   0,R0            ;

sti   R0,@S0_xdata    ; DXR data value

ldi   @S0_gctrl_val,R0; Setup serial port

sti   R0,@S0_gctrl    ; global control

;======================================================;

; This section of code initializes the AIC             ;

;======================================================;

AIC_INIT  LDI   0×10,IE         ; Enable only XINT interrupt

andn  0×34,IF         ;

ldi   0,R0            ;

sti   R0,@S0_xdata    ;

RPTS  0×040           ;

LDI   2,IOF           ; XF0=0 resets AIC

rpts  0×40            ;

LDI   6,IOF           ; XF0=1 runs AIC

;———————

ldi   @C_REG,R0       ; Setup control register

call  prog_AIC        ;

ldi   0xfffc  ,R0     ; Program the AIC to be real slow

call  prog_AIC        ;

ldi   0xfffc|2,R0     ;

call  prog_AIC        ;

ldi   @B_REG,R0       ; Bump up the Fs to final rate

call  prog_AIC        ; (smallest divisor should be last)

ldi   @A_REG,R0       ;

call  prog_AIC        ;

b     main            ; the DRR before going to the main loop

;——————————-

prog_AIC  ldi   @S0_xdata,R1    ; Use original DXR data during 2 ndy

sti   R1,@S0_xdata    ;

idle

ldi   @S0_xdata,R1    ; Use original DXR data during 2 ndy

or    3,R1            ; Request 2 ndy XMIT

sti   R1,@S0_xdata    ;

idle                  ;

sti   R0,@S0_xdata    ; Send register value

idle                  ;

andn  3,R1            ;

sti   R1,@S0_xdata    ; Leave with original safe value in DXR

;———————

ldi   @S0_rdata,R0    ; Fix the receiver underrun by reading

rets                  ;

stack     .word   $             ; Put stack here

;****************************************************;

; Install the XINT/RINT ISR handler directly into    ;

; the vector RAM location it will be used for        ;

;****************************************************;

.start   “SP0VECTS”,0x809FC5

.sect    “SP0VECTS”

B        DAC2         ; XINT0

B        ADC2         ; RINT0

7.       Play back the original speech and the signal  filtered by your filter. Listen carefully to both and comment on what you hear.

The signal filtered by my filter is muffled in comparison to the original speech. The ‘s’ part of ‘shark’ is barely audible.

Appendix A.

The code used for part 1, 2 and 3.

filter.h

//Author: Sameer Kumar

//Date: 22/11/2006

#include <iostream>

#include <math.h>

#include <fstream>

using namespace std;

class Filter

{

//number of taps

int m_tap;

//Cut-of frequency

int m_fc;

//Sampling frequency

int m_fs;

//Nyquist Frequency

double m_nqFreq;

//Array of coefficients

double *p_mcoeff;

//Take input parameters from prompt

void TakeArguments();

//Calculate coefficients

void CalCoeff();

//Apply windowing function to coefficients

void Windowing();

//Display coefficients

void Display();

//Calculate frequecncy response of FIR filter

void FreqResponse();

public:

//main function to do filtering

void Filtering();

//Destructor to delete memory allocated for coefficeints.

~Filter()

{

delete [] p_mcoeff;

};

};

main.cpp

//Author: Sameer Kumar

//Date: 22/11/2006

// main.cpp : Defines the entry point for the console application.

//

#include “filter.h”

int main(int argc, char* argv[])

{

Filter f;

f.Filtering();

return 0;

}

filter.cpp

//Author: Sameer Kumar

//Date: 22/11/2006

#include “filter.h”

const double PI = 3.14;

//Take input parameters from prompt

void Filter::TakeArguments()

{

//Take taps as a input parameter.

cout<<”Please enter number of taps”<<endl;

cin>>m_tap;

//Take cut-off frequecy as a input parameter

cout<<”Please enter the cut-off frequency”<<endl;

cin>>m_fc;

//Take sampling frequency as a input parameter.

cout<<”Please enter the sampling frequency”<<endl;

cin>>m_fs;

//Calculate nyquist frequency

m_nqFreq = 2 * PI * m_fc/m_fs;

}

//Calculate FIR coefficeints.

void Filter::CalCoeff()

{

//Allocate memory for coefficients

p_mcoeff = new double[m_tap];

int i=1,count;

//To keep our filter causal, shift the centre of it to the middle of taps.

if(m_tap%2 == 0)

{

count = (m_tap – 1)>>1;

}

else

{

count = m_tap >> 1;

}

//Calculate centre value of coefficient.

p_mcoeff[count] = m_nqFreq/PI;

//Calculate remaining values of coefficient.

while(i<=count)

{

p_mcoeff[count-i]=sin(i*m_nqFreq)/PI/i;

p_mcoeff[count+i]=p_mcoeff[count-i];

i++;

}

}

//Apply hanning window function to coefficients.

void Filter::Windowing()

{

for(int i = 0 ; i < m_tap ; i++)

{

double win_val = 0.5 – 0.5 * cos( 2*PI*(i+ 1)/(m_tap+1));

p_mcoeff[i] *= win_val;

}

}

//Display the coefficients of FIR filter.

void Filter::Display()

{

for(int i = 0 ; i < m_tap ; i++)

{

cout<<p_mcoeff[i]<<endl;

}

}

//Calculate frequecy response (Amplitude & Phase)

void Filter::FreqResponse()

{

int degree = 180;

ofstream ampFile,phaseFile;

//Open files to write amplitude and phase values.

ampFile.open (“amp.txt”);

phaseFile.open (“phase.txt”);

double temp;

for(int i=0;i<=degree;i++ )

{

double real=0,imag = 0;

double nqfreq = ((double) 2*i/degree -1)*PI;

//Calculate real and imaginary frequecies.

for(int j=0;j<m_tap;j++ )

{

int time = j – (m_tap – 1)/2;

real += p_mcoeff[j]*cos(time*nqfreq);

imag -= p_mcoeff[j]*sin(time*nqfreq );

}

if(nqfreq > 0)

{

//Calculate amplitude

temp = sqrt(pow(real,2) + pow(imag,2));

ampFile<<temp<<endl;

//Calculate phase.

temp = atan(imag/real);

phaseFile<<temp<<endl;

}

}

//Close txt files.

ampFile.close();

phaseFile.close();

}

//Do filtering

void Filter::Filtering()

{

bool window;

//Take input parameter

TakeArguments();

//Calculate coefficients

CalCoeff();

//Take input parameter for window selection

cout<< “Please Enter the windowing option”<<endl;

cout<<”0: No Window”<<endl;

cout<<”1: With Hanning Window”<<endl;

cout<<”2: With rectangular Window”<<endl;

cin>>window;

//Depending upon window option, select windowing function.

//For rectangular and no window option, w(n) = 1

if(window == 1)

{

Windowing();

}

Display();

FreqResponse();

}

Appendix B.

The code used for Part 4.

main.cpp

//Author: Sameer Kumar

//Date: 22/11/2006

#include “filter.h”

int main(int argc, char* argv[])

{

Filter fp;

char inFile[20],coeffFile[20];

//Take the coefficient file as argument.

cout<<”Please enter the coefficient file”<<endl;

cin>>coeffFile;

//Take the input wave file as argument.

cout<<”Please enter the input wave file”<<endl;

cin>>inFile;

try

{

//Do filtering

fp.Filtering(coeffFile,inFile);

}

catch(Exception e)

{

cout<<e.GetMessage()<<endl;

}

return 0;

}

filter.cpp

//Author: Sameer Kumar

//Date: 22/11/2006

#include “filter.h”

//Check wave header

void WavHeader::ConfirmHeader()

{

//Compares rID with “RIFF”

if(!((rID[0]==’R')||(rID[1]==’I')||(rID[2]==’F')||(rID[3]==’F')))

{

throw Exception(“Wrong RIFF Format”);

}

//Compares wID with “WAVE”

if(!((wID[0]==’W')||(wID[1]==’A')||(wID[2]==’V')||(wID[3]==’E')))

{

throw(“Wrong WAVE Format”);

}

//Compares fID with “fmt”

if(!((fId[0]==’f')||(fId[1]==’m')||(fId[2]==’t')))

{

throw(“Wrong fmt format”);

}

//Checks formatTag

if(wFormatTag!=1)

{

throw(“Wrong Wave Format tag”);

}

//Checks bits per sample with 16 & 8

if( (nBitsPerSample != 16) && (nBitsPerSample != 8) )

{

throw(“Wrong Bits per sample”);

}

}

//Checks whether chunk is data chunk or not

int ChunkHeader::IsDataChunk()

{

//Checks dID with “data”

if((dId[0]==’d') && (dId[1]==’a') && (dId[2]==’t')&& (dId[3]==’a'))

{

return 1;

}

return 0;

}

//Reads coefficients from file.

void Filter::ReadCoeff(char* fileName)

{

ifstream myfile (fileName);

if (myfile.is_open())

{

//Read length of coeffcients

myfile>>m_coeffLen;

//Allocate memory for coeffcients

m_coeff = new double[m_coeffLen];

//Reads all coefficients

for(int i=0;((i<m_coeffLen) && (!myfile.eof()));i++)

{

myfile>> m_coeff[i];

}

myfile.close();

}

else

{

throw(“Can not open coefficient file”);

}

}

//Read Input speech samples

void Filter::ReadSpeechInput(char *fileName)

{

ifstream::pos_type size;

char* memblock;

int index=0;

ifstream file (fileName, ios::in|ios::binary|ios::ate);

WavHeader *hdr = new WavHeader;

ChunkHeader *hdr1 = new ChunkHeader;

int chunkhdrSize = sizeof(ChunkHeader);

ofstream inFile;

inFile.open(“input.txt”);

if (file.is_open())

{

//Get the size of wav file

size = file.tellg();

//Allocate memory for memblock

memblock = new char [size];

file.seekg (0, ios::beg);

//reads all data from file

file.read (memblock, size);

file.close();

}

else

{

throw(“Unable to open file”);

}

//Read wave header

memcpy(hdr,memblock,sizeof(WavHeader));

//Check wave header

hdr->ConfirmHeader();

index = sizeof(WavHeader);

memblock += index;

// read chunks until a ‘data’ chunk is found

int data_chunk = 1;

while(index<(int)size)

{

if(data_chunk > 10)

{

throw(“Too many chunks”);

}

if(((int)size – index) > chunkhdrSize)

{

//read the chunk header

data_chunk++;

index +=chunkhdrSize;

memcpy(hdr1,memblock,chunkhdrSize);

memblock+=chunkhdrSize;

}

else

{

throw(“Wrong data”);

}

//Breaks the loop if , got data chunk

if(hdr1->IsDataChunk()==1)

{

break;

}

}

//Calculate the length of samples

m_inputLen = hdr1->dLen * 8/hdr->nBitsPerSample;

//Allocate memory for input samples

m_input = new double[m_inputLen];

//Reads data in m_input samples

if(hdr->nBitsPerSample == 16)

{

short *temp = (short*)memblock;

for(int i=0;i<m_inputLen;i++)

{

m_input[i] = (double)temp[i];

//Each 64th sample of sound is added to file.

if((i%64)== 0)

{

inFile<<m_input[i]<<endl;

}

}

}

else

{

unsigned char* temp = (unsigned char*) memblock;

for(int i=0;i<m_inputLen;i++)

{

m_input[i] = (double)temp[i];

//Each 64th sample of sound is added to file.

if((i%64)== 0)

{

inFile<<m_input[i]<<endl;

}

}

}

inFile.close();

}

//Convolution of two arrays

void Filter::convol()

{

//Calculate the length of output samples.

int outLen = m_inputLen + m_coeffLen -1;

m_output = new double[outLen];

ofstream outFile;

outFile.open(“output.txt”);

for(int i=0;i<outLen;i++)

{

m_output[i] = 0;

for(int j=0;j<m_coeffLen;j++)

{

if(((i-j)>=0) && ((i-j)<m_inputLen))

{

m_output[i]+=(m_input[i-j]*m_coeff[j]);

}

}

//Each 64th sample of sound is added to file.

if((i%64)== 0)

{

outFile<<m_output[i]<<endl;

}

}

outFile.close();

}

//Filter the input samples

void Filter::Filtering(char* coeffFile,char*wavFile)

{

//Read coefficients

ReadCoeff(coeffFile);

//Read input speech sample

ReadSpeechInput(wavFile);

//Convolution of two arrays

convol();

}

VN:F [1.8.8_1072]
Rating: 0.0/10 (0 votes cast)
VN:F [1.8.8_1072]
Rating: -1 (from 1 vote)

Related posts:

  1. C++ Compression / Decompression Application
  2. Dundonia – Adventure Platform Game
  3. Direct X Winter Scene
  4. Space Out 3D – Playstation 2
  5. Linux Systems Administration And Network Security

Leave a Reply

(required)

(required)