diff --git a/ttakahashi/chapter04/q01.py b/ttakahashi/chapter04/q01.py new file mode 100644 index 0000000..110b191 --- /dev/null +++ b/ttakahashi/chapter04/q01.py @@ -0,0 +1,26 @@ +import numpy as np + + +def pad(x, L, S): + x_pad = np.pad(x, [L - S, L - S]) + re = np.mod(x_pad.size, S) + if re != 0: + x_pad = np.pad(x_pad, [0, S - re]) + return x_pad + + +def main(): + L = 4 + S = 3 + + x = np.ones(8) + x_pad = pad(x, L, S) + + print(f"x: {x}") + print(f"x_pad: {x_pad}") + + +if __name__ == "__main__": + main() + + print("Finished") diff --git a/ttakahashi/chapter04/q02.py b/ttakahashi/chapter04/q02.py new file mode 100644 index 0000000..e2c8f79 --- /dev/null +++ b/ttakahashi/chapter04/q02.py @@ -0,0 +1,29 @@ +import numpy as np +from q01 import pad + + +def frame_div(x, L, S): + x_pad = pad(x, L, S) + T = int(np.floor((x_pad.size - L) / S)) + 1 + x_t = np.array([x_pad[t * S : t * S + L] for t in range(T)]) + return x_t + + +def main(): + L = 4 + S = 3 + + x = np.ones(8) + x_pad = pad(x, L, S) + x_t = frame_div(x, L, S) + + print(f"x: {x}") + print(f"x_pad: {x_pad}") + print(f"x_t: {x_t}") + print(f"x_t.shape: {x_t.shape}") + + +if __name__ == "__main__": + main() + + print("Finished") diff --git a/ttakahashi/chapter04/q03.py b/ttakahashi/chapter04/q03.py new file mode 100644 index 0000000..9c3c494 --- /dev/null +++ b/ttakahashi/chapter04/q03.py @@ -0,0 +1,34 @@ +import numpy as np +from q01 import pad +from q02 import frame_div + + +def stft(x, L, S, wnd): + x_t = frame_div(x, L, S) + T = len(x_t) + X = np.array([np.fft.rfft(x_t[t] * wnd) for t in range(T)], dtype="complex") + return X.T + + +def main(): + L = 4 + S = 3 + + x = np.ones(8) + wnd = np.hamming(L) + x_pad = pad(x, L, S) + x_t = frame_div(x, L, S) + x_stft = stft(x, L, S, wnd) + + print(f"x: {x}") + print(f"x_pad: {x_pad}") + print(f"x_t: {x_t}") + print(f"x_t.shape: {x_t.shape}") + print(f"x_stft: {x_stft}") + print(f"x_stft.shape: {x_stft.shape}") + + +if __name__ == "__main__": + main() + + print("Finished") diff --git a/ttakahashi/chapter04/q04.py b/ttakahashi/chapter04/q04.py new file mode 100644 index 0000000..83ed920 --- /dev/null +++ b/ttakahashi/chapter04/q04.py @@ -0,0 +1,80 @@ +from pathlib import Path +from typing import Union +import numpy as np +import matplotlib.pyplot as plt +from q03 import stft + + +config = { + "figure.subplot.bottom": 0.15, + "figure.subplot.left": 0.15, + "figure.figsize": [10, 8], + "font.size": 24, + "font.family": "Times New Roman", + "mathtext.fontset": "cm", + "pdf.fonttype": 42, + "legend.borderaxespad": 1, + "lines.linewidth": 2, + "savefig.transparent": True, +} + + +LABELS = { + 0: ("viridis", "Power spectrogram"), + 1: ("viridis", "Phase spectrogram"), + 2: (plt.cm.Reds, "Cosine of phase spectrogram"), + 3: (plt.cm.Blues, "Sine of hase spectrogram"), +} + + +def main(output_dir: Union[Path, str]): + out_p = Path(output_dir) + + A = 1 # amplitude + f = 440 # frequency (Hz) + sec = 0.1 # time (sec) + sr = 16000 # sampling rate (Hz) + + t = np.arange(sec * sr) / sr + y = A * np.sin(2 * np.pi * f * t) + + L = 1000 + S = 500 + wnd = np.hamming(L) + y_stft = stft(y, L, S, wnd) + + print(f"y_stft.shape: {y_stft.shape}") + + spec = [np.abs(y_stft), np.angle(y_stft), np.cos(np.angle(y_stft)), np.sin(np.angle(y_stft))] + + plt.rcParams.update(config) + fig, ax = plt.subplots(4, 1) + for i in range(len(spec)): + # ax[i].pcolormesh(spec[i]) + ax[i].imshow( + spec[i], + cmap=LABELS[i][0], + interpolation="nearest", + aspect="auto", + origin="lower", + extent=[0, y_stft.shape[1], 0, y_stft.shape[0]], + ) + ax[i].set_title(LABELS[i][1]) + ax[i].set_rasterized(True) + fig.supxlabel("Frame") + fig.supylabel("Frequency (Hz)") + plt.tight_layout() + fig.subplots_adjust(left=0.13, right=1 - 0.13, bottom=0.11, top=1 - 0.11, hspace=0.8) + plt.savefig(out_p / "04.pdf", dpi=300) + plt.clf() + plt.close() + + +if __name__ == "__main__": + out_p = Path.cwd() / "outputs" + if not out_p.exists(): + out_p.mkdir(parents=True) + + main(out_p) + + print("Finished") diff --git a/ttakahashi/chapter04/q05.py b/ttakahashi/chapter04/q05.py new file mode 100644 index 0000000..44cc5cf --- /dev/null +++ b/ttakahashi/chapter04/q05.py @@ -0,0 +1,62 @@ +from pathlib import Path +from typing import Union +import numpy as np +import matplotlib.pyplot as plt + + +config = { + "figure.subplot.bottom": 0.15, + "figure.subplot.left": 0.15, + "figure.figsize": [10, 8], + "font.size": 24, + "font.family": "Times New Roman", + "mathtext.fontset": "cm", + "pdf.fonttype": 42, + "legend.borderaxespad": 1, + "lines.linewidth": 2, + "savefig.transparent": True, +} + + +def comp_wnd(wnd, S): + L = wnd.size + Q = int(np.floor(L / S)) + cwnd = np.empty(L, dtype=np.float64) + for i in range(L): + k = i - (Q - 1) * S + if k < 0: + k = 0 + cwnd[i] = wnd[i] / np.sum(wnd[k : i + (Q - 1) * S] ** 2) + return cwnd + + +def main(output_dir: Union[Path, str]): + out_p = Path(output_dir) + + L = 1000 + S = 500 + wnd = np.hamming(L) + cwnd = comp_wnd(wnd, S) + + plt.rcParams.update(config) + fig, ax = plt.subplots(2, 1) + ax[0].plot(wnd) + ax[0].grid() + ax[0].set_title("Hamming window") + ax[1].plot(cwnd) + ax[1].set_title("Composite window") + ax[1].grid() + plt.tight_layout() + plt.savefig(out_p / "05.pdf") + plt.clf() + plt.close() + + +if __name__ == "__main__": + out_p = Path.cwd() / "outputs" + if not out_p.exists(): + out_p.mkdir(parents=True) + + main(out_p) + + print("Finished")