5_1:ピッチ抽出(Pitch Detection) ml5.js JavaScript

pitchDetection()

ピッチ抽出アルゴリズムは、音声信号のピッチや基本周波数を推測する方法です。このメソッドを使用すると、訓練済みの機械学習ピッチ抽出モデルを使って、サウンドファイルのピッチを推測することができます。

ピッチ抽出アルゴリズム(PDA)はWikipediaの「Pitch detection algorithm」によると、音声学、音楽情報検索、音声符号化、音楽演奏システムなどさまざまな状況で使用され、通常、準周期信号の周期を推定し、その値を反転して周波数を求める、とあります。

現時点で、ml5.jsはCREPEモデルのみサポートします。このモデルはgithub.com/marl/crepeを直接移植したもので、ブラウザのマイクから直接入ってくる入力でのみ機能します。

コンストラクタ

ml5.pitchDetection(model, audioContext, stream, callback)

パラメータ

model – 訓練済みモデルへのパス。現在CREPEのみ使用可。大文字小文字の区別あり。
audioContext – 使用する、ブラウザのAudioContext(音声コンテキスト)
stream MediaStream – 使用するメディアストリーム
callback – オプション。モデルが読み込まれたときに呼び出されるコールバック。callbackが与えられない場合は、モデルが読み込まれたときに解決されるPromiseを返す。

プロパティ

.audioContext – AudioContextインスタンス。Contains sampleRate、currentTime、state、baseLatencyを含む。
.model – ピッチ抽出モデル
.results – 分類モデルからの、現在のピッチ抽出の推測結果
.running – モデルインスタンスが実行中かどうかを表すブール値。
.stream – MediaStreamインスタンス。idとブール値のactive値を含む。

メソッド

.getPitch(?callback)
ピッチの推測を試行するモデルからのピッチを返す

callback – オプション。モデルが内容を生成したときに呼び出される関数。callbackが与えられない場合は、モデルがピッチを推測したときに解決されるPromiseを返す。

Chromeブラウザは本稿執筆時現在、音声の自動再生を行わない仕様になっており、音声を再生するにはユーザーからの積極的な、クリックなどのアクションが必要です。pitchDetection()のサンプルではこれが考慮されていないので、本稿の例ではユーザーからの積極的なクリックアクションを取り入れています。

ピッチ値を得るまでの基本的な手順

HTMLでは、p5.sound.jsライブラリを読み込みます。

<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.0/addons/p5.dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.0/addons/p5.sound.min.js"></script>
<script src="https://unpkg.com/ml5@0.1.2/dist/ml5.min.js" type="text/javascript"></script>

JavaScriptコードは適切な順番で実行する必要があります。

  1. p5.jsによって最初に呼び出されるsetup()関数で、マイクからオーディオを取得しマイクをオンにする。
  2. p5.jsによって、画面のクリックで呼び出されるtouchStarted()関数で、AudioContextオブジェクトを取得し、実際の処理をスタートする。
  3. ml5.pitchDetection()でAudioContext、マイク、モデルを関連付ける。
  4. ml5.pitchDetection()によってモデルが読み込まれたら呼び出される関数で、ピッチの値を得る。
let audioContext;
let mic;
let pitch;

// 一番最初に呼び出される。
function setup() {
    noCanvas();
    // 1) マイクからオーディオ入力(AudioIn)を作成し、マイクをオンにする。
    mic = new p5.AudioIn();
    mic.start();
}

// 3) ml5.pitchDetection()でAudioContext、マイク、モデルを関連付ける。
const startPitch = () => {
    pitch = ml5.pitchDetection('./model/', audioContext, mic.stream, modelLoaded);
}

//  4) ml5.pitchDetection()によってモデルが読み込まれたら呼び出される
const modelLoaded = () => {
    console.log('モデルが読み込まれた');
    getPitching();
}

// 5) ピッチの値を得る
const getPitching = () => {
    pitch.getPitch(function(err, frequency) {
        if (frequency) {
            console.log(frequency);
        }
        else {
            console.log('ピッチは抽出されていない');
        }
        // 繰り返す
        getPitching();
    })
}

// オーディオの自動再生をブロックするChromeへの対処
// 2) ユーザーの画面クリックでAudioContextオブジェクトを取得し、処理をスタート
function touchStarted() {
    // AudioContextオブジェクトを得る
    if (getAudioContext().state !== 'running') {
        audioContext = getAudioContext();
        // あらかじめ中断させられた音声コンテキストの時間の進行を返す。
        audioContext.resume();
        // ここから本格スタート
        startPitch();
    }
}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA