#sin波の重ね合わせ
さまざまな周波数のsin波を重ね合わせることで,好きな音を作ることができます.
sin_sound_synthetic.py
import wave
import numpy as np
from matplotlib import pylab as plt
import struct
a = 1 #振幅
fs = 44100 #サンプリング周波数
f0 = 440 #周波数(ラの音にあたります)
sec = 5 #秒
voice = []
#倍音にあたる部分
a1 = 0.6 #振幅
f01 = 880 #周波数
voice1 = []
a2 = 0.4 #振幅
f02 = 1320 #周波数
voice2 = []
a3 = 0.8 #振幅
f03 = 1760 #周波数
voice3 = []
a4 = 0.6 #振幅
f04 = 2220 #周波数
voice4 = []
a5 = 0.75 #振幅
f05 = 2640 #周波数
voice5 = []
#サイン波を合成
for n in np.arange(fs * sec):
s = a * np.sin(2.0 * np.pi * f0 * n / fs) + \
a1 * np.sin(2.0 * np.pi * f01 * n / fs) + \
a2 * np.sin(2.0 * np.pi * f02 * n / fs) + \
a3 * np.sin(2.0 * np.pi * f03 * n / fs) + \
a4 * np.sin(2.0 * np.pi * f04 * n / fs) + \
a5 * np.sin(2.0 * np.pi * f05 * n / fs)
voice.append(s)
#正規化(各要素を最大振幅で割る)
maxvoice = np.max(voice)
maxvoice = np.abs(maxvoice)#絶対値をとる
minvoice = np.min(voice)
maxvoice = np.abs(minvoice)#絶対値をとる
if minvoice < maxvoice:
voice = voice/maxvoice
else:
voice = voice/minvoice
#横軸:tは時間方向での離散値です.voiceの長さをサンプルレートで切っているので,サンプル数分の配列になってます.
t = np.arange(0, len(voice))/fs
#サイン波を表示
plt.plot(t,voice)
plt.xlim([0,0.02])#範囲指定0秒〜0.02秒
plt.show()
#サイン波を-32768から32767の整数値に変換(signed 16bit pcmへ)
voice = [int(x * 32767.0) for x in voice]
#バイナリ化
binwave = struct.pack("h" * len(voice), *voice)
#サイン波をwavファイルとして書き出し
w = wave.Wave_write("sin_sound_synthetic.wav")
p = (1, 2, fs, len(binwave), 'NONE', 'not compressed')
w.setparams(p)
w.writeframes(binwave)
w.close()
実行は以下のコマンドで
$ python sin_sound_synthetic.py
作業ディレクトリの中に
sin_sound_synthetic.wav
というファイルが生成されているはずです.
どんな音色になっていますか?