You are on page 1of 64

ELEC 484 Audio Signal Processing

Assignment 5:
Time Frequency Processing:
Cyclic and Acyclic Convolution, Windowing, FFT

Prepared for:
Dr. Peter Driessen
ELEC 484
University of Victoria

Prepared by:
Tim I. Perry
V00213455
June, 2009

Tim Perry
V00213455

CONTENTS
1.

2.

CONVOLUTION ................................................................................................................................. 2
1.1.

Cyclic (periodic) Convolution ...................................................................................................... 2

1.2.

Acyclic (aperiodic) Convolution ................................................................................................. 10

1.3

Cyclic (periodic) Convolution using Overlap-Add ..................................................................... 15

1.4

Acyclic (aperiodic) Convolution with Rectangular Windowing................................................. 23

FAST FOURIER TRANSFORM ....................................................................................................... 29

REFERENCES ........................................................................................................................................... 38
APPENDIX A ............................................................................................................................................. 39

Tim Perry
V00213455

ELEC 484 ASSIGNMENT 5


1. CONVOLUTION
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.
a. Circular (cyclic, periodic) convolution in frequency domain (entire file length). Result will be same
length as input.
b. Acyclic (aperiodic) convolution in frequency domain using zero padding (entire file length) (result will
be twice the original file length)
c. Circular (cyclic, periodic) convolution on windowed overlapping segments, raised cosine windows,
cyclic shift, and overlap-add (DAFX figure 8.5 where the time-frequency processing is a multiplication
with the time/frequency coefficients of a second signal, keep the phases of only one of the signals). See
also figure 8.28. Use windows 8 samples long for numbers, 2048 samples long for audio file.
d. Acyclic (aperiodic) convolution in frequency domain using zero padding using rectangular windows
(DAFX figure 8.20) and overlap-add.
e.
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.

1.1. Cyclic (periodic) Convolution

Figure 1: Basic technique of circular convolution [2]

Figure 1 graphically illustrates the concept of circular convolution in the time domain.
Mathematically, the circular (cyclic, periodic) convolution of two functions h[n] and x[n] can be
expressed as:

Tim Perry
V00213455

(1)

1.1.1. Time Domain Cyclic Convolution


In order to perform the time domain cyclic convolution in Matlab for two vectors/signals with
length N, the operation will be expressed as:

(2)

Where (n-k)mod N performs an integer division of n-k by N, and returns the remainder.
The resulting signal will be of length N, as both original signals have the same length. Due to
modulo indexing, some of the convolution terms will wrap around with this technique and add
back onto earlier terms.

Figure 2: Time domain cyclic convolution of two vectors of length N=32

Tim Perry
V00213455

Figure 3: Cyclic convolution of two alternative vectors (different from Figure 1) of length N=32

The numerical results of the above vector convolutions are contained in Table 1 and Table 2,
where they are compared with the frequency domain methods for circular convolution. From the
above figures, it is clear that the convolution result requires more than N samples to be identical
to a linear convolution. It will be shown later that circular convolution should be avoided as it
leads to time domain aliasing.

Tim Perry
V00213455

1.1.2. Frequency Domain Cyclic Convolution


The identical result from above can be achieved hundreds of times faster by taking the FFT of
both signals, performing frequency-domain multiplication, and then taking the IFFT:
= {{ {

(3)

This is the most common way to compute a cyclic convolution. Frequency domain cyclic
convolution was performed using two methods:


Manually computing the DFT of x(n) and h(n), multiplying the results in the frequency
domain, and then manually computing the IDFT of the result (performed in Matlab).

Performing the identical operation using Matlabs built in FFT and IFFT routines.

Figure 4: Circular convolution versus fast convolution [1]

Table 1 and 2 demonstrate that the numerical results for the convolution of two equal length
vectors is identical using frequency domain cyclic convolution and time domain cyclic
convolution. However, the FFT/DFT and inverse FFT/DFT processes lead to time aliasing when
performing a cyclic convolution. This is because with circular convolution, the DFTs time
domain is viewed as N points, rather than a periodic signal, infinitely long, with period N. Since
the frequency domain interprets the time domain as being periodic, the frequency domain
convolution acts as if the time domain is circular, with sample 0 next to sample N-1 [3]. In order
to obtain a linear convolution, zero padding must be performed on both input signals (leading to
the technique of fast convolution, which will be covered later) [1].
In order to perform the circular convolution with two sound files of different length, zeros were
appended onto the end of the shorter sound file. The results are summarized below.

Tim Perry
V00213455

Table 1: Cyclic Convolution of Two Vectors of Length N = 32 (Figure 2 Data Set)


Time Domain Circular Convolution

Frequency Domain Equivalent

y = ifft(fft(h).*fft(x)

Manual DFTs

Matlab FFT function

h(n)

x(n)

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
24
28
29
30
31

0
15
15
15
15
10
10
10
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

0
0
0
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0

240
165
105
60
30
25
45
90
150
220
300
390
480
570
660
750
840
930
1020
1080
1110
1110
1080
1030
960
870
780
690
600
510
420
330

240
165
105
60
30
25
45
90
150
220
300
390
480
570
660
750
840
930
1020
1080
1110
1110
1080
1030
960
870
780
690
600
510
420
330

240
165
105
60
30
25
45
90
150
220
300
390
480
570
660
750
840
930
1020
1080
1110
1110
1080
1030
960
870
780
690
600
510
420
330

Tim Perry
V00213455

Table 2: Cyclic Convolution of Two Vectors of Length N = 32 (Figure 3 Data Set)


Time Domain Circular Convolution

Frequency Domain Equivalent

n
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
24
28
29
30
31

h(n)
0
15
15
10
10
10
5
5
5
5
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

x(n)
0
0
0
0
2
4
6
8
10
12
14
12
10
8
6
4
2
0
0
1
2
3
4
5
6
6
5
4
3
2
1
0

=
160
120
80
50
30
45
95
170
270
390
520
660
750
790
790
750
670
570
450
340
255
205
185
195
225
270
300
315
315
295
255
205

y = ifft(fft(h).*fft(x)

Manual DFTs

Matlab FFT function

=
160
120
80
50
30
45
95
170
270
390
520
660
750
790
790
750
670
570
450
340
255
205
185
195
225
270
300
315
315
295
255
205

=
160
120
80
50
30
45
95
170
270
390
520
660
750
790
790
750
670
570
450
340
255
205
185
195
225
270
300
315
315
295
255
205

Tim Perry
V00213455

Figure 5: Frequency domain cyclic convolution of "flute2.wav" (red) with Eidolon_DrumSeg1.wav (top).
Output File: A5_1a-CyclicConv1.wav.

Figure 6: Frequency domain cyclic convolution of "flute2.wav" (red) with TranSiberian_drums.wav (top)
Output File: A5_1a-CyclicConv2.wav.

Tim Perry
V00213455
The output wav files for the frequency domain cyclic convolutions have a timbre resembling the
flute (resembling a time stretched flute signal with the original pitch and formants largely
retained),Some of the amplitude mapping from the drum tracks can be heard; however, the
rhythmic effect of the drums in these examples are subtle. An element of the timbre from the
pitched anvil in the second drum track (Error! Reference source not found.) can be heard in the
file A5_1a-CyclicConv2.wav. The final output file is of length N (the length of the
corresponding drum track), and has non-zero signal values at all values of n.
Distortion can be heard in the output files, which are due to aliasing that has occurred. This is
because after the frequency domain multiplication, an N point IDFT was used to transform the
result back into the time domain. However, since DFTs are periodic, they have nonzero values
for n>= N and hence the product of 2 DFTs will be nonzero for n>=N..The resulting signal from
the convolution needs more than N time-domain values to be properly represented. Therefore, the
N point signal y(n) is a distorted version of the signal that would have arose from a correct linear
convolution.

Figure 7: Circular convolution (produces aliasing due to overlapping samples) [3]

Tim Perry
V00213455

1.2.Acyclic (aperiodic) Convolution

Figure 8: Acyclic convolution of two signals (schematic depiction). [4]

By implementing acyclic convolution using cyclic convolution with zero-padding, the FFT can be used to
perform a cyclic convolution when its length N is a power of 2 [4]. Using zero padding in the time
domain results in more samples and tighter spacing in the frequency domain (like a higher sampling rate
will achieve). The resulting number of nonzero output samples will be at most Nx + Nh -1 (Figure 8).
The motivation to embed and acyclic convolution into a zero-padded cyclic convolution (fast
convolution) is that a cyclic convolution is very efficient to compute. However, if insufficient zeros are
added with this method, the same problem as encountered with cyclic convolution will occur: some
convolution terms will wrap around and add back onto earlier terms, causing time domain aliasing.

1.2.1. Time Domain Acyclic Convolution

Figure 9: Acyclic convolution performed in time domain using zero padding (entire file length)

10

Tim Perry
V00213455
The time domain acyclic convolution of x(n) with h(n) can be mathematically reduced to:

(4)

where the result is zero for n< 0 and n > (Nx + Nh 1) -1.
This corresponds to at most Nx + Nh -1 samples.
For N = Nx = Nh, as displayed in Figure 9, the resulting time domain is 2N samples. This method
produces the correct linear convolution result, unlike cyclic convolution.

1.2.2. Frequency Domain Acyclic Convolution (Fast Convolution)


The identical result as above was obtained using frequency domain acyclic convolution implemented with
a zero padded cyclic convolution. This is high-speed/fast convolution. The procedure was as follows:





x(n) and h(n) were zero padded up to the length 2N


The 2N-point FFT was taken of both signals
Frequency domain multiplication was performed = , = 0, 1, , 2 1
The 2-N point IFFT of Y(k) was taken, yielding y(n), a 2N length signal with n = 0, 1,...2N-1

Figure 10: Time domain results of acyclic convolution performed in the frequency domain using a zero
padded cyclic convolution.

11

Tim Perry
V00213455

Table 3: Cyclic Convolution of Two Vectors of Length N = 32 (Figure 3 Data Set)


n
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
24
28
29
30
31
32
33
34
35
36
37
38
39
40 to
N=63

h(n)

x(n)

[zero padded]

[zero padded]

0
15.00
15.00
10.00
10.00
10.00
5.00
5.00
5.00
5.00
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

0
0
0
0
2.00
4.00
6.00
8.00
10.00
12.00
14.00
12.00
10.00
8.00
6.00
4.00
2.00
0
0
1.00
2.00
3.00
4.00
5.00
6.00
5.00
4.00
3.00
2.00
1.00
0
0
0
0
0
0
0
0
0
0
0

Time Domain Acyclic Conv.

Frequency Domain Acyclic Conv.

0
0
0
0
0
30.00
90.00
170.00
270.00
390.00
520.00
660.00
750.00
790.00
790.00
750.00
670.00
570.00
450.00
340.00
255.00
205.00
185.00
195.00
225.00
270.00
300.00
315.00
315.00
295.00
255.00
205.00
160.00
120.00
80.00
50.00
30.00
15.00
5.00
0
0

0
0
0
0
0
30.00
90.00
170.00
270.00
390.00
520.00
660.00
750.00
790.00
790.00
750.00
670.00
570.00
450.00
340.00
255.00
205.00
185.00
195.00
225.00
270.00
300.00
315.00
315.00
295.00
255.00
205.00
160.00
120.00
80.00
50.00
30.00
15.00
5.00
0
0

12

Tim Perry
V00213455

Figure 11: Frequency domain acyclic convolution of "flute2.wav" (red) with Eidolon_DrumSeg1.wav (top).
Output File: A5_1b-CyclicConv1.wav.

The results of fast convolution with the audio files provide the correct output signal, without
aliasing. The shorter audio file had zeros appended to its time domain representation such that it
was the same length as the drum file. Then, both files were doubled in length zero padding before
performing the frequency domain acyclic convolution as a zero-padded cyclic convolution (2Npoint FFT based convolution, or fast convolution, as described above). Figure 11and Figure 12
demonstrate that the resulting output file is twice the length of the longest input file.
The resulting output audio is longer than with the N-point cyclic convolution, and decays more
gracefully. The mapping to the rhythm is more precise, because there is no wrap around of
convolution terms (and hence no aliasing related distortions). This method produces the correct
result, and is much faster to compute than the corresponding time-domain acyclic convolution.

13

Tim Perry
V00213455

Figure 12: Frequency domain cyclic convolution of "flute2.wav" (red) with TranSiberian_drums.wav (top)
Output File: A5_1a-CyclicConv2.wav.

14

Tim Perry
V00213455

1.3 Cyclic (periodic) Convolution using Overlap-Add


Circular (cyclic, periodic) convolution on windowed overlapping segments, raised cosine windows, cyclic
shift, and overlap-add (DAFX figure 8.5 where the time-frequency processing is a multiplication with the
time/frequency coefficients of a second signal, keep the phases of only one of the signals). See also figure
8.28. Use windows 8 samples long for numbers, 2048 samples long for audio file.

The convolution of an N sample signal with an M sample filter kernel (a windowed sinc LPF, for
example) should result in an output signal that is N + M - 1 samples long (it will be expanded by M-1
points) [2]. Immediately, its apparent that cyclic convolution without zero padding will not achieve this
output signal length, and will instead have an output length of N. Since two signals will be convolved
together, one of the signals will be treated as the filter kernel, and will be windowed. For the cyclic
overlap-add implementation, raised cosine windowing with cyclic shift will be used.

Figure 13: Phase vocoder using FFT/IFFT for the short-time FT. With Time-Frequency processing, y(n) can
be constructed with a synthesis hop size Rs. [2]

15

Tim Perry
V00213455

Time domain

Frequency domain
50

0
-50
Magnitude (dB)

Amplitude

0.8

0.6

0.4

-100
-150
-200
-250

0.2
-300
0

-350
1

4
5
Samples

0.2
0.4
0.6
0.8
Normalized Frequency ( rad/sample)

Figure 14: Three potential raised cosine windows to use. The blue is a Hann window, the green is a
Hanning window (removes multiplications by zero), and the red is a periodic Hann window, designed for
overlap-adding of successive blocks. The periodic Hann window was used.

The potential raised cosine windows to use are outlined in Figure 14. In practice, however, the use of a
Hamming or Blackman window would probably be preferred. The three different raised cosine window
forms are:
%----Hann Window: "Hanning" removes multiplications by
w = .5*(1 - cos(2*pi*(0:M-1)'/M));
%periodic Hann
w1 = .5*(1 - cos(2*pi*(0:M-1)'/(M-1))); %Raised Cosine
w2 = .5*(1 - cos(2*pi*(1:M)'/(M+1)));
%Raised Cosine

zero
for overlap add
(Hann) window
(Hanning) window

Time Domain Acyclic Convolution


There were multiple ways to interpret this problem. To most strongly emphasize the effects of cyclic
convolution, I chose to do the following:

Each block of x(n) was cyclic convolved with each windowed kernel h(n), without zero
padding.
To facilitate overlap adding, a stepping size Ra = M/2 was used, where M = 8 was the
window size.

The results from the time domain cyclic convolution using windowed blocks and overlap add
produced disastrous, as expected. Aliasing related distortions are added for each successive block
convolution, and the resulting output signal (length N) looks nothing like the result of a linear
convolution. Moreover, the output signal is discontinuous at the beginning and end of each block,
because each convolution result from a set of convolved blocks was forced to fit into an M = 8
sample block (where a 16 sample block is required for a linear convolution of the two blocks).

16

Tim Perry
V00213455
Finally, the overlap add process enhanced the distortions and discontinuities when a bounce size of
M/2 = 4 samples was used. If the hop size is instead chosen to be Ra = M = 8, these extra distortions
are not introduced, but no overlap adding is actually taking place.

Figure 15: Cyclic convolution with windowing and overlap-add using a hop size Ra = M/2 =
4 and rectangular windowing.

Figure 16: Cyclic convolution with rectangular windowing and a hop size Ra = M= 8,
producing no overlap adding.

17

Tim Perry
V00213455

Figure 17: Cyclic convolution with raised cosine windowing and overlap-add using a hop size
Ra = M/2 = 4 and raised cosine windowing.

Figure 18: Cyclic convolution with raised cosine windowing, circular shift and overlap-add
using a hop size Ra = M/2 = 4.

18

Tim Perry
V00213455

The loop of the Matlab program written to perform this convolution is included below. The full
code can be found in the appendix.
%--------------------------------------------------------------------% Time Domain Cyclic Conv with raised cosine windowing, cyclic shift
%--------------------------------------------------------------------n = 0;
% initialize sample index
y1 = zeros(1,NsigOut); %allocate output (for cyclic, same length as inputs)

for m = 0:(Nframes-1)
% m is frame/block number
index = m*Ra+1:min(m*Ra+M,N);
% indices for the mth frame
hm = w*h(index);
% raised cosine windowed mth frame of h (kernal)
hm = circshift(hm,[0,M/2]);
% circular shift
xm = x(index);
% rectangular windowed mth frame of x
for k = n+1:n+M
% convolve mth frames
ym(k) = sum(xm(1:M).*hm(mod(k-1:-1:k-M, M)+1));
% mod(Nk,Nh) if Nh ~= 0,returns Nk - k.*Nh where k = floor(Nk./Nh).
n = k;
end
indexOut = m*Ra+1:(m*Ra + Nconv);
ym = circshift(ym, [0, M/2]);
% circular shift
y1(indexOut) = y1(indexOut) + ym(indexOut);
% overlap add output frames
end

This method was based on an FFT filtering approach, but done with cyclic convolution such that the
resulting output signal length is N. However, since the filter kernel was created by windowing a segment
of h, and x was also windowed, a full convolution (that in part, requires each nonzero value of each signal
to be multiplied together) was not actually performed in the time domain. To perform a full convolution
of the signals, only one signal should be windowed into blocks, or else each window of h should be
multiplied by each window of x. This will be achieved using frequency domain convolution.

Frequency Domain Cyclic Convolution with Overlap-Add


Cyclic convolution with overlap-add was again implemented, this time in the frequency domain using
cyclic FFT convolution. This time, the filter h(n) was not segmented; only x(n) was cut into frames,
windowed and cyclic shifted. Each segment was multiplied with H(k) in the frequency domain.
Only the phase of X(k) was kept and transferred to the output signal. Figure 19 shows the results. Aliasing
does occur, as expected from the algorithm; however, the signal is continuous during the length N, unlike
with the method used above. Other distortions that are introduced are likely due to windowing. Its
apparent that the overlap-add process did not perform an ideal re-construction.

19

Tim Perry
V00213455
The main loop of the algorithm that was for windowed FFT cyclic convolution written is shown below.
The rest of the code can be found in the appendix.
H = fft(h);
y = zeros(1,N);

% FR of filter kernal (no padding for cyclic)


% vector for output signal (same length as input)

%---apply cyclic FFT convolution with overlap add---for m = 0:(Nframes-1)


index = m*Ra+1:min(m*Ra+M,N); % mth frame indices
xm = w'.*x(index); % raised cosine windowed mth frame
xm = circshift(xm,[0,M/2]);
% circular shift
%----Frequency domain processing---------xmzp = [xm zeros(1,NFFT-length(xm))]; %zero pad the signal to length N
% FFT of padded mth frame
Xm = fft(xmzp);
%Ym = Xm .* H;
% freq domain multiplication = time domain conv
Ym = Xm .* real(H);
% keep phase of only Y
%----Synthesis (overlap-add)----------% ym = real(ifft(Ym));
% return results to time domain
ym = (ifft(Ym));
% return results to time domain
ym = circshift(ym, [0, M/2]);
% circular shift
indexOut(1:m*Ra) = (NFFT-m*Ra+1):NFFT
indexOut(m*Ra+1:NFFT)=1:NFFT-m*Ra
y(indexOut) = y(indexOut) + ym;
apply overlap adding
end

Figure 19: Cyclic convolution with raised cosine windowing, circular shift and overlap-add using a
hop size Ra = M/2 = 4.

20

Tim Perry
V00213455

Figure 20: Figure 19: Cyclic convolution with raised cosine windowing, circular shift and overlapadd using a hop size Ra = M= 8.

Time domain

Frequency domain
100

1
0
Magnitude (dB)

Amplitude

0.8

0.6

0.4

-200

-300

0.2

-100

-400
500

1000
Samples

1500

2000

0.2
0.4
0.6
0.8
Normalized Frequency ( rad/sample)

Figure 21: The periodic Hann window (raised cosine) of length M = 2048 that was used for the cyclic
convolution on audio files, with cyclic shift and overlap-add.

21

Tim Perry
V00213455
Cyclic FFT convolution with overlap add was also applied to the audio files. The flute track was taken as
the filter kernel h(n), and was padded to be the same length as the drum track x(n). The output signal is
the length of the original drum track, N = Nx. Clearly, the signal is requires more space for the
convolution, as it cuts in and cuts out. The effects aliasing from circular convolution terms wrapping
around can be heard. In fact, space for these aliasing terms had to be specified in the algorithm in order
for the convolution output to be indexed for overlap adding:
indexOut(1:m*Ra) = (NFFT-m*Ra+1):NFFT;
% indices for wrap around terms
indexOut(m*Ra+1:NFFT)=1:NFFT-m*Ra;
% indices for additional terms
y(indexOut) = y(indexOut) + ym; % apply overlap-adding

Figure 22: Cyclic convolution with raised cosine windowing, circular shift and overlap-add applied to audio
signal. The phase of the drum signal x[m] was kept and applied to the output. Output file is A5_1cCyclicWinOA.wav.

22

Tim Perry
V00213455

1.4 Acyclic (aperiodic) Convolution with Rectangular Windowing

The solution to the aliasing problems mentioned above is to pad each signal to be convolved with
sufficient zeros. The resulting output signal requires a sample space of N+M-1 in order to be represented
as a linear convolution [3]. For the vector convolutions, cyclic FFT convolution with rectangular
windows and overlap-add was originally implemented as follows:


One signal/vector was chosen to be the filter h(n), of length L = Nh =N. The filter was then zero
padded to length 2N. Next, the filters FFT was taken, yielding H(k).

The second signal/vector x(n) was segmented into segments , of length M, where M is the
window size. Each of these frames was zero padded to a length 2N.

The FFT of each zero padded frame was taken, yielding = 0, 1, 2, 2 1.

Frequency domain multiplication was applied:


=

The inverse FFT was taken of each .

The convolution results were overlap added, yielding y(n).

The results from this FFT convolution can be seen in Figure 23 and Figure 24. The resulting FFT size was
NFFT = 2N = 64, and the output signal length was NFFT + N. However, this method is typically intended
for convolution of a signal with a filter that is shorter than . The typical FFT filtering
approach would be to create window sizes M that are the same size as , assuming that h(n) is shorter
than . Since in this case (using vectors of length N=32) = = , both the un-segmented signal
and filter are the same length; while the window size is M = 8 and the hop size is Ra = 8.
A more efficient implementation that makes better use of this small window size was used next. Instead
of NFFT = 2N, the FFT length was chosen to be the filter length N plus the block/frame length, M:
NFFT = N + M. This implementation produced the identical convolution result, but with a shorter FFT
size (NFFT = 40 for the vector implementation). The results from this implementation are shown in
Figure 27.
Frequency domain acyclic convolutions with overlap-add was also applied to the audio files (Figure 28),
convolving flute.wav with TranSiberian_Drums.wav. The second implementation described above
was used. Here, however, the two input files are different lengths. The file A5_1d-AcyclicWinOA-1.wav
is the result of FFT convolving the segmented drum file with the flute file, where the flute was treated as
the filter h(n). With this result, the output file is the length of the drum file Nx = N plus the window
length of M = 2048 samples. The file A5_1d-AcyclicWinOA-2.wav instead uses the drum file as the
23

Tim Perry
V00213455
filter, and as a result the output file is much shorter (NsigOut = N + L, where N is the length of the flute
file). Next, A5_1d-AcyclicWinOA-3.wav applies zero padding to the shorter filter (the flute file) to
make it the same length as the drum signal before applying the FFT convolution with overlap add.
All of the above mentioned audio files are truncated. The correct FFT convolution can be found in
A5_1d-AcyclicWinOA.wav. This convolution used an output signal length of:
N + L - 1 = Nx + Nh +1

Figure 23: FFT convolution using Nfft = 2N = 64

24

Tim Perry
V00213455

Figure 24: mth blocks for FFT convolution with Nfft = 2N = 64

Figure 25: Alternative FFT convolution using Nfft = N+M = 40. The output of the FFT convolution can be
stored in N + M = 40 samples.

25

Tim Perry
V00213455

Figure 26: mth blocks for FFT convolution with Nfft = N + M = 40.

Figure 27: The output of the FFT convolution can be stored in N + M = 40 samples.

26

Tim Perry
V00213455
A revised acyclic FFT convolution with rectangular windows and overlap-add was implemented for the
audio files (Figure 27) as follows:


One signal/vector was chosen to be the filter h(n), of length N. The filter was then zero padded to
length N +L 1. Next, the filters FFT was taken, yielding H(k).

The second signal/vector x(n) was segmented into segments , of length M, where M is the
window size. Each of these frames was zero padded to a length N + M.

The FFT of each zero padded frame was taken, yielding = 0, 1, 2, + 1.

Frequency domain multiplication was applied:


=

The IFFT was taken of each .

The convolution results were overlap added, yielding y(n).

This method of FFT convolution yields the same result as a linear convolution, but is much more
computationally efficient for long signals (and hence faster). For filter kernel lengths over about 50 to
80 samples, depending on the hardware, FFT convolution is faster than standard convolution. In
practice, precision of a convolution result (assuming a correct convolution without aliasing) is
determined by the speed of the calculation. This is due to round-off error in the computation, which is
proportional to computation time [3].

27

Tim Perry
V00213455

Figure 28: Frequency domain acyclic convolutions with overlap-add applied to the audio files; shown is h(n)
as the flute track, and x(n) the drum track. A5_1d-AcyclicWinOA'.wav is the output file.

28

Tim Perry
V00213455

2. FAST FOURIER TRANSFORM


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.
- Repeat for a different FFT block size, e.g. 256.
- Repeat for a cosine wave with a non-integer number of samples per
cycle.
- Repeat again after windowing the cosine wave with a raised cosine
window (256 sample window).
- Repeat again after shifting the cosine wave by 90 degrees (e.g. use
sine instead).
-Explain all results

FFT of cosine wave with integer number of samples per cycle


FFT algorithms have a computational complexity of O(n log n) versus O(n^2) for the direct
application of a DFT. The maximum efficiency is achieved if n is a power of 2.
The rectangular windowed FFT of the cosine wave is plotted below for NFFT = 8 (Figure 29) and
NFFT = 256 (Figure 30). The resulting magnitude and phase is plotted for the positive region of
the Nyquist band. For both instances, the magnitude spectrum consists of a single spike at f1 =
1kHz, the frequency of the sine wave. Since the time function x = cos(2*pi*f1*nT) is
real, the even portions FFT is even and real, and the odd portion of the FFT is odd and imaginary.
This symmetry and asymmetry respectively would be visible if the negative Nyquist band was
also plotted.

As expected, the magnitude spectrum has only one spike in the positive Nyqiuist band, at
f1= 1000Hz. While the zero points at other frequencies should theoretically be zero, they
are very close to zero due to round-off errors during and calculation or truncation.

The phase spectrum, however, is misleading. The phase is zero at f1 = 1000Hz, as


expected. However, the phase appears to be random everywhere else in the spectrum
(particularly with the FFT size of 256, which has a higher frequency resolution). The
phase at all values other than f1 should be ignored, as the points were calculated from
round-off errors at frequencies where the spectrum should be zero.

29

Tim Perry
V00213455

Figure 29: FFT of cosine wave with 8 samples per cycle and rectangular windowing.

Figure 30: FFT of cosine wave with 256 samples per cycle.

30

Tim Perry
V00213455

FFT of cosine wave with non-integer number of samples per cycle


The next 2 plots show the FFT on the same cosine wave as above, but using non-integer numbers
of samples per cycle. The respective FFT sizes are:
NFFT_1 = 10.4
NFFT_2 = 293.7

Due to the non-integer sampling over the period, the fundamental frequency is no longer
represented in the magnitude or phase spectrum. This is the result of truncation, leading to
spectral leakage. However, viewing the interpolation of the phase spectrum (red-line on the phase
plots), the interpolation phase line does cross 0 at the fundamental frequency. There is, however,
no spectral data at the fundamental, f1 = 1000Hz.
While the spectrum no longer represents that of the sin wave due to spectral leakage, the phase
plots are now more relevant, as there are non-zero values defined at multiple frequencies about
f1. At f1, there is a zero crossing of the phase; the phase was increasing along with the amplitude
up to close to f1, where there is a sudden phase-shift.

Figure 31: FFT of cosine wave with NFFT = 10.4 and rectangular windowing.

31

Tim Perry
V00213455

Figure 32: FFT of cosine wave with NFFT = 293.7 and rectangular windowing.

FFT of cosine wave with raised cosine window and NFFT = 256
The figures below show the results of windowing the cosine wave with window size M = NFFT = 256.
Two forms of the raised cosine wave were used:
1) The period Hann window, which overlaps onto the next potential FFT frame as it designed for use
with the overlap-add technique, was specified as:
w = .5*(1 - cos(2*pi*(0:M-1)'/M));

%periodic Hann for overlap add

2) The standard centered Hann window, which is centered on the FFT frame, was specified as:
w1 = .5*(1 - cos(2*pi*(0:M-1)'/(M-1))); %Raised Cosine (Hann) window

32

Tim Perry
V00213455
Time domain

Frequency domain
50

0
-50
Magnitude (dB)

Amplitude

0.8

0.6

0.4

-100
-150
-200
-250

0.2
-300
0

-350
50

100
150
Samples

200

250

0.2
0.4
0.6
0.8
Normalized Frequency ( rad/sample)

Figure 33: Raised Cosine Window for NFFT = 256 if a periodic Hann window is used (overlaps into next FFT
frame overlap add).

Figure 34: FFT of cosine wave using periodic Hann window.

33

Tim Perry
V00213455

Time domain

Frequency domain
50

1
0
Magnitude (dB)

Amplitude

0.8

0.6

0.4

-100

-150

0.2

-50

-200
50

100
150
Samples

200

250

0.2
0.4
0.6
0.8
Normalized Frequency ( rad/sample)

Figure 35: Raised Cosine Window for NFFT = 256 if a centered Hann window is used (centered about the
FFT frame).

Figure 36: FFT of cosine wave using centered Hann window.

34

Tim Perry
V00213455
With both windowing schemes, the results of truncation are basically the same on the magnitude
response. Spectral leakage occurs with windowing, as seen in the plots. Interestingly, the magnitude
response from the raised cosine window has two sidebands. This result is analogous to AM modulation.
In fact, looking at the windowed cosine wave in the time domain, the waveform is that of an AM
modulated wave over one cycle, with the modulation index set to 100% (fully modulated). Confirming
this in the frequency domain: the sum of the magnitude in the two sidebands is equal to the magnitude of
the carrier.
The phase response is different for each windowing scheme. The centered Hann window has a phase
response that is more correlated to the signal due to the symmetry of the windowing, and is thus more
suitable for analysis. Here, this phase response is in agreement with the fact that this is an even function:
the magnitude spectrum is symmetric, but the phase spectrum is asymmetric. To view the asymmetry
fully, however, the negative half of the Nyquist band would need to be plotted.

FFT of cosine wave shifted by 90 degrees (sine wave)


The results of applying the FFT to the shifted cosine wave (sine wave) are shown in the plots
below. In all cases, the magnitude response looks identical. This is because the absolute value of
the magnitude response was taken. With respect to 0, the shifted cosine wave, or sine wave, is an
odd function. As a result, the double sided power spectrum would yield a negative spike in the
positive nyquist band, and a positive spike in the negative nyquist band.
This can be confirmed by looking at the phases of the plots below, particularity Figure 40, as it
has additional non-zero magnitude values in the form of two evenly spaced, equal power
sidebands about f1. Here, we see that the phase at f1 is not zero, it is -90 degrees. This means
that the output signal is not real at f1. Taking the FFT without taking the absolute value of the
amplitude confirms this: the spike in the positive nyquist band is negative. Taking the real part of
the FFT also confirms this: the resulting display shows nothing in the amplitude spectrum. When
non-integer sampling is applied, there are signals with real parts that occur near f1. However, f1
is not being represented in the frequency domain in this case, as already discussed.

35

Tim Perry
V00213455

Figure 37: FFT of sine wave with NFFT = 10.4 and rectangular windowing. Since the signal is 90 degrees out
of phase at f1, its real part at f1 is zero.

Figure 38: FFT of sine wave with 256 samples per cycle. Since the signal is 90 degrees out of phase at f1, its
real part at f1 is zero.

36

Tim Perry
V00213455

Figure 39: FFT of sine wave with NFFT = 10.4 and rectangular windowing. Since the signal is 90 degrees out
of phase at f1, its real part at f1 is zero.

Figure 40: FFT of sine wave with NFFT = 293.7 and rectangular windowing. Since the signal is 90 degrees out
of phase at f1, its real part at f1 is zero.

37

Tim Perry
V00213455

Figure 41: FFT of sine wave using centered Hann window. Since the signal is 90 degrees out of phase at f1, its
real part at f1 is zero.

REFERENCES
[1]

Udo Zlzer, DAFX. John Wiley & Sons, 2002.

[2]

http://www.lss.uni-stuttgart.de/matlab/cycconv/index.en.html

[3]

http://www.dspguide.com/pdfbook.htm

[4]

http://ccrma.stanford.edu/~jos/sasp/Pictorial_View_Acyclic_Convolution.html

38

Tim Perry
V00213455

APPENDIX A
Part 1a (Cyclic Convolution of Equal Length Vectors)
Matlab Code
%==========================================================================
% a4pt1a_CyclicConv_vectors.m
Author: Tim Perry
% Elec484: DAFX
V00213455
% Assignment 5, Part 1a
2009-06-03
%
% 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.
% a. Circular (cyclic, periodic) convolution in frequency domain
% (entire file length). Result will be same length as input.
%==========================================================================
clear all;
close all;
%-----------------------------------------------------------% Inputs (2 vectors of 32 numbers each)
%-----------------------------------------------------------x =[0 0 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0]
h = [ 0 15 15 15 15 10 10 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
Nx = length(x)
Nh = length(h)
%---------- check inputs -----------------if(Nx~=Nh)
% for cyclic conv, vectors must be the same length
error('Vectors to must be equal length');
end
N = Nx;
% Since x and h are same length
%-----------------------------------------------------------% Cyclic Convolution (Time Domain)
%-----------------------------------------------------------% Time Domain Circular Convolution
for n=1:Nx
y1(n) = sum(x(1:Nx).*h(mod(n-1:-1:n-Nh, Nh)+1));
% mod(Nk,Nh) if Nh ~= 0,returns Nk - n.*Nh where n = floor(Nk./Nh).
end
%----------------------------------------------------------% Cyclic Convolution (Frequency Domain)
%----------------------------------------------------------%----DTFT of h-------for n = 0:N-1
sum = 0;
for k = 0:N-1
sum = sum + (h(k+1)*exp(-i*2*pi/N*k*n));
end
H_f(n+1) = sum;
end
% DTFT of x
for n = 0:N-1
sum = 0;

39

Tim Perry
V00213455
for k = 0:N-1
sum = sum + (x(k+1)*exp(-i*2*pi/N*k*n));
end
X_f(n+1) = sum;
end
% Frequency Domain Multiplication (same effect as time domain convolution)
Y_f = H_f.*X_f;
%----Inverse DTFT transforms result back to time domain-------for n = 0:N-1
sum = 0;
for k = 0:N-1
sum = sum + (Y_f(k+1)*exp(i*2*pi/N*k*n));
end
y2(n+1) = sum/N;
end
y2 = real(y2);
%---------------------------------------------------------------% Cyclic Convolution (Frequency Domain) using Matlab FFT routine
%---------------------------------------------------------------y3 = ifft(fft(x).*fft(h));
% Note use IFFT(X,H) undefined for input arguments of type 'double'
% Must use ifft(y,h);
%-----------------------------------------------------------% Plots
%-----------------------------------------------------------Nsamples = linspace(0,N,N);
axis_inputs = [0 N 1.1*min(h) 1.1*max(h)];
axis_result = [0 N 0 1.1*max(y1)];
figure (1)
% Time domain convolution results
subplot(3,1,1);
stem(Nsamples, h,'.','b-','MarkerSize',9);
axis(axis_inputs)
title('h[n]')
ylabel('h[n]')
subplot(3,1,2);
stem(Nsamples, x,'.','r-','MarkerSize',9);
axis(axis_inputs)
title('x[n]')
ylabel('x[n]')
subplot(3,1,3);
stem(Nsamples, y1,'.','g-','MarkerSize',9);
axis(axis_result)
title('y[n] = h[n]*x[n]
(Cyclic Convolution in Time Domain)')
xlabel('n')
ylabel('y[n]')
%-----column vector representations for exporting--------h_col = h.'
x_col = x.'
y1_col = y1.'
y2_col = y2.';
y3_col = y3.';

40

Tim Perry
V00213455

Part 1a (Cyclic Convolution of Unequal Length Audio Files)


Matlab Code
%==========================================================================
% a4pt1a_CyclicConv_audio.m
Author: Tim Perry
% Elec484: DAFX
V00213455
% Assignment 5, Part 1a
2009-06-08
%
% Convolve 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 2nd sound file,
% use a drum signal.
%
% a. Circular (cyclic, periodic) convolution in frequency domain
% (entire file length). Result will be same length as input.
%==========================================================================
clear all;
close all;
%---------------------------------------------% Inputs (2 audio files)
%---------------------------------------------% input audio
wavfile1 = 'flute2.wav';
%wavfile2 = 'Eidolon_DrumSeg1.wav';
wavfile2 = 'TransSiberian_Drums.wav';
[x fs nbits] = wavread(wavfile1);
[h fs nbits] = wavread(wavfile2);
x = x./2;

% bring down level of flute

% Default to left channel for mono treatment of stereo input files


x = x(:,1);
h = h(:,1);
Nx = length(x)
Nh = length(h)
%------------------ check inputs -----------------% if not equal length, add zeros to end of shorter file
% if (Nh < Nx)
%
h1=[h, zeros(1, Nx-Nh)];
% else
%
h1=h;
% end;
% if(Nh > Nx)
%
x1=[x, zeros(1 ,Nh-Nx)];
% else
%
x1=x;
% end;

% If row vectors, change to column vectors for matrix operations


if size(h,2)>1,
h=h';
end
if size(x,2)>1,
x=x';
end
% If not equal length, append zeros to end of shorter file

41

Tim Perry
V00213455
if (Nx > Nh),
h1 =[h ; zeros(Nx-Nh,1)];
else
h1=h;
end
if (Nh > Nx),
x1=[x ; zeros(Nh-Nx,1)];
else
x1=x;
end
N = length(h1);

% N is the same for h1 and x1

%----------------------------------------------------------% Cyclic Convolution (Frequency Domain)


%----------------------------------------------------------% H2_f =zeros(1, fs/2);
%accocating memory
% X2_f =zeros(1, fs/2);
% y2 = zeros(size(x1));
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%

%----DTFT of h-------for n = 0:N-1


sum = 0;
for k = 0:N-1
sum = sum + (h(k+1)*exp(-i*2*pi/N*k*n));
end
H2_f(n+1) = sum;
end
% DTFT of x
for n = 0:N-1
sum = 0;
for k = 0:N-1
sum = sum + (x(k+1)*exp(-i*2*pi/N*k*n));
end
X2_f(n+1) = sum;
end
% Frequency Domain Multiplication (same effect as time domain convolution)
Y2_f = H2_f.*X2_f;
%----Inverse DTFT transforms result back to time domain-------for n = 0:N-1
sum = 0;
for k = 0:N-1
sum = sum + (Y2_f(k+1)*exp(i*2*pi/N*k*n));
end
y2(n+1) = sum/N;
end
y2 = real(y2);

%---------------------------------------------------------------% Cyclic Convolution (Frequency Domain) using Matlab FFT routine


%---------------------------------------------------------------X_f = fft(x1);
H_f = fft(h1);
Y_f = X_f.*H_f;
y = ifft(Y_f);

% y = ifft(fft(x).*fft(h));

42

Tim Perry
V00213455
% Note use IFFT(X,H) undefined for input arguments of type 'double'
% Must use ifft(y,h);

%-----------------------------------------------------------% Plots (Time Domain)


%-----------------------------------------------------------Nsamples = linspace(0,N,N);
axis_inputs = [0 N 1.1*min(h) 1.1*max(h)];
axis_result = [0 N 1.1*min(y) 1.1*max(y)];
figure (1)
% Time domain convolution results
subplot(3,1,1);
% stem(Nsamples, h1,'.','b-','MarkerSize',9);
plot(Nsamples, h1,'b-');
grid on;
axis(axis_inputs)
title('h[n]')
ylabel('h[n]')
subplot(3,1,2);
% stem(Nsamples, x1,'.','r-','MarkerSize',9);
plot(Nsamples, x1,'r-');
grid on;
axis(axis_inputs)
title('x[n]')
ylabel('x[n]')
subplot(3,1,3);
% stem(Nsamples, y3,'.','g-','MarkerSize',9);
plot(Nsamples, y,'b-');
grid on;
axis(axis_result)
title('y[n] = h[n]*x[n]
(Cyclic Convolution in Frequency Domain on Audio)')
xlabel('n')
ylabel('y[n]')

%-----------------------------------------% Output Audio File


%-----------------------------------------y = y/max(abs(y)); %normalize output mag to prevent wavwrite

clipping

%name output file


file_out=strcat('A5_1a','-CyclicConv');
% write output audio file
wavwrite(y, fs, nbits, file_out);
%wavplay(x1, fs);
%wavplay(h1, fs);
wavplay(y, fs);

%play processed output

43

Tim Perry
V00213455

Part 1b (Acyclic Convolution of Vectors)


Matlab Code
%==========================================================================
% a4pt1b_AcyclicConv_vectors.m
Author: Tim Perry
% Elec484: DAFX
V00213455
% Assignment 5, Part 1b
2009-06-03
%
% 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.
% b. Acyclic (aperiodic) convolution in frequency domain using zero padding
%
(entire file length) (result will be twice the original file length)
%==========================================================================
clear all;
close all;
%-----------------------------------------------------------% Inputs (2 vectors of 32 numbers each)
%-----------------------------------------------------------x = [0 0 0 0 2 4 6 8 10 12 14 12 10 8 6 4 2 0 0 1 2 3 4 5 6 5 4 3 2 1 0 0]
h = [ 0 15 15 10 10 10 5 5 5 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
Nx = length(x)
Nh = length(h)
%-----------------------------------------------------------% Acyclic Convolution (Time Domain)
%-----------------------------------------------------------Nconv = 2^nextpow2(Nx + Nh - 1);
y = zeros(1,Nx+Nh-1);
y1 = zeros(1,Nconv);

% allocate memory for products of all inputs terms


% allocate memory for convolution result

for (m=1:Nx),
for (n=1:Nh),
y(m,n)=x(m)*h(n);
% multiply each m by n, store in y
end;
end;
for (n=1:Nx+Nh-1),
for i=1:Nx,
for j=1:Nh,
if(i+j==n+1)
y1(n)= y1(n) + y(i,j);
% compute convolution sum
end;
end;
end;
end;
%---------------------------------------------------------------% Acyclic Convolution (Frequency Domain) zero padding
%---------------------------------------------------------------NFFT = 2^nextpow2(Nx + Nh - 1);

% size of FFT

h_padded = [h, zeros(1, NFFT-Nh)];


x_padded = [x, zeros(1, NFFT-Nx)];

% zero padding input signals

H_f = fft(h_padded);
X_f = fft(x_padded);

% NFFT point FFTs of inputs

Y_f = H_f.*X_f;

% Freq domain multiplication

44

Tim Perry
V00213455
y2 = ifft(Y_f);
y2 = real(y2);

% Return result to time domain

%-----------------------------------------------------------% Plots (Time Domain)


%-----------------------------------------------------------Nsamples = linspace(0,NFFT,NFFT);
axis_inputs = [0 NFFT 1.1*min(h_padded) 1.1*max(h_padded)];
axis_result = [0 NFFT 0 1.1*max(y2)];
figure (1)
% -------Time domain convolution results plotted in time domain-----subplot(3,1,1);
stem(Nsamples, h_padded,'.','b-','MarkerSize',9);
axis(axis_inputs)
grid on;
title('h[n]')
ylabel('h[n]')
subplot(3,1,2);
stem(Nsamples, x_padded,'.','r-','MarkerSize',9);
axis(axis_inputs)
grid on;
title('x[n]')
ylabel('x[n]')
subplot(3,1,3);
stem(Nsamples, y1,'.','g-','MarkerSize',9);
axis(axis_result)
grid on;
title('y[n] = h[n]*x[n]
(Ayclic Convolution in Time Domain)')
xlabel('n')
ylabel('y[n]')
figure (2)
% ---------Freq Domain Convolution results plotted in time domain----subplot(3,1,1);
stem(Nsamples, h_padded,'.','b-','MarkerSize',9);
axis(axis_inputs)
grid on;
title('h[n]')
ylabel('h[n]')
subplot(3,1,2);
stem(Nsamples, x_padded,'.','r-','MarkerSize',9);
axis(axis_inputs)
grid on;
title('x[n]')
ylabel('x[n]')
subplot(3,1,3);
stem(Nsamples, y2,'.','b-','MarkerSize',9);
axis(axis_result)
grid on;
title('y[n] = h[n]*x[n]
(Ayclic Convolution in Frequency Domain)')
xlabel('n')
ylabel('y[n]')
%-----column vector representations for exporting--------format bank;
h_padded_col = h_padded.'
x_padded_col = x_padded.'
% y1_col = y1.'
y2_col = y2.';

45

Tim Perry
V00213455

Part 1b (Acyclic Convolution of Audio Files)


Matlab Code
%==========================================================================
% a4pt1b_AcyclicConv_audio.m
Author: Tim Perry
% Elec484: DAFX
V00213455
% Assignment 5, Part 1b
2009-06-08
%
% Convolve two sound files 3-5 seconds long each (frequency domain only).
% For the first sound file, use the flute signal, for the 2nd sound file,
% use a drum signal.
%
% b. Acyclic (aperiodic) convolution in frequency domain using zero padding
%
(entire file length) (result will be twice the original file length)
%==========================================================================
clear all;
close all;
%---------------------------------------------% Inputs (2 audio files)
%---------------------------------------------wavfile1 = 'flute2.wav';
%wavfile2 = 'Eidolon_DrumSeg1.wav';
wavfile2 = 'TransSiberian_Drums.wav';
[x fs nbits] = wavread(wavfile1);
[h fs nbits] = wavread(wavfile2);
x = x./2;

% bring down level of flute

% Default to left channel for mono treatment of stereo input files


x = x(:,1);
% (since left channel is col vectors)
h = h(:,1);
Nx = length(x)
Nh = length(h)

% length of audio files

%----------------check input files------------------------------% If row vectors, change to column vectors for matrix operations
if size(h,2)>1,
h=h';
end
if size(x,2)>1,
x=x';
end
% If not equal length, append zeros to end of shorter file
if (Nx > Nh),
h1 =[h ; zeros(Nx-Nh,1)];
%
h1 =[h ; zeros(1, Nx-Nh)];
else
h1=h;
end
if (Nh > Nx),
x1=[x ; zeros(Nh-Nx,1)];
%
x1 =[x , zeros(1, Nh-Nx)];
else
x1=x;
end
N = length(h1);

% N is the same for h1 and x1

46

Tim Perry
V00213455
%---------------------------------------------------------------% Acyclic Convolution (Frequency Domain)
%---------------------------------------------------------------NFFT = 2^nextpow2(2*N - 1);
% size of FFT
h_padded = [h1; zeros(NFFT-N, 1)];
x_padded = [x1; zeros(NFFT-N, 1)];

% zero padding input signals

H_f = fft(h_padded);
X_f = fft(x_padded);

% NFFT point FFTs of inputs

Y_f = H_f.*X_f;

% Freq domain multiplication

y = ifft(Y_f);
y = real(y);

% Return result to time domain

%-----------------------------------------------------------% Plots (Time Domain)


%-----------------------------------------------------------Nsamples = linspace(0,NFFT,NFFT);
axis_inputs = [0 NFFT 1.1*min(h_padded) 1.1*max(h_padded)];
axis_result = [0 NFFT 1.1*min(y) 1.1*max(y)];
figure (1)
% Time domain convolution results
subplot(3,1,1);
plot(Nsamples, h_padded,'b-');
grid on;
axis(axis_inputs)
title('h[n]')
ylabel('h[n]')
subplot(3,1,2);
plot(Nsamples, x_padded,'r-');
grid on;
axis(axis_inputs)
title('x[n]')
ylabel('x[n]')
subplot(3,1,3);
plot(Nsamples, y,'b-');
grid on;
axis(axis_result)
title('y[n]=h[n]*x[n] (Acyclic Convolution in Frequency Domain on Audio)')
xlabel('n')
ylabel('y[n]')
%-----------------------------------------% Output Audio File
%-----------------------------------------y = y/max(abs(y)); %normalize output mag to prevent wavwrite

clipping

%name output file


file_out=strcat('A5_1b','-AcyclicConv');
% write output audio file
wavwrite(y, fs, nbits, file_out);
%wavplay(x1, fs);
%wavplay(h1, fs);
wavplay(y, fs);

%play processed output

47

Tim Perry
V00213455

Part 1c (Cyclic Convolution of Vectors using Overlap-Add)


Matlab Code
%==========================================================================
% a5pt1c_CyclicWinOA_vec.m
Author: Tim Perry
% Elec484: DAFX
V00213455
% Assignment 5, Part 1d
2009-06-03
%
% 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.
%
% c. Circular (cyclic, periodic) convolution on windowed overlapping
% segments, raised cosine windows, cyclic shift, and overlap-add (DAFX
% figure 8.5 where the time-frequency processing is a multiplication with
% the time/frequency coefficients of a second signal, keep phases of only
% one of the signals). See also figure 8.28. Use windows 8 samples long for
% numbers, 2048 samples long for audio file
%==========================================================================
clear all;
close all;
%-----------------------------------------------------------% Inputs (2 vectors of 32 numbers each)
%-----------------------------------------------------------x = [0 0 0 0 2 4 6 8 10 12 14 12 10 8 6 4 2 0 0 1 2 3 4 5 6 5 4 3 2 1 0 0]
h = [ 0 15 15 10 10 10 5 5 5 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
Nx = length(x)
Nh = length(h)
%---------- check inputs -----------------if(Nx~=Nh)
% for cyclic conv, vectors must be the same length
error('Vectors to must be equal length');
end
N = Nx;
% Signal length, since x and h are same length
%---------------------------------------------------------------------% Parameters for cyclic conv with raised cosine windows and overlap-add
%---------------------------------------------------------------------M = 8
% Window length
%Ra = M;
% hop size for acyclic
Ra = M/2;
% hop size for cyclic
Nconv = M
% block to convolve (time domain).
NFFT = N
% FFT method (see later). For cyclic, Nfft = M
Nframes = 1+floor((N-M)/Ra);
% # of complete frames
% NsigOut = 2^nextpow2(N + NFFT)
% for Acyclic, NsigOut is smallest
%
% power of 2 that is >= |Nx+Nh-1|
NsigOut = N
% for Cyclic, output signal same length as input sigs
n = -M/2:M/2-1;
%----Hann Window: "Hanning" removes multiplications by zero
w = .5*(1 - cos(2*pi*(0:M-1)'/M));
%periodic Hann for overlap add
w1 = .5*(1 - cos(2*pi*(0:M-1)'/(M-1))); %Raised Cosine (Hann) window
w2 = .5*(1 - cos(2*pi*(1:M)'/(M+1)));
%Raised Cosine (Hanning) window
winview = wvtool(w1,w2,w);
% view window
set(winview, 'Color', [1 1 1])

48

Tim Perry
V00213455
%--------------------------------------------------------------------% Time Domain Cyclic Conv with raised cosine windowing, cyclic shift
%--------------------------------------------------------------------n = 0;
% initialize sample index
y1 = zeros(1,NsigOut); %allocate output (for cyclic, same length as inputs)

for m = 0:(Nframes-1)
% m is frame/block number
index = m*Ra+1:min(m*Ra+M,N);
% indices for the mth frame
% raised cosine windowed mth frame of h (kernal)
hm = w*h(index);
hm = circshift(hm,[0,M/2]);
% circular shift
% rectangular windowed mth frame of x
xm = x(index);
%
hmzp = [hm zeros(1,Nconv-length(hm))]; % zero padding signals
%
xmzp = [xm zeros(1,Nconv-length(xm))]; % zero padding the signal
for k = n+1:n+M
% convolve mth frames
ym(k) = sum(xm(1:M).*hm(mod(k-1:-1:k-M, M)+1));
% mod(Nk,Nh) if Nh ~= 0,returns Nk - k.*Nh where k = floor(Nk./Nh).
n = k;
end
indexOut1 = m*Ra+1:(m*Ra + Nconv);
% circular shift
ym = circshift(ym, [0, M/2]);
y1(indexOut1) = y1(indexOut1) + ym(indexOut1);
% overlap add output frames
end

%=======================================================================
% Cyclic Conv with raised cosine windows and overlap-add (Freq Domain)
%=======================================================================
N = Nx;
% Set Nx to be the signal length
M = 8
% Window length
NFFT = N;
% size of FFT
Ra = M;
% hop size
Nframes = 1+floor((N-M)/Ra);
% # of full blocks to convolve
NsigOut = N
% for cyclic, output same length as inputs
%----Hann Window: "Hanning" removes multiplications by zero
w = .5*(1 - cos(2*pi*(0:M-1)'/M));
%periodic Hann for overlap add
H = fft(h);
y = zeros(1,N);

% FR of filter kernal (no padding for cyclic)


% vector for output signal (same length as input)

%---apply cyclic FFT convolution with overlap add---for m = 0:(Nframes-1)


index = m*Ra+1:min(m*Ra+M,N); % mth frame indices
xm = w'.*x(index); % raised cosine windowed mth frame
xm = circshift(h,[0,M/2]);
% circular shift
%----Frequency domain processing---------xmzp = [xm zeros(1,NFFT-length(xm))]; %zero pad the signal to length N
Xm = fft(xmzp);
% FFT of padded mth frame
%Ym = Xm .* H;
% freq domain multiplication = time domain conv
Ym = Xm .* real(H);
% keep phase of only Y
%----Synthesis (overlap-add)----------% ym = real(ifft(Ym));
% return results to time domain
ym = (ifft(Ym));
% return results to time domain
ym = circshift(ym, [0, M/2]);
% circular shift
indexOut(1:m*Ra) = (NFFT-m*Ra+1):NFFT
% indices for wrap around terms
indexOut(m*Ra+1:NFFT)=1:NFFT-m*Ra
% indices for additional terms
y(indexOut) = y(indexOut) + ym; % apply overlap adding
end

49

Tim Perry
V00213455
%-----------------------------------------------------------% Plots (Time Domain)
%-----------------------------------------------------------Nsamples = linspace(0,NsigOut,NsigOut);
axis_inputs = [0 NsigOut 1.1*min(h) 1.1*max(h)];
axis_result = [0 NsigOut 0 1.1*max(y)];
% -------Time domain convolution results plotted in time domain-----figure(3)
subplot(3,1,1);
stem(Nsamples, h,'.','b-','MarkerSize',9);
axis(axis_inputs)
grid on;
title('h[n]')
ylabel('h[n]')
subplot(3,1,2);
stem(Nsamples, x,'.','r-','MarkerSize',9);
axis(axis_inputs)
grid on;
title('x[n]')
ylabel('x[n]')
subplot(3,1,3);
stem(Nsamples, y1,'.','g-','MarkerSize',9);
axis(axis_result)
grid on;
title('y[n] = h[n]*x[n] (Time Domain Cyclic Conv w/ Windowing and Overlap-Add)')
xlabel('n')
ylabel('y[n]')
% ---------Freq Domain Convolution results plotted in time domain----figure(4)
subplot(3,1,1);
stem(Nsamples, h,'.','b-','MarkerSize',9);
axis(axis_inputs)
grid on;
title('h[n]')
ylabel('h[n]')
subplot(3,1,2);
stem(Nsamples, x,'.','r-','MarkerSize',9);
axis(axis_inputs)
grid on;
title('x[n]')
ylabel('x[n]')
subplot(3,1,3);
stem(Nsamples, y,'.','b-','MarkerSize',9);
axis(axis_result)
grid on;
title('y[n] = h[n]*x[n] (FFT Cyclic Conv w/ Windowing and Overlap-Add)')
xlabel('n')
ylabel('y[n]')
%-----column vector representations for exporting--------format bank;
%h_col = h.'
%x_col = x.'
y1_col = y1.'
y_col = y.'

50

Tim Perry
V00213455

Part 1c (Cyclic Convolution of Audio using Overlap-Add)


Matlab Code
%==========================================================================
% a5pt1d_AcyclicWinOA_vec.m
Author: Tim Perry
% Elec484: DAFX
V00213455
% Assignment 5, Part 1b
2009-06-14
%
% Convolve two sound files 3-5 seconds long each (frequency domain only).
% For the first sound file, use the flute signal, for the 2nd sound file,
% use a drum signal.
%
% c. Circular (cyclic, periodic) convolution on windowed overlapping
% segments, raised cosine windows, cyclic shift, and overlap-add (DAFX
% figure 8.5 where the time-frequency processing is a multiplication with
% the time/frequency coefficients of a second signal, keep phases of only
% one of the signals). See also figure 8.28. Use windows 8 samples long for
% numbers, 2048 samples long for audio file
%==========================================================================
clear all;
close all;
%---------------------------------------------% Inputs (2 audio files)
%---------------------------------------------wavfile1 = 'flute2.wav';
%wavfile2 = 'Eidolon_DrumSeg1.wav';
wavfile2 = 'TransSiberian_Drums.wav';
[h fs nbits] = wavread(wavfile1);
[x fs nbits] = wavread(wavfile2);
h = h./2;

% bring down level of flute

% Default to left channel for mono treatment of stereo input files


x = x(:,1);
% (since left channel is col vectors)
h = h(:,1);
Nx = length(x)
Nh = length(h)

% length of audio files

%----------------check input files------------------------------% If col vectors, change to row vectors for matrix operations
if size(h,1)>1,
h=h';
end
if size(x,1)>1,
x=x';
end
% If not equal length, append zeros to end of shorter file
if (Nx > Nh),
%
h =[h ; zeros(Nx-Nh,1)];
hzp =[h , zeros(1, Nx-Nh)];
end
if (Nh > Nx),
%
x = [x ; zeros(Nh-Nx,1)];
x =[x , zeros(1, Nh-Nx)];
end
Nx = length(x)
% new padded lengths (if changed)
Nh = length(hzp)
%---------------------------------------------------------------

51

Tim Perry
V00213455
%---------------------------------------------------------------------% Parameters for Cyclic conv with raised cosine windows and circular shift
%---------------------------------------------------------------------% Set Nx to be the signal length
N = Nx;
M = 2048
% Window length
%NFFT = 2^nextpow2(M + Nh - 1);
NFFT = N;
% size of FFT
%M = NFFT-Nh+1
% optimized window length
% hop size
Ra = M;
Nframes = 1+floor((N-M)/Ra);
% # of full blocks to convolve
% for cyclic, output same length as inputs
NsigOut = N
%----Hann Window: "Hanning" removes multiplications by
%periodic Hann
w = .5*(1 - cos(2*pi*(0:M-1)'/M));
w1 = .5*(1 - cos(2*pi*(0:M-1)'/(M-1))); %Raised Cosine
w2 = .5*(1 - cos(2*pi*(1:M)'/(M+1)));
%Raised Cosine
%winview = wvtool(w1,w2,w);
%set(winview, 'Color', [1 1 1])

zero
for overlap add
(Hann) window
(Hanning) window

% view window

%=======================================================================
% Cyclic Conv with raised cosine windows and overlap-add (Freq Domain)
%=======================================================================
H = fft(hzp);
y = zeros(1,N);

% FR of filter kernal (no padding for cyclic)


% vector for output signal (same length as input)

%---apply cyclic FFT convolution with overlap add---for m = 0:(Nframes-1)


index = m*Ra+1:min(m*Ra+M,N); % mth frame indices
xm = w'.*x(index); % raised cosine windowed mth frame
xm = circshift(xm,[0,M/2]);
% circular shift
%----Frequency domain processing---------xmzp = [xm zeros(1,NFFT-length(xm))]; %zero pad the signal to length N
Xm = fft(xmzp);
% FFT of padded mth frame
%Ym = Xm .* H;
% freq domain multiplication = time domain conv
Ym = Xm .* real(H);
% keep phase of only Y
%----Synthesis (overlap-add)----------% ym = real(ifft(Ym));
% return results to time domain
ym = (ifft(Ym));
% return results to time domain
ym = circshift(ym, [0, M/2]);
% circular shift
indexOut(1:m*Ra) = (NFFT-m*Ra+1):NFFT;
% indices for wrap around terms
indexOut(m*Ra+1:NFFT)=1:NFFT-m*Ra;
% indices for additional terms
y(indexOut) = y(indexOut) + ym; % apply overlap adding
end

%-----------------------------------------------------------% Plots (Time Domain)


%-----------------------------------------------------------NsigOut = length(y);
Nsamples_h = linspace(0,Nh,Nh);
Nsamples_x = linspace(0,Nx,Nx);
Nsamples_padded = linspace(0, length(hzp), length(hzp));
Nsamples_xm = linspace(0, length(xm), length(xm));
Nsamples_Out = linspace(0,NsigOut,NsigOut);
axis_inputs = [0 NsigOut 1.1*min(hzp) 1.1*max(hzp)];
axis_result = [0 NsigOut 0 1.1*max(y)];
figure (2)

52

Tim Perry
V00213455
% ---------Freq Domain Convolution results plotted in time domain----NsigOut = length(y);
Nsamples_h = linspace(0,Nh,Nh);
Nsamples_x = linspace(0,Nx,Nx);
Nsamples_padded = linspace(0, length(hzp), length(hzp));
Nsamples_xm = linspace(0, length(xm), length(xm));
Nsamples_Out = linspace(0,NsigOut,NsigOut);
axis_inputs = [0 NsigOut 1.1*min(hzp) 1.1*max(hzp)];
axis_result = [0 NsigOut 1.1*min(y) 1.1*max(y)];
figure (2)
% ---------FFT Convolution results plotted in time domain----subplot(4,1,1);
plot(Nsamples_padded, hzp,'b-');
axis(axis_inputs)
grid on;
title('h[n]
(filter)')
ylabel('h[n]')
subplot(4,1,2);
plot(Nsamples_x, x,'r-');
axis(axis_inputs)
grid on;
title('x[n]')
ylabel('x[n]')
subplot(4,1,3);
plot(Nsamples_padded, xmzp,'r-');
axis(axis_inputs)
grid on;
title(['x_mzp[n]
(windowed, block of x[n]), m=',num2str(m)])
ylabel('x_mzp[n]')
subplot(4,1,4);
plot(Nsamples_Out, y,'b-');
axis(axis_result)
grid on;
title('y[n] = h[n]*x[n] (Cyclic FFT Convolution with Overlap Add)')
xlabel('n')
ylabel('y[n]')

%----------------------------------------------------% Output Audio File


%----------------------------------------------------y = y/max(abs(y)); %normalize output mag to prevent wavwrite
y = y*0.8;
% bring level down further

clipping

file_out=strcat('A5_1c','-CyclicWinOA');
wavwrite(y, fs, nbits, file_out);

% name output file


% write output audio file

%wavplay(x1, fs);
%wavplay(h1, fs);
wavplay(y, fs);

% play processed output

53

Tim Perry
V00213455

Part 1d (Acyclic Convolution of Vectors using Overlap-Add)


Matlab Code
%==========================================================================
% a5pt1d_AcyclicWinOA_vec.m
Author: Tim Perry
% Elec484: DAFX
V00213455
% Assignment 5, Part 1d
2009-06-03
%
% 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.
%
% d. Acyclic (aperiodic) convolution in frequency domain using zero padding
% using rectangular windows (DAFX figure 8.20) and overlap-add. 8
% samples long for numbers, 2048 samples long for audio file.
%==========================================================================
clear all;
close all;
%-----------------------------------------------------------% Inputs (2 vectors of 32 numbers each)
%-----------------------------------------------------------x = [0 0 0 0 2 4 6 8 10 12 14 12 10 8 6 4 2 0 0 1 2 3 4 5 6 5 4 3 2 1 0 0]
h = [ 0 15 15 10 10 10 5 5 5 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
Nx = length(x)
Nh = length(h)
N = Nx;

% choose x to be the signal, where h will be the filter

%---------------------------------------------------------------------% Parameters for Acyclic conv with rectangular windows and overlap-add
%---------------------------------------------------------------------M = 8

% Window length

Nconv = 2^nextpow2(M + Nh - 1); % size of conv(time domain implementation)


%NFFT = 2^nextpow2(M + Nh - 1);
% size of FFT
NFFT = N+M;
% size of FFT
%M = NFFT-Nh+1
Ra = M;
% hop size for acyclic with rectangular win
Nframes = 1+floor((N-M)/Ra);
% # of full blocks to convolve
%NsigOut = 2^nextpow2(N + NFFT)
% for Acyclic, NsigOut is smallest
%
% power of 2 that is >= |Nx+Nh-1|
%===============================================================
% Acyclic Convolution (Time Domain)
%===============================================================
% %------Windowing Parameters---------------% M = 8;
% Window length
%
% hzp = [h zeros(1,NFFT-Nh)]; % pad filter kernal h to FFT size
% H = fft(hzp);
% frequency response of filter kernal
%
% %y2 = zeros(1,N + M); % vector for output signal
%
% y2 = zeros(1,N + NFFT); % vector for output signal
%
% figure(5)
%
% %---apply FFT convolution with overlap add---% for m = 0:(Nframes-1)
%
index = m*Ra+1:min(m*Ra+M,N); % mth frame indices
%
xm = x(index); % rectangular windowed mth frame
%
xmzp = [xm zeros(1,NFFT-length(xm))]; % zero padding
%
%
%-------plot mth frame-------------------%
subplot(Nframes, 1, m+1)
%
stem(xmzp,'.','b-','MarkerSize',13);

54

Tim Perry
V00213455
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
% end

grid on;
title(['x_',num2str(m),'zp[n]
(mth padded frame in time domain)'])
axis([0 length(xmzp) 0 1.2*max(x)])
xlabel('n')
ylabel('y[n]')
ym = zeros(1,Nx+Nh-1);
ym1 = zeros(1,Nconv);

% allocate memory for products of all inputs terms


% allocate memory for convolution result

for (m=1:M),
for (n=1:Nconv),
ym(m,n)=xmzp(m)*hzp(n);
% multiply each m by n, store in ym
end;
end;
for (n=1:Nx+Nh-1),
for i=1:Nx,
for j=1:Nh,
if(i+j==n+1)
y1(n)= y1(n) + y(i,j);
% compute convolution sum
end;
end;
end;
end;
%----Synthesis (overlap-add)----------%indexOut = m*Ra+1:(m*Ra + NFFT);
indexOut = m*Ra+1:(m*Ra+NFFT);
y2(indexOut) = y2(indexOut) + ym; % apply overlap adding

%===============================================================
% Acyclic Convolution (Frequency Domain) zero padding
%===============================================================
hzp = [h zeros(1,NFFT-Nh)]; % pad filter kernal h to FFT size
H = fft(hzp);
% frequency response of filter kernal
%y2 = zeros(1,N + M); % vector for output signal
y2 = zeros(1,N + NFFT); % vector for output signal
figure(5)
%---apply FFT convolution with overlap add---for m = 0:(Nframes-1)
index = m*Ra+1:min(m*Ra+M,N); % mth frame indices
xm = x(index); % rectangular windowed mth frame
xmzp = [xm zeros(1,NFFT-length(xm))]; % zero padding
%-------plot mth frame-------------------subplot(Nframes, 1, m+1)
stem(xmzp,'.','b-','MarkerSize',13);
grid on;
title(['x_',num2str(m),'zp[n]
(mth padded frame in time domain)'])
axis([0 length(xmzp) 0 1.2*max(x)])
xlabel('n')
ylabel('y[n]')
%----Frequency domain processing---------Xm = fft(xmzp);
% FFT of padded mth frame
Ym = Xm .* H;
% freq domain multiplication = time domain conv
%----Synthesis (overlap-add)----------ym = real(ifft(Ym))
% return results to time domain
%indexOut = m*Ra+1:(m*Ra + NFFT);
indexOut = m*Ra+1:(m*Ra+NFFT);
y2(indexOut) = y2(indexOut) + ym; % apply overlap adding
end
%y = y(1:Nx+Nh-1);

% truncate output signal to length N+L-1

55

Tim Perry
V00213455
%-----------------------------------------------------------% Plots (Time Domain)
%-----------------------------------------------------------NsigOut = length(y2);
Nsamples_h = linspace(0,Nh,Nh);
Nsamples_x = linspace(0,Nx,Nx);
Nsamples_padded = linspace(0, length(hzp), length(hzp))
Nsamples_xm = linspace(0, length(xm), length(xm))
Nsamples_Out = linspace(0,NsigOut,NsigOut);
axis_inputs = [0 NsigOut 1.1*min(hzp) 1.1*max(hzp)];
axis_result = [0 NsigOut 0 1.1*max(y2)];
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%

-------Time domain convolution results plotted in time domain-----figure(1)


subplot(3,1,1);
stem(Nsamples_h, hzp,'.','b-','MarkerSize',9);
axis(axis_inputs)
grid on;
title('h[n]')
ylabel('h[n]')
subplot(3,1,2);
stem(Nsamples_x, xmzp,'.','r-','MarkerSize',9);
axis(axis_inputs)
grid on;
title('x[n]')
ylabel('x[n]')
subplot(3,1,3);
stem(Nsamples_Out, y1,'.','g-','MarkerSize',9);
axis(axis_result)
grid on;
title('y[n] = h[n]*x[n]
(Ayclic Convolution in Time Domain)')
xlabel('n')
ylabel('y[n]')

figure (2)
% ---------Freq Domain Convolution results plotted in time domain----subplot(4,1,1);
stem(Nsamples_h, h,'.','b-','MarkerSize',9);
axis(axis_inputs)
grid on;
(filter)')
title('h[n]
ylabel('h[n]')
subplot(4,1,2);
stem(Nsamples_x, x,'.','r-','MarkerSize',9);
axis(axis_inputs)
grid on;
title('x[n]')
ylabel('x[n]')
subplot(4,1,3);
stem(Nsamples_padded, xmzp,'.','r-','MarkerSize',9);
axis(axis_inputs)
grid on;
title(['x_mzp[n]
(windowed, zero padded block of x[n]), m=',num2str(m)])
ylabel('x_mzp[n]')
subplot(4,1,4);
stem(Nsamples_Out, y2,'.','b-','MarkerSize',9);
axis(axis_result)
grid on;
title('y[n] = h[n]*x[n] (Ayclic FFT Convolution with Overlap Add)')
xlabel('n')
ylabel('y[n]')
%-----column vector representations for exporting--------format bank;
hzp_col = hzp.'
xmzp_col = xmzp.'
% y1_col = y1.'
y2_col = y2.';

56

Tim Perry
V00213455

Part 1d (Acyclic Convolution of Audio using Overlap-Add)


Matlab Code
%==========================================================================
% a5pt1d_AcyclicWinOA_wav.m
Author: Tim Perry
% Elec484: DAFX
V00213455
% Assignment 5, Part 1d
2009-06-14
%
% Convolve two sound files 3-5 seconds long each (frequency domain only).
% For the first sound file, use the flute signal, for the 2nd sound file,
% use a drum signal.
%
% d. Acyclic (aperiodic) convolution in frequency domain using zero padding
% using rectangular windows (DAFX figure 8.20) and overlap-add. 8
% samples long for numbers, 2048 samples long for audio file.
%==========================================================================
clear all;
close all;
%---------------------------------------------% Inputs (2 audio files)
%---------------------------------------------wavfile1 = 'flute2.wav';
%wavfile2 = 'Eidolon_DrumSeg1.wav';
wavfile2 = 'TransSiberian_Drums.wav';
[h fs nbits] = wavread(wavfile1);
[x fs nbits] = wavread(wavfile2);

x = x./2;

% bring down level of flute

% Default to left channel for mono treatment of stereo input files


x = x(:,1);
% (since left channel is col vectors)
h = h(:,1);
Nx = length(x)
Nh = length(h)

% original length of audio files

%----------------check input files------------------------------% If col vectors, change to row vectors for matrix operations
if size(h,1)>1,
h=h';
end
if size(x,1)>1,
x=x';
end
% Optional: if not equal length, append zeros to end of shorter file
% if (Nx > Nh),
%
h =[h , zeros(1, Nx-Nh)];
% end
% if (Nh > Nx),
%
x =[x , zeros(1, Nh-Nx)];
% end
%
% Nx = length(x)
% new padded lengths (if changed)
% Nh = length(h)
%---------------------------------------------------------------

57

Tim Perry
V00213455
%---------------------------------------------------------------------% Parameters for Acyclic conv with rectangular windows and overlap-add
%---------------------------------------------------------------------N = Nx;
% Set Nx to be the signal length
% Set Nh to be the filter length
L = Nh;
M = 2048
% Window length
NFFT = 2^nextpow2(M + Nh + - 1);
%NFFT = Nh+M;
% size of FFT
%M = NFFT-Nh+1
% optimized window length
% hop size for acyclic with rectangular win
Ra = M;
Nframes = 1+floor((N-M)/Ra);
% # of full blocks to convolve
%NsigOut = 2^nextpow2(N + NFFT)
% for Acyclic, NsigOut is smallest
%
% power of 2 that is >= |Nx+Nh-1|
%===============================================================
% Acyclic Convolution (Frequency Domain) zero padding
%===============================================================
hzp = [h zeros(1,NFFT-Nh)]; % pad filter kernal h to FFT size
H = fft(hzp);
% frequency response of filter kernal
%y = zeros(1,N + M); % vector for output signal
y = zeros(1,N + NFFT); % vector for output signal
%---apply FFT convolution with overlap add---for m = 0:(Nframes-1)
index = m*Ra+1:min(m*Ra+M,N); % mth frame indices
xm = x(index); % rectangular windowed mth frame
xmzp = [xm zeros(1,NFFT-length(xm))]; % zero padding
%----Frequency domain processing---------Xm = fft(xmzp);
% FFT of padded mth frame
Ym = Xm .* H;
% freq domain multiplication = time domain conv
%----Synthesis (overlap-add)----------ym = real(ifft(Ym));
% return results to time domain
%indexOut = m*Ra+1:(m*Ra + NFFT);
indexOut = m*Ra+1:(m*Ra+NFFT);
y(indexOut) = y(indexOut) + ym; % apply overlap adding
end
y = y(1:Nx + Nh - 1); % truncate output signal to length Nx + Nh + M
%-----------------------------------------------------------% Plots (Time Domain)
%-----------------------------------------------------------NsigOut = length(y);
Nsamples_h = linspace(0,Nh,Nh);
Nsamples_x = linspace(0,Nx,Nx);
Nsamples_padded = linspace(0, length(hzp), length(hzp));
Nsamples_xm = linspace(0, length(xm), length(xm));
Nsamples_Out = linspace(0,NsigOut,NsigOut);
axis_inputs = [0 NsigOut 1.1*min(hzp) 1.1*max(hzp)];
axis_result = [0 NsigOut 1.1*min(y) 1.1*max(y)];
figure (2)
% ---------Freq Domain Convolution results plotted in time domain----subplot(4,1,1);
plot(Nsamples_h, h,'b-');
axis(axis_inputs)
grid on;
title('h[n]
(filter)')
ylabel('h[n]')

58

Tim Perry
V00213455
subplot(4,1,2);
plot(Nsamples_x, x,'r-');
axis(axis_inputs)
grid on;
title('x[n]')
ylabel('x[n]')
subplot(4,1,3);
plot(Nsamples_padded, xmzp,'r-');
axis(axis_inputs)
grid on;
title(['x_mzp[n]
(windowed, zero padded block of x[n]), m=',num2str(m)])
ylabel('x_mzp[n]')
subplot(4,1,4);
plot(Nsamples_Out, y,'b-');
axis(axis_result)
grid on;
title('y[n] = h[n]*x[n] (Ayclic FFT Convolution with Overlap Add)')
xlabel('n')
ylabel('y[n]')
%----------------------------------------------------% Output Audio File
%----------------------------------------------------y = y/max(abs(y)); %normalize output mag to prevent wavwrite
y = y*0.8;
% bring level down further

clipping

file_out=strcat('A5_1d','-AcyclicWinOA');
wavwrite(y, fs, nbits, file_out);

% name output file


% write output audio file

%wavplay(x1, fs);
%wavplay(h1, fs);
wavplay(y, fs);

% play processed output

59

Tim Perry
V00213455

Part 2 (FFT) Matlab Code


%==========================================================================
% a4pt1a_CyclicConv_audio.m
Author: Tim Perry
% Elec484: DAFX
V00213455
% Assignment 5, Part 2
2009-06-11
%
% 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.
% - Repeat for a different FFT block size, e.g. 256.
% - Repeat for a cosine wave with a non-integer number of samples per cycle.
% - Repeat again after windowing the cosine wave with a raised cosine
%
window (256 sample window).
% - Repeat again after shifting the cosine wave by 90 degrees (e.g. use
%
sine instead).
% -Explain all results
%==========================================================================
close all;
clear all;
fs = 8000;
Ts = 1/fs;
f1 = 1000;
NFFT_1 = 8;
NFFT_2 = 256;
% NFFT_1 = 10.4
% NFFT_2 = 293.7

%
%
%
%

sampling freq
sampling period
freq of cosine wave
integer FFT block size (samples per cycle)
% noninteger FFT block size (samples per cycle)

nT_1 = (0:NFFT_1-1)*Ts;
nT_2 = (0:NFFT_2-1)*Ts;
nT = (0:fs-1)*Ts;
t = (0:1:1000);

% time vector

%----------------------------------------------------------% Input Cosine/Sin Waves


%----------------------------------------------------------% wavename = 'Cosine'%uncomment these 3 lines, comment next 3 for cosine wave
% x1 = cos(2*pi*f1*nT);
% x2 = cos(2*pi*f1*nT);
wavename = 'Sine'
x1 = sin(2*pi*f1*nT);
x2 = sin(2*pi*f1*nT);

% uncomment these 3 lines for sine wave


% shifted by 90 degrees
% shifted by 90 degrees

%--------------------------------------------------------------% Windowing with Hann Window: ("Hanning" removes multiplications by zero)


%--------------------------------------------------------------M = NFFT_2
% window size
w = .5*(1 - cos(2*pi*(0:M-1)'/M));
%periodic Hann for overlap add
w1 = .5*(1 - cos(2*pi*(0:M-1)'/(M-1))); %Raised Cosine (Hann) window
w2 = .5*(1 - cos(2*pi*(1:M)'/(M+1)));
%Raised Cosine (Hanning) window
% winview = wvtool(w1);
% view window
% set(winview, 'Color', [1 1 1])
xw = w1'.*x2(1:NFFT_2);

% raised-cosine windowed cosine wave

%--------------------------------------------------------------% Take FFT


%--------------------------------------------------------------X_f = fft(x1);
% FFT of unframed signal (for comparison)
X1_f = fft(x1, NFFT_1)*Ts;
% take FFT of of size NFFT
X2_f = fft(x2, NFFT_2)*Ts;

60

Tim Perry
V00213455
Xw_f = fft(xw, NFFT_2)*Ts;

% FFT of raised-cosine windowed signal

f=[0:1:fs/2];
% freq range 0 to fs/2 (positive Nyquist band)
%freq1 = fs.*nT_1.*(0:NFFT_1-1);
%freq1 = linspace(0,1,1 + NFFT_1/2).*(fs/2);
%freq2 = linspace(0,1,1 + NFFT_2/2).*(fs/2);
%freq2 = fs.*nT_2.*(0:NFFT_2-1);

%=========================================
% Freq Response Plots
%=========================================
freq1 = linspace(0,1,1 + NFFT_1/2).*(fs/2);
freq2 = linspace(0,1,1 + NFFT_2/2).*(fs/2);
X1_mag
X2_mag
arg_X1
arg_X2

=
=
=
=

2*abs(X1_f(1:1+NFFT_1/2));
2*abs(X2_f(1:1+NFFT_2/2));
angle(X1_f(1:1+NFFT_1/2));
angle(X2_f(1:1+NFFT_2/2));

Xw_mag = 2*abs(Xw_f(1:1+NFFT_2/2));
arg_Xw = angle(Xw_f(1:1+NFFT_2/2));

%
%
%
%

magnitude spectrum of x1(nT)


magnitude spectrum of x2(nT)
phase of x1(nT)
phase of x2(nT)

% magnitude spectrum of xw(nT)


% phase of x2(nT)

% figure(1)
%-------FFT size of 8---subplot(3,1,1)
hold on;
plot(nT(1:NFFT_1+1)*fs,x1(1:NFFT_1+1));
stem(nT(1:NFFT_1)*fs,x1(1:NFFT_1),'.','MarkerSize',13);
stem(nT(1:NFFT_1)*fs,x1(1:NFFT_1));
grid on;
axis([0 NFFT_1 1.2*min(x2) 1.2*max(x2)])
title([wavename,' x[n] windowed using NFFT = ', num2Str(NFFT_1)])
ylabel('x[n]')
xlabel('n (samples)')
hold off;
subplot(3,1,2)
hold on;
%plot(abs(X_f))
% un windowed magnitude
stem(freq1, X1_mag, '.','r-','LineWidth',1.5);
% windowed magnitude
%stem(freq1, X1_mag,'r-');
grid on;
axis([0 fs/2 0 2.2*max(abs(X1_f))])
title(['Amplitude |X(f)| using NFFT = ', num2Str(NFFT_1)])
ylabel('|X(f)|')
xlabel('f (Hz)')
hold off;

subplot(3,1,3)
hold on;
plot(freq1,arg_X1,'r-');
stem(freq1,arg_X1,'.','r-');
stem(freq1,arg_X1);
grid on;
axis([0 fs/2 -pi pi])
title(['Phase of X(f) using NFFT = ', num2Str(NFFT_1)])
ylabel('Arg(H(f)) (rad)')
xlabel('Frequency (Hz)')
hold off;

61

Tim Perry
V00213455
%-------raise cosine windowed FFT size of 256----figure(2)
subplot(3,1,1)
hold on;
plot(nT(1:NFFT_2+1)*fs,x2(1:NFFT_2+1), 'LineWidth',0.1);
stem(nT(1:NFFT_2)*fs,x2(1:NFFT_2),'.','MarkerSize',13);
grid on;
axis([0 NFFT_2 1.2*min(x2) 1.2*max(x2)])
title([wavename,' wave x[n] sampled using NFFT = ', num2Str(NFFT_2)])
ylabel('x[n]')
xlabel('n (samples)')
hold off;
subplot(3,1,2)
hold on;
%plot(abs(X2_f),'r-');
plot(abs(X_f))
% un windowed magnitude
% windowed magnitude
stem(freq2, X2_mag, '.','r-','LineWidth',1.5);
grid on;
axis([0 fs/2 0 2.2*max(abs(X2_f))])
title(['Amplitude |X(f)| using NFFT = ', num2Str(NFFT_2)])
ylabel('|X(f)|')
xlabel('f (Hz)')
hold off;
subplot(3,1,3)
hold on;
plot(freq2,arg_X2,'r-');
stem(freq2,arg_X2,'.','r-');
grid on;
axis([0 fs/2 -pi pi])
title(['Phase of X(f) using NFFT = ', num2Str(NFFT_2)])
ylabel('Arg(H(f)) (rad)')
xlabel('Frequency (Hz)')
hold off;
%-------FFT size of 256----figure(3)
subplot(3,1,1)
hold on;
plot(nT(1:NFFT_2)*fs,xw(1:NFFT_2), 'b.');
plot(nT(1:NFFT_2)*fs,xw(1:NFFT_2),'LineWidth',0.1);
%stem(nT(1:NFFT_2)*fs,xw(1:NFFT_2),'.','MarkerSize',13);
grid on;
axis([0 NFFT_2 1.2*min(xw) 1.2*max(xw)])
title([wavename, ' wave x[n] Hann windowed using NFFT = ', num2Str(NFFT_2)])
ylabel('x[n]')
xlabel('n (samples)')
hold off;
subplot(3,1,2)
hold on;
%plot(abs(X_f))
% un windowed magnitude
stem(freq2, Xw_mag, '.','r-','LineWidth',1.5);
% windowed magnitude
grid on;
axis([0 fs/2 0 2.2*max(abs(Xw_f))])
title(['Amplitude |X_w(f)| using NFFT = ', num2Str(NFFT_2)])
ylabel('|X_w(f)|')
xlabel('f (Hz)')
hold off;

62

Tim Perry
V00213455

subplot(3,1,3)
hold on;
plot(freq2,arg_Xw,'r-');
stem(freq2,arg_Xw,'.','r-');
grid on;
axis([0 fs/2 -pi pi])
title(['Phase of X_w(f) using NFFT = ', num2Str(NFFT_2)])
ylabel('Arg(X_w_(f)) (rad)')
xlabel('Frequency (Hz)')
hold off;

%-----------------------------------------------------% Two sided power spectrum of signal (over 10 seconds)


%-----------------------------------------------------% t = 0:1/fs:10-1/fs;
% 10 sec sample
% x = cos(2*pi*f1*t);
% x0 = fftshift(x);
% circular shift (for zero centered spectrum)
% %freq = (0:Nfft-1)*(fs/Nfft);
% Frequency range
% f0 = (-NFFT_2/2:NFFT_2/2-1)*(fs/NFFT_2); % 0-centered frequency range
%
% M = NFFT_2
% Nfft = pow2(nextpow2(M)); % Transform length
% X0 = fft(x0,Nfft);
% DFT
% Xpower = X0.*conj(X0)/Nfft;
% Power of the DFT
%
% figure(4)
%
% subplot(2, 1, 1)
% plot(f0,Xpower)
% xlabel('Frequency (Hz)')
% ylabel('Power')
% title('{\bf Power Spectrum of cosine wave of over ten seconds}')

63

You might also like