Skip to content

Commit 91daef1

Browse files
authored
Merge pull request #22 from kuu8902/kkoiso/chapter04
4章を追加 koiso
2 parents 490bd88 + 54f359e commit 91daef1

File tree

10 files changed

+279
-0
lines changed

10 files changed

+279
-0
lines changed

kkoiso/chapter04/q01.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
4+
5+
def zero_padding(x, L, S):
6+
N = len(x)
7+
padding_size = L - S
8+
padded_x = np.concatenate(([0] * padding_size, x, [0] * padding_size))
9+
zero_add = S - (len(padded_x) % S) + (L - S)
10+
padded_x = np.concatenate((padded_x, [0] * zero_add))
11+
12+
return padded_x

kkoiso/chapter04/q02.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
from q01 import zero_padding
4+
5+
6+
def frame_split(x, L, S):
7+
padded_x = zero_padding(x, L, S)
8+
T = (len(padded_x) - L) // S + 1
9+
10+
frames = np.zeros((T, L))
11+
for t in range(T):
12+
frames[t] = padded_x[t * S : t * S + L]
13+
14+
return frames

kkoiso/chapter04/q03.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
from q02 import frame_split
4+
5+
6+
def stft(x, L, S, w):
7+
frames = frame_split(x, L, S)
8+
windowed_frames = frames * w
9+
stft_matrix = np.fft.rfft(windowed_frames, axis=1)
10+
11+
return stft_matrix

kkoiso/chapter04/q04.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
from q03 import stft
4+
5+
6+
fs = 16000
7+
f = 440
8+
a = 1.0
9+
t = np.arange(0, 0.1, 1 / fs)
10+
x = a * np.sin(2 * np.pi * f * t)
11+
12+
13+
L = 1000
14+
S = 500
15+
w = np.hamming(L)
16+
17+
stft_matrix = stft(x, L, S, w)
18+
19+
Amplitude_spectrogram = np.abs(stft_matrix)
20+
phase_spectrogram = np.angle(stft_matrix)
21+
22+
num_frames, num_freq_bins = Amplitude_spectrogram.shape
23+
time_axis = np.arange(num_frames) * (S / fs)
24+
freq_axis = np.linspace(0, fs / 2, num_freq_bins)
25+
plt.figure(figsize=(10, 8))
26+
27+
plt.subplot(2, 1, 1)
28+
plt.title("Ampliitude Spectrogram")
29+
plt.pcolormesh(time_axis, freq_axis, Amplitude_spectrogram.T)
30+
plt.ylabel("Frequency")
31+
plt.xlabel("Frame")
32+
33+
plt.subplot(2, 1, 2)
34+
plt.title("Phase Spectrogram")
35+
plt.pcolormesh(time_axis, freq_axis, phase_spectrogram.T)
36+
plt.ylabel("Frequency")
37+
plt.xlabel("Frame")
38+
39+
plt.tight_layout()
40+
plt.show()

kkoiso/chapter04/q05.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
4+
5+
import numpy as np
6+
7+
8+
def synthesis_window(w, S):
9+
L = len(w)
10+
Q = L // S
11+
w_s = np.zeros(L)
12+
13+
for l in range(L):
14+
sum_w = 0
15+
for m in range(-(Q - 1), Q):
16+
idx = l - m * S
17+
if 0 <= idx < L:
18+
sum_w += w[idx] ** 2
19+
if sum_w > 0:
20+
w_s[l] = w[l] / sum_w
21+
else:
22+
w_s[l] = 0
23+
24+
return w_s
25+
26+
27+
w = np.ones(6)
28+
print(synthesis_window(w, 2))

kkoiso/chapter04/q06.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
from q05 import synthesis_window
4+
5+
import numpy as np
6+
7+
8+
def istft(X, S, w):
9+
10+
F, T = X.shape
11+
N = 2 * (F - 1)
12+
M = S * (T - 1) + N
13+
14+
x_hat = np.zeros(M)
15+
w_s = synthesis_window(w, S)
16+
for t in range(T):
17+
z_t = np.fft.irfft(X[:, t], n=N)
18+
19+
for n in range(N):
20+
x_hat[t * S + n] += w_s[n] * z_t[n]
21+
22+
return x_hat

kkoiso/chapter04/q07.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
from q03 import stft
4+
from q06 import istft
5+
from q05 import synthesis_window
6+
7+
fs = 16000
8+
f = 440
9+
a = 1.0
10+
t = np.arange(0, 0.1, 1 / fs)
11+
x = a * np.sin(2 * np.pi * f * t)
12+
13+
14+
L = 1000
15+
S = 500
16+
w = np.hamming(L)
17+
w_s = synthesis_window(w, S)
18+
stft_matrix = stft(x, L, S, w).T
19+
x_reconstructed = istft(stft_matrix, S, w)
20+
plt.figure(figsize=(10, 4))
21+
22+
plt.subplot(2, 1, 1)
23+
plt.plot(x)
24+
plt.title("Original Signal")
25+
26+
plt.subplot(2, 1, 2)
27+
plt.plot(x_reconstructed)
28+
plt.title("Reconstructed Signal")
29+
plt.grid(True)
30+
plt.tight_layout()
31+
plt.show()

