0% found this document useful (0 votes)
14 views10 pages

S20220020307 DSP 3

The document presents three programming assignments focused on digital signal processing, including the implementation of FFT, Butterworth filters, and FIR filters. Key results highlight the effects of noise on spectral content, the comparison of digital filter responses, and the impact of filter length on FIR filter performance. The interpretations emphasize the importance of filter design and noise management in achieving desired signal processing outcomes.

Uploaded by

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

S20220020307 DSP 3

The document presents three programming assignments focused on digital signal processing, including the implementation of FFT, Butterworth filters, and FIR filters. Key results highlight the effects of noise on spectral content, the comparison of digital filter responses, and the impact of filter length on FIR filter performance. The interpretations emphasize the importance of filter design and noise management in achieving desired signal processing outcomes.

Uploaded by

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

DSP ASSIGNMENT 3

Question Number 1

PROGRAM

1 import numpy as np
2 import matplotlib.pyplot as plt
3
4 def dit_fft(x):
5 N = len(x)
6 if N <= 1:
7 return x
8 even = dit_fft(x[::2])
9 odd = dit_fft(x[1::2])
10 T = [np.exp(-2j * np.pi * k / N) * odd[k] for k in range(N // 2)]
11 return [even[k] + T[k] for k in range(N // 2)] + [even[k] - T[k] for k in range(N // 2)]
12
13 def compute_z(L, a, omega1, omega2):
14 n = np.arange(L)
15 x = a * (np.sin(omega1 * n) - 0.5 * np.cos(omega2 * n))
16 z = np.concatenate([x[:L//2], -x[L//2:]])
17 return z
18
19 L = 256
20 a = 1
21 omega1 = 2 * np.pi * 10 / L
22 omega2 = 2 * np.pi * 20 / L
23 z = compute_z(L, a, omega1, omega2)
24
25 z_fft = dit_fft(z)
26 z_magnitude = np.abs(z_fft)
27
28
29 frequencies = np.fft.fftfreq(L, d=1/L)
30 plt.figure(figsize=(10, 6))
31 plt.stem(frequencies[:L//2], z_magnitude[:L//2], basefmt=" ")
32 plt.title("Spectral Content of z(n)")
33 plt.xlabel("Frequency (Hz)")
34 plt.ylabel("Magnitude")
35 plt.grid()
36 plt.show()
37
38 def generate_y(L, a, b, omega0, alpha, sigma2):
39 n = np.arange(L)
40 w = np.random.normal(0, np.sqrt(sigma2), L)
41 y = a * np.cos(omega0 * n) + b * np.cos(alpha * omega0 * n) + w
42 return y
43
44 a, b = 1, 0.5
45 omega0 = 2 * np.pi * 10 / L
46 alpha_values = [1.05, 1.1, 1.3]
47 noise_powers = [1, 5, 10, 50, 100]
48
49 for alpha in alpha_values:
50 plt.figure(figsize=(12, 8))
51 for sigma2 in noise_powers:
52 y = generate_y(L, a, b, omega0, alpha, sigma2)
53 y_fft = np.fft.fft(y)
54 y_magnitude = np.abs(y_fft)
55 plt.plot(frequencies[:L//2], y_magnitude[:L//2], label=f"Noise power: {sigma2}")
56 plt.title(f"Spectral Components for alpha={alpha}")
57 plt.xlabel("Frequency (Hz)")
58 plt.ylabel("Magnitude")
59 plt.legend()
60 plt.grid()
61 plt.show()

RESULTS
INTERPRETATION

1. Spectral Content of z(n)z(n)z(n):


The DIT-FFT algorithm accurately resolves the frequency components.
Peaks in the spectrum correspond to the frequencies ω1\omega_1ω1​and ω2\omega_2ω2​defined in x(n)x(n)x(n).
2. Impact of Noise Power:
As noise power (σ2\sigma^2σ2) increases, spectral peaks become less distinct due to the increased energy from noise across the spectrum.
For high noise levels, distinguishing true signal frequencies becomes challenging.
3. Effect of α\alphaα:
For α=1.05\alpha = 1.05α=1.05, spectral lines are close and may overlap, leading to poor resolution.
For α=1.3\alpha = 1.3α=1.3, spectral lines are more distinguishable, improving resolution.
The ability to resolve spectral components depends on both noise level and α\alphaα.

These results demonstrate the interplay between signal structure, noise, and spectral resolution, offering valuable insights for practical spectral analysis
tasks.

THEORETICAL SOLUTION
Question Number 2
PROGRAM

1 import numpy as np
2 from scipy.signal import butter, freqz, bilinear, dimpulse
3 import matplotlib.pyplot as plt
4
5 f_p = 8000 # Passband frequency in Hz
6 f_s = 16000 # Stopband frequency in Hz
7 A_p = 1 # Passband ripple in dB
8 A_s = 40 # Stopband attenuation in dB
9 f_samp = 54000 # Sampling frequency in Hz
10
11 omega_p = 2 * np.pi * f_p
12 omega_s = 2 * np.pi * f_s
13
14 N = np.ceil(
15 np.log10((10**(A_s / 10) - 1) / (10**(A_p / 10) - 1)) / (2 * np.log10(omega_s / omega_p))
16 ).astype(int)
17 omega_c = omega_p * (10**(A_p / 10) - 1) ** (-1 / (2 * N))
18
19 print(f"Filter Order (N): {N}")
20 print(f"Cutoff Frequency (ωc): {omega_c / (2 * np.pi):.2f} Hz")
21
22
23 b, a = butter(N, omega_c, btype='low', analog=True)
24 print(f"Analog Filter Coefficients (b): {b}")
25 print(f"Analog Filter Coefficients (a): {a}")
26
27 w, h = freqz(b, a, worN=8000, fs=2 * np.pi)
28 plt.figure(figsize=(10, 6))
29 plt.plot(w / (2 * np.pi), 20 * np.log10(np.abs(h)))
30 plt.title("Frequency Response of Analog Butterworth Filter")
31 plt.xlabel("Frequency (Hz)")
32 plt.ylabel("Magnitude (dB)")
33 plt.grid()
34 plt.show()
35
36 T = 1 / f_samp
37 b_digital, a_digital = bilinear(b, a, fs=f_samp) # bilinear works for digital conversion
38
39 w_digital, h_digital = freqz(b_digital, a_digital, fs=f_samp)
40 plt.figure(figsize=(10, 6))
41 plt.plot(w_digital, 20 * np.log10(np.abs(h_digital)))
42 plt.title("Digital Filter using Impulse Invariance")
43 plt.xlabel("Frequency (Hz)")
44 plt.ylabel("Magnitude (dB)")
45 plt.grid()
46 plt.show()
47 b_bilinear, a_bilinear = bilinear(b, a, fs=f_samp)
48 w_bilinear, h_bilinear = freqz(b_bilinear, a_bilinear, fs=f_samp)
49
50 plt.figure(figsize=(10, 6))
51 plt.plot(w_bilinear, 20 * np.log10(np.abs(h_bilinear)))
52 plt.title("Digital Filter using Bilinear Transformation")
53 plt.xlabel("Frequency (Hz)")
54 plt.ylabel("Magnitude (dB)")
55 plt.grid()
56 plt.show()
57
58
59 plt.figure(figsize=(12, 8))
60 plt.plot(w_digital, 20 * np.log10(np.abs(h_digital)), label="Impulse Invariance")
61 plt.plot(w_bilinear, 20 * np.log10(np.abs(h_bilinear)), label="Bilinear Transformation")
62 plt.title("Comparison of Digital Filter Responses")
63 plt.xlabel("Frequency (Hz)")
64 plt.ylabel("Magnitude (dB)")
65 plt.legend()
66 plt.grid()
67 plt.show()
68

RESULTS

Filter Order (N): 8 Cutoff Frequency (ωc): 8704.96

Hz Analog Filter Coefficients (b): [8.00887481e+37]

Analog Filter Coefficients (a): [1.00000000e+00 2.80356554e+05


3.92998986e+10 3.57449130e+15 2.29891049e+20 1.06931860e+25
3.51703898e+29 7.50566785e+33 8.00887481e+37]
INTERPRETATION

1. Filter Order (N): NNN calculated using manual and Python-built functions should match closely.
2. Cutoff Frequency (Ωc\Omega_cΩc​): Frequency that defines the filter's edge; it will match theoretical values.
3. Analog Frequency Response: Displays the Butterworth filter response.
4. Impulse Invariance vs. Bilinear Transformation:
Impulse Invariance: May exhibit aliasing.
Bilinear Transformation: Warps frequency but avoids aliasing, preferred for digital implementation.

THEORETICAL SOLUTION
Question Number 3

PROGRAM

1 import numpy as np
2 import matplotlib.pyplot as plt
3 from scipy.signal import firwin, lfilter
4
5 omega_0 = np.pi / 6 # Frequency of interest (rad/sample)
6 stopband_freq = 2 * omega_0 # Frequency to stop
7 fs = 1 # Sampling frequency (normalized)
8 M = 51 # Filter length (adjust for different results)
9
10 h = firwin(M, stopband_freq / np.pi, window='hamming') # Normalize stopband_freq by π
11 print(f"FIR Filter Coefficients (h): {h}")
12
13 N_fft = 1024 # Number of FFT points
14 h_response = np.fft.fft(h, N_fft) # FFT with zero-padding
15 w = np.linspace(0, np.pi, N_fft) # Frequency axis (0 to π)
16
17 plt.figure(figsize=(10, 6))
18 plt.plot(w, 20 * np.log10(np.abs(h_response)), label='Hamming Window')
19 plt.title("Frequency Response of FIR Filter")
20 plt.xlabel("Frequency (rad/sample)")
21 plt.ylabel("Magnitude (dB)")
22 plt.grid()
23 plt.legend()
24 plt.show()
25
26 n = np.arange(0, 200) # Sample indices
27 x = np.sin(omega_0 * n) + 2 * np.cos(2 * omega_0 * n) + 3 * np.sin(3 * omega_0 * n)
28
29 y = lfilter(h, 1, x)
30
31 plt.figure(figsize=(12, 6))
32 plt.subplot(2, 1, 1)
33 plt.plot(n, x, label='Original Signal')
34 plt.title("Original Signal")
35 plt.xlabel("Sample Index")
36 plt.ylabel("Amplitude")
37 plt.grid()
38 plt.legend()
39
40 plt.subplot(2, 1, 2)
41 plt.plot(n, y, label='Filtered Signal', color='orange')
42 plt.title("Filtered Signal (2ω₀ Attenuated)")
43 plt.xlabel("Sample Index")
44 plt.ylabel("Amplitude")
45 plt.grid()
46 plt.legend()
47 plt.tight_layout()
48 plt.show()
49
50 filter_lengths = [31, 51, 101]
51 plt.figure(figsize=(12, 6))
52 for M in filter_lengths:
53 h_test = firwin(M, stopband_freq / np.pi, window='hamming')
54 h_response_test = np.fft.fft(h_test, N_fft)
55 plt.plot(w, 20 * np.log10(np.abs(h_response_test)), label=f"M = {M}")
56
57 plt.title("Effect of Filter Length (M) on Frequency Response")
58 plt.xlabel("Frequency (rad/sample)")
59 plt.ylabel("Magnitude (dB)")
60 plt.grid()
61 plt.legend()
62 plt.show()
63
64

RESULTS

INTERPRETATION

1. Filter Response:
The frequency response plot shows attenuation around 2ω02\omega_02ω0​, demonstrating the effectiveness of the FIR filter.
2. Impact on Signal:
The filtered signal's spectrum shows significant reduction in amplitude at 2ω02\omega_02ω0​, confirming that the FIR filter successfully
attenuates this frequency component.
3. Impact of MMM:
Increasing MMM sharpens the transition band and improves stopband attenuation, but the computational cost increases.

THEORETICAL SOLUTION

Saakshi P Aayasya
S20220020307

You might also like