リアルタイムに変化する音声のFFTスペクトルを表示するPythonスクリプト

STFTとか何とか。スペクトルがギザギザしてますね。

#!/usr/local/bin/python3
# -*- coding:utf-8 -*-

# プロット関係のライブラリ
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
import sys

# 音声関係のライブラリ
import pyaudio

sample_rate = 16000
frame_length = 1024
frame_shift = 80


class PlotWindow:
    def __init__(self):

        # プロット初期設定
        self.win = pg.GraphicsWindow()
        self.win.setWindowTitle(u"FFTスペクトルのリアルタイムプロット")
        self.win.resize(1100, 800)
        self.plt = self.win.addPlot()
        self.ymin = -100
        self.ymax = 80
        self.plt.setYRange(self.ymin, self.ymax)

        # yukara
        self.plt.setXRange(0, frame_length / 2, padding=0)
        specAxis = self.plt.getAxis("bottom")
        specAxis.setLabel("Frequency [Hz]")
        specAxis.setScale(sample_rate / 2. / (frame_length / 2 + 1))
        hz_interval = 500
        newXAxis = (
            np.arange(int(sample_rate / 2 / hz_interval)) + 1) * hz_interval
        oriXAxis = newXAxis / (sample_rate / 2. / (frame_length / 2 + 1))
        specAxis.setTicks([zip(oriXAxis, newXAxis)])

        self.curve = self.plt.plot()  # プロットデータを入れる場所
        self.epsiron = 0.0001

        # マイク設定
        self.CHUNK = frame_length
        self.RATE = sample_rate
        self.audio = pyaudio.PyAudio()
        self.stream = self.audio.open(format=pyaudio.paInt16,
                                      channels=1,
                                      rate=self.RATE,
                                      input=True,
                                      output=True,
                                      frames_per_buffer=self.CHUNK)

        # アップデート時間設定
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.update)
        self.timer.start(10)  # 10msごとにupdateを呼び出し

        # 音声データの格納場所(プロットデータ)
        self.data = np.zeros(self.CHUNK)

    def update(self):
        self.data = self.AudioInput()

        y = np.fft.fft(self.data[0:self.CHUNK])
        y = np.abs(y) ** 2
        y = y[0:int(self.CHUNK / 2)]
        y = 20 * np.log10(y + self.epsiron)

        self.curve.setData(y)  # プロットデータを格納

    def AudioInput(self):
        ret = self.stream.read(self.CHUNK)
        ret = np.frombuffer(ret, dtype="int16") / 32768
        return ret


if __name__ == "__main__":
    plotwin = PlotWindow()

    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

こちらの記事を参考にしました。ありがとうございました。
takeshid.hatenadiary.jp