kkoiso/chapter04/q08.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
from q03 import stft
4+
5+
6+
def unity_synthesis_window(X, S):
7+
F, T = X.shape
8+
N = 2 * (F - 1)
9+
M = S * (T - 1) + N
10+
11+
x_hat = np.zeros(M)
12+
13+
for t in range(T):
14+
z_t = np.fft.irfft(X[:, t], n=N)
15+
16+
for n in range(N):
17+
x_hat[t * S + n] += z_t[n]
18+
19+
return x_hat
20+
21+
22+
fs = 16000
23+
f = 440
24+
a = 1.0
25+
t = np.arange(0, 0.1, 1 / fs)
26+
x = a * np.sin(2 * np.pi * f * t)
27+
28+
29+
L = 1000
30+
S = 500
31+
w = np.hamming(L)
32+
stft_matrix = stft(x, L, S, w).T
33+
34+
x_reconstructed_unity_ws = unity_synthesis_window(stft_matrix, S)
35+
36+
37+
plt.figure(figsize=(10, 4))
38+
39+
plt.subplot(2, 1, 1)
40+
plt.plot(x)
41+
plt.title("Original Signal")
42+
43+
plt.subplot(2, 1, 2)
44+
plt.plot(x_reconstructed_unity_ws)
45+
plt.title("Reconstructed Signal with Unity Synthesis Window")
46+
plt.grid(True)
47+
plt.tight_layout()
48+
plt.show()

kkoiso/chapter04/q09.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from scipy.signal import chirp
2+
import numpy as np
3+
import matplotlib.pyplot as plt
4+
from q03 import stft
5+
6+
fs = 16000
7+
t = np.linspace(0, 1, fs)
8+
chirp_signal = chirp(t, f0=100, f1=16000, t1=1, method="linear")
9+
10+
11+
params = [(100, 50), (200, 100), (400, 200), (800, 400)]
12+
13+
14+
plt.figure(figsize=(10, 8))
15+
for i, (L, S) in enumerate(params):
16+
w = np.hamming(L)
17+
stft_matrix = stft(chirp_signal, L, S, w)
18+
Amplitude_spectrogram = 2 * np.log(np.abs(stft_matrix))
19+
20+
plt.subplot(len(params), 1, i + 1)
21+
plt.pcolormesh(Amplitude_spectrogram.T)
22+
plt.title(f"Spectrogram Window Size {L} and Shift {S}")
23+
plt.ylabel("Frequency Bin")
24+
plt.xlabel("Frame")
25+
26+
plt.tight_layout()
27+
plt.show()

kkoiso/chapter04/q10.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
from q03 import stft
4+
5+
6+
def convert(spectrogram, fs, S):
7+
num_frames, num_freq_bins = spectrogram.shape
8+
time_axis = np.arange(num_frames) * (S / fs)
9+
freq_axis = np.linspace(0, fs / 2, num_freq_bins)
10+
return time_axis, freq_axis
11+
12+
13+
fs = 16000
14+
f = 440
15+
a = 1.0
16+
t = np.arange(0, 0.1, 1 / fs)
17+
x = a * np.sin(2 * np.pi * f * t)
18+
19+
20+
L = 1000
21+
S = 500
22+
w = np.hamming(L)
23+
24+
stft_matrix = stft(x, L, S, w)
25+
26+
Amplitude_spectrogram = np.abs(stft_matrix)
27+
phase_spectrogram = np.angle(stft_matrix)
28+
29+
time_axis, freq_axis = convert(Amplitude_spectrogram, fs, S)
30+
31+
plt.figure(figsize=(10, 8))
32+
33+
plt.subplot(2, 1, 1)
34+
plt.title("Ampliitude Spectrogram")
35+
plt.pcolormesh(time_axis, freq_axis, Amplitude_spectrogram.T)
36+
plt.ylabel("Frequency")
37+
plt.xlabel("Frame")
38+
39+
plt.subplot(2, 1, 2)
40+
plt.title("Phase Spectrogram")
41+
plt.pcolormesh(time_axis, freq_axis, phase_spectrogram.T)
42+
plt.ylabel("Frequency")
43+
plt.xlabel("Frame")
44+
45+
plt.tight_layout()
46+
plt.show()

0 commit comments

Comments
 (0)