スペクトログラムの逆変換がしたい(1)

 おれだ。

 久しぶりだな。

 研究で必要になる可能性があるので、音声処理の勉強をしている。

 備忘録と学習内容の整理のために記事を書いていく。

 内容は既存の記事の劣化コピー劣化コピーみてえなもんになるが、ゆるして。

作業環境

 おさけ:グレンフィデック12年 ストレート

 おつまみ:カレ・ド・ショコラ ストロベリー

 BGM:5/17 0:00~ 周防パトラの生放送アーカイブ

スペクトログラムってなんだよ

 なんかフーリエ変換すると出てくるやつだよ。

 横軸は時間、縦軸が周波数、色で信号の強さを表すらしい。

 一枚で音について丸わかりってワケ。

どうやってスペクトログラムを出すんだ

 フーリエ変換すると出てくるっつってんだろ。

 今回は短時間フーリエ変換(STFT)ってやつを使う。

 おれはクソプログラマなので、文中にカンマピリオドは使わないしSTFTはふんわりしか理解していないが、librosaという神ライブラリが全部やってくれるぞ。

とりあえずスペクトログラムを出力する

 とりあえずコードを書いた。

 ほぼほぼ写経だ。

 元ファイルにはDetroit: Become Humanから、コナーの"28箇所の刺し傷だぞ!"というセリフが入っている。

import librosa
import librosa.display
import numpy as np
import matplotlib.pyplot as plt

def main():
    # fileload
    y, sr = librosa.load('28_points.mp3')

    # STFT
    S = np.abs(librosa.stft(y))

    # output
    plt.figure(figsize=(10, 4))
    librosa.display.specshow(librosa.amplitude_to_db(S, ref=np.max), y_axis='log', x_axis='time')
    plt.colorbar(format='%+2.0f dB')

    plt.tight_layout()
    plt.savefig('spec.png')
    
if __name__ == "__main__":
    main()

 出力されたスペクトログラムはこんなんだ。

f:id:emracrue:20190517230538p:plain

 よくわからん。

 このままでは画像から逆変換できなさそうなので、凡例や余白とバイバイする。

 コードはこれ。

import librosa
import librosa.display
import numpy as np
import matplotlib.pyplot as plt

def main():
    # fileload
    y, sr = librosa.load('28_points.mp3')

    # STFT
    S = np.abs(librosa.stft(y))

    # output
    plt.figure(figsize=(10, 4))
    librosa.display.specshow(librosa.amplitude_to_db(S, ref=np.max))
    plt.savefig('spec.png', transparent = True, bbox_inches="tight", pad_inches=0.0)

if __name__ == "__main__":
    main()

 できた。

 再度出力すると、こんな感じ。

f:id:emracrue:20190517231921p:plain

 うまく余白が消えた。

じゃ逆変換するか

 まてしばし。

 いまたいへん苦しんでいるので、更新はしばらく先になるかもわからん。

 STFTで生成したスペクトログラムって不可逆だったっけ?

 左から順に逆変換すればいけるかな……。

 超絶勉強不足を感じる。

 音声信号処理に詳しいマンがいたらおれのことを助けてくれ。