2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

web版空間オーディオを利用した仮想空間での位相と距離の調整方法

Last updated at Posted at 2022-12-21

はじめに

今回の記事ではagoraの空間オーディオ(spatial audio)がweb版で正式リリースされたので、そちらを使用したサンプルを作成していきます。

以前に投稿したこちらの記事では、各ユーザー間の位置の距離に応じてボリュームを変更するサンプルを作成しています。
今回の記事では、こちらの制作物に空間オーディオを導入し、よりパワーアップさせます。

今回空間オーディオとして実装するパラメーターは以下の2点とします。
1, 位相
→自分よりも左のpisitionにいるユーザーの声は左から、右にいるユーザーの声は右から聴こえる
2, 距離
→自他のposition間の距離が遠くなると声が小さくなる

2に関しては、前記事の制作物の段階では setVolume APIを用いて音量を調整していましたが、これを空間オーディオ要素の一種である、距離を指定するパラメーターを使用した実装に置き換えていきます。

完成物は以下になります。
github

開発環境

Chrome 107.0.5304.121
その他は上記記事参照

実装

ここからは、index.html内の記述を改良していきます。

事前準備

使用するagoraRTCを最新のものに置き換えておきます。

<script src="https://download.agora.io/sdk/release/AgoraRTC_N.js"></script>

また、jqueryも同リポジトリのこちらから jquery-{バージョン}.min.js を元々のjquery.js と入れ替え、scriptタグの相対パスを書き換えておきます。

また、後にjavascriptの記述を module として扱う関係上、buttonタグのonClick属性やonChange属性が正常に動かなくなります。

そこで予めこれらの属性は削除し、代わりにjqueryでJS上から発火させる形に変えておきます。

async function join() → $(“join”).click(async function (e)

changePosition() の方も同様です。

また、125~128行目のrtmのjoinに関しては現状の記述では警告が出る可能性があるので、以下に置き換えます。

await client.join(appId.value,channel.value, null, userInfo.uid)
localTracks.audioTrack = await AgoraRTC.createMicrophoneAudioTrack({microphoneId:audioSource.value});

spatialAudioExtension導入

agora社のドキュメントにもあるように、以下のフローでの導入を行います。

スクリーンショット 2022-12-20 16.17.37.png

今回は既に出来ているソースに付加していく形になるので、こちらのagora社の提供しているサンプルから、spatialAudioの導入に必要な以下の3ファイルを拝借し、同ディレクトリに配置します。

「audio_spatializer.wasm」
「index.esm.js」
「spatial-audio-worker.js」

続いて、SpatialAudioExtensionクラスをindex.esm.jsからimportする為、javascriptをmodule化します。

<script language="javascript" type="module">

その後importとインスタンスの生成を行います。

import { SpatialAudioExtension } from "./index.esm.js";

const extension = new SpatialAudioExtension();
AgoraRTC.registerExtensions([extension]);

続いて、リモートユーザーのaudioTrackをspatialAudioとして再生する為の処理を記述します。
subscribe() を以下に置き換えます。

async function subscribe(user, mediaType,volume) {
  const uid = user.uid;
  await client.subscribe(user, mediaType);
  console.log("subscribe success");

  //以下が空間オーディオに関わる記述
  const processor = extension.createProcessor();
  user.processor = processor;
  const track = user.audioTrack;
  track.pipe(processor).pipe(track.processorDestination);

  track.play();
}

ここからは、positionに応じて空間オーディオのパラメーターを調整する処理を記述して行きます。

冒頭で記述した通り、今回触るパラメーターは2種類です。

・位相(=azimith)
・距離(=distance)

スクリーンショット 2022-12-20 15.51.07.png

位相は0が前から、90は自分から見て左から、180は後ろ、270は右から聞こえます。
距離は[1,50]の範囲で調整可能であり、数値が大きくなると距離が遠くなるので声が小さくなります。

ここから実際にコードを記述していきます。

自分が位置を変更した時

$("#position").change(function (e) 内の以下の記述で、position間の距離を用いて setVolume API のパラメーターに使用する volumeを計算しています。

var dist = userInfo.position - res.position;
var volume = 100 - (Math.abs(dist))*20;
remoteUsers[i].user.audioTrack.setVolume(volume);

volumeの数値に関しては API が従来の setVolume ではなく空間オーディオ用のものを使う為、若干計算式が変わるのでここでの volume の算出の行は削除します。

ここからは、新たに空間オーディオのパラメーターを変更する為の関数 updateRemotePosition を作成します。

まず左右の振り分けに関して、dist < 0 であれば自分より相手が右にいる事になります。

オーディオの位相を指定する際には pudateSpatialAzimuth([0, 360])が使用できます。

ですので、声が右から聴こえるようにするには processor.updateSpatialAzimuth(270);
で実装が可能です。

距離に関しては同様に updateSpatialDistance([1, 50])で指定ができます。

これらを踏まえて、以下の記述を追記します。

function updateRemotePosition(memberId, dist){
  if(dist < 0){
    remoteUsers[memberId].user.processor.updateSpatialAzimuth(270);
  }else if(dist == 0){
    remoteUsers[memberId].user.processor.updateSpatialAzimuth(0);
  }else{
    remoteUsers[memberId].user.processor.updateSpatialAzimuth(90);
  }

  var volume = 1 + (Math.abs(dist))*7;
  remoteUsers[memberId].user.processor.updateSpatialDistance(volume);
}

その後、先ほどの setVolume API で音量を調整していた箇所を、今作成した関数の呼び出しに置き換えます。

updateRemotePosition(i, dist)

相手が位置を変更した時

空間オーディオのパラメーターを更新する関数は先ほど作成しているので、ここからあまり記述する内容はありません。

joinRtm() の終盤にある以下の記述の箇所が、音量を調整している箇所になります。

var dist = userInfo.position - res.position;
var volume = 100 - (Math.abs(dist))*20;
remoteUsers[memberId].user.audioTrack.setVolume(volume);

先ほどと同様に volume の算出の行を消し、setVolume API を使用している行を以下に置き換えます。

updateRemotePosition(memberId, dist);

以上で、今回の作業は終了です。

二人以上でお試しいただき、相手の声が空間オーディオのパラメーターによって変化しているのが確認できれば成功です。

関連リンク

最後に

agora.ioに関するお問い合わせはこちらから
Agoraの詳細はこちら

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?