onset(音の開始点)

目的

楽曲のテンポを求める際に,音の開始点であるonsetを使用することが多い.ここではonsetを求める方法を学ぶ.

説明

onsetの検出

RMS

音の開始点では音が大きくなると考えられる.オーディオデータの振幅は正負の量であり,正の値が大きい程,負の値が小さい程,大きい音となる.音の大きさを表すには,振幅の絶対値か振幅を2乗したものを求めればよい.ここでは振幅を2乗したものを考えよう.オーディデータに対してフレーム処理を行い,各フレームの音の大きさに相当する量を求めるには,振幅を2乗したものの平均を求めればよい.最後に,2乗して求めたデータのスケールを元のスケールに戻すために平方根を求める.これを2乗平均の平方根(Root Mean Square: RMS)と呼び,オーディオデータの各フレームの音の大きさを表すのに使用されることがある.RMSを使用して音の開始点であるonsetを推定してみよう.

10,11行目でフレーム長とフレーム周期に相当する標本点数を指定し,12行目でRMSを求め,14行目でRMSのshapeを表示している.実行すると以下のように表示され,RMSのshapeが(1, 87)であることがわかる.RMSは1次元の量であるため,shape[0]は1であり,87はオーディオデータの標本点数をフレーム周期に相当する標本点数で割った数に1を足した数である.13行目でこれを確認している.

音の開始点ではRMSのフレーム間の差分が大きくなると考えられる.17行目でRMSのフレーム間の差分を求めている.ここでは,RMSが大きくなる場合だけ(フレーム間差分が正の場合だけ)を考えることとし,18行目でフレーム間差分が負の場合に値を0としている.19行目で値が0から1の間に収まるように大きさを正規化している.このようにして求めたものをonset envelopeと呼び,求めたonset envelopeの横軸のデータを29行目で作成し,38行目で描画している.実行すると以下のように表示され,オーディオデータの振幅が大きくなる点でonset envelopeの値が大きくなっていることが確認できる.

onset envelopeがピークとなる点が音の開始点であるとして,onsetを求めてみよう.21行目から26行目で,pre_maxを20ms,post_maxを0ms,pre_avgを100ms,post_avgを100ms,waitを30ms,deltaを0.07とし,27行目でonset envelopeのピークを求めている.この場合,onset envelopeが,-100ms〜100msの平均値+0.07以上であり,かつ,-30ms-0msの最大値であり,かつ,1つ前のピークから30ms離れているとき,その点をピークとして検出している.検出した結果を39行目で描画している.実行すると以下のようになり,onset envelopeのピークがonsetとして検出されていることがわかる.

短時間離散フーリエ変換によるスペクトログラム

以上の例では,オーディオデータのRMSによりonsetを検出した.ここでは,短時間離散フーリエ変換によって求められるスペクトログラムからonsetを検出してみよう.

10行目から16行目で,オーディオデータに短時間離散フーリエ変換をかけ,対数パワースペクトログラムを求めている.音の開始点では対数パワースペクトルのフレーム間の差分が大きくなると考えられる.17行目で対数パワースペクトルのフレーム間差分を求め,18行目で周波数成分ごとに得られたフレーム間差分の平均を求めている.ここでは対数パワーが大きくなる場合だけを考えることとし,19行目でフレーム間差分の平均が負の場合に値を0としている.20行目で値が0から1の間に収まるように大きさを正規化している.これをonset envelopeとし,onsetを求めている.実行すると以下のように表示され,対数パワーが大きくなる箇所がonsetとして検出されていることがわかる.

メル周波数スペクトログラム

次に,メル周波数スペクトログラムからonsetを検出してみよう.

10行目から17行目で,オーディオデータからメル周波数対数パワースペクトログラムを求め,18行目から21行目でonset envelopeを,23行目から29行目でonsetを検出している.実行すると以下のように表示され,メル周波数対数パワーが大きくなる箇所がonsetとして検出されていることがわかる.

librosaモジュールによるonsetの検出

