如何将一个或两个乐器连接到 Web Audio API 并拆分立体声信号?
Posted
技术标签:
【中文标题】如何将一个或两个乐器连接到 Web Audio API 并拆分立体声信号?【英文标题】:How to connect one or two musical instruments to the Web Audio API and split the stereo signal? 【发布时间】:2015-09-13 14:59:04 【问题描述】:编辑 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 分析声音。我知道可以使用麦克风,但插入真正的乐器呢?
【问题讨论】:
你必须得到一个前置放大器,将你的吉他插入前置放大器,然后从前置放大器获取输出并将其插入你的麦克风输入。 【参考方案1】:是的。我一直这样做(使用非麦克风源)。只需获得支持吉他/乐器输入的 USB 音频接口即可。
【讨论】:
哇!我几乎可以肯定我不能......还有两个问题:你用什么 js 类/接口来从 USB 获取声音?从 MDN 我了解了如何获取麦克风,但我还不清楚获取 USB 源的正确代码是什么。和 q#2:是否可以分别分析 2 个同时源(例如 usb + mic)?我想为 [keyboards: source 1] 和其他乐器 [guitar+bass+sax: source 2] 进行不同视觉效果的现场表演。 您可以通过getMediaDevices选择输入设备-我在输入效果演示中使用它(webaudiodemos.appspot.com/input/index.html)-相关代码从github.com/cwilso/Audio-Input-Effects/blob/master/js/…开始。 (搜索 gotSources 看看它的作用。) 关于分析单独的音源——Chrome 至少目前只支持单声道和立体声源;当然,您可以通过立体声输入的单独通道为您的键盘和其他乐器提供信号,并这样做。 (您需要使用 ChannelSplitterNode 拆分成两个输出并通过单独的 AnalyserNode 运行每个输出。)多通道(不仅仅是立体声)输入是我们正在处理的一个错误。另一方面,多设备——同时使用你的耳机麦克风和USB音频输入设备——要复杂得多,我不希望在不久的将来工作。 非常感谢,我会选择立体声方式。你的演示非常令人印象深刻! :) cwilso:请注意,如果您可以/想要/有时间/等.. ;) ***.com/questions/32915635/…【参考方案2】:所以,最初的问题是关于将更多乐器/实时源(例如乐器和麦克风)连接到网络音频 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);
);
最后要测试的小提琴在这里:jsfiddle.net/stratboy/aapafrbu
您可以在播放时看到位的变化。
作为一名网络程序员,我不明白的一件事是,当在键盘上播放单个音符时,没有可以捕捉到的“onAudioSomething”事件。但也许这很合乎逻辑,因为我猜这样的事件通常对一首音乐毫无用处,因为音频增益通常没有“零点”。所以分析来源的方法是通过 requestAnimationFrame() 进行轮询。
希望它可以帮助其他一些探索者:)
【讨论】:
它仍然使用麦克风,所以没有区别。以上是关于如何将一个或两个乐器连接到 Web Audio API 并拆分立体声信号?的主要内容,如果未能解决你的问题,请参考以下文章
如何将带有前缀列的表连接到 PHP MySQL 或 Laravel 中的另外两个表
IOS上的 Audio Memos SE 如何分享和传输录音到电脑?
Inter App Audio 技术:使效果节点和乐器节点独立
如何使用 Web3.js 将 Metamask 连接到 Angular App?