python으로 소리 처리 ~ 부립엽 레벨로 펼쳐진 톱니파 ~

개시하다


부립엽 급수 전개는sin과cos의 조합으로 어떤 주기를 가진 파형을 나타내는 것을 가리킨다
이로써 어떤 신호에 주파수가 다른 in파와cos파가 각각 얼마나 많은 성분을 함유하고 있는지 알 수 있다.
실제 예로 특정 주파수의 소리를 절단하고 이미지를 압축하는 데 쓰인다.
이번에 이 기술을 사용해서 피코피코음이라 불리는 톱니파의 음파를 만들어 보자

부립엽 레벨 전개


부립엽 급수가 전개될 때sin과cos로 어떤 주기 신호 f(t)를 표시한다.각주파수ω, sin과cos의 진폭은 각각 a, b이며, c로 편이되면 다음과 같은 표현방식으로
 f(x) = \sum_{n = 1}^\infty (a_n \sin n\omega t + b_n \cos n\omega t) + c
부립엽 급수를 전개하려면 각 각 각 주파수의 진폭과 편이량을 구할 수 있다

오프셋 구하기


sin,cos의 각 주파수가 어떤 값이든 주기 T포인트를 사용하면 0이다
따라서 f(t)의 주기적분 후의 값을 너비 T, 높이 c의 직사각형 면적으로 한다
상기 요구 c 다음 용도에 사용
\int_{0}^T f(t)  dt = T \times c \Leftrightarrow c = \frac{1}{T} \int_0 ^T f(t)  dt 

각주파수 nωt처sin의 진폭을 구하다


삼각함수의 정교성보다 신호 f(t)에 진폭을 가하여 1에서 꺼낸 각주파수의 물건으로 포인트를 얻으려면 꺼낸 파 이외의 파의 면적이 0이 된다
자세히 알고 싶은 사람은 그림이 섞여 있어서 알기 쉽게 쓰여져 있으니 참조이 책.
또한 추출한 파의 성분의 면적은 진폭 xT/2이기 때문에 진폭의 값을 구할 수 있다
 \int_{0}^T f(t) \sin n\omega t  dt = \frac{a_nT}{2} \Leftrightarrow a_n = \frac{2}{T} \int_0 ^T f(t) \sin n\omega t  dt 

각주파수 nωt부위cos의 진폭 구하기


cos도sin과 같이 계산할 수 있기 때문에 다음과 같다
b_n = \frac{2}{T} \int_0 ^T f(t) \cos n\omega t  dt

톱날의 치파를 푸리엽 급수로 전개하다


톱날의 치파는 $f(t)=\rac{A}t\,(0\leqt각 계수에 관하여 계산은 아래와 같다
\begin{align}
c &=\frac{1}{T} \int_0 ^T f(t)  dt =\frac{1}{T} \int_0 ^T \frac{A}{T} t \,dt \\
  &=\frac{A}{T^2} \Big[t^2\Big]^T_0 \\
  &=\frac{A}{2}
\end{align}
\begin{align}
a_n &= \frac{2}{T} \int_0 ^T f(t) \sin n\omega t dt = \frac{2}{T} \int_0 ^T \frac{A}{T}t \sin n\omega t dt \\
&= \frac{2A}{T^2}\int_0^T t\sin n \omega t dt = \frac{2A}{T^2}\Big[ - \frac{t \cos n \omega t}{n \omega} + \frac{\sin n \omega t}{(n \omega)^2} \Big]^T_0 \\
  &= - \frac{A}{n \pi} \, (\because \omega = \frac{2 \pi}{T})
\end{align}
\begin{align}
b_n &= \frac{2}{T} \int_0 ^T f(t) \cos n\omega t dt = \frac{2}{T} \int_0 ^T \frac{A}{T}t \cos n\omega t dt \\
&= \frac{2A}{T^2}\int_0^T t\cos n \omega tdt = \frac{2A}{T^2}\Big[ \frac{t \sin n \omega t}{n \omega} + \frac{\cos n \omega t}{(n \omega)^2} \Big]^T_0 \\
  &= 0 \, (\because \omega = \frac{2 \pi}{T})
\end{align}
따라서 이 톱날의 치파는 다음과 같이 표현할 수 있다
f(t) = -\frac{A}{\pi}\sum_{n=1}^\infty \frac{1}{n} \sin n\omega t + \frac{A}{2}

도표로 톱날의 치파를 표시하다


상술한 계산 결과가 톱날 모양의 파도인지 그려 보아라
컴퓨터가 무한 처리할 수 없기 때문에 유한한 n개수를 톱니파와 비슷하게 설정한다.
pytohon에 도표를 그리는 코드는 다음과 같다
def sawtooth_wave(N):
    dt = 0.01
    T = 2 * np.pi / 4.
    A = 1
    omega = 2 * np.pi / T
    t = np.arange(0, 2*np.pi, 0.01)
    y = np.zeros(len(t))
    for n in range(1,N):
        y += - A / (np.pi * n) * np.sin( n * 2 * np.pi / T * t)
    y += A / 2.
    plt.plot(t, y, label="n = {}".format(N))
    plt.yticks([0.5], ["A/2"])
    plt.xticks([T, 2*T, 3*T, 4*T], ["T", "2T", "3T", "4T"])
    plt.legend(loc="upper left")
다음은 n=0, 1, 5100의 톱날 파도

그림에서 보듯이 n을 증가하면 톱니 모양의 파도에 가까워진다

톱날 파도


지그재그로 어떤 소리가 들리는지 저장해 주세요.
import numpy as np

# 定数
SR = 44100 # サンプリング周波数
f = 440.        # 周波数
A = 1             # 振幅
T = 5             # 音声の時間
N = 5000     # sin波の重ねる数

# 各時間
t = np.linspace(0, T, SR * T)[:-1] 

# ノコギリ波の計算
y = np.zeros(len(t))
for n in range(1,N):
    y += - A / (np.pi * n) * np.sin( n * 2 * np.pi * f  * t)
y += A / 2.

# 16bitで量子化
y2 = (y * np.iinfo(np.int16).max).astype(np.int16)

# ステレオに変換
y3 = np.array(np.c_[y2,y2])    

# 保存
import scipy.io.wavfile as siw
siw.write("sawtooth.wav", SR, y3)
Qita에 오디오 파일을 붙일 수 없으니 위쪽의 프로그램을 직접 진행하거나 확인하세요
싸이혼 사운드 처리~ 부립엽 레벨을 펼쳐 만든 톱니파~ - 그래서 너무 좋았어요.
파형은 톱니 모양으로 전자 소리처럼 들린다

총결산


부립엽 급수의 전개를 소개하고, 실제 톱니파의 부립엽 급수를 전개하였다.
이상!

좋은 웹페이지 즐겨찾기