本稿は「ml5-examples/p5js/PitchDetection/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>
sketch.js
let audioContext;
let mic;
let pitch;
// 一番最初に呼び出される。
function setup() {
// オーディオ入力の作成
// マイクなどの入力からオーディオを取得。
// https://p5js.org/reference/#/p5.AudioIn
mic = new p5.AudioIn();
// AudioInをオンにする(マイクをオン状態にする)
// デフォルトではスピーカーに接続されないので音声は聞こえない。
mic.start();
}
// setup()の次に呼び出される。
function draw() {
// p5.jsのキャンバスの背景色を黒に設定
// https://p5js.org/reference/#/p5/background
background(0);
// AudioInのAmplitude(振幅、ボリュームレベル)を読み取る
// https://p5js.org/reference/#/p5.AudioIn
micLevel = mic.getLevel();
// 楕円を描画する。
// ellipse(x, y, w, [h])
// https://p5js.org/reference/#/p5/ellipse
// 値を、最小値と最大値の間に制限する
// constrain(n, low, high)
// https://p5js.org/reference/#/p5/constrain
ellipse(width / 2, constrain(height - micLevel * height * 5, 0, height), 10, 10);
}
const startPitch = () => {
// オーディオ信号のピッチや基本周波数を推測する
// ml5.pitchDetection(model, audioContext, stream, callback)
// https://ml5js.org/docs/PitchDetection
pitch = ml5.pitchDetection('./model/', audioContext, mic.stream, modelLoaded);
}
// ml5.pitchDetection()によってモデルが読み込まれたら呼び出される
const modelLoaded = () => {
select('#status').html('モデルが読み込まれた');
getPitching();
}
//
const getPitching = () => {
// ピッチの予測を試行するモデルからのピッチを返す
// .getPitch(?callback)
// https://ml5js.org/docs/PitchDetection
pitch.getPitch(function(err, frequency) {
if (frequency) {
select('#result').html(frequency);
}
else {
select('#result').html('ピッチは抽出されていない');
}
// ピッチ値の表示を繰り返す
getPitching();
})
}
// オーディオの自動再生をブロックするChromeへの対処
//
// タッチが登録されるたびに呼び出される
// https://p5js.org/reference/#/p5/touchStarted
function touchStarted() {
console.log(getAudioContext().state);
// このスケッチのAudioContextを返す
// https://p5js.org/reference/#/p5.sound/getAudioContext
if (getAudioContext().state !== 'running') {
// https://developer.mozilla.org/ja/docs/Web/API/AudioContext
// AudioContextオブジェクト
audioContext = getAudioContext();
// あらかじめ中断させられた音声コンテキストの時間の進行を返す。
audioContext.resume();
// ここから本格スタート
startPitch();
}
}