Professional Documents
Culture Documents
Assignment 5:
Prepared for:
Dr. Peter Driessen
ELEC 484
University of Victoria
Prepared by:
Tim I. Perry
V00213455
June, 2009
Tim Perry
V00213455
CONTENTS
1. 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
2. FAST FOURIER TRANSFORM ....................................................................................................... 29
REFERENCES ........................................................................................................................................... 38
APPENDIX A ............................................................................................................................................. 39
1
Tim Perry
V00213455
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.
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:
2
Tim Perry
V00213455
(1)
= (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.
3
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.
4
Tim Perry
V00213455
= {{ { (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.
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.
5
Tim Perry
V00213455
= y = ifft(fft(h).*fft(x)
Manual DFTs Matlab FFT function
n h(n) x(n) = = =
0 0 0 240 240 240
1 15 0 165 165 165
2 15 0 105 105 105
3 15 0 60 60 60
4 15 1 30 30 30
5 10 2 25 25 25
6 10 3 45 45 45
7 10 4 90 90 90
8 0 5 150 150 150
9 0 6 220 220 220
10 0 7 300 300 300
11 0 8 390 390 390
12 0 9 480 480 480
13 0 10 570 570 570
14 0 11 660 660 660
15 0 12 750 750 750
16 0 13 840 840 840
17 0 14 930 930 930
18 0 13 1020 1020 1020
19 0 12 1080 1080 1080
20 0 11 1110 1110 1110
21 0 10 1110 1110 1110
22 0 9 1080 1080 1080
23 0 8 1030 1030 1030
24 0 7 960 960 960
25 0 6 870 870 870
26 0 5 780 780 780
24 0 4 690 690 690
28 0 3 600 600 600
29 0 2 510 510 510
30 0 1 420 420 420
31 0 0 330 330 330
6
Tim Perry
V00213455
= y = ifft(fft(h).*fft(x)
Manual DFTs Matlab FFT function
n h(n) x(n) = = =
0 0 0 160 160 160
1 15 0 120 120 120
2 15 0 80 80 80
3 10 0 50 50 50
4 10 2 30 30 30
5 10 4 45 45 45
6 5 6 95 95 95
7 5 8 170 170 170
8 5 10 270 270 270
9 5 12 390 390 390
10 0 14 520 520 520
11 0 12 660 660 660
12 0 10 750 750 750
13 0 8 790 790 790
14 0 6 790 790 790
15 0 4 750 750 750
16 0 2 670 670 670
17 0 0 570 570 570
18 0 0 450 450 450
19 0 1 340 340 340
20 0 2 255 255 255
21 0 3 205 205 205
22 0 4 185 185 185
23 0 5 195 195 195
24 0 6 225 225 225
25 0 6 270 270 270
26 0 5 300 300 300
24 0 4 315 315 315
28 0 3 315 315 315
29 0 2 295 295 295
30 0 1 255 255 255
31 0 0 205 205 205
7
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.
8
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.
9
Tim Perry
V00213455
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.
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.
Figure 10: Time domain results of acyclic convolution performed in the frequency domain using a zero
padded cyclic convolution.
11
Tim Perry
V00213455
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 (2N-
point 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
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
0.8 -50
Magnitude (dB)
-100
Amplitude
0.6
-150
0.4 -200
-250
0.2
-300
0 -350
1 2 3 4 5 6 7 8 0 0.2 0.4 0.6 0.8
Samples 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:
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
%---------------------------------------------------------------------
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.
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.
%----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 overlap-
add using a hop size Ra = M= 8.
0
0.8
Magnitude (dB)
-100
Amplitude
0.6
-200
0.4
0.2 -300
0 -400
500 1000 1500 2000 0 0.2 0.4 0.6 0.8
Samples 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:
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_1c-
CyclicWinOA.wav.
22
Tim Perry
V00213455
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 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
24
Tim Perry
V00213455
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.
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
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 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.
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
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:
2) The standard centered Hann window, which is centered on the FFT frame, was specified as:
32
Tim Perry
V00213455
0.8 -50
Magnitude (dB)
-100
Amplitude
0.6
-150
0.4 -200
-250
0.2
-300
0 -350
50 100 150 200 250 0 0.2 0.4 0.6 0.8
Samples 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).
33
Tim Perry
V00213455
0
0.8
Magnitude (dB)
-50
Amplitude
0.6
-100
0.4
0.2 -150
0 -200
50 100 150 200 250 0 0.2 0.4 0.6 0.8
Samples Normalized Frequency ( rad/sample)
Figure 35: Raised Cosine Window for NFFT = 256 if a centered Hann window is used (centered about the
FFT frame).
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.
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
[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
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)
%------------------------------------------------------------
% Cyclic Convolution (Time Domain)
%------------------------------------------------------------
%-----------------------------------------------------------
% 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
%----------------------------------------------------------------
% Cyclic Convolution (Frequency Domain) using Matlab FFT routine
%----------------------------------------------------------------
y3 = ifft(fft(x).*fft(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)
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]')
40
Tim Perry
V00213455
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);
Nx = length(x)
Nh = length(h)
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
%-----------------------------------------------------------
% 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)
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
%wavplay(x1, fs);
%wavplay(h1, fs);
wavplay(y, fs); %play processed output
43
Tim Perry
V00213455
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)
%------------------------------------------------------------
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
%----------------------------------------------------------------
44
Tim Perry
V00213455
%------------------------------------------------------------
% 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)
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]')
45
Tim Perry
V00213455
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);
46
Tim Perry
V00213455
%----------------------------------------------------------------
% Acyclic Convolution (Frequency Domain)
%----------------------------------------------------------------
NFFT = 2^nextpow2(2*N - 1); % size of FFT
%------------------------------------------------------------
% 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)
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
%wavplay(x1, fs);
%wavplay(h1, fs);
wavplay(y, fs); %play processed output
47
Tim Perry
V00213455
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)
%----------------------------------------------------------------------
% 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;
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)
%=======================================================================
% 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
%----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)];
50
Tim Perry
V00213455
%----------------------------------------------
% 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);
51
Tim Perry
V00213455
%----------------------------------------------------------------------
% Parameters for Cyclic conv with raised cosine windows and circular shift
%----------------------------------------------------------------------
N = Nx; % Set Nx to be the signal length
M = 2048 % Window length
%NFFT = 2^nextpow2(M + Nh - 1);
NFFT = N; % size of FFT
%M = NFFT-Nh+1 % optimized window length
Ra = M; % hop size
Nframes = 1+floor((N-M)/Ra); % # of full blocks to convolve
NsigOut = N % for cyclic, output same length as inputs
%=======================================================================
% Cyclic Conv with raised cosine windows and overlap-add (Freq Domain)
%=======================================================================
%----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 clipping
y = y*0.8; % bring level down further
%wavplay(x1, fs);
%wavplay(h1, fs);
wavplay(y, fs); % play processed output
53
Tim Perry
V00213455
%------------------------------------------------------------
% 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)
%----------------------------------------------------------------------
% Parameters for Acyclic conv with rectangular windows and overlap-add
%----------------------------------------------------------------------
M = 8 % Window length
%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
% 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); % allocate memory for products of all inputs terms
% ym1 = zeros(1,Nconv); % 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
% end
%===============================================================
% 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
figure(5)
%----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)];
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;
title('h[n] (filter)')
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]')
56
Tim Perry
V00213455
%----------------------------------------------
% 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);
57
Tim Perry
V00213455
%----------------------------------------------------------------------
% Parameters for Acyclic conv with rectangular windows and overlap-add
%----------------------------------------------------------------------
N = Nx; % Set Nx to be the signal length
L = Nh; % Set Nh to be the filter length
M = 2048 % Window length
NFFT = 2^nextpow2(M + Nh + - 1);
%NFFT = Nh+M; % size of FFT
%M = NFFT-Nh+1 % optimized window length
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 (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
%----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
%------------------------------------------------------------
% 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 clipping
y = y*0.8; % bring level down further
%wavplay(x1, fs);
%wavplay(h1, fs);
wavplay(y, fs); % play processed output
59
Tim Perry
V00213455
nT_1 = (0:NFFT_1-1)*Ts;
nT_2 = (0:NFFT_2-1)*Ts;
nT = (0:fs-1)*Ts; % time vector
t = (0:1:1000);
%-----------------------------------------------------------
% 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);
%---------------------------------------------------------------
% 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])
%---------------------------------------------------------------
% 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
%=========================================
% Freq Response Plots
%=========================================
freq1 = linspace(0,1,1 + NFFT_1/2).*(fs/2);
freq2 = linspace(0,1,1 + NFFT_2/2).*(fs/2);
% 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
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
stem(freq2, X2_mag, '.','r-','LineWidth',1.5); % windowed magnitude
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;
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