Python マイク入力音声をリアルタイムで波形(グラフ)表示する方法[Windows Pyaudioとmatplotlib]

Python
この記事は約4分で読めます。

今回は、pythonでマイク音声を入力する方法について記載しようと思います。

筆者は組み込みエンジニアでオーディオ関連の仕事をすることもあるので、Visual Studio C++で、音声入力とフーリエ変換をするプログラム書いたことがあり、ちょっと興味があって今回挑戦してみました。

ライブラリのインストール

まず初めにマイクの入力と波形を出力するために、以下の2つライブラリをインストールします。

①pyaudio ・・・ pythonでAudioデバイスを制御するためのライブラリ

(windowsでのDirectXみたいなものなのかな??ちょっと詳しくは知りません。。。)

②matplotlib ・・・ グラフ等を表示するためのライブラリ

pyaudio のインストール

pyaudioは、windowsPCの場合、インターネット経由のpipコマンドでインストールするのは無理そうでした。

まず、Microsoft C++ Build Toolsを入れるように怒られ、そしてもしインストールしたとしても、「portaudio.h」というものがないって怒られてインストールに失敗しました。

で、ちょっと調べてみたところ、以下のサイトにあるwhlからインストールすれば使えるとのことで

以下からダウンロードしました。

※Unofficialとのことで、使用する際には自己責任でインストールしてください。

Python Extension Packages for Windows - Christoph Gohlke

以下のようなページが表示されますので、pyaudioを探してください。

以下のような感じでありますので、環境にあったものをインストールしてください。

そして、ダウンロードできたら、コマンドプロンプトへ以下の通りコマンドを入力しインストールしてください。

pip install PyAudio-0.2.11-cp39-cp39-win_amd64.whl
※ PyAudio-0.2.11-cp39-cp39-win_amd64.whlはダウンロードしたファイルを指定してください。

以下のような感じで簡単にインストールできます。

matplotlibのインストール

続いて、 「matplotlib」のインストールです。

コマンドプロンプトを開き、以下の通りコマンドを実行してください。

pip install matplotlib

※こちらは、ネット経由で勝手にインストールしてくれます。

以下のようになります。

これで準備は完了です。

サンプルコード

では実際のプログラムです。

import pyaudio
import matplotlib.pyplot as plot

def audiostart():
    audio = pyaudio.PyAudio() 
    stream = audio.open( format = pyaudio.paInt16,
                         rate = 44100,
                         channels = 1, 
                         input_device_index = 1,
                        input = True, 
                        frames_per_buffer = 1024)
    return audio, stream

def audiostop(audio, stream):
    stream.stop_stream()
    stream.close()
    audio.terminate()

def read_plot_data(stream):
    data = stream.read(1024)
    audiodata = numpy.frombuffer(data, dtype='int16')
    
    plot.plot(audiodata)
    plot.draw()
    plot.pause(0.001)
    plot.cla()

if __name__ == '__main__':
    (audio,stream) = audiostart()
    
    while True:
        try:
            read_plot_data(stream)
        except KeyboardInterrupt:
            break

    audiostop(audio,stream)

そして、実際に実行させたときの表示はこのような感じになります。

実行結果

乱れてはいますが、これはマイクに1Khzの 正弦波 を近づけたときの波形です。

一応正弦波になっています。

続いてはプログラムの解説ですが、解説は次ページにて記載します。

コメント

  1. 北極のペンギン より:

    こんにちは。
    いま、ステレオ音声をLRそれぞれFFTにかけようとしています。
    同様にPyaudioを用いて、channels=2としてステレオ入力にして、ちゃんとステレオで読み込めてはいるようですが、LとRに分けてのFFTができません。
    もし、Pyaudioを用いる用いないにかかわらずLとR別々にFFTを行う方法をご存じでしたらご教示戴けませんでしょうか。

    • にいやん より:

      コメントありがとうございます。
      ステレオでデータが取得できているのであれば、データは単純に L CH 16Bit + R Ch 16Bitのデータ列になっていますので、LChとRChでデータを分割してFFTすれば各チャンネルの周波数が取れます。
      LRを分けて周波数を取得するサンプルコードを追記しましたので、参考にしてみてください。

タイトルとURLをコピーしました