Web Audio APIを呼び出すJavaScript … 3(webaudio-1.0.0.js)
initメソッドは4.のJavaScriptを呼び出し、AudioWorkletのプログラムを起動します。
3.のJavaScriptでは、Web Audio APIの実体ともいえる、AudioContextのオブジェクトを生成し、AudioContextのaddModuleメソッドで、4.のJavaScriptに記述しているAudioWorkletProcessorクラスのオブジェクトを呼び出します。
3.と4.のJavaScriptのファイルが別々のファイルになっているのは、「AudioWorkletProcessorクラスのオブジェクトは、addModuleメソッドでファイル名(URL)を指定して呼び出さなければならない」という制約によるものです。
今回は、4.のJavaScriptを呼び出して生成したAudioWorkletNodeオブジェクトに、setFrequencyというメソッド(function)を追加しています。
AudioWorkletNodeオブジェクトのport.postMessageメソッドを使うと、4.のJavaScriptに記述されているプログラムにメッセージを送ることができます。今回のプログラムでは、setFrequencyメソッドの中で、発声したい周波数の値を送るために使用しています。
逆に、AudioWorkletNodeオブジェクトのport.onmessage変数の値(ハンドラ)として例のようなコードを記述すると、4.のJavaScriptに記述されているプログラムからのメッセージを受け取ることができます。今回のプログラムでは、4.のJavaScriptの中のprocessメソッドの動作が始まったことを「enabled」メッセージで教えてもらい、2.のJavaScriptでinitメソッドの引数として渡された関数を呼び出す(コールバックする)ために使用しています。
このメッセージのやりとりは双方向で行えます。
"use strict";
var WEBAUDIO = function () {
var wapAudioWorklet;
this.enable = false;
var rate = 44100;
// ChromeではAudioContext、Safari 14.1より前のバージョンではwebkitAudioContext
var AudioContext = window.AudioContext || window.webkitAudioContext;
var ctx, gain;
var onenabledcallback;
// AudioWorklet有効化時のコールバック関数
var onenabled = function () {
this.enable = true;
if (onenabledcallback) onenabledcallback();
};
// 初期化
this.init = function (callback) {
this.enable = false;
onenabledcallback = callback;
ctx = new AudioContext();
gain = ctx.createGain();
gain.gain.value = 1;
gain.connect(ctx.destination);
rate = ctx.sampleRate;
try {
ctx.audioWorklet.addModule('webaudioawp-1.0.1.js').then(() => {
wapAudioWorklet = new AudioWorkletNode(ctx, "WEBAUDIO", {
processorOptions: {
rate: rate
}
});
wapAudioWorklet.setFrequency = (function (value) {
this.port.postMessage({
message: 'frequency',
freq: value
})
}).bind(wapAudioWorklet);
wapAudioWorklet.port.onmessage = function (event) {
const message = event.data;
switch (message.message) {
case 'enabled':
wapAudioWorklet.connect(gain).connect(ctx.destination);
onenabled.bind(this)();
break;
}
}.bind(this);
});
} catch (e) {
// AudioWorkletに対応していない
console.info('This browser not support AudioWorklet.');
}
}
this.setFrequency = function (freq) {
if (wapAudioWorklet) wapAudioWorklet.setFrequency(freq);
};
this.getAudioContext = function () {
return ctx;
}
};