0% found this document useful (0 votes)
3 views11 pages

ECE251s Signals Project

The document details an audio filter project using MATLAB, where a 10th-order Butterworth low-pass filter is applied to an audio file to enhance speech clarity by removing high-frequency noise. The project includes contributions from multiple team members, a step-by-step code procedure, and analysis of time and frequency domain energy to confirm Parseval's theorem. The final output is a filtered audio file along with visual plots comparing original and filtered signals in both time and frequency domains.

Uploaded by

eladawy205
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views11 pages

ECE251s Signals Project

The document details an audio filter project using MATLAB, where a 10th-order Butterworth low-pass filter is applied to an audio file to enhance speech clarity by removing high-frequency noise. The project includes contributions from multiple team members, a step-by-step code procedure, and analysis of time and frequency domain energy to confirm Parseval's theorem. The final output is a filtered audio file along with visual plots comparing original and filtered signals in both time and frequency domains.

Uploaded by

eladawy205
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

Signals & Systems Fundamentals

ECE251s, Spring 2025

Audio Filter Project


PROJECT’S REPORT

PREPARED BY:
• Omar Samir Salem Mohamed: 2300720.
• Yousef Osama Elsayed Mohamed: 2300647.
• Ziad Mohamed Sobhy Ali: 2300089.
• Mostafa Ramadan Mohamed: 2300486.
• Ali Amir Abouzaid Abdelhamid: 2300157.
• Youssef Ahmed Hassan Fakhry 2300551.
• Mohamed Hisham Saad Elsayed 2301257.
• Youssef Mohamed Ahmed Eladawy 2300578.
• Youssef Mohamed Ali Abubakr 2300652.
• Zeyad Saber Hussein Mohamed 2300247.

PREPARED FOR:
Dr. George Albert Adib Abdel Sayed

Dr. Ahmed Amr Eweis Elsayed


SUBMISSION DATE: 22/5/2025
CONTRIBUTION TABLE

Names Contribution
Ziad Mohamed Sobhy Ali Preparing audio file (.wav) and
Mostafa Ramdan Mohamed calculating time-domain energy
Ali Amir Abouzaid Abdelhamid Performing Fast-Fourier-Tranform
Youssef Mohamed Ali Abubakr ,calculating Frequency-domain
energy
Yousef Osama Elsayed Mohamed Designing and applying the 10th-
Zeyad Saber Hussein Mohamed order Butterworth filter (low-pass)

Youssef Mohamed Ahmed Eladawy Ploting all the original and


Youssef Ahmed Hassan Fakhry filtered waveforms

Omar Samir Salem Mohamed Saving the output audio and writing
Mohamed Hisham Saad Elsayed the projects documentation

CONTENTS:
1.Project Overview
2.Code Review
3.Waveforms (plots)
4.Full Code (copyable)
1.PROJECT OVERVIEW
This project uses MATLAB to apply a 10th-order Butterworth low-pass
filter to an audio file in the frequency domain. We then convert the filtered
signal back to the time domain, plot every waveform (original and
filtered), and save the result as a new audio file.

We picked a 4 kHz cutoff because our recording is each of us saying our


names, and nearly all the information needed to understand speech is
below 5 kHz. Filtering at 4 kHz keeps our names sounding clear while
cutting out high-frequency noise and hiss.

Code Procedure:
1. Read & plot the raw audio

2. Compute time-domain energy

3. FFT + FFT-shift to convert the signal into the frequency domain

4. Compute Frequency-domain energy

5. Compare Time & Freq energy to confirm Parseval’s theorem

6. Design Butterworth (Low pass filter) with cutoff frequency = 4KHz

7. Apply it to the signal in the frequency domain

8. IFFT-shift and IFFT to get the signal back into the time domain

9. Plot time domain and frequency domain signal before and after
filtering

10. Save filtered audio


2.CODE REVIEW
1. Reading Audio:
%% 1. Setup and Read Audio
inputFilename = 'input.wav';
outputFilename = 'output.wav';
[timeSignal, sampleRate] = audioread(inputFilename);
signalLength = length(timeSignal);
timeAxis = (0:signalLength-1) / sampleRate;

