如何将一个或两个乐器连接到 Web Audio API 并拆分立体声信号?
How to connect one or two musical instruments to the Web Audio API and split the stereo signal?
编辑 3:
这只是一个 Firefox 问题,在 Chrome 中有效,所以问题已解决,请参阅下面的答案。谢谢克里斯的帮助!
编辑 2:
按照 Chris 的建议,我更改了 getUserMedia 调用中的一行,但它现在不起作用,也许我使用了错误的语法,但此功能未记录:
if(navigator.getUserMedia){
navigator.getUserMedia(
{ audio: { optional: [{ echoCancellation: false }] } }
,function(stream){ init_stream(stream); }
,function(err){ console.log('The following gUM error occured: ' + err); }
);
}
此外,您现在可以在此处关注进度:
http://jsfiddle.net/stratboy/aapafrbu/1/
编辑 1:
我目前正在演奏键盘 > 调音台 > behringer UCA222 > mac (usb)。我当前查看一些数据的代码如下。我看到左声道的数据在变化,但右声道的数据没有变化,尽管我在调音台上做了什么。可能是什么原因?
window.AudioContext = window.AudioContext || window.webkitAudioContext;
navigator.getUserMedia = (navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
var audiocontext = new (window.AudioContext || window.webkitAudioContext)();
var analyser_left = audiocontext.createAnalyser();
var analyser_right = audiocontext.createAnalyser();
var splitter = audiocontext.createChannelSplitter(2);
var index = 0;
function init_stream(stream){
window.audiosource = audiocontext.createMediaStreamSource(stream);
audiosource.connect(splitter);
splitter.connect(analyser_left,0);
splitter.connect(analyser_right,1);
listen();
}
function listen(){
requestAnimationFrame(listen);
analyser_left.fftSize = 256;
var leftBufferLength = analyser_left.frequencyBinCount;
var leftDataArray = new Uint8Array(leftBufferLength);
analyser_left.getByteTimeDomainData(leftDataArray);
$('.monitor_left').html(JSON.stringify(leftDataArray));
analyser_right.fftSize = 256;
var rightBufferLength = analyser_right.frequencyBinCount;
var rightDataArray = new Uint8Array(rightBufferLength);
analyser_right.getByteTimeDomainData(rightDataArray);
$('.monitor_right').html(JSON.stringify(rightDataArray));
}
if(navigator.getUserMedia){
navigator.getUserMedia(
{ audio: true }
,function(stream){ init_stream(stream); }
,function(err){ console.log('The following gUM error occured: ' + err); }
);
}
我想把我的吉他弹奏到电脑上,然后通过网络音频分析声音API。我知道可以使用麦克风,但如果插入真实乐器呢?
是的。我一直这样做(使用非麦克风源)。只需要一个支持guitar/instrument输入的USB音频接口即可。
因此,最初的问题是关于将更多 instruments/real 时间源(例如乐器和麦克风)连接到网络音频 api 并分析流。
答案几乎是肯定的:P 正如 Chris 所写,现在不可能获得多种乐器,但可以分离立体声信号!所以我所做的是通过一个带有 2 个源的混音器(比如,一个键盘和一个麦克风),将一个放在左声道,一个放在右声道。然后连接到某种 USB 声卡(我目前使用的是便宜的 Behringer UCA222)。
原来Firefox好像还是不能分信号,不过Chrome可以,对我来说已经足够了。一些工作代码是这样的,它是不言自明的:
window.AudioContext = window.AudioContext || window.webkitAudioContext;
navigator.getUserMedia = (navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
var audiocontext = new (window.AudioContext || window.webkitAudioContext)();
var analyser_left = audiocontext.createAnalyser();
var analyser_right = audiocontext.createAnalyser();
var splitter = audiocontext.createChannelSplitter(2);
var index = 0;
function init_stream(stream){
window.audiosource = audiocontext.createMediaStreamSource(stream);
audiosource.connect(splitter);
splitter.connect(analyser_left,0);
splitter.connect(analyser_right,1);
listen();
}
function listen(){
requestAnimationFrame(listen);
analyser_left.fftSize = 256;
var leftBufferLength = analyser_left.frequencyBinCount;
var leftDataArray = new Uint8Array(leftBufferLength);
analyser_left.getByteTimeDomainData(leftDataArray);
$('.monitor_left').html(JSON.stringify(leftDataArray));
analyser_right.fftSize = 256;
var rightBufferLength = analyser_right.frequencyBinCount;
var rightDataArray = new Uint8Array(rightBufferLength);
analyser_right.getByteTimeDomainData(rightDataArray);
$('.monitor_right').html(JSON.stringify(rightDataArray));
}
if(navigator.getUserMedia){
navigator.getUserMedia(
{ audio: true }
,function(stream){ init_stream(stream); }
,function(err){ console.log('The following gUM error occured: ' + err); }
);
}
最后要测试的 fiddle 在这里:jsfiddle.net/stratboy/aapafrbu
您可以在播放时看到位在变化。
作为网络程序员,我不明白的一件事是没有 'onAudioSomething' 事件可以捕获,比如在键盘上弹奏一个音符时。但这也许是合乎逻辑的,因为我猜想此类事件通常对一段音乐毫无用处,因为通常音频增益没有 'zero points'。因此,分析来源的方法是通过 requestAnimationFrame() 进行轮询。
希望它能帮助其他探索者:)
编辑 3:
这只是一个 Firefox 问题,在 Chrome 中有效,所以问题已解决,请参阅下面的答案。谢谢克里斯的帮助!
编辑 2:
按照 Chris 的建议,我更改了 getUserMedia 调用中的一行,但它现在不起作用,也许我使用了错误的语法,但此功能未记录:
if(navigator.getUserMedia){
navigator.getUserMedia(
{ audio: { optional: [{ echoCancellation: false }] } }
,function(stream){ init_stream(stream); }
,function(err){ console.log('The following gUM error occured: ' + err); }
);
}
此外,您现在可以在此处关注进度:
http://jsfiddle.net/stratboy/aapafrbu/1/
编辑 1:
我目前正在演奏键盘 > 调音台 > behringer UCA222 > mac (usb)。我当前查看一些数据的代码如下。我看到左声道的数据在变化,但右声道的数据没有变化,尽管我在调音台上做了什么。可能是什么原因?
window.AudioContext = window.AudioContext || window.webkitAudioContext;
navigator.getUserMedia = (navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
var audiocontext = new (window.AudioContext || window.webkitAudioContext)();
var analyser_left = audiocontext.createAnalyser();
var analyser_right = audiocontext.createAnalyser();
var splitter = audiocontext.createChannelSplitter(2);
var index = 0;
function init_stream(stream){
window.audiosource = audiocontext.createMediaStreamSource(stream);
audiosource.connect(splitter);
splitter.connect(analyser_left,0);
splitter.connect(analyser_right,1);
listen();
}
function listen(){
requestAnimationFrame(listen);
analyser_left.fftSize = 256;
var leftBufferLength = analyser_left.frequencyBinCount;
var leftDataArray = new Uint8Array(leftBufferLength);
analyser_left.getByteTimeDomainData(leftDataArray);
$('.monitor_left').html(JSON.stringify(leftDataArray));
analyser_right.fftSize = 256;
var rightBufferLength = analyser_right.frequencyBinCount;
var rightDataArray = new Uint8Array(rightBufferLength);
analyser_right.getByteTimeDomainData(rightDataArray);
$('.monitor_right').html(JSON.stringify(rightDataArray));
}
if(navigator.getUserMedia){
navigator.getUserMedia(
{ audio: true }
,function(stream){ init_stream(stream); }
,function(err){ console.log('The following gUM error occured: ' + err); }
);
}
我想把我的吉他弹奏到电脑上,然后通过网络音频分析声音API。我知道可以使用麦克风,但如果插入真实乐器呢?
是的。我一直这样做(使用非麦克风源)。只需要一个支持guitar/instrument输入的USB音频接口即可。
因此,最初的问题是关于将更多 instruments/real 时间源(例如乐器和麦克风)连接到网络音频 api 并分析流。
答案几乎是肯定的:P 正如 Chris 所写,现在不可能获得多种乐器,但可以分离立体声信号!所以我所做的是通过一个带有 2 个源的混音器(比如,一个键盘和一个麦克风),将一个放在左声道,一个放在右声道。然后连接到某种 USB 声卡(我目前使用的是便宜的 Behringer UCA222)。
原来Firefox好像还是不能分信号,不过Chrome可以,对我来说已经足够了。一些工作代码是这样的,它是不言自明的:
window.AudioContext = window.AudioContext || window.webkitAudioContext;
navigator.getUserMedia = (navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
var audiocontext = new (window.AudioContext || window.webkitAudioContext)();
var analyser_left = audiocontext.createAnalyser();
var analyser_right = audiocontext.createAnalyser();
var splitter = audiocontext.createChannelSplitter(2);
var index = 0;
function init_stream(stream){
window.audiosource = audiocontext.createMediaStreamSource(stream);
audiosource.connect(splitter);
splitter.connect(analyser_left,0);
splitter.connect(analyser_right,1);
listen();
}
function listen(){
requestAnimationFrame(listen);
analyser_left.fftSize = 256;
var leftBufferLength = analyser_left.frequencyBinCount;
var leftDataArray = new Uint8Array(leftBufferLength);
analyser_left.getByteTimeDomainData(leftDataArray);
$('.monitor_left').html(JSON.stringify(leftDataArray));
analyser_right.fftSize = 256;
var rightBufferLength = analyser_right.frequencyBinCount;
var rightDataArray = new Uint8Array(rightBufferLength);
analyser_right.getByteTimeDomainData(rightDataArray);
$('.monitor_right').html(JSON.stringify(rightDataArray));
}
if(navigator.getUserMedia){
navigator.getUserMedia(
{ audio: true }
,function(stream){ init_stream(stream); }
,function(err){ console.log('The following gUM error occured: ' + err); }
);
}
最后要测试的 fiddle 在这里:jsfiddle.net/stratboy/aapafrbu
您可以在播放时看到位在变化。
作为网络程序员,我不明白的一件事是没有 'onAudioSomething' 事件可以捕获,比如在键盘上弹奏一个音符时。但这也许是合乎逻辑的,因为我猜想此类事件通常对一段音乐毫无用处,因为通常音频增益没有 'zero points'。因此,分析来源的方法是通过 requestAnimationFrame() 进行轮询。
希望它能帮助其他探索者:)