以上では,RMS・スペクトログラム・メル周波数スペクトログラムからonset envelopeを求め,onset envelopeのピークを検出することでonsetを求めた.librosaモジュールを用いると,これらの処理を簡単に実行できる.

9,10行目でフレーム長とフレーム周期を指定し,11行目でonsetに対応するフレーム番号を求めている.12行目で求めたフレーム番号を時間に変換し,17行目で表示している.実行すると以下のように表示され,onsetが検出されていることがわかる.

以上の例ではオーディオデータから直接onsetを検出したが,librosaモジュールを使用してonset envelopeを求めてからonsetを検出することもできる.

9,10行目でフレーム長とフレーム周期を指定し,11行目でonset envelopeを求め,12行目で求めたonset envelopeからonsetを求めている.実行すると以下のように表示され,onset envelopeとonsetが求められていることが確認できる.

RMS

librosaモジュールでは,onset envelopeを求める際に様々な特徴量を指定することができる.ここでは,RMSを指定してonset envelopeを求め,onsetを検出してみよう.

11行目でオーディオデータのRMSを求め,12行目でRMSからonset envelopeを求めている.実行すると以下のように表示され,onset envelopeとonsetが求められていることがわかる.

短時間離散フーリエ変換によるスペクトログラム

次に,短時間離散フーリエ変換によりスペクトログラムを求め,求めたスペクトログラムを指定してonset envelopeを求め,onsetを検出してみよう.

10行目から16行目で,オーディオデータに短時間離散フーリエ変換をかけ,対数パワーを求め,17行目で求めた対数パワーを指定してonset envelopeを求めている.実行すると以下のように表示され,onset envelopeとonsetが求められていることがわかる.

メル周波数スペクトログラム

次に,メル周波数スペクトログラムを求め,求めたメル周波数スペクトログラムを指定してonset envelopeを求め,onsetを検出してみよう.

10行目から16行目で,オーディオデータからメル周波数対数パワーを求め,17行目で求めたメル周波数対数パワーを指定してonset envelopeを求めている.実行すると以下のように表示され,onset envelopeとonsetが求められていることがわかる.

Constant-Q変換によるスペクトログラム

次に,Constant-Q変換によりスペクトログラムを求め,求めたスペクトログラムを指定してonset envelopeを求め,onsetを検出してみよう.

10行目から18行目で,オーディオデータにConstant-Q変換をかけ,対数パワーを求め,19行目で求めた対数パワーを指定してonset envelopeを求めている.実行すると以下のように表示され,onset envelopeとonsetが求められていることがわかる.

Aggregateの指定

以上の例では,スペクトログラムからonset envelopeを求める際に,周波数成分ごとに得られたフレーム間差分の平均を使用していた.librosaモジュールでスペクトログラムからonset envelopeを求める際に,周波数成分ごとに得られたフレーム間差分をどのようにまとめるかを指定することができる.平均を使用する代わりに中央値(median)を使用するには,以下のように記述すればよい.

10行目から17行目でメル周波数対数パワースペクトログラムを求め,18行目でキーワード引数aggregateにnp.medianを指定し,周波数ごとに得られたフレーム間差分の中央値からonset envelopeを求めている.実行すると以下のように表示され,onset envelopeとonsetが求められていることがわかる.

マルチバンド

librosaモジュールには,周波数帯域ごとにonset envelopeを求め,onsetを求めることができる.

10行目で周波数帯域を指定している.この場合,0-32Hz, 32-64Hz, 64-96Hz, 96-128Hzの4つの帯域を指定していることになる.11行目で各帯域のonset envelopeを求め,12行目でそのshapeを表示している.実行すると以下のように表示され,4つの帯域に対してonset envelopeが求められていることがわかる.

27行目で4つの帯域のonset envelopeを描画している.13行目から15行目で,各帯域に対してonsetを検出し,34行目でonsetを描画している.実行すると以下のように表示され,各帯域に対してonsetが検出されていることがわかる.

バックトラック