-audioread(): Reads the wav audio and puts it into a a vector called
timeSignal of size (N*1) and stores the sampling rate for future
calculations

-We also store the length of the signal vector (total number of samples N)

-We create a timeAxis vector so we can plot the time on the x axis

2. Time-Domain Energy:
energyTimeDomain = sum(abs(timeSignal).^2);

Computes the total signal energy in time domain through the relation:
𝑁−1

𝐸𝑡 = ∑ |𝑥[𝑛]|2
𝑛=0
3. Frequency-Domain Analysis:
freqSignal = fft(timeSignal);
freqSignalShifted = fftshift(freqSignal);
freqAxis = (-floor(signalLength/2):ceil(signalLength/2)-1) * (sampleRate /
signalLength);
energyFreqDomain = (1/signalLength) * sum(abs(freqSignal).^2);

-fft(timeSignal): Converts the time-domain samples into their complex


frequency‐domain bins

-fftshift(freqSignal): Reorders the FFT output so that negative frequencies


come first, then the positive

-freqAxis :Stores frequency vector from –Fs/2 up to +Fs/2

energyFreqDomain: We calculate the Frequency domain energy with the


relation:
𝑁−1
1
𝐸𝑓 = ∑ |𝑋[𝑘]|2
𝑁
𝑘=0

4. Checking Parseval’s theorem:


energyDiff = energyTimeDomain - energyFreqDomain;

Parseval’s theorem guarantees that the total energy calculated in the time
domain is exactly the same as the total energy calculated in the frequency
domain
𝑁−1 𝑁−1
1
∑ |𝑥[𝑛]|2 = ∑ |𝑋[𝑘]|2
𝑁
𝑛=0 𝑘=0

So ΔE must near Zero


5. Design Butterworth Low-Pass Filter:
filterOrder = 10;
cutoffFrequency = 4000; % Hz

% Create filter in the centered frequency domain


H = 1 ./ sqrt(1 + (abs(freqAxis)/cutoffFrequency).^(2*filterOrder));
H = H(:); %Convert to N×1 column vector (to match the form of signal vector)

-filterOrder & cutoffFrequency: Defines the Butterworth order and its


cutoff (4 kHz).

-Calculate the filter’s frequency response for each freq bin through the
equation:
1
𝐻(𝑓) =
|𝑓| 2𝑁
√1 + ( )
𝑓𝑐

6. Apply the Butterworth Filter:


filteredFreqSignalShifted = freqSignalShifted .* H;
filteredFreqSignal = ifftshift(filteredFreqSignalShifted);
timeDomainSignalComplex = ifft(filteredFreqSignal);
filteredTimeSignal = real(timeDomainSignalComplex);

-We apply the filter in the frequency domain by multiplying each bin by its
frequency response or gain in the H vector

-ifftshift: Re‐orders the bins back into the FFT’s natural ordering (0 to Fs)
so we can use ifft

- ifft: Moves signal back into time domain

- Because MATLAB uses floating-point math, the steps aren’t perfectly


exact. Tiny rounding errors break symmetry that should keep a real signal
real, so we end up with small imaginary noise which real() throws away

6.Save Filtered Audio:


%% Save Filtered Audio
audiowrite(outputFilename, filteredTimeSignal, sampleRate);
disp(['Filtered audio saved to ', outputFilename]);
3.WAVEFORMS (PLOTS)
1.Original Audio Signal and Energy:

2.Filtered Audio Signal:


3.Time Domain Comparison:

4.Frequency Domain Comparison:


4.FULL CODE (COPYABLE)
%% 1. Setup and Read Audio
inputFilename = 'input.wav';
outputFilename = 'output.wav';
[timeSignal, sampleRate] = audioread(inputFilename);
signalLength = length(timeSignal);
timeAxis = (0:signalLength-1) / sampleRate;

%% 2. Time-Domain Energy
energyTimeDomain = sum(abs(timeSignal).^2);

%% 3. Frequency-Domain Analysis
freqSignal = fft(timeSignal);
freqSignalShifted = fftshift(freqSignal);
freqAxis = (-floor(signalLength/2):ceil(signalLength/2)-1) * (sampleRate /
signalLength);
energyFreqDomain = (1/signalLength) * sum(abs(freqSignal).^2);

