LoginSignup
1
4

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-01-21

昨夜の話で、やはり音声データ入力忘れていたので思い出しました。
というか、参考のサイトが見つかったので、忘れないうちに記事にしておこうと思います。

とりあえずの目標

以下のとおり、
※リンクされているものは記事にしたものであり、その記事を前提知識として書いて行くので、参照すると理解し易いと思います。
Scipy環境を作る
 ・環境の確認
不確定原理について
・FFT変換・逆変換してみる;時間軸が消える
・STFT変換・逆変換してみる;窓関数について
・wavelet変換・逆変換してみる;スペクトログラムの解釈と不確定原理
音声や地震データや株価や、。。。とにかく一次元の実時系列データに応用する
④FFTからwavelet変換まで簡単にたどってみる(上記以外のちょっと理論)
⑤二次元データに応用してみる
⑥天体観測データに応用してみる
⑦リアルタイムにスペクトログラムしてみる

今回やったこと

昨夜、お約束の以下の事項を記事にしておきます。
※wavファイル取得については、別途記事にしたいと思います
前にやったのは、RasPiで取得しましたが、ほぼ同じコードで動きました。
ただし、環境はWindowsでマイク入力というのが、ジャックからの入力で実施しました。
ということで、以下の順に記載します。
①pyaudioのインストール
②音声データ入力、書き出し
③ちょっと音声アプリ
【参考】
PyAudioの基本メモ2 音声入出力@たけし備忘録

①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)の時のアプリではまんまだと動きませんでしたが、ちょっとした変更で動きました。

# -*- coding: utf-8 -*-
#マイク0番からの入力を受ける。一定時間(RECROD_SECONDS)だけ録音し、ファイル名:入力名.wavで保存する。

import pyaudio
import sys
import time
import wave

つまり、測定条件は以下の通りでした(過去形)。

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の定義は以下のとおり、

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

    print("* recording")

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

    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を意味するそうです。

    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)とかにするとさらに遊べます。。

# -*- 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変換に一歩近づいた

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4