Академический Документы
Профессиональный Документы
Культура Документы
Assignment 5
Matthew Pierce
V00126204
Part 1
Convolve two sequences (vectors) of 32 numbers in several ways as described below,
both in time and frequency domain, and check to see if both give the same result. Repeat
by convolving two sound files 3-5 seconds long each (frequency domain only, no need to
compare with time domain). For the first sound file use the flute signal, for the second
sound file, use a drum signal.
Explain which method(s) is/are correct, and what is wrong with the other methods.
Provide the Matlab code, numerical results for short vectors, and copies of the input and
output wav files in each case.
The following Matlab program computes the circular convolution of two signals (x and
h) in the time domain (the software is also available on the website):
for n=1:N:length(x)
if(n+N>length(x))
% Account for the last segment
x_i = x(n:length(x)-1);
else
% Partition the signal into size N
x_i = x(n:n+N-1);
end
% Overlap add the first half of the output (after first pass)
if(n>1)
y(n:n+len/2-1) = y(n:n+len/2-1) + y_temp(1:len/2);
elseif(n==1)
y(n:n+len-1) = y_temp;
continue;
end
end
end
Another, similar program, used to compute the circular convolution of two signals in the
frequency domain (using FFT filtering) is given below (again, also available on the
website):
for n=1:N:length(x)
if(n+N>length(x))
% If the segment is shorter than h, only take the n point fft
H = fft(h, length(x)-n);
x_i = x(n:length(x)-1);
else
% Partition the signal into size N
x_i = x(n:n+N-1);
end
% Find the inverse fft to get the convolution for this segment
y_temp = ifft(Y_i);
if(mod(length(y_temp), 2)>0)
y_temp(length(y_temp)+1) = 0;
end
len = length(y_temp);
% Overlap add the first half of the output (after first pass)
if(n>1)
y(n:n+len/2-1) = y(n:n+len/2-1) + y_temp(1:len/2);
elseif(n==1)
y(n:n+len-1) = y_temp;
continue;
end
end
end
Process:
First, I tested the two programs using two numerical vectors of length 32 with the
following values:
x = linspace(0, 1, 32);
h = linspace(1, 0, 32);
Using the plots produced by each program, we can see that the results are the same:
Following this, I read two audio files into the x and h vectors (both original audio files
are available on the website):
x = wavread(flute2.wav);
h = wavread(short_beat.wav);
Using just the frequency domain convolution program, I convolved the two signals
together to produce a signal that could be written to an output audio file using the
following commands:
y = cyc_convolve_freq(x, h);
wavwrite(y, 44100, 16, cyc_conv_freq.wav);
for n=1:N:length(x)
if(n+N>length(x))
% If the segment is shorter than h find the proper length
x_i = [x(n:length(x)-1), zeros(1, (n+N)-length(x)), zeros(1, N)];
else
% Partition the signal into size N and zero pad
x_i = [x(n:n+N-1), zeros(1, N)];
end
% Overlap add the first half of the output (after first pass)
if(n>1)
y(n:n+N-1) = y(n:n+N-1) + y_temp(1:N);
elseif(n==1)
y(n:n+2*N-1) = y_temp(1:length(x)*2);
continue;
end
end
plot(y);
title('Acyclic Convolution: Time Domain'), xlabel('Time'), ylabel('Convolved Signals');
end
Another, similar program, used to compute the acyclic convolution of two signals in the
frequency domain (using FFT filtering) is given below (again, also available on the
website):
for n=1:N:length(x)
if(n+N>length(x))
% If the segment is shorter than h find the proper length
x_i = [x(n:length(x)-1), zeros(1, (n+N)-length(x)), zeros(1, N)];
else
% Partition the signal into size N and zero pad
x_i = [x(n:n+N-1), zeros(1, N)];
end
% Partition the signal into size N, zero pad, and take its fft
X_i = fft(x_i);
% Find the inverse fft to get the convolution for this segment
y_temp = ifft(Y_i);
% Overlap add the first half of the output (after first pass)
if(n>1)
y(n:n+N-1) = y(n:n+N-1) + y_temp(1:N);
elseif(n==1)
y(n:n+N*2-1) = y_temp;
continue;
end
end
plot(y);
title('Acyclic Convolution: Frequency Domain'), xlabel('Time'), ylabel('Convolved
Signals');
end
Process:
First, I tested the two programs using two numerical vectors of length 32 with the
following values:
x = linspace(0, 1, 32);
h = linspace(1, 0, 32);
Using the plots produced by each program, we can see that the results are the same:
Following this, I read two audio files into the x and h vectors (both original audio files
are available on the website):
x = wavread(flute2.wav);
h = wavread(short_beat.wav);
Using just the frequency domain convolution program, I convolved the two signals
together to produce a signal that could be written to an output audio file using the
following commands:
y = acyc_convolve_freq(x, h);
wavwrite(y, 44100, 16, acyc_conv_freq.wav);
The following Matlab program computes the circular convolution of two signals (x and
h) using windowed overlapping segments, raised cosine windows, cyclic shift, and
overlap-add (the software is also available on the website):
for n=1:N:length(x)
if(n+N>=length(x))
% Account for shorter segment (last one)
x_i = x(n:length(x));
h_i = h(n:length(x));
H_i = fft(h_i);
rcos_win = 1/2*(1-cos(2*pi*(1:length(x)-n+1)/(length(x)-n+1)));
else
% Partition the signals into size N
x_i = x(n:n+N-1);
h_i = h(n:n+N-1);
% Take the fft of the filter to get time-freq coefficients
H_i = fft(h_i);
end
% Overlap add the first half of the output (after first pass)
if(n>1)
y(n:n+len/2-1) = y(n:n+len/2-1) + y_rcos(1:len/2);
elseif(n==1)
y(n:n+len-1) = y_rcos;
continue;
end
end
end
Process:
First, I tested the program using two numerical vectors of length 32 with the following
values:
x = rand(1, 32);
h = linspace(0, 1, 32);
and a window size (N value) of 8. Using the plot produced by the program, we can see
the results:
Cyclic convolution using raised cosine windowing
Following this, I read two audio files into the x and h vectors (both original audio files
are available on the website):
x = wavread(flute2.wav);
h = wavread(short_beat.wav);
Using the convolution program with a window size of 2048, I convolved the two signals
together to produce a signal that could be written to an output audio file using the
following commands:
y = cyc_rcos_window_conv(x, h, 2048);
wavwrite(y, 44100, 16, cyc_rcos_win_conv.wav);
% Acyclic convolution in the frequency domain using FFT filtering and rectangular
windowing of size N
function y = acyc_win_conv(x, h, N)
for n=1:N:length(x)
if(n+N>length(x))
% If the segment is shorter than N find the proper length
x_i = [x(n:length(x)-1), zeros(1, (n+N)-length(x)), zeros(1, N)];
else
% Partition the signal into size N and zero pad
x_i = [x(n:n+N-1), zeros(1, N)];
end
% Find the inverse fft to get the convolution for this segment
y_temp = ifft(Y_i);
% Overlap add the first half of the output (after first pass)
if(n>1)
y(n:n+N-1) = y(n:n+N-1) + y_temp(1:N);
elseif(n==1)
y(n:n+N*2-1) = y_temp;
continue;
end
end
end
Process:
First, I tested the program using two numerical vectors of length 32 with the following
values:
x = rand(1, 32);
h = linspace(0, 1, 32);
and a window size (N value) of 8. Using the plot produced by the program, we can see
the results:
Acyclic convolution using rectangular windows
Following this, I read two audio files into the x and h vectors (both original audio files
are available on the website):
x = wavread(flute2.wav);
h = wavread(short_beat.wav);
Using the convolution program with a window size of 2048, I convolved the two signals
together to produce a signal that could be written to an output audio file using the
following commands:
y = acyc_win_conv(x, h, 2048);
wavwrite(y, 44100, 16, acyc_win_conv.wav);
Discussion:
Most of these methods (with the exception of the time domain methods) have a minimal
runtime. The most refined method, which can be heard in its output track, is the raised
cosine windowing method (part c). The other methods give a primitive, noisy sound and
the time saved is not worth the loss of quality.
Part 2
Take the FFT of a cosine wave, which has an integer number of samples per cycle (e.g 8)
and plot the result (both amplitude and phase). For example with 8 KHz sampling rate,
use 1 KHz cosine wave.
The following Matlab program was used to derive all the following cosine waves and
FFTs (and their respective plots). The fc (center frequency) and fft_size parameters are
adjusted accordingly for each question (this software is also available on the website):
% Create a cosine wave with center frequency fc and take its fft
% The win_flag sets whether or not to do cosine windowing
function Y = my_fft(fc, fft_size, win_flag)
for n=1:fft_size:length(wave)
if(n+fft_size>=length(wave))
% Account for shorter segment (last one)
wave_i = wave(n:length(wave));
rcos_win = 1/2*(1-cos(2*pi*(1:length(wave)-n+1)/(length(wave)-n+1)));
else
% Partition the signal into size N
wave_i = wave(n:n+fft_size-1);
end
% Overlap add the first half of the output (after first pass)
if(n>1)
Y(n:n+len/2-1) = Y(n:n+len/2-1) + Y_temp(1:len/2);
elseif(n==1)
Y(n:n+len-1) = Y_temp;
continue;
end
end
The first cosine and its FFT are given by the following parameters:
The second cosine and its FFT are given by the following parameters:
fc = 1000Hz
FFT size = 256
The third cosine and its FFT are given by the following parameters:
fc = 976Hz
FFT size = 256
The fourth cosine and its FFT are given by the following parameters:
fc = 976Hz
FFT size = 256
Cosine window size = 256
(For this question, the above code was simply modified so that the cos wave became a sin
wave)
The fifth wave and its FFT are given by the following parameters:
fc = 976Hz
FFT size = 256
Cosine window size = 256
The first three sets of plots are all similar, however the initial two sets are less accurate
due to poorer resolution. The third set of plots is ideal. The fourth and fifth sets of plots
represent a more accurate fft magnitude spectrum (were a greater resolution required),
however, due to the cosine windowing, phase-smearing has occurred, which is obvious in
the third plot of each set.