ウマ娘の声をPythonで波形の表示と周波数解析を行った

# はじめに
こんにちは，Umamusume22です．今回は私の大好きなウマ娘の声をPythonで周波数解析をしてみました．ゴールドシップ(以下，ゴルシ)が他のウマ娘のモノマネを行っている動画がyoutubeにあります．
ゴルシのモノマネが上手だったのでどのくらい似ているのか定量的評価をします．
今回はスペシャルウィークを検証の対象にしました．スペシャルウィークはアニメ1期のヒロインで1998年に活躍したウマ娘でありサイレンススズカと異母兄弟でレースでは(オタク特有の早口のため略

オタク特有の早口は置いといて検証に使ったYoutubeのリンクを貼っておきます．

https://youtu.be/gF9ABtanFHY?si=k26C0aULsSmbUOec

# pc環境
mac Catalina(10.15.7)
Python 3.12.3


# Pythonで音声データを周波数解析[1]

### 必要なモジュールをインストール
Pythonで音声データを周波数解析するためにpydubをインストールしました．homebrewでパッケージ管理している場合は以下のコマンドを打ってください．ffmpegとは動画や音声を記録や変換、再生、情報の取得などが行えるソフトウェアのことです[2]．

```
$ brew install ffmpeg
```
ffmpegのインストールが終わったらpydubのインストールを行います．pipによってはpip3の場合があります．ご自身のpythonの環境に合わせてpipまたはpip3をインストールしてください．
pydubをインストールするときは以下のコマンドを打ってください．

```
pip install pydub
```

### 音声データを取得
今回，使う音声データははじめにのリンクで貼り付けたゴルシのモノマネとスペシャルウィークの声です．動画としてはゴルシの音声が0s~5sでスペシャルウィークは5s~8sです．
これら二つの動画を編集してmp4に変換します．
mp4に変換するにあたって以下のサイトが参考になりました[3]．
https://ssyoutube.com/ja33Dy/youtube-to-mp4

### 音声データを読み込んで波形の表示と周波数解析を行う
以下はソースコードです．

```voice_umamusume.py

import matplotlib.pyplot as plt
import numpy as np
from pydub import AudioSegment

# mp4の音声データを読み込む
sounds = AudioSegment.from_file('ここにウマ娘のmp4のパスを入力', 'mp4')

# 基本情報の表示
print(f'channel: {sounds.channels}')
print(f'frame rate: {sounds.frame_rate}')
print(f'duration: {sounds.duration_seconds} s')

# チャンネルが2 （ステレオ) の場合，交互にデータが入っているので，二つおきに読み出す。
# ただし，今回の場合はモノラルのはず。つまり，sounds.channels = 1
sig = np.array(sounds.get_array_of_samples())[::sounds.channels]
dt = 1.0/sounds.frame_rate # サンプリング時間

# 時間アレイを作る
tms = 0.0 # サンプル開始時間を0にセット
tme = sounds.duration_seconds # サンプル終了時刻
tm = np.linspace(tms, tme, len(sig), endpoint=False) # 時間ndarrayを作成

# DFT
N = len(sig)
X = np.fft.fft(sig)
f = np.fft.fftfreq(N, dt) # Xのindexに対応する周波数のndarrayを取得

# データをプロット
fig, (ax01, ax02) = plt.subplots(nrows=2, figsize=(6, 8))
plt.subplots_adjust(wspace=0.0, hspace=0.6)

ax01.set_xlim(tms, tme)
ax01.set_xlabel('time (s)')
ax01.set_ylabel('x')
ax01.plot(tm, sig) # 入力信号

ax02.set_xlim(0, 2000)
ax02.set_xlabel('frequency (Hz)')

ax02.set_ylabel('|X|/N')
ax02.plot(f[0:N//2], np.abs(X[0:N//2])/N) # 振幅スペクトル

plt.show()

```
上記のソースコードは以下のサイトを参考にしました．詳細は以下のサイトを参考にしてください．
https://zenn.dev/labcode/articles/7eaca4f7e9dbcf

プログラムを実行するにあたってvoice_umamusume.pyのパスに移動して以下のコマンドを打ってください

```
python voice_umamusume.py
```
pythonの環境によってはpython3の場合もあります．ご自身の環境に合わせてpythonまたはpython3と入力してください．

# 実行結果
ゴルシが"お母ちゃん！　私，日本一のウマ娘になります！"と言っているセリフを音声データとして入力した結果，以下のようになりました．

![gorushi_supe.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/964975/39cb017e-566e-0bec-3958-9f7644e16b19.png)

次にスペシャールウィークが"私，日本一のウマ娘になりたいです！"とアニメ1期で言っていたセリフを入力した結果，以下のようになりました．

![honmono_supe.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/964975/b236dd2d-c103-4fe0-a181-5d62ba4b88a5.png)

# 考察
周波数の結果が割と似ていますね．セリフが若干違うのとbgmの有無を考慮しても割と似ていると思います．"お母ちゃん"と言っている最初はゴルシの場合，振幅が20を超えていますがスペシャルウィークは超えていません．しかし，Hzが300~800の間はそこそこ似ています．


# 最後に
今回はスペシャルウィークを対象に検証を行いました．検証した結果，モノマネが似ていることが音声の解析結果より分かります．BGMとセリフが若干違う点を考慮しても周波数の結果が特に似ています．ゴルシの声優は上田瞳さんというナレーションも上手な方です．上田瞳のモノマネが上手い．さすがプロですね

※ウマ娘の声をフーリエ変換した記事も書いて発信しています．suzuが私です．興味がある方はぜひご覧ください！
https://vigne-cla.com/31-1/#toc5

※noteも始めました．
https://note.com/madoka235/n/nbba2153326e1

ぜひフォローよろしくお願いします！！！！


# 参考文献
[1]"【Python】pydub使ったら音声データの解析がめっちゃ簡単だった"
https://zenn.dev/labcode/articles/7eaca4f7e9dbcf

[2]"FFmpegを使って動画や音声の処理を行う"
https://www.otsuka-bs.co.jp/web-creation/blog/archive/20231011-02.html

[3]"Youtubeからmp4へのダウンロード"
https://ssyoutube.com/ja33Dy/youtube-to-mp4