【Scipy】FFT、STFTとwavelet変換で遊んでみた♬～③音声データ入力編～

昨夜の話で、やはり音声データ入力忘れていたので思い出しました。
というか、参考のサイトが見つかったので、忘れないうちに記事にしておこうと思います。
###とりあえずの目標
以下のとおり、
※リンクされているものは記事にしたものであり、その記事を前提知識として書いて行くので、参照すると理解し易いと思います。
①[Scipy環境を作る](https://qiita.com/MuAuan/items/8850e037babcff991b8e)
　・環境の確認
②[不確定原理について](https://qiita.com/MuAuan/items/504160465e83e556dd3e)
・FFT変換・逆変換してみる；時間軸が消える
・STFT変換・逆変換してみる；窓関数について
・wavelet変換・逆変換してみる；スペクトログラムの解釈と不確定原理
③[音声や地震データや株価や、。。。とにかく一次元の実時系列データに応用する](https://qiita.com/MuAuan/items/858aab2879708668e2bb)
④FFTからwavelet変換まで簡単にたどってみる（上記以外のちょっと理論）
⑤二次元データに応用してみる
⑥天体観測データに応用してみる
⑦リアルタイムにスペクトログラムしてみる
###今回やったこと
昨夜、お約束の以下の事項を記事にしておきます。
※wavファイル取得については、別途記事にしたいと思います
前にやったのは、RasPiで取得しましたが、ほぼ同じコードで動きました。
ただし、環境はWindowsでマイク入力というのが、ジャックからの入力で実施しました。
ということで、以下の順に記載します。
①pyaudioのインストール
②音声データ入力、書き出し
③ちょっと音声アプリ
【参考】
・[PyAudioの基本メモ2 音声入出力@たけし備忘録](http://takeshid.hatenadiary.jp/entry/2016/01/10/153503)
###①pyaudioのインストール
インストールしたPythonは以下のとおり

```
Python 3.5.2 |Anaconda 4.2.0 (64-bit)| (default, Jul  5 2016, 11:41:13) [MSC v.1900 64 bit (AMD64)] on win3
```

```
>pip install pyaudio
```
でうまくインストールできました。
ただし、動かし始めてから、当初音量が小さくて聞き取れず、少し試行錯誤しました。
Windows10の環境設定のサウンドの設定をいじりました。
特に、マイクをジャックからの入力にしました。
※RasPiのときはUSBコネクタで入力しました⇒その時の設定は今回はパスします

###②音声データ入力、書き出し
RasPi(ubuntu)の時のアプリではまんまだと動きませんでしたが、ちょっとした変更で動きました。

```py
# -*- coding: utf-8 -*-
#マイク0番からの入力を受ける。一定時間(RECROD_SECONDS)だけ録音し、ファイル名：入力名.wavで保存する。
 
import pyaudio
import sys
import time
import wave
```
つまり、測定条件は以下の通りでした（過去形）。

```py
if __name__ == '__main__':
    CHUNK = 1024 #1024
    FORMAT = pyaudio.paInt16
    CHANNELS = 1  #monoral
    #サンプリングレート、マイク性能に依存
    RATE = 22100
    # 録音時間
    RECORD_SECONDS = input('Please input recoding time>>>')
    filename=input('input filename=')
    
    p = pyaudio.PyAudio()
    
```
streamの定義は以下のとおり、

```py
    stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)

    print("* recording")
```
ここでint(RECORD_SECONDS)が目を引くと思いますが、最初なかなかわかりませんでしたが、文字列をintで変換しています。
※これRasPiでは動いていました。。のはず（笑）
　また、参考のように数値で与えていれば特に必要ありません。
以下のように音声を一定時間framesにため込みます。

```py
    frames = []
    for i in range(0, int(RATE / CHUNK * int(RECORD_SECONDS))):
        data = stream.read(CHUNK)
        frames.append(data)
    print("* done recording")
    stream.stop_stream()
    stream.close()
    p.terminate()
```
最後に、ため込んだframesをファイルに書き出します。
ここで、ウワンは未確認ですが、width=2は16bitを意味するそうです。

```py
    wf = wave.open(filename+'.wav', 'wb')
    wf.setnchannels(CHANNELS)
    wf.setsampwidth(p.get_sample_size(FORMAT))  #width=2 ; 16bit
    wf.setframerate(RATE)
    wf.writeframes(b''.join(frames))
    wf.close()
```
ということで、めでたくWindows10でも音声など音を拾えることとなりました。
###③ちょっと音声アプリ
参考に面白い例があったので、応用して以下のアプリを作ってみました。
※あくまでここではFFTやWavelet変換は使わないということで。。

以下のアプリは、音声を入力したと同時に出力するアプリです。
そして、入力から出力の間に、ここではだんだん音が大きくなるようにしています。
このアプリを動かすと最初は単に音が大きくなるが、途中から音の発生が遅れだし、かつ音が割れだして、最後はエイリアンの消滅のような壊れた音で消えます。。。
※print(s)⇒time.sleep(s/10000)とかにするとさらに遊べます。。

```py
# -*- coding:utf-8 -*-
import pyaudio

CHUNK=1024
RATE=44100
p=pyaudio.PyAudio()

stream=p.open(	format = pyaudio.paInt16,
		channels = 1,
		rate = RATE,
		frames_per_buffer = CHUNK,
		input = True,
		output = True) # inputとoutputを同時にTrueにする

def audio_trans(input,s):
    print(s)
    ret=input*int(s/100)
    return ret

s=1
while stream.is_active():    
    input = stream.read(CHUNK)
    s += 1
    input = audio_trans(input,s)
    output = stream.write(input)

stream.stop_stream()
stream.close()
p.terminate()
print( "Stop Streaming")
```
###まとめ
・Windows10で音声入力環境を構築した
・パラメータの意味が判明した
・ちょっとしたアプリを作って遊んでみた

・リアルタイムなFFT,STFT、そしてwavelet変換に一歩近づいた