マツコの知らない音声解析の世界

# はじめに
本記事は [長野高専 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/nnct) 20日目の記事となります。皆さん大変素晴らしい記事を書かれていますね。この記事ではPythonを利用して音声解析を行うプログラムを作成します。

# お前誰だよ
・電子制御工学科の学生（情報じゃねえのかよ）
・機械学習・深層学習を勉強中
・プログラミングなんもわからん
・なのに研究でPythonを使ってる
・最近ブルアカにはまった（お前ら笑うなっ！）

という感じのお世辞にもつよつよとは言えないスペックの人間です。なのであまり期待せずにどうか温かい目で見てやってください。~~ちなみにブルアカで好きなキャラは天雨アコです。あと最近ヒナ委員長も好きになりました。~~

# 音声解析用ライブラリ「librosa」
さて、前置きが長くなりましたが本題に入りましょう。

Pythonにはlibrosaと呼ばれる音楽・音声を解析するための便利なライブラリがあります。音声データの特徴量の抽出やスペクトル解析、音源分離など様々なことができるようです。すごいですね。詳細は[公式サイト](https://librosa.org/doc/latest/index.html#)を確認してください（他力本願寺）。

librosaはpipあるいはcondaでインストールできます。
```python
#pipの場合
pip install librosa

#condaの場合
conda install -c conda-forge librosa
```

# wavファイルを読み込む
librosaで利用できるオーディオファイルの形式としてはwavやmp3などがあります。今回はwavファイルを読み込んでみます。[Music-Note.jp](http://www.music-note.jp/) 様のbrighteningという楽曲を使用させて頂くことにします。
~~~python
import librosa
import IPython.display as ipd

file_path = 'data/brightening.wav' #wavファイルのパスを記述
y, sr = librosa.load(file_path, sr=44100) #オーディオファイルの読み込み
ipd.Audio(y, rate=sr) #オーディオファイルの再生
~~~
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1629005/b3484a35-48e8-f124-3d4e-9c09b3acadaa.png)
`ipd.Audio`を使用することでプレーヤーが表示され、音声の再生が可能になります。プレーヤーを再生し、楽曲が正常に読み込めていることを確認しましょう。

`librosa.load`を使用することで、オーディオファイルを浮動小数点時系列として読み込むことができます。読み込んだ際の戻り値は`y`と`sr`の2つがあり、yはオーディオファイルの数字データ、srはサンプルレート[Hz]を意味します。
数字データは配列として取得されます。サンプルレートとは1秒間に実行するサンプリング処理の回数であり、一般的には44.1kHzとされています。librosaではサンプルレートを指定しない場合、srの値は22050Hzとなるので注意が必要です。

librosaではオーディオファイルの一部を切り出して読み込むこともできます。
~~~python
file_path = 'data/brightening.wav'
y, sr = librosa.load(file_path, sr=44100,offset=0,duration=5)
~~~
`offset`は何秒から読み込みを開始するか、`duration`はoffsetから何秒間のデータにするかを指定します。上記のプログラムでは開始から5秒間のデータを切り出して出力しています。

# 波形を表示する
続いて音声データの波形を表示します。波形の表示にあたって、matplotlibと呼ばれるグラフ描画用のライブラリを使用します（インストール方法はlibrosaと同様の手順になります）。
~~~python
import librosa.display
import matplotlib.pyplot as plt

plt.figure(figsize=(10, 5)) #グラフのサイズを指定
librosa.display.waveshow(y, sr) #波形の表示
~~~
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1629005/034b32b3-1b79-2441-ef8b-3312850d93a4.png)
`librosa.display.waveshow`を使用することで波形のデータを可視化することができます。

# フーリエ変換してみる
次にフーリエ変換を行います。フーリエ変換とは時間領域のデータを周波数領域へ変換するアルゴリズムのことであり、特に信号処理などの分野においては重要な技術となっています。
~~~python
import numpy as np

fft = np.abs(librosa.stft(y)) #フーリエ変換

plt.figure(figsize=(10, 5))
plt.plot(fft)
plt.xlabel("Frequency [Hz]") #x軸ラベルの指定
plt.ylabel("Amplitude") #y軸ラベルの指定
~~~
![fft.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1629005/5dcede85-5209-497b-0711-56fa8ac916ff.png)
計算に時間がかかりますが我慢しましょう。`librosa.stft`は短時間フーリエ変換(STFT：Short-time Fourier Transformの略)を行う関数であり、オーディオファイルの数字データに対してフーリエ変換を行っています。`np.abs`は配列の各要素に対して絶対値を取った配列を作る関数であり、フーリエ変換の結果の絶対値を取ることで振幅スペクトルを出力しています。


# スペクトログラムを可視化する
最後にスペクトログラムを可視化します。スペクトログラムとは周波数成分の時間変化であり、先程行ったフーリエ変換を時間を区切って行うことで実現できます。
~~~python
spec = librosa.amplitude_to_db(fft, ref=np.max)

plt.figure(figsize=(10, 5))
librosa.display.specshow(spec, sr=sr, x_axis='time', y_axis='log') #スペクトログラムの表示
plt.colorbar()
plt.show()
~~~
![spec.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1629005/6282ae4f-75f5-43f1-1a94-55531755daef.png)
`librosa.amplitude_to_db`では強度をdB単位へと変換しています。`librosa.display.specshow`はスペクトログラムを描画するコードであり、スペクトログラムのデータ、サンプルレート、x軸、y軸の指定を行っています。今回作成した画像においては、明るい色の部分はデシベルが大きく、暗い色の部分はデシベルが小さくなっています。