ファミコンっぽい効果音をAIで自動生成したい【WaveNet】

# はじめに
最近は**NovelAI**や**Stable Diffution**などの画像生成AIが生み出すイラストやアートのクオリティが高まってて話題になってますよね。これらはLineチャットボットやDiscordサーバーで誰でも気軽に試せるような環境も整っているみたいです。

一方で音楽や音声の方面はどんな感じだろうと前々から気になっていたのですが、ファミコンっぽい効果音くらい今ならサクッと自動生成できるのでは？と思い、音声合成モデルの一つである**WaveNet**を使って趣味程度に遊んでみた記事になります。

# WaveNet
WaveNetは2016年にGoogle DeepMindが開発した**TTS**（Text To Speech、テキスト読み上げ）のためのディープニューラルネットワークの音声合成モデルで、例えば[Google CloudのText-To-Speechサービス](https://cloud.google.com/text-to-speech?hl=ja)として既に製品に実装されているようです。wavデータのような生の音声波形データを直接学習・生成することができる点が特徴的な手法で、TTSの領域において既存手法より自然な音声が生成可能であるといわれています。技術的詳細や実際の生成例は[公式ドキュメント](https://www.deepmind.com/blog/wavenet-a-generative-model-for-raw-audio)で紹介されていますので、ご参照ください。


# 実装
今回はGitHubにて公開されている[こちら](https://github.com/ibab/tensorflow-wavenet)のPython実装を利用させていただきました。


# 学習

## 学習データ
学習データの作成には[sfxr](https://www.drpetter.se/project_sfxr.html)という効果音作成ソフトを利用させていただきました。ファミコンっぽい効果音を手軽に作ることができるソフトで、以下の動画を見るとどんな音が作れるか雰囲気が伝わるかと思います。

<iframe width="560" height="315" src="https://www.youtube.com/embed/4PvDoZisCOY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

--
今回は1秒前後のwavファイルを合計1100個作成しました。ファミコンチックなジャンプ音やダメージ音、爆発音など、11のカテゴリにつき100個ずつの内訳としました。作成した学習データは[こちら](https://www.dropbox.com/sh/iny1nc9yp9o5a62/AAAfAo9zxFLdZ6A_9k8q1ehWa?dl=0)にアップロードしていますので、よければご参照ください。

## 学習させる
学習データを`samples`ディレクトリに格納し、`train.py`のあるディレクトリで以下のコマンドを実行します。
```train.sh
python train.py --data_dir=samples
```
学習済みモデルはデフォルトで`logdir/train`ディレクトリ以下に出力されます。
今回はパラメータはデフォルトの設定のまま、100000ステップの学習を行いました。


# 生成
学習済みモデルを用いて、16kHzのサンプリング周波数で1秒間の音をランダムに生成します。`generate.py`のあるディレクトリで例えば以下のようにコマンドを実行します。
```generate.sh
python generate.py --wav_out_path=generated.wav --samples 16000 logdir/train/100000steps/model.ckpt-99999
```
学習時に生成された学習済みモデル（この例では`logdir/train/100000steps/model.ckpt-99999`）を引数として指定してやる必要があります。また、オプションとして`--sample 16000`を指定することで1秒間の音声データを生成しています。

## 生成データ
今回の検証で作ったモデルから生成した音声を以下の動画にまとめてみました。

<iframe width="560" height="315" src="https://www.youtube.com/embed/-JH-Fy56ob8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

--
多くがブザー音や叫び声のような音になってしまったものの、カーソル移動音っぽいものや障害物にぶつかった感じの、そこそこ効果音に使えそうな音がたまーに生成できている印象でした。以下にもいくつか抜粋して載せてみます。

- [サンプル1](https://www.dropbox.com/s/0q7povcfycf225s/generated_2022-11-02-01-41-41.wav?dl=0)
    - ぶつかった音とかキャンセル音などに使えそう？

- [サンプル2](https://www.dropbox.com/s/9qjyu6ntkll6t0u/generated_2022-11-02-01-48-53.wav?dl=0)
    - 回復音やカーソル音っぽい？

- [サンプル3](https://www.dropbox.com/s/h4nou3mu6g1r7ra/generated_2022-11-02-01-59-56.wav?dl=0)
    - ブザーか叫び声みたいな音…



## 効果音として使ってみた
せっかくなので（？）RPGツクールMVで試しに効果音として使ってみました。戦闘中のカーソル移動音、決定音、キャンセル音、攻撃音、ダメージ音をなるべくそれっぽくなるように差し替えてみています。全体的にノイジーな感じはあるものの、そこまで悪くない気もする…？

<iframe width="560" height="315" src="https://www.youtube.com/embed/aH44XDuJRng?start=5" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


# おわりに
粗はあるものの、ごく単純な効果音程度であれば一般公開されているモデルをそのまま使っても意外と自動生成できそうかも…？という感覚が少し得られました（そもそもsfxrから直接生成すればいいのでは、と突っ込みたくなりますが、今回は検証ということで…）。

本来WaveNetはTTSに対する手法であるため、今回対象としたような効果音をうまく生成するためにはおそらくパラメータ調整やネットワーク自体の構造をもっとそれ向けに最適化すべきだと思うのですが、いかんせん非専門なのもあってそのあたりを全然試せておらず…余裕があれば勉強して試行錯誤してみたいところです。


# 参考
[WaveNet: A generative model for raw audio](https://www.deepmind.com/blog/wavenet-a-generative-model-for-raw-audio)
[A TensorFlow implementation of DeepMind's WaveNet paper](https://github.com/ibab/tensorflow-wavenet)