【Audio入門】音を発生する♬

これまでなんとなく当然だと思っていたが、まず正しい音を正確に出力するところからやろうと思う。
技術的には、これまでも何度か書いているので、いきなりコードを出してちょっと説明したいと思う。
###コード解説
```py
import wave
import numpy as np
from matplotlib import pylab as plt
import struct
import pyaudio
import matplotlib
```
以下に発生する音の属性を示す。

```py
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にする
```
以下で実際に出力するサイン波を生成する。
※今回は二つの波を重畳する

```py
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秒の図を描画するが、
昨夜プロットの配置の仕方を学んだので、それを応用している。
※配置する図のデータは同一で範囲指定など変えて、描画できる

```py
#サイン波を表示
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ファイルとして保存する。

```py
#サイン波を-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に代入してから出力している

```py
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]
```
結果は以下のような画像が得られる。
![sound_400_401.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/28ca4556-9ca5-45b8-47a4-3e906cb367c0.jpeg)
上記のパラメータでGifアニメーションにする。
![sound_modulation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/c6d04d11-960e-9f6a-f6d5-276133675fac.gif)
対応する音は以下に置いた。
[AudioAutoencoder/sound_generation/melody.wav](https://github.com/MuAuan/AudioAutoencoder/blob/master/sound_generation/melody.wav)
###音の不思議
作成した音を聞いてみると、
1．400-402の重畳はいわゆるハウリングのようにウワ～ンウワ～ンと聞こえます
2．高周波例えば400-1000の重畳だと、この高調波側が周波数が高くなるにしたがって、大きな音で聞こえます
3．低周波の音との重畳400-1などでは、1Hzは可聴音ではないので関係なさそうです。しかし、音が大きくなったり小さくなったり、ハウリングのように聞こえることもあります
4．一番たぶん音声と関係するのはそれらの間の周波数例えば、400-600のような場合です。これは、まだまだですが音声の’う’と同じような音が出ます。これは先日のフォルマント合成の話と同じような現象です。
###コードは以下に置きました
・[AudioAutoencoder/sin_sound.py](https://github.com/MuAuan/AudioAutoencoder/blob/master/sin_sound.py)
###まとめ
・いろいろな音をサイン波で作成して遊んでみた
・発生した音は高々二音だが、「音の不思議」に記載したように多彩な音を発生する

・これらをFFT～STFT,そしてwavelet変換して分析する
・さらに男性声、女性声の分析及びそれらの音声合成を実施する