• 3
    Like
  • 1
    Comment

もう一年も前になりますがWeb Audio APIの仕様(2015-12-08)にBaseAudioContextの項目が追加されました。経緯などはこのあたりが参考になります。

従来の継承関係ではリアルタイムレンダリングのAudioContextとオフラインレンダリングのOfflineAudioContextの差異を表現できない。そのため共通部分をBaseAudioContextとして定義し直して、継承関係を整理する。いわゆる破壊的変更だけど影響は少ないだろう。という感じ。

この記事では変更によってどのような影響があるのかを説明します。

変更点

  • OfflineAudioContextはAudioContextのサブクラスではなくなった
  • 共通のスーパークラスとして新しくBaseAudioContextが定義された

更新前の継承ツリー

audio-context

更新後の継承ツリー

base-audio-context

実装状況

Chrome55はすでにBaseAudioContextを使った実装になっています。Firefox50やSafari10はまだ未対応。Edgeは未確認。(どなたか教えてください:pray:

影響

普通に使っている分にはおそらく影響はありません。ただし、モンキーパッチやポリフィルを使っている場合には対応が必要な場合があります。問題になるケースを書きます。

1. OfflineAudioContextがAudioContextのサブクラスでなくなる

次のようなコードはBaseAudioContextの対応状況によってtrueになったりfalseになったりします。こういうコードの必要性をあまり感じないし見たこともないけど、TypeScriptとかだと困ることがあるのかも知れません。

const context = new OfflineAudioContext(2, 44100 * 10, 44100);

assert(context instanceof AudioContext);

対処方法

どちらかであればtrueを返す関数を用意する。

var AudioContext = window.AudioContext || window.webkitAudioContext;
var OfflineAudioContext = window.OfflineAudioContext || window.webkitOfflineAudioContext;

function isAudioContext(context) {
  return (!!AudioContext && context instanceof AudioContext) || (!!OfflineAudioContext && context instanceof OfflineAudioContext);
}

npmモジュール

https://github.com/mohayonao/is-audio-context

2. AudioContext.prototype.hasOwnProertyが壊れる

モンキーパッチなんかで使われるコードが原因でエラーを引き起こす可能性があります。例えば、次のようなコードでcreateGain()がBaseAudioContextで定義されていると条件式がfalseとなりオーディオコンテキストが壊れます。もしくは、AudioContextの拡張がOfflineAudioContextに反映されないというのが考えられます。

if (!AudioContext.prototype.hasOwnProperty('createGain'))
  AudioContext.prototype.createGain = AudioContext.prototype.createGainNode;

対処方法

古いモンキーパッチを使っている場合は、今はまず必要ないので使うのをやめれば良いと思います。それ以外でAudioContextの拡張を行なっている場合は、AudioContext.prototypeを使わずにBaseAudioContext.prototypeを使うようにします。ただし、Chrome55の実装ではwindow.BaseAudioContextが定義されていないので、次の方法で取得する必要があります。

var AudioContext = window.AudioContext || window.webkitAudioContext;
var OfflineAudioContext = window.OfflineAudioContext || window.webkitOfflineAudioContext;

var BaseAudioContext = window.BaseAudioContext || (
  typeof OfflineAudioContext === "function" ? Object.getPrototypeOf(OfflineAudioContext) : AudioContext
);

npmモジュール

https://github.com/mohayonao/base-audio-context

おわり

というわけで、新しく定義されたBaseAudioContextとその変更の影響についてまとめました。

それでは良いウェブオーディオライフを!:santa::santa::santa:

参考

Web Audio API (日本語訳) 2.1 BaseAudioContext インターフェース

おかしな部分や不明な点があれば気軽にコメントしてください。