.

案例研究使用Chrome的JAM我们如

JAMwithChrome是由Google创建的基于网络的音乐项目。JAMwithChrome可以让来自世界各地的人们在浏览器中实时组成乐队并即兴演奏。我们DinahMoe很高兴成为这个项目的一部分。我们的职责是为应用程序制作音乐,并设计和开发音乐组件。开发包括三个主要领域:一个音乐工作站,包括MIDI播放、软件采样器、音频效果、路由和混音;实时交互控制音乐的音乐逻辑引擎;以及一个同步组件,可确保会话中的所有玩家同时听到音乐,这是能够一起玩的先决条件。

为了实现最高级别的真实性、准确性和音频质量,我们选择使用WebAudioAPI。本案例研究将讨论我们遇到的一些挑战,以及我们如何解决这些挑战。HTML5Rocks上已经有许多很棒的介绍性文章可以帮助您开始使用WebAudio,因此我们将直接跳入池的深处。

编写自定义音频效果

WebAudioAPI在规范中包含许多有用的效果,但我们需要为JAMwithChrome中的乐器提供更精细的效果。有很多种例如WebAudio中有一个本地延迟节点,但延迟——立体声延迟、乒乓延迟、回弹延迟等等。幸运的是,所有这些都可以使用原生效果节点和一些想象力在网络音频中创建。

由于我们希望能够以尽可能透明的方式使用本机节点和我们自己的自定义效果,因此我们决定需要创建一种包装格式来实现这一点。WebAudio中的本地节点使用其连接方法将节点链接在一起,因此我们需要模拟这种行为。这就是基本的想法:

varMyCustomNode=function(){this.input=audioContext.createGain();varoutput=audioContext.createGain();this.connect=function(target){output.connect(target);};};

通过这种模式,我们真的很接近本地节点。让我们看看如何使用它。

//createacoupleofnativenodesandourcustomnodevargain=audioContext.createGain(),customNode=newMyCustomNode(),anotherGain=audioContext.createGain();//connectourcustomnodetothenativenodesandsendtotheoutputgain.connect(customNode.input);customNode.connect(anotherGain);anotherGain.connect(audioContext.destination);

我们的自定义节点和本机节点之间的唯一区别是我们必须连接到自定义节点输入属性。我敢肯定有办法规避这一点,但这对我们的目的来说已经足够接近了。可以进一步开发此模式以模拟本机AudioNode的断开连接方法,以及在连接时容纳用户定义的输入/输出等。查看规范以了解本机节点可以做什么。

现在我们有了创建自定义效果的基本模式,下一步是实际为自定义节点提供一些自定义行为。让我们看一下slapback延迟节点。

喜欢你的意思

slapback延迟,有时称为slapback回声,是一种用于多种乐器的经典效果,从50年代风格的人声到冲浪吉他。该效果采用传入的声音并播放声音的副本,并略微延迟大约75-50毫秒。这给人一种声音被拍回来的感觉,因此得名。我们可以像这样创建效果:

varSlapbackDelayNode=function(){//createthenodeswe’llusethis.input=audioContext.createGain();varoutput=audioContext.createGain(),delay=audioContext.createDelay(),feedback=audioContext.createGain(),wetLevel=audioContext.createGain();//setsomedecentvaluesdelay.delayTime.value=0.15;//msdelayfeedback.gain.value=0.5;wetLevel.gain.value=0.5;//setuptheroutingthis.input.connect(delay);this.input.connect(output);delay.connect(feedback);delay.connect(wetLevel);feedback.connect(delay);wetLevel.connect(output);this.connect=function(target){output.connect(target);};};

正如你们中的一些人可能已经意识到的那样,这种延迟也可以用于更大的延迟时间,从而成为带有反馈的常规单声道延迟。这是一个使用此延迟的示例,让您听到它的声音。

按下鼠标发出声音

这个简单的效果可以做很多事情。它是其他效果的基础,如合唱和移相器,但它也可以通过例如插入仅影响延迟信号的其他效果来进一步发展。

路由音频

在专业音频应用程序中使用不同的乐器和音乐部分时,必须有一个灵活的路由系统,让您能够以有效的方式混合和调制声音。在带有Chrome的JAM中,我们开发了一个音频总线系统,类似于物理混音板中的系统。这使我们能够将所有需要混响效果的乐器连接到公共总线或通道,然后将混响添加到该总线,而不是将混响添加到每个单独的乐器。这是一项重大优化,强烈建议您在开始执行更复杂的应用程序后立即执行类似的操作。

幸运的是,这在网络音频中很容易实现。我们基本上可以使用我们为效果定义的骨骼并以相同的方式使用它。

varAudioBus=function(){this.input=audioContext.createGain();varoutput=audioContext.createGain();//createeffectnodes(ConvolverandEqualizerareothercustomeffectsfromthelibrarypresentedattheendofthearticle)vardelay=newSlapbackDelayNode(),convolver=newtuna.Convolver(),equalizer=newtuna.Equalizer();//route‘em//equalizer-delay-convolverthis.input.connect(equalizer);equalizer.connect(delay.input);delay.connect(convolver);convolver.connect(output);this.connect=function(target){output.connect(target);};};

这将像这样使用:

//createsomenativeoscillatorsandourcustomaudiobusvarbus=newAudioBus(),instrument1=audioContext.createOscillator(),instrument=audioContext.createOscillator(),instrument=audioContext.createOscillator();//connectourinstrumentstothesamebusinstrument1.connect(bus.input);instrument.connect(bus.input);instrument.connect(bus.input);bus.connect(audioContext.destination);

我们以一半的成本应用了延迟、均衡和混响(这是一种相当昂贵的效果,性能明智),就好像我们将效果应用于每个单独的乐器一样。如果我们想给总线添加一些额外的趣味,我们可以添加两个新的增益节点-preGain和postGain-这将允许我们以两种不同的方式关闭或淡化总线中的声音。preGain放在效果之前,postGain放在链的末尾。如果我们随后淡化preGain,则在增益达到底部后效果仍会产生共鸣,但如果我们淡化postGain,所有声音将同时静音。

从这里到哪里?

我在这里描述的这些方法可以而且应该得到进一步发展。诸如自定义节点的输入和输出以及连接方法之类的东西可以/应该使用基于原型的继承来实现。总线应该能够通过传递效果列表来动态创建效果。

为了庆祝JAMwithChrome的发布,我们决定将我们的效果框架开源。如果这个简短的介绍引起了您的兴趣,请看一下并随意贡献。有一个这里关于标准化自定义网络音频实体格式的讨论。




转载请注明:http://blog.hzbdfjk.com/sszl/8547.html