spleeterを使って音源分離を試しただけ

はじめに

界隈で有名な、音源分離のためのPythonパッケージであるspleeterを使ってみたという話。
github.com

手順

事前にffmpegとlibsndfileはインストールしておく必要はあるとのこと。
https://github.com/deezer/spleeter/wiki/1.-Installation#using-pip

spleeterのインストールはpipでOK。

pip install spleeter

分離対象となる音楽を用意する。
soundcloud.com

以下のPythonスクリプトを実行する。spleeterは5音源まで対応できるということなので、機械的に試してみた。
gist.github.com
初回実行時はモデルパラメータをダウンロードするために時間がかかることには注意。また、実行時には当該のライブラリ由来で色々と警告が出されるかもしれないが、無視してOKである。

分離結果

元の音楽にはピアノやベースの音源が含まれていないので、対応する分離結果もほぼ無音になるのは興味深い。

  • 2音源(ボーカルとインスト)

soundcloud.com

  • 4音源(ボーカル、ベース、ドラム、その他)

soundcloud.com

  • 5音源(ボーカル、ピアノ、ベース、ドラム、その他)

soundcloud.com

まとめ

少なくとも、ボーカルとドラムの抽出には便利に使えそうなライブラリである。

Pyroomacousticsを使って部分空間法に基づく雑音抑圧を試してみた

概要

Pyroomacousticsというパッケージを使って部分空間法に基づく雑音抑圧をやってみた。

結果
  • 元の音声

soundcloud.com

  • 雑音入りの音声

soundcloud.com

  • 雑音抑圧後の音声

soundcloud.com

雑音を大きく削れば、それだけ元の音も削られるため、ある程度の歪みが発生することは避けられない。apply_subspace関数に渡すパラメータを調整する必要はあるが、雑音抑圧後にミュージカルノイズはあまり発生しないのが特徴と言えるだろう。

Pyroomacousticsを使って雑音抑圧(スペクトルサブトラクション法)のバッチ処理を試してみた

概要

Pyroomacousticsというパッケージに同梱のJupyter notebook(下記リンク)を参考に、スペクトルサブトラクション法に基づく雑音抑圧をバッチ処理的にやってみただけである。ノートブックのほぼコピペなので新しいところはない。
nbviewer.jupyter.org

Pyroomacousticsのインストールは以下。

pip install pyroomacoustics

音声ファイルや雑音ファイルは以下からダウンロードできる。
pyroomacoustics/notebooks at master · LCAV/pyroomacoustics · GitHub

Pythonスクリプト

雑音入の音声を用意し、推定した雑音抑圧フィルタをSTFTスペクトルに乗算することで処理を実現する。処理後のSTFTスペクトルは音声へと逆変換され、結果をファイルに保存するという流れである。
gist.github.com

結果
  • 元の音声

soundcloud.com

  • 雑音入りの音声

soundcloud.com

  • 雑音抑圧後の音声

soundcloud.com



「元の雑音」は抑圧できていることが分かる。

考察

雑音抑圧後にも残る(むしろ新たに発生する)雑音は「ミュージカルノイズ」と呼ばれる。スクリプト中の db_reduc の数値を大きくすると、元の雑音はより抑圧できるが、ミュージカルノイズも増える。雑音抑圧レベルとミュージカルノイズのレベルはトレードオフ関係にあるといえる。

雑音抑圧前後のスペクトログラムの表示は今後の予定。

oct2pyを使って独立低ランク行列分析の音源分離デモ(MATLAB)をPython上で動かした話

ブラインド音源分離手法の1つである独立低ランク行列分析(Independent Low-Rank Matrix Analysis; ILRMA)のデモスクリプトが、論文著者により公開されている。
github.com
上記スクリプトMATLAB/Octave用の言語で書かれているが、oct2pyにより(無理やり)Pythonで動かすスクリプトを書いてみた、というのが本記事の主旨である。

以下にPythonスクリプトを示す。オリジナルのMATLABスクリプトにおけるサンプリング周波数変更のためのresample関数をscipy.signal.resample_polyに変更したのが大きい。それ以外は行列のインデックスの調整が主であるが、MATLABにおけるtrueをoctave.logical(1)で置き換えたり、乱数のシードを固定するためにOctaveのseed関数を使うなどした。
gist.github.com

ピアノとドラム音からなる混合観測信号に対して音源分離を行った結果は以下のリンクから試聴できる。

いい感じに音源が分離できていることが分かる。

おまけ
  • ILRMAについて気になった読者はぜひオリジナルの論文にも目を通されたい:

