可以使用Web Audio API实现自定义
AudioNode吗?
我想构建一个包含其他几个节点(ChannelSplitters和AnalyserNodes)的节点.理想情况下,我可以像任何其他AudioNode一样连接到这个自定义节点.例如,
var customNode = new CustomNode(); mediaStreamSource = context.createMediaStreamSource(userMedia); // This will not work,as I need to know what to implement in CustomNode mediaStreamSource.connect(customNode); customNode.connect(context.destination);
根据MDN documentation,AudioNode实现了EventTarget interface.这是所有用于洗牌音频吗?如果是这样,怎样才能实现这个界面来处理音频?
解决方法
AudioNode类文件
"use strict"; var AudioNode = global.AudioNode; var AudioNode$connect; var AudioNode$disconnect; function connect() { var args = [].slice.call(arguments); if (args.length && typeof args[0].__connectFrom === "function") { args[0].__connectFrom.apply(args[0],[ this ].concat(args.slice(1))); } else { AudioNode$connect.apply(this,args); } } function disconnect() { var args = [].slice.call(arguments); if (args.length && typeof args[0].__disconnectFrom === "function") { args[0].__disconnectFrom.apply(args[0],[ this ].concat(args.slice(1))); } else { AudioNode$disconnect.apply(this,args); } } function use() { if (typeof AudioNode !== "undefined" && AudioNode.prototype.connect !== connect) { AudioNode$connect = AudioNode.prototype.connect; AudioNode$disconnect = AudioNode.prototype.disconnect; AudioNode.prototype.connect = connect; AudioNode.prototype.disconnect = disconnect; } } function unuse() { if (typeof AudioNode !== "undefined" && AudioNode.prototype.connect === connect) { AudioNode.prototype.connect = AudioNode$connect; AudioNode.prototype.disconnect = AudioNode$disconnect; } } module.exports = { use: use,unuse: unuse,};
"use strict"; var assert = require("power-assert"); var PowerAudioNode = require("../"); function CustomAudioNode(audioContext) { this.audioContext = audioContext; this.gain1 = audioContext.createGain(); this.gain2 = audioContext.createGain(); this.inlet = this.gain1; this.outlet = this.gain2; } CustomAudioNode.prototype.connect = function() { this.gain1.connect(this.gain2); this.gain2.connect.apply(this.gain2,arguments); }; CustomAudioNode.prototype.disconnect = function() { this.gain1.disconnect(); this.gain2.disconnect.apply(this.gain2,arguments); }; CustomAudioNode.prototype.__connectFrom = function(source) { source.connect(this.gain1); }; CustomAudioNode.prototype.__disconnectFrom = function(source) { source.disconnect(); }; describe("PowerAudioNode",function() { describe("use(): void",function() { before(PowerAudioNode.use); before(PowerAudioNode.use); it("works",function() { var audioContext = new global.AudioContext(); var oscillator = audioContext.createOscillator(); var customAudioNode = new CustomAudioNode(audioContext); var compressor = audioContext.createDynamicsCompressor(); oscillator.connect(customAudioNode); customAudioNode.connect(compressor); compressor.connect(audioContext.destination); assert(audioContext.destination.$isConnectedFrom(compressor)); assert(compressor.$isConnectedFrom(customAudioNode.outlet)); assert(customAudioNode.inlet.$isConnectedFrom(oscillator)); oscillator.disconnect(customAudioNode); customAudioNode.disconnect(); compressor.disconnect(); assert(!audioContext.destination.$isConnectedFrom(compressor)); assert(!compressor.$isConnectedFrom(customAudioNode.outlet)); assert(!customAudioNode.inlet.$isConnectedFrom(oscillator)); }); }); describe("unuse(): void",function() { before(PowerAudioNode.unuse); it("works",function() { var audioContext = new global.AudioContext(); var oscillator = audioContext.createOscillator(); var customAudioNode = new CustomAudioNode(audioContext); var compressor = audioContext.createDynamicsCompressor(); assert.throws(function() { oscillator.connect(customAudioNode); }); customAudioNode.connect(compressor); compressor.connect(audioContext.destination); assert(audioContext.destination.$isConnectedFrom(compressor)); assert(compressor.$isConnectedFrom(customAudioNode.outlet)); assert(!customAudioNode.inlet.$isConnectedFrom(oscillator)); oscillator.disconnect(); customAudioNode.disconnect(); compressor.disconnect(); assert(!audioContext.destination.$isConnectedFrom(compressor)); assert(!compressor.$isConnectedFrom(customAudioNode.outlet)); assert(!customAudioNode.inlet.$isConnectedFrom(oscillator)); }); }); });