Mac で Spleeter を使ってみた

# はじめに
なんとなく、Pythonを使った何かを体験したかったところで、この `Spleeter` の情報を見かけて、実際に使ってみることにしました。

# Spleeterって?
[Spleeter](https://github.com/deezer/spleeter)は、フランスの音楽配信サイトである [Deezer](https://www.deezer.com/ja/offers/hifi)が開発した、AI を利用して、音楽をパート別を分離するアプリケーションソフトです。
任意の楽曲をこのアプリに読み込ませるとボーカル、ベース、ドラムなどのパートに分離した音声ファイルを出力することができます。
最近はご無沙汰なのですが、DTMの打ち込みをやるにあたり、耳コピは非常につらいものがありますので、これが少しでも低減できるのは嬉しいものです。

# Spleeterの導入手順
`Spleeter`はPythonで動作するアプリケーションですので、Pythonの環境を構築してから`Spleeter`をインストールします。
ここでは、以下のようなmacOSの環境で構築、インストールしました。

|項目||
|-|-|
|OS|macOS Big Sur 11.5.2|
|ハード|MacBook Pro (13-inch, 2017, Four Thunderbolt 3 Ports)|
|CPU|3.1GHz デュアルコア Intel Core i5|
|メモリ|8GByte|

## Homebrewのインストール
まず、Homebrewをインストールします。すでにインストールされて場合はこれをスキップしてください。

①ターミナルを起動します。
②[Homebrew](https://brew.sh/index_ja)のページに行き、ここに表示されるコマンドをコピー&ペーストします。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/1b8cb661-bf82-d936-46cf-de81ce2e68a5.png)

```
% /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
==> Checking for `sudo` access (which may request your password)...
Password:
==> This script will install:
/usr/local/bin/brew
/usr/local/share/doc/homebrew
/usr/local/share/man/man1/brew.1
/usr/local/share/zsh/site-functions/_brew
/usr/local/etc/bash_completion.d/brew
/usr/local/Homebrew
==> The following new directories will be created:
/usr/local/Cellar
/usr/local/Caskroom

Press RETURN to continue or any other key to abort:
```
※`Press RETURN to continue or any other key to abort:` では Retern(Enter)キーを押下します。

```
==> /usr/bin/sudo /bin/mkdir -p /usr/local/Cellar /usr/local/Caskroom
==> /usr/bin/sudo /bin/chmod ug=rwx /usr/local/Cellar /usr/local/Caskroom
==> /usr/bin/sudo /usr/sbin/chown katz /usr/local/Cellar /usr/local/Caskroom

~~~ 中略 ~~~

Error: 
  homebrew-core is a shallow clone.
  homebrew-cask is a shallow clone.
To `brew update`, first run:
  git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallow
  git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask fetch --unshallow
These commands may take a few minutes to run due to the large size of the repositories.
This restriction has been made on GitHub's request because updating shallow
clones is an extremely expensive operation due to the tree layout and traffic of
Homebrew/homebrew-core and Homebrew/homebrew-cask. We don't do this for you
automatically to avoid repeatedly performing an expensive unshallow operation in
CI systems (which should instead be fixed to not use shallow clones). Sorry for
the inconvenience!
Failed during: /usr/local/bin/brew update --force --quiet
```
③エラーが出てしまいました。エラ〜メッセージにしたがってコマンドを実施します。

```
% git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallow
remote: Enumerating objects: 563045, done.
remote: Counting objects: 100% (563035/563035), done.
remote: Compressing objects: 100% (199938/199938), done.
remote: Total 554214 (delta 357072), reused 548563 (delta 351428), pack-reused 0
Receiving objects: 100% (554214/554214), 201.13 MiB | 8.05 MiB/s, done.
Resolving deltas: 100% (357072/357072), completed with 4197 local objects.
From https://github.com/Homebrew/homebrew-core
   7d8991e9851..c17ee8e4b64  master     -> origin/master
```

```
% git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask fetch --unshallow
remote: Enumerating objects: 351943, done.
remote: Counting objects: 100% (351936/351936), done.
remote: Compressing objects: 100% (103184/103184), done.
remote: Total 345455 (delta 246585), reused 340583 (delta 241717), pack-reused 0
Receiving objects: 100% (345455/345455), 137.32 MiB | 7.88 MiB/s, done.
Resolving deltas: 100% (246585/246585), completed with 3252 local objects.
From https://github.com/Homebrew/homebrew-cask
   56c5e308ba..531e6ba041  master     -> origin/master
```
④②を再実行します。

```
% /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
==> Checking for `sudo` access (which may request your password)...
Password:
==> This script will install:
/usr/local/bin/brew
/usr/local/share/doc/homebrew
/usr/local/share/man/man1/brew.1
/usr/local/share/zsh/site-functions/_brew
/usr/local/etc/bash_completion.d/brew
/usr/local/Homebrew

Press RETURN to continue or any other key to abort:
==> /usr/bin/sudo /usr/sbin/chown -R katz:admin /usr/local/Homebrew
==> Downloading and installing Homebrew...
Updating files: 100% (2716/2716), done.
HEAD is now at 4c3f32534 Merge pull request #12482 from Bo98/zero_ar_date
Updated 2 taps (homebrew/core and homebrew/cask).
==> Installation successful!

==> Homebrew has enabled anonymous aggregate formulae and cask analytics.
Read the analytics documentation (and how to opt-out) here:
  https://docs.brew.sh/Analytics
No analytics data has been sent yet (nor will any be during this install run).

==> Homebrew is run entirely by unpaid volunteers. Please consider donating:
  https://github.com/Homebrew/brew#donations

==> Next steps:
- Run brew help to get started
- Further documentation:
    https://docs.brew.sh
```
⑤Homebrewのバージョン確認によりインストール完了を確認します。

```
% brew -v
Homebrew 3.3.5
Homebrew/homebrew-core (git revision 48bd7e9937c; last commit 2021-11-28)
Homebrew/homebrew-cask (git revision 531e6ba041; last commit 2021-11-28)
```
## pyenvのインストール
`pyenv` は、システム上に複数バージョンのPythonを同居させて使い分けられるようにするものです。Pythonを扱う際にインストールしておくと何かと便利なようです。

① Homebrew で pyenv をインストールします。

```
% brew install pyenv
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> Updated Formulae
Updated 2 formulae.

Error: The following directories are not writable by your user:
/usr/local/share/zsh
/usr/local/share/zsh/site-functions

You should change the ownership of these directories to your user.
  sudo chown -R $(whoami) /usr/local/share/zsh /usr/local/share/zsh/site-functions

And make sure that your user has write permission.
  chmod u+w /usr/local/share/zsh /usr/local/share/zsh/site-functions
```
エラーが出てしまいました。
権限などが不足しているようです。
エラーメッセージにしたがって追加します

```
% sudo chown -R $(whoami) /usr/local/share/zsh /usr/local/share/zsh/site-functions
Password:
% chmod u+w /usr/local/share/zsh /usr/local/share/zsh/site-functions
```
③あらためて①を実行します。

```
% brew install pyenv                                                              
==> Downloading https://ghcr.io/v2/homebrew/core/m4/manifests/1.4.19
######################################################################## 100.0%

~~~ 中略 ~~~

==> Installing pyenv
==> Pouring pyenv--2.2.2.big_sur.bottle.tar.gz
🍺  /usr/local/Cellar/pyenv/2.2.2: 834 files, 2.8MB
```

④pyenvがインストールできたか確認します。

```
% pyenv -v
pyenv 2.2.2
```

⑤シェルの環境変数などの定義を追加します。

```
% echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
% echo 'export PATH="$PYENV_ROOT/shims:$PATH"' >> ~/.zshrc
% echo 'eval "$(pyenv init -)"' >> ~/.zshrc
% source ~/.zshrc
```
※`export PATH="$PYENV_ROOT/shims:$PATH"` の部分ですが、古いPythonバージョンでは `export PATH="$PYENV_ROOT/bin:$PATH"` のようです。この後に手順にある Pythonバージョンの切り替えがうまくいかない場合はこの部分を見直してみてください。

## Pythonのインストール
Pythonをインストールします。`Spleeter`は、2021年11月28日現在、Python3.8.xまでにしか対応していないようなので、Python3.8の最新版をインストールします。

①Pythonをインストールします。

```
% pyenv install 3.8.12
python-build: use openssl@1.1 from homebrew
python-build: use readline from homebrew
Downloading Python-3.8.12.tar.xz...

~~~ 中略 ~~~

python-build: use zlib from xcode sdk
Installed Python-3.8.12 to /Users/katz/.pyenv/versions/3.8.12
```
②`python`コマンドで使用するPythonバージョンを、インストールしたバージョンに設定します、

```
% pyenv global 3.8.12
% python -V
Python 3.８.12
```

## ffmpegのインストール
`ffmpeg`は、動画や音声を加工するのに強力で万能なツールアプリケーションです。

①Homebrewを使って ffmpeg をインストールします。

```
% brew install ffmpeg
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> Updated Formulae
Updated 5 formulae.

==> Downloading https://ghcr.io/v2/homebrew/core/brotli/manifests/1.0.9
######################################################################## 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/brotli/blobs/sha256:9d3009fd246d0f6cf9fd11d0a3bd388f6c043c75fa302decf0dd935163fb0f4b

~~~ 中略 ~~~

==> Installing ffmpeg
==> Pouring ffmpeg--4.4.1_3.big_sur.bottle.tar.gz
🍺  /usr/local/Cellar/ffmpeg/4.4.1_3: 276 files, 51MB
```

## Spleeterのインストール
ここまででようやく Spleeter インストールの準備ができましたので、Spleeterをインストールします。

①pip を利用して Spleeter をインストールします。

```
% pip install spleeter                     
Collecting spleeter
  Downloading spleeter-2.3.0-py3-none-any.whl (51 kB)
     |████████████████████████████████| 51 kB 3.7 MB/s 
Collecting llvmlite<0.37.0,>=0.36.0
  Downloading llvmlite-0.36.0-cp38-cp38-macosx_10_9_x86_64.whl (18.5 MB)
     |████████████████████████████████| 18.5 MB 3.6 MB/s 

~~~ 中略 ~~~

Successfully installed absl-py-0.15.0 anyio-3.4.0 appdirs-1.4.4 astunparse-1.6.3 audioread-2.1.9 cachetools-4.2.4 certifi-2021.10.8 cffi-1.15.0 charset-normalizer-2.0.8 click-7.1.2 decorator-5.1.0 ffmpeg-python-0.2.0 flatbuffers-1.12 future-0.18.2 gast-0.4.0 google-auth-2.3.3 google-auth-oauthlib-0.4.6 google-pasta-0.2.0 grpcio-1.34.1 h11-0.12.0 h2-4.1.0 h5py-3.1.0 hpack-4.0.0 httpcore-0.13.7 httpx-0.19.0 hyperframe-6.0.1 idna-3.3 importlib-metadata-4.8.2 joblib-1.1.0 keras-nightly-2.5.0.dev2021032900 keras-preprocessing-1.1.2 librosa-0.8.0 llvmlite-0.36.0 markdown-3.3.6 norbert-0.2.1 numba-0.53.1 numpy-1.19.5 oauthlib-3.1.1 opt-einsum-3.3.0 packaging-21.3 pandas-1.3.4 pooch-1.5.2 protobuf-3.19.1 pyasn1-0.4.8 pyasn1-modules-0.2.8 pycparser-2.21 pyparsing-3.0.6 python-dateutil-2.8.2 pytz-2021.3 requests-2.26.0 requests-oauthlib-1.3.0 resampy-0.2.2 rfc3986-1.5.0 rsa-4.8 scikit-learn-1.0.1 scipy-1.7.3 six-1.15.0 sniffio-1.2.0 soundfile-0.10.3.post1 spleeter-2.3.0 tensorboard-2.7.0 tensorboard-data-server-0.6.1 tensorboard-plugin-wit-1.8.0 tensorflow-2.5.0 tensorflow-estimator-2.5.0 termcolor-1.1.0 threadpoolctl-3.0.0 typer-0.3.2 typing-extensions-3.7.4.3 urllib3-1.26.7 werkzeug-2.0.2 wheel-0.37.0 wrapt-1.12.1 zipp-3.6.0
WARNING: You are using pip version 21.1.1; however, version 21.3.1 is available.
You should consider upgrading via the '/Users/katz/.pyenv/versions/3.8.12/bin/python3.8 -m pip install --upgrade pip' command.
```

②`WARNING: You are using pip version 21.1.1; however, version 21.3.1 is available.` と pip のバージョンアップをうながされましたので、実施しておきます。

```
% pip install --upgrade pip
Requirement already satisfied: pip in ./.pyenv/versions/3.8.12/lib/python3.8/site-packages (21.1.1)
Collecting pip
  Using cached pip-21.3.1-py3-none-any.whl (1.7 MB)
Installing collected packages: pip
  Attempting uninstall: pip
    Found existing installation: pip 21.1.1
    Uninstalling pip-21.1.1:
      Successfully uninstalled pip-21.1.1
Successfully installed pip-21.3.1
```

③Spleeter がインストールできたか確認します。

```
% spleeter --version
Spleeter Version: 2.3.0
```

# Spleeterを使ってみる
Spleeter はコマンドラインを使ってパート分離を行います。
基本的なコマンドオプションは [Spleeter](https://github.com/deezer/spleeter) にのっておりますのでこれを参照してください。
分離元となる音楽ファイルのフォーマットは特に問わないようです。MP3,AAC,ALAC(Apple Lossless)で分離ができることは確認できました。

ざっくりとしては、下記で分離を行うことができます。

```
spleeter separate -o 【出力先ディレクトリ】 -p 【分離方法】 【分離を行う音楽ファイル名】
```
分離方法は下記から選択します。

|オプション名|分離方法|
|-|-|
|spleeter:2stems|ボーカル、伴奏に分離 (`-p` オプションを指定しない場合のデフォルト)|
|spleeter:4stems|ボーカル、ベース、ドラム、その他に分離|
|spleeter:5stems|ボーカル、ピアノ、ベース、ドラム、その他に分離|
【`spleeter:5stems`での実行例】

```
% spleeter separate -o ~/output -p spleeter:5stems ~/TestMusic/AloneAgain.m4a
INFO:spleeter:Downloading model archive https://github.com/deezer/spleeter/releases/download/v1.4.0/5stems.tar.gz
INFO:spleeter:Validating archive checksum
INFO:spleeter:Extracting downloaded 5stems archive
INFO:spleeter:5stems model file(s) extracted
INFO:spleeter:File /Users/katz/output/AloneAgain/piano.wav written succesfully
INFO:spleeter:File /Users/katz/output/AloneAgain/vocals.wav written succesfully
INFO:spleeter:File /Users/katz/output/AloneAgain/bass.wav written succesfully
INFO:spleeter:File /Users/katz/output/AloneAgain/drums.wav written succesfully
INFO:spleeter:File /Users/katz/output/AloneAgain/other.wav written succesfully
% ls -l ~/output/AloneAgain 
total 381440
-rw-r--r--@ 1 katz  staff  38780750 11 28 20:49 bass.wav
-rw-r--r--@ 1 katz  staff  38780750 11 28 20:49 drums.wav
-rw-r--r--@ 1 katz  staff  38780750 11 28 20:49 other.wav
-rw-r--r--@ 1 katz  staff  38780750 11 28 20:49 piano.wav
-rw-r--r--@ 1 katz  staff  38780750 11 28 20:49 vocals.wav
```

※分離方式の初回実行時にはモデルのアーカイブファイルをダウンロードするため少し時間がかかります。

# どこまで分離できる?
手持ちの色々なジャンル(J-POP,Rock,Jazz,Fusion,Eurobeat,Dance,)の曲で`spleeter:5stems`と`spleeter:2stems`を試してみました。
細かい評価は省略しますが、総合的には以下の傾向でした。

* ボーカルはかなり明瞭に分離できる。
* `spleeter:2stems`の伴奏部分(=カラオケ状態)は、ラジカセ等のボーカルカット機能よりもかなり明瞭にボーカルカットが可能。
* ドラムもかなり明瞭に分離できる。
* ベースは総じて聞き取りづらい。
* ピアノはソロパートは聞き取りやすいがバッキングはかなり聞き取りづらい。たまにその他のパートに入ることがある。

# あとがき
ゆっくり検証する時間がとれないのですが、もう少しいろいろ検証してみたいです。