以上の例ではonset envelopeのピークをonsetとして検出した.音の開始点を音が鳴り始めた点だと考えると,ピークより前の時点を検出したいことがある.そのような場合にはonsetからバックトラックすることで音が成り始めた点を検出することができる.

10行目でonset envelopeを求め,11行目でonsetを検出し,12行目でonsetからバックトラックすることで音が成り始めた点を検出している.実行すると以下のように表示され,音が成り始めた点が検出されていることがわかる.

onset区間ごとの処理

これまでにオーディオデータに対してフレーム処理を行い,各フレームに対して音名やコードの推定を行った.onsetが検出できれば,onsetから次のonsetまでの各区間に対して処理することもできる.ここではonsetを検出し,検出したonsetの各区間に対して音名やコードの推定をしてみよう.

音名の推定

ピアノで「C3 D3 E3 F3 G3 A3 B3 C4」の8音を順に弾いたオーディオデータからonsetを検出し,検出したonsetの各区間に対して音名を推定するには以下のように記述すればよい.

26,27行目でonsetのフレーム番号と時間を求め,29行目から35行目でConstant-Q変換を行い,スペクトログラムを求めている.38行目から40行目で,求めたonsetの各区間に対して繰り返し処理を行っている.41行目で振幅が最大となる音名に対応するインデックス番号を時間毎に求め,42行目で時間方向に走査し,最も多く現れるインデックス番号を求め,45行目で求めたインデックス番号に対応する音名を表示している.43,44行目で各区間の開始時間と終了時間を求め,45行目で表示している.実行すると以下のように表示され,onsetの各区間で正しく音名が推定できていることがわかる.

コード進行の推定

ピアノで「C-G-Am-F」と2回演奏したオーディオデータからonsetを検出し,検出したonsetの各区間に対してコードを推定してみよう.

25,26行目でonsetのフレーム番号と時間を求め,28行目から32行目でクロマグラムを求めている.60行目から62行目で,求めたonsetの各区間に対して繰り返し処理を行っている.63行目で時間方向にクロマグラムの平均を求め,64,65行目で値の大きい3つの音名に対応するインデックス番号からなる集合を求め,68行目で3つの音名を,69行目から72行目でそれに対応するコードがあればコード名を表示している.実行すると以下のように表示され,onsetの各区間の多くで正しくコードが推定できていることがわかる.

課題

課題0

librosaのサンプルオーディオデータからonsetを検出し,表示せよ.

課題1

librosaのサンプルオーディオデータからonset envelopeを求め,onset envelopeからonsetを検出し,表示せよ.

課題2

librosaのサンプルオーディオデータからRMSを,RMSからonset envelopeを求め,onset envelopeからonsetを検出し,表示せよ.

課題3

librosaのサンプルオーディオデータから短時間離散フーリエ変換によりスペクトログラムを,スペクトログラムからonset envelopeを求め,onset envelopeからonsetを検出し,表示せよ.

課題4

librosaのサンプルオーディオデータからメル周波数スペクトログラムを,メル周波数スペクトログラムからonset envelopeを求め,onset envelopeからonsetを検出し,表示せよ.

課題5

librosaのサンプルオーディオデータからConstant-Q変換によりスペクトログラムを,スペクトログラムからonset envelopeを求め,onset envelopeからonsetを検出し,表示せよ.

課題6

librosaのサンプルオーディオデータから,0-32Hz・32-64Hz・64-96Hz・96-128Hzの4つの周波数帯域毎にonset envelopeを求め,onset envelopeからonsetを検出し,表示せよ.

課題7

librosaのサンプルオーディオデータからonset envelopeを求め,onset envelopeからonsetを検出し,表示せよ.また,バックトラックにより音が成り始めた点を検出し,表示せよ.

課題8

ピアノで「C3 D3 E3 F3 G3 A3 B3 C4」の8音を順に弾いたオーディオデータからonsetを検出し,検出したonsetの各区間に対して音名を推定せよ.

課題9

ピアノで「C-G-Am-F」と2回演奏したオーディオデータからonsetを検出し,検出したonsetの各区間に対してコードを推定せよ.