├── AudioContextMonkeyPatch.js ├── README.md └── index.html /AudioContextMonkeyPatch.js: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Chris Wilson 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | /* 17 | 18 | This monkeypatch library is intended to be included in projects that are 19 | written to the proper AudioContext spec (instead of webkitAudioContext), 20 | and that use the new naming and proper bits of the Web Audio API (e.g. 21 | using BufferSourceNode.start() instead of BufferSourceNode.noteOn()), but may 22 | have to run on systems that only support the deprecated bits. 23 | 24 | This library should be harmless to include if the browser supports 25 | unprefixed "AudioContext", and/or if it supports the new names. 26 | 27 | The patches this library handles: 28 | if window.AudioContext is unsupported, it will be aliased to webkitAudioContext(). 29 | if AudioBufferSourceNode.start() is unimplemented, it will be routed to noteOn() or 30 | noteGrainOn(), depending on parameters. 31 | 32 | The following aliases only take effect if the new names are not already in place: 33 | 34 | AudioBufferSourceNode.stop() is aliased to noteOff() 35 | AudioContext.createGain() is aliased to createGainNode() 36 | AudioContext.createDelay() is aliased to createDelayNode() 37 | AudioContext.createScriptProcessor() is aliased to createJavaScriptNode() 38 | AudioContext.createPeriodicWave() is aliased to createWaveTable() 39 | OscillatorNode.start() is aliased to noteOn() 40 | OscillatorNode.stop() is aliased to noteOff() 41 | OscillatorNode.setPeriodicWave() is aliased to setWaveTable() 42 | AudioParam.setTargetAtTime() is aliased to setTargetValueAtTime() 43 | 44 | This library does NOT patch the enumerated type changes, as it is 45 | recommended in the specification that implementations support both integer 46 | and string types for AudioPannerNode.panningModel, AudioPannerNode.distanceModel 47 | BiquadFilterNode.type and OscillatorNode.type. 48 | 49 | */ 50 | (function (global, exports, perf) { 51 | 'use strict'; 52 | 53 | function fixSetTarget(param) { 54 | if (!param) // if NYI, just return 55 | return; 56 | if (!param.setTargetAtTime) 57 | param.setTargetAtTime = param.setTargetValueAtTime; 58 | } 59 | 60 | if (window.hasOwnProperty('webkitAudioContext') && 61 | !window.hasOwnProperty('AudioContext')) { 62 | window.AudioContext = webkitAudioContext; 63 | 64 | if (!AudioContext.prototype.hasOwnProperty('createGain')) 65 | AudioContext.prototype.createGain = AudioContext.prototype.createGainNode; 66 | if (!AudioContext.prototype.hasOwnProperty('createDelay')) 67 | AudioContext.prototype.createDelay = AudioContext.prototype.createDelayNode; 68 | if (!AudioContext.prototype.hasOwnProperty('createScriptProcessor')) 69 | AudioContext.prototype.createScriptProcessor = AudioContext.prototype.createJavaScriptNode; 70 | if (!AudioContext.prototype.hasOwnProperty('createPeriodicWave')) 71 | AudioContext.prototype.createPeriodicWave = AudioContext.prototype.createWaveTable; 72 | 73 | 74 | AudioContext.prototype.internal_createGain = AudioContext.prototype.createGain; 75 | AudioContext.prototype.createGain = function() { 76 | var node = this.internal_createGain(); 77 | fixSetTarget(node.gain); 78 | return node; 79 | }; 80 | 81 | AudioContext.prototype.internal_createDelay = AudioContext.prototype.createDelay; 82 | AudioContext.prototype.createDelay = function(maxDelayTime) { 83 | var node = maxDelayTime ? this.internal_createDelay(maxDelayTime) : this.internal_createDelay(); 84 | fixSetTarget(node.delayTime); 85 | return node; 86 | }; 87 | 88 | AudioContext.prototype.internal_createBufferSource = AudioContext.prototype.createBufferSource; 89 | AudioContext.prototype.createBufferSource = function() { 90 | var node = this.internal_createBufferSource(); 91 | if (!node.start) { 92 | node.start = function ( when, offset, duration ) { 93 | if ( offset || duration ) 94 | this.noteGrainOn( when || 0, offset, duration ); 95 | else 96 | this.noteOn( when || 0 ); 97 | }; 98 | } else { 99 | node.internal_start = node.start; 100 | node.start = function( when, offset, duration ) { 101 | if( typeof duration !== 'undefined' ) 102 | node.internal_start( when || 0, offset, duration ); 103 | else 104 | node.internal_start( when || 0, offset || 0 ); 105 | }; 106 | } 107 | if (!node.stop) { 108 | node.stop = function ( when ) { 109 | this.noteOff( when || 0 ); 110 | }; 111 | } else { 112 | node.internal_stop = node.stop; 113 | node.stop = function( when ) { 114 | node.internal_stop( when || 0 ); 115 | }; 116 | } 117 | fixSetTarget(node.playbackRate); 118 | return node; 119 | }; 120 | 121 | AudioContext.prototype.internal_createDynamicsCompressor = AudioContext.prototype.createDynamicsCompressor; 122 | AudioContext.prototype.createDynamicsCompressor = function() { 123 | var node = this.internal_createDynamicsCompressor(); 124 | fixSetTarget(node.threshold); 125 | fixSetTarget(node.knee); 126 | fixSetTarget(node.ratio); 127 | fixSetTarget(node.reduction); 128 | fixSetTarget(node.attack); 129 | fixSetTarget(node.release); 130 | return node; 131 | }; 132 | 133 | AudioContext.prototype.internal_createBiquadFilter = AudioContext.prototype.createBiquadFilter; 134 | AudioContext.prototype.createBiquadFilter = function() { 135 | var node = this.internal_createBiquadFilter(); 136 | fixSetTarget(node.frequency); 137 | fixSetTarget(node.detune); 138 | fixSetTarget(node.Q); 139 | fixSetTarget(node.gain); 140 | return node; 141 | }; 142 | 143 | if (AudioContext.prototype.hasOwnProperty( 'createOscillator' )) { 144 | AudioContext.prototype.internal_createOscillator = AudioContext.prototype.createOscillator; 145 | AudioContext.prototype.createOscillator = function() { 146 | var node = this.internal_createOscillator(); 147 | if (!node.start) { 148 | node.start = function ( when ) { 149 | this.noteOn( when || 0 ); 150 | }; 151 | } else { 152 | node.internal_start = node.start; 153 | node.start = function ( when ) { 154 | node.internal_start( when || 0); 155 | }; 156 | } 157 | if (!node.stop) { 158 | node.stop = function ( when ) { 159 | this.noteOff( when || 0 ); 160 | }; 161 | } else { 162 | node.internal_stop = node.stop; 163 | node.stop = function( when ) { 164 | node.internal_stop( when || 0 ); 165 | }; 166 | } 167 | if (!node.setPeriodicWave) 168 | node.setPeriodicWave = node.setWaveTable; 169 | fixSetTarget(node.frequency); 170 | fixSetTarget(node.detune); 171 | return node; 172 | }; 173 | } 174 | } 175 | 176 | if (window.hasOwnProperty('webkitOfflineAudioContext') && 177 | !window.hasOwnProperty('OfflineAudioContext')) { 178 | window.OfflineAudioContext = webkitOfflineAudioContext; 179 | } 180 | 181 | }(window)); 182 | 183 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | AudioContext monkeypatch 2 | ============================== 3 | 4 | This monkeypatch library is intended to be included in projects that are 5 | written to the proper AudioContext spec (instead of webkitAudioContext), 6 | and that use the new naming and proper bits of the Web Audio API (e.g. 7 | using BufferSourceNode.start() instead of BufferSourceNode.noteOn()), but may 8 | have to run on systems that only support the deprecated bits. 9 | 10 | This library should be harmless to include if the browser supports 11 | unprefixed "AudioContext", and/or if it supports the new names. 12 | 13 | The patches this library handles: 14 | --------------------------------- 15 | if window.AudioContext is unsupported, it will be aliased to webkitAudioContext(). 16 | if AudioBufferSourceNode.start() is unimplemented, it will be routed to noteOn() or 17 | noteGrainOn(), depending on parameters. 18 | 19 | The following aliases only take effect if the new names are not already in place: 20 | 21 | - AudioBufferSourceNode.stop() is aliased to noteOff() 22 | - AudioContext.createGain() is aliased to createGainNode() 23 | - AudioContext.createDelay() is aliased to createDelayNode() 24 | - AudioContext.createScriptProcessor() is aliased to createJavaScriptNode() 25 | - AudioContext.createPeriodicWave() is aliased to createWaveTable() 26 | - OscillatorNode.start() is aliased to noteOn() 27 | - OscillatorNode.stop() is aliased to noteOff() 28 | - AudioParam.setTargetAtTime() is aliased to setTargetValueAtTime() 29 | - OscillatorNode.setPeriodicWave() is aliased to setWaveTable() 30 | 31 | This library does NOT patch the enumerated type changes, as it is 32 | recommended in the specification that implementations support both integer 33 | and string types for AudioPannerNode.panningModel, AudioPannerNode.distanceModel 34 | BiquadFilterNode.type and OscillatorNode.type. 35 | 36 | You can copy the AudioContextMonkeyPatch.js into your project if you 37 | like, or include it as http://cwilso.github.com/AudioContext-MonkeyPatch/AudioContextMonkeyPatch.js. 38 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |You can, however, link directly to http://cwilso.github.com/AudioContext-MonkeyPatch/AudioContextMonkeyPatch.js in your code if you like. 11 | 12 | 13 | --------------------------------------------------------------------------------