これまでなんとなく当然だと思っていたが、まず正しい音を正確に出力するところからやろうと思う。
技術的には、これまでも何度か書いているので、いきなりコードを出してちょっと説明したいと思う。
###コード解説
import wave
import numpy as np
from matplotlib import pylab as plt
import struct
import pyaudio
import matplotlib
以下に発生する音の属性を示す。
a = 1 #振幅
fs = 44100 #サンプリング周波数
f0 = 400 #基準周波数
f1 = f0+10 #重畳する音の周波数
sec = 5 #秒;発生時間
CHUNK=1024 #一度にサンプリングするframe数
p=pyaudio.PyAudio()
stream=p.open( format = pyaudio.paInt16,
channels = 1,
rate = fs,
frames_per_buffer = CHUNK,
input = True,
output = True) # inputとoutputを同時にTrueにする
以下で実際に出力するサイン波を生成する。
※今回は二つの波を重畳する
swav=[]
for n in np.arange(fs * sec):
#サイン波を生成
s = (a * np.sin(2.0 * np.pi * f0 * n / fs)+ a * np.sin(2.0 * np.pi * f1 * n / fs))/2
swav.append(s)
発生するサイン波を描画する。
0-0.1秒までのものとハウリングを見るために全体0-5秒の図を描画するが、
昨夜プロットの配置の仕方を学んだので、それを応用している。
※配置する図のデータは同一で範囲指定など変えて、描画できる
#サイン波を表示
matplotlib.rcParams.update({'font.size': 18, 'font.family': 'sans', 'text.usetex': False})
fig = plt.figure(figsize=(8,6)) #(width,height)
x_offset=np.round(0.05*4,decimals=2)
y_offset=np.round(0.05*10,decimals=2)
width=0.3
height=0.3
axes1 = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # main axes
axes2 = fig.add_axes([x_offset, y_offset, width, height]) # insert axes
x = np.linspace(0, sec, int(fs*sec)) #sec;サンプリング時間、fs*sec;サンプリング数
axes1.set_ylim(-1.2,1.2)
axes1.set_xlim(0,0.1) #0-0.1 sec
axes1.plot(x,swav)
axes2.set_ylim(-1.2,1.2)
axes2.set_xlim(0,5) #0-5 sec
axes2.plot(x,swav)
plt.pause(1)
plt.savefig('./fft/sound_'+str(f0)+'_'+str(f1)+'.jpg')
swavに格納された音データを以下によりwavファイルとして保存する。
#サイン波を-32768から32767の整数値に変換(signed 16bit pcmへ)
swav = [int(x * 32767.0) for x in swav]
#バイナリ化
binwave = struct.pack("h" * len(swav), *swav)
#サイン波をwavファイルとして書き出し
w = wave.Wave_write("./fft/output"+str(f0)+"_"+str(f1)+".wav")
params = (1, 2, fs, len(binwave), 'NONE', 'not compressed')
w.setparams(params)
w.writeframes(binwave)
w.close()
最後に作成した音をスピーカーから出力する。
※inputに置き換える必要はないが、一応勘違い防止のために一度inputに代入してから出力している
input = binwave
output = stream.write(input)
###いろいろな音を作成して聞き比べる
今回は、基準振動を400Hzとして、以下の音を重畳して作成して遊んでみた
f_list=[0.01,0.1,0.5,1,2,5,10,50,100,200,300,350,400.1,400.2,400.5,401,402,405,410,420,450,500,600,800,1000,1200,1400,1600]
結果は以下のような画像が得られる。
上記のパラメータでGifアニメーションにする。
対応する音は以下に置いた。
AudioAutoencoder/sound_generation/melody.wav
###音の不思議
作成した音を聞いてみると、
1.400-402の重畳はいわゆるハウリングのようにウワ~ンウワ~ンと聞こえます
2.高周波例えば400-1000の重畳だと、この高調波側が周波数が高くなるにしたがって、大きな音で聞こえます
3.低周波の音との重畳400-1などでは、1Hzは可聴音ではないので関係なさそうです。しかし、音が大きくなったり小さくなったり、ハウリングのように聞こえることもあります
4.一番たぶん音声と関係するのはそれらの間の周波数例えば、400-600のような場合です。これは、まだまだですが音声の’う’と同じような音が出ます。これは先日のフォルマント合成の話と同じような現象です。
###コードは以下に置きました
・AudioAutoencoder/sin_sound.py
###まとめ
・いろいろな音をサイン波で作成して遊んでみた
・発生した音は高々二音だが、「音の不思議」に記載したように多彩な音を発生する
・これらをFFT~STFT,そしてwavelet変換して分析する
・さらに男性声、女性声の分析及びそれらの音声合成を実施する