D. Kitamura, N. Ono, H. Sawada, H. Kameoka, H. Saruwatari, "Determined blind source separation unifying independent vector analysis and nonnegative matrix factorization," IEEE/ACM Trans. ASLP, vol. 24, no. 9, pp. 1626-1641, September 2016.

  • 日本語論文は以下。

北村大地, 小野順貴, 澤田宏, 亀岡弘和, 猿渡洋, "独立低ランク行列分析に基づくブラインド音源分離," IEICE Technical Report, EA2017-56, vol. 117, no. 255, pp. 73–80, Toyama, October 2017

  • ILRMAの解説スライドは以下が参考になる。

www.slideshare.net

http://d-kitamura.net/pdf/misc/AlgorithmsForIndependentLowRankMatrixAnalysis.pdf

  • PythonライブラリのpyroomacousticsにはILRMAが実装されている:

Independent Low-Rank Matrix Analysis (ILRMA) — Pyroomacoustics 0.3.1 documentation

oct2pyを使ってMATLAB版legacy-STRAIGHTをPythonから呼び出す

音声の分析合成ツールの1つであるlegacy-STRAIGHTが公開されている。
github.com

このライブラリはMATLAB/Octaveで利用可能なm-fileとして書かれているため、Pythonからは利用できないと諦めていたのだが、最近、m-fileをPythonから起動できるoct2pyなるパッケージの存在を知った。
github.com

タイトルにある通り、oct2py経由でlegacy-STRAIGHTを呼び出すことができたので、本記事はその記録である。

まず公式にある通りoct2pyをインストールする:

pip install oct2py

次にlegacy-STRAIGHTをダウンロードし、src/にある各種ライブラリ群を適切なディレクトリに置く。

Octave forgeからsignalパッケージをダウンロードし、適切なディレクトリに置く。
octave.sourceforge.io

テスト用のwavを用意して、以下のPythonスクリプトを実行する。ちなみにvaiueo2d.wavはlegacy-STRAIGHTのsrc/内にある。

from oct2py import octave
octave.addpath('/path/to/straight')
octave.addpath('/path/to/signal')

x, fs = octave.audioread('vaiueo2d.wav', nout=2)
f0raw = octave.MulticueF0v14(x, fs)
ap = octave.exstraightAPind(x, fs, f0raw)
n3sgram = octave.exstraightspec(x, f0raw, fs)
synthesized_signal = octave.exstraightsynth(f0raw, n3sgram, ap, fs)
octave.audiowrite('out_file.wav', synthesized_signal / 32768, fs)

なお上記のスクリプトにおいて、audioreadの第2引数noutが曲者であった。oct2pyは仕様として、出力の戻り値の個数は明示的に指定する必要がある(noutのデフォルト値は1)。これは知らないとハマる点である。

counsel-switch-bufferとivy-switch-bufferの違い

counsel-switch-bufferは候補選択時に、バッファ内容のプレビューがデフォルトで有効になっている。
ivy-switch-bufferではプレビューはデフォルトで無効になっている。C-M-nやC-M-pで選択時にはプレビューが有効になる。

;; 候補選択時、バッファプレビューあり
(global-set-key (kbd "C-x b") 'counsel-switch-buffer)

;; 候補選択時、バッファプレビューなし (C-M-n, C-M-pでプレビューしながら選択できる)
(global-set-key (kbd "C-x b") 'ivy-switch-buffer)

ivy-posframeの設定

ivy-posframeとは実行コマンドごとにivyのメニューの表示位置を調整できるパッケージだ。
github.com

私の設定は以下:

;; コマンドごとに位置を制御できる
;; nilはivy-posframeの適用なし
(setq ivy-posframe-display-functions-alist
      '((swiper          . nil)
        (swiper-avy      . nil)
        (swiper-isearch  . nil)
        (complete-symbol . ivy-posframe-display-at-point)
        (counsel-M-x     . ivy-posframe-display-at-point)
        (flyspell-correct-ivy . ivy-posframe-display-at-point)
        (counsel-recentf . ivy-posframe-display-at-frame-center)
        (t               . ivy-posframe-display)
        ))

;; ivy-posframeの利用中でもswiper-avyを有効にするおまじない
(define-key ivy-posframe-mode-map
  [remap swiper-avy] nil)

;; フリンジの表示
(setq ivy-posframe-parameters
      '((left-fringe . 8)
        (right-fringe . 8)))

;; コマンドごとにフレームの高さも制御できる(tはデフォルト)
(setq ivy-posframe-height-alist '((t      . 20)))

;; 有効化
(ivy-posframe-mode 1)