%% 4. Compute Energy Difference


energyDiff = energyTimeDomain - energyFreqDomain;
disp('Energy Calculations:');
disp(['Time-domain Energy: ', num2str(energyTimeDomain)]);
disp(['Frequency-domain Energy: ', num2str(energyFreqDomain)]);
disp(['Energy Difference: ', num2str(energyDiff)]);
disp('-----------------------------------');

%% 5. Butterworth Low-Pass Filter Design


filterOrder = 10;
cutoffFrequency = 4000;
H = 1 ./ sqrt(1 + (abs(freqAxis)/cutoffFrequency).^(2*filterOrder));
H = H(:);

%% 6. Apply Filter & Recover Time Signal


filteredFreqSignalShifted = freqSignalShifted .* H;
filteredFreqSignal = ifftshift(filteredFreqSignalShifted);
timeDomainSignalComplex = ifft(filteredFreqSignal);
filteredTimeSignal = real(timeDomainSignalComplex);
%% 7. Plot
figure('Name','Audio Filtering Overview','NumberTitle','off');

halfIdx = 1 : floor(signalLength/2)+1;
f_pos_khz = (halfIdx-1) * (sampleRate/signalLength) / 1000;
origMag_pos = abs(freqSignal(halfIdx)) / signalLength;
filtMag_pos = abs(filteredFreqSignal(halfIdx)) / signalLength;

% (1) Original Time Domain


subplot(2,2,1);
plot(timeAxis, timeSignal);
title('Original Signal (Time)');
xlabel('Time (s)');
ylabel('Amplitude');
grid on;

% (2) Original Spectrum


subplot(2,2,2);
plot(f_pos_khz, origMag_pos);
xlim([0 sampleRate/2/1000]);
title('Original Spectrum');
xlabel('Frequency (kHz)');
ylabel('Magnitude');
grid on;

% (3) Filtered Signal


subplot(2,2,3);
plot(timeAxis, filteredTimeSignal);
title('Filtered Signal (Time)');
xlabel('Time (s)');
ylabel('Amplitude');
grid on;

% (4) Filtered Spectrum


subplot(2,2,4);
plot(f_pos_khz, filtMag_pos);
xlim([0 sampleRate/2/1000]);
title('Filtered Spectrum');
xlabel('Frequency (kHz)');
ylabel('Magnitude');
grid on;
titleStr = sprintf([ ...
'Butterworth Low-Pass Filter – Order: %d, Cutoff: %d Hz\n' ...
'Time-domain E = %.2f | Freq-domain E = %.2f | ΔE = %.2f' ...
], ...
filterOrder, cutoffFrequency, ...
energyTimeDomain, energyFreqDomain, energyDiff);

sgtitle(titleStr,'FontSize',12,'FontWeight','bold');
%% 8. Save Filtered Audio
audiowrite(outputFilename, filteredTimeSignal, sampleRate);
disp(['Filtered audio saved to ', outputFilename]);

%% 9. Original vs. Filtered in Time Domain


figure('Name','Time Domain Comparison','NumberTitle','off');
plot(timeAxis, timeSignal, 'b', 'LineWidth', 1); hold on;
plot(timeAxis, filteredTimeSignal, 'r', 'LineWidth', 1);
hold off;
xlabel('Time (s)');
ylabel('Amplitude');
title('Original vs. Filtered Signal (Time Domain)');
legend('Original','Filtered');
grid on;

%% 10. Original vs. Filtered in Frequency Domain


figure('Name','Frequency Domain Comparison','NumberTitle','off');
plot(f_pos_khz, origMag_pos, 'b', 'LineWidth', 1); hold on;
plot(f_pos_khz, filtMag_pos, 'r', 'LineWidth', 1);
hold off;
xlabel('Frequency (kHz)');
ylabel('Magnitude');
xlim([0 sampleRate/2/1000]);
title('Original vs. Filtered Spectrum (Frequency Domain)');
legend('Original','Filtered');
grid on;

You might also like