以下の Babylon.js 8.0 の記事からもリンクが貼られていた、音関連の話題です。
●Introducing Babylon.js 8.0. Our mission is to build one of the most… | by Babylon.js | Mar, 2025 | Medium
https://babylonjs.medium.com/introducing-babylon-js-8-0-77644b31e2f9
上記の記事内の説明を見ると「オーディオエンジンが刷新された」とのことで、既存のオーディオエンジンが大幅にアップグレードされたようです。具体的には、Web Audio API の機能をより活用できるように進化していたり、利用者が扱いやすいものになっているようです。
今回、公式が提供しているオーディオエンジン関連のサンプルを、少し見ていきます。
公式情報を見ていく
上記の記事で、以下の記載がありました。
Check out a demo: https://aka.ms/babylon8AudioEnginev2Demo
Learn more here: https://aka.ms/babylon8AudioEnginev2Doc
この 2つのうち、2つ目のほう(公式ドキュメント)を見てみます。
公式ドキュメント
上記のリンク先となる、公式ドキュメントのページは以下になります。
●Playing Sounds and Music | Babylon.js Documentation
https://doc.babylonjs.com/features/featuresDeepDive/audio/playingSoundsMusic/
目次を見ると、以下のような内容が並んでいます。
- Creating an audio engine
- Playing a sound
- Streaming a sound
- Sound instances
- Looping playback
- Volume
- Stereo pan
- Spatial audio
- Attaching meshes
- Audio buses
- Main audio buses
- Intermediate audio buses
- Analyzer
- Sound buffers
- Using browser-specific audio codecs
- Browser autoplay considerations
- Playing sounds after the audio engine is unlocked
- Unmute button
- Feature requests and bug fixes
公式サンプル 1つ目を見てみる
今回、これらを見ていく中で、最初に出てくる以下のサンプルなどを見てみます。
●AudioEngineV2 | Babylon.js Playground
https://playground.babylonjs.com/#1BZK59#10
コード
サンプル 1つ目のコードは、以下の通りです。
var createScene = async function () {
// Create a basic scene
var scene = new BABYLON.Scene(engine);
scene.clearColor = BABYLON.Color3.BlackReadOnly;
scene.createDefaultEnvironment({
createGround: false,
createSkybox: false,
createDefaultCameraOrLight: false,
});
scene.createDefaultCameraOrLight(true, true, false);
scene.activeCamera.alpha = Math.PI / 2;
scene.activeCamera.radius = 0.05;
BABYLON.AppendSceneAsync("https://playground.babylonjs.com/scenes/BoomBox.glb", scene);
// Load the sound and play it when the audio engine is unlocked.
(async () => {
const audioEngine = await BABYLON.CreateAudioEngineAsync();
const gunshot = await BABYLON.CreateSoundAsync("gunshot", "https://playground.babylonjs.com/sounds/gunshot.wav");
// Wait for the audio engine to unlock
await audioEngine.unlockAsync();
gunshot.play();
})();
return scene;
};
動作確認
動作としては「モデルなどのロードが終わった後、画面左上に出ているアイコン(以下の赤矢印で示した部分)を押すと、音が再生される」というシンプルなものです。
音を扱うコード
音を扱う部分は、上記のコードの中の以下になると思われます。
// Load the sound and play it when the audio engine is unlocked.
(async () => {
const audioEngine = await BABYLON.CreateAudioEngineAsync();
const gunshot = await BABYLON.CreateSoundAsync("gunshot", "https://playground.babylonjs.com/sounds/gunshot.wav");
// Wait for the audio engine to unlock
await audioEngine.unlockAsync();
gunshot.play();
})();
公式ドキュメントの説明を見ると、「非同期関数(async functionを作成してすぐに実行しているものの、await を使ってオーディオエンジンの "ロック解除" を待つ」という処理になっているようです。
これは「ブラウザの制約により、ユーザーが何か操作をするまで、音の再生がブロックされる」という仕様に対応したもののようです。
今回で言うと、「画面上のアイコンをクリック」=「音の再生が可能になるトリガー(ユーザーの操作)」です。
公式サンプル 2つ目
次は、以下の公式サンプル 2つ目です。
●AudioEngineV2 | Babylon.js Playground
https://playground.babylonjs.com/#1BZK59#11
表示される内容、音を鳴らすトリガーは 1つ目のサンプルと同じです。
画面上のアイコンを押すと、0 から数字をカウントアップしていく音声が流れます。
コード
コードは、以下のとおりです。
var createScene = async function () {
// Create a basic scene
var scene = new BABYLON.Scene(engine);
scene.clearColor = BABYLON.Color3.BlackReadOnly;
scene.createDefaultEnvironment({
createGround: false,
createSkybox: false,
createDefaultCameraOrLight: false,
});
scene.createDefaultCameraOrLight(true, true, false);
scene.activeCamera.alpha = Math.PI / 2;
scene.activeCamera.radius = 0.05;
BABYLON.AppendSceneAsync("https://playground.babylonjs.com/scenes/BoomBox.glb", scene);
// Load a streaming sound and play it when the audio engine is unlocked
(async () => {
const audioEngine = await BABYLON.CreateAudioEngineAsync();
const narration = await BABYLON.CreateStreamingSoundAsync("narration", "https://assets.babylonjs.com/sound/testing/60-count.mp3");
// Wait for the audio engine to unlock
await audioEngine.unlockAsync();
narration.play();
})();
return scene;
};
音を扱う部分は、以下になるようです。
// Load a streaming sound and play it when the audio engine is unlocked
(async () => {
const audioEngine = await BABYLON.CreateAudioEngineAsync();
const narration = await BABYLON.CreateStreamingSoundAsync("narration", "https://assets.babylonjs.com/sound/testing/60-count.mp3");
// Wait for the audio engine to unlock
await audioEngine.unlockAsync();
narration.play();
})();
実装内容
実装内容について、公式ドキュメントの記載を見てみます。
今回の音の再生では「ストリーミング再生」が行われているようです。
この機能では、ブラウザの HTMLMediaElement を活用しているようです。
再生方法がストリーミングの場合、再生時には音声ファイルの一部だけをメモリに保持して、全体をオーディオバッファに読み込む前に再生を開始できます。そのため、長時間の音声ファイルを再生する際に使うメモリを節約できたり、BGM や 長尺のナレーションなどに向いているとのことです。
おわりに
今回、Babylon.js の「Playing Sounds and Music」のサンプルを 2つほど見てみました。
JavaScript で音を扱う話(ブラウザ上のものと Node.js を使ったもの)は、以下を使ったもの等を過去に色々と試しましたが、今回の記事で書いた Babylon.js のオーディオエンジンの機能も扱っていければと思います。