５分で動かせる！Pythonで音源分離（demucs）

# demucsって？
2021年4月ごろに、facebookのメタ研究チームが開発した音源分離ライブラリです。これまでspleeterなども提供されていましたが、畳み込みニューラルネットワーク（CNN）を使ったモデルとして最近注目されています。

https://github.com/facebookresearch/demucs

ただ、ライブラリの細かいメソッドが紹介されているドキュメントはまだ用意されておらず、現状、使い方の参考となっているのはこのGitHubリポジトリのリードスのみなのです。

# やること
すでに多くのライターがdemucsについて紹介していますが、Pythonスクリプト（かつmacOS）で紹介しているものは少なかった気がするので、今回は開発環境の構築からスクリプトでの実行まで紹介できればと思います。

# 環境構築
まずは環境を作っていきます。今回は以下の環境で作成していきます。pythonとpythonのパッケージマネージャーが用意できていれば大丈夫です。pipenv以外でも構いませんが、condaなどは対応していない可能性があります。細かいセットアップは別の記事を参考にしてみてください。
<ul>
<li>Mac OS Ventura 13.5.2</li>
<li>チップ：Apple M1</li>
<li>実行環境：pipenv（Python 3.11.3）</li>
</ul>


テキトーにディレクトリを作って、環境を用意します。
```terminal
$ mkdir demucs
$ cd demucs
$ pipenv install --python 3.11.3(最新ver)
```
pipenvを使ってらっしゃる場合、Githubに今回使う環境のリポジトリを用意しておきましたのでもしよければ使ってみてください。事前にpipenvをインストールしておく必要があります。

https://github.com/pdmuds4/demucs-test

```terminal
$ git clone https://github.com/pdmuds4/demucs-test (もしくはDL&unzip)
$ cd demucs-test
$ pipenv install
```

# demucsを動かそう
ライブラリをインストールします。
```terminal
$ pip install demucs
```
実行コードを書きます。ベースとなるプログラムはたったこれだけです。
`options`について説明してきます。
```python:test_demucs.py
import demucs.separate

options = []
demucs.separate.main(options)
```
## options
簡単に言うと、コマンドラインで実行する時のコマンドを入れるだけです。
環境下のターミナルで確認できます。以下、重要な要素だけ紹介します。
```terminal
$ demucs -h
...
positional arguments:
  tracks                Path to tracks
options:
  -n NAME, --name NAME  Pretrained model name or signature. Default is htdemucs.
  --two-stems STEM      Only separate audio into {STEM} and no_{STEM}.
  --int24               Save wav output as 24 bits wav.
  --float32             Save wav output as float32 (2x bigger).
  --flac                Convert the output wavs to flac.
  --mp3                 Convert the output wavs to mp3.
```
### `tracks`
分離する音源のファイルパスです。これは必須なので入れておきましょう。
**macOSは`.mp3`だとエラーを吐いてしまうので、ffmpegで`.wav`に変換してから使うことを推奨します。**
```python:test_demucs.py
options = ["sample/no_vocal.wav"]
```


### `-n NAME`
使用するモデルの名前です。demucsにはいくつかの分離モデルを使用できるようになっており、ここで設定できます。何も指定がない場合は、デフォルトの`htdemucs`が使用されます。

| 分離モデル名 | 説明 |
|:--|:-----|
|`htdemucs`|デフォルトのモデル。[`two-stems`](#--two-stems STEM)がなければ`bass`、`drum`、`vocal`、`other`の4種類に分類する。|
|`htdemucs_ft`|微調整版、４倍の時間がかかるが、精度は高くなる。|
|`htdemucs_6s`|加えて`piano`、`guiter`に分類する。あまり精度は良くない。|
|`hdemucs_mmi`|旧モデル|
|`mdx`|コンテスト用に作成されたモデル。優勝したらしい。|
|`mdx_extra`|追加のトレーニングデータを含むモデル。2位にランクイン。|
|`mdx_q`|軽容量化モデル。品質が悪くなる可能性がある。|

こんな感じで設定します。
```python:test_demucs.py
options = ["sample/on_vocal.wav",
           "-n", "htdemucs"]
```

### `--two-stems STEM`
これを入れると、`vocal`、`other`の２種類に分類します。`STEM`には、分離後のファイル名（`vocal -> {STEM} / other -> no_{STEM}）を設定できます。
```python:test_demucs.py
options = ["sample/on_vocal.wav",
           "-n", "htdemucs",
           "--two-stems", "vocal"]
```

### `--int24`
24bitの`.wav`ファイルで出力します。

### `--float32`
32bitの浮動小数点数で`.wav`ファイルを出力します。
`--int24`よりもサイズが2倍になります。

### `--flac`
`.flac`ファイルで出力します。

### `--mp3`
`.mp3`ファイルで出力します。

<br>
<br>

以下同様でこんな感じです。
```python:test_demucs.py
options = ["sample/on_vocal.wav",
           "-n", "htdemucs",
           "--two-stems", "vocals",
           "--mp3"]
```

## 結果
実行すると、こんな感じでカレントディレクトリ直下に`separated`ディレクトリが作成され、モデル・曲名ごとに分割されます。
```terminal
$ cd separated
$ tree .
.
├── htdemucs
│   ├── music1
│   │   ├── bass.wav
│   │   ├── drums.wav
│   │   ├── other.wav
│   │   └── vocals.wav
│   ├── music2
│   │   ├── no_vocals.mp3
│   │   └── vocals.mp3
└── htdemucs_6s
    └── music3
        ├── no_vocals.mp3
        └── vocals.mp3
```

# 最後に
再生ディスプレイを埋め込めないので視聴はできませんが...^^;
代わりにさっき紹介したリポジトリに実行結果の音声ファイルも入ってるのでよかったら聞いてみてください。また、引数にオプションをつけると動く関数も用意してみたので（`function_demucs.py`）使ってみてください。

https://github.com/pdmuds4/demucs-test


### 参考

https://note.com/mayu_hiraizumi/n/n02cf8212be71

https://qiita.com/rynan4818/items/027fcad54d3fea3e4b31