# DSP Lab – Week 1

### Constructing the Complex Plane

Suppose we have a sampled signal defined by the sequence $h(n)$, $n=0,1,2,...,N-1$

Its Z- transform is given by $H(z) = sum_{n=0}^{N-1} h(n)z^{-n}$ .

It maps the original sequence into a new domain, which is the complex plane $z=e^{sT}$ where $s=sigma+jomega$ is the parameter in the Laplace domain and $T$ is the sampling period.

The $jomega$ axis in the $s$-plane maps onto the unit circle with centre at the origin in the $z$-plane. So the value of $H(z)$ at different points on the unit circle actually gives the contribution of the frequency component given by $angle z$, in the original signal.

This, in effect, gives the Discrete Fourier Transform of the sequence. Consider the following example:

```%original sequence
h = [1,2,3,4];

%number of chosen points on the unit circle
N = 64;

%define the chosen points
z = complex(cos(2*pi/N*(0:N-1)),sin(2*pi/N*(0:N-1)));

%evaluate H(z) at each point
for i = 1:N
H(i) = 1+2*z(i)^-1+3*z(i)^-2+4*z(i)^-3;
end

%plot the unit circle
plot(z)

%plot the value of H(z) along the unit circle
figure
plot(abs(H))

%plot the N-point DFT of h(n)
figure
plot(abs(fft(h,64)))
```

This example computes the value of $H(z)$ at 64 uniformly spaced points on the unit circle and compares it with the 64 point DFT. We can see that both (fig. b & c) are identical.

# Digital Signal Processing Lab

We are very lucky to have Abhilash sir in charge of DSP lab this semester. I really used to enjoy his classes during the Signals and Systems course in the third semester. In fact it’s the only course so far, in which I’ve felt like paying attention. I think I will document whatever we do in the lab, on my blog, when I get time.

# FFT with Phoenix

A companion analog box for Phoenix, is being developed here at IAUC, with which you can study AM, FM etc. It’s still in the process of development, but I had observed AM and FM signals generated by it, and studied their frequency spectra using the fft() in SciPy. We felt that it would be convenient to add these functions to the Python library of Phoenix, as given below. You can use these functions by adding this code segment to the file /usr/lib/python2.4/site-packages/phm.py

But since this bit of code has not really been tested, it’s better to avoid mixing these functions with the original phm.py . Instead, you can save this file to your home directory, and import it along with phm. It can be used just like phm, and you can initialize an object by typing “s=phsig.phsig()”.

```    def fft(self, data):
"""
Returns the Fourier transform of the signal represented by the samples
in 'data' which is obtained by a read_block() call.
Usage example:
x = p.read_block(200,10,1)
y = p.fft(x)
"""
from scipy import fft
np = len(data)
delay = data[1][0] - data[0][0]

v = []
for i in range(np):
v.append(data[i][1])

ft = fft(v)

#corrections in the frequency axis
fmax = 1/(delay*1.0e-6)
incf = fmax/np
freq = []
for i in range(np/2):
freq.append(i*incf - fmax/2)
for i in range(np/2,np):
freq.append((i-np/2)*incf)

ft_freq = []

for i in range(np/2):
x = [freq[i], abs(ft[i+np/2])/np]
ft_freq.append(x)

for i in range(np/2,np):
x = [freq[i], abs(ft[i-np/2])/np]
ft_freq.append(x)
return ft_freq

def plot_fft(self, data):
"""
Plots the Fourier transform of the signal represented by the samples in
'data'. Calls self.fft() for obtaining the Fourier Transform
Usage example:
x = p.read_block(200,10,1)
p.plot_fft(x)
"""
ft_freq = self.fft(data)
np = len(data)
delay = data[1][0] - data[0][0]
fmax = 1/(delay*1.0e-6)

y = 0.0
for i in range(np):
if ft_freq[i][1] > y:
y = ft_freq[i][1]

if self.root == None:
self.window(400,300,None)
self.remove_lines()
self.set_scale(-fmax/2, 0, fmax/2, y*1.1)
self.line(ft_freq)

def freq_comp(self, data):
"""
Returns and displays the frequency components with the greatest
spectral density. Calls self.fft() for obtaining the Fourier transform
Usage example:
x = p.read_block(200,10,1)
p.freq_comp(x)    #Only prints the components
y = p.freq_comp(x) #Prints and stores the components in a variable
#as an array of [strength, component]
"""
ft_freq = self.fft(data)
np = len(data)
delay = data[1][0] - data[0][0]

peaks = []
for n in range(1,np-1):
a = ft_freq[n-1][1]
b = ft_freq[n][1]
c = ft_freq[n+1][1]
if (b>50) & (b>a) & (b>c):
peaks.append([ft_freq[n][1],ft_freq[n][0]])

peaks.sort()
peaks.reverse()
print 'Dominant frequency components are:'
for i in range(len(peaks)):
print '%6.3f Hz, %5.3f mV'%(peaks[i][1],peaks[i][0])
return peaks```