如何将一个或两个乐器连接到Web Audio API并分离立体声信号?

时间:2015-09-13 14:59:05

标签: google-chrome audio split html5-audio web-audio

编辑3:

这只是一个Firefox问题,适用于Chrome,所以问题解决了,请参阅下面的答案。谢谢Chris的帮助!

编辑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分析声音。我知道可以使用麦克风,但插入真正的乐器呢?

1 个答案:

答案 0 :(得分:0)

因此,最初的问题是将更多乐器/实时源(例如乐器和麦克风)连接到Web音频api并分析流。

答案几乎是肯定的:P正如克里斯写的那样,现在不可能得到几种乐器,但是可以分割立体声信号!所以我所做的就是通过一个带有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); }
  );
}

测试的最后小提琴在这里:jsfiddle.net/stratboy/aapafrbu

你可以在比赛时看到比特变化。

作为一名网络程序员,我不明白的一件事是,当在键盘上弹奏一个音符时,没有'onAudioSomething'事件可以说。但也许它是合乎逻辑的,因为我猜这种事件往往对一段音乐无用,因为音频增益通常没有“零点”。因此,分析源的方式是通过requestAnimationFrame()进行轮询。

希望它可以帮助其他探险家:)