当前位置: 首页 > Web前端 > HTML

Tone.js——WebAudioFramework中文使用指南

时间:2023-03-28 14:06:08 HTML

原文地址:Tone.js原文:Tone.orgTone.js官方文本没有中文支持,入门比较难,本文增加了一些WebAudio和音乐-相关内容在原文翻译基础知识的基础上。如有错误,欢迎批评指正。Tone.js是一个用于在浏览器中创建交互式音乐的网络音频框架。Tone.js旨在为基于网络音频应用程序的音乐家和音频程序员所熟悉。在应用层,Tone.js提供通用的DAW(数字音频工作站)功能,例如用于同步和调度事件的全局传输,以及预构建的合成器和音效。此外,Tone.js提供高性能构建块来创建您自己的合成器、音效和复杂的控制信号。安装安装最新的稳定版本npminstalltone或安装最新的下一个版本npminstalltone@nextimportTone.jsimport*asTonefrom'tone'HelloTone//创建一个合成器并将其连接到主输出设备(你的扬声器)constsynth=newTone.Synth().toDestination();//播放时'C'的音调在8个音符的持续时间内synth.triggerAttackRelease("C4","8n");Tone.SynthTone.Synth是一款带有单振荡器和ADSR包络的基本合成器。包络(Envelope)是指描绘音色波形粗略轮廓的参数,用以表达音色在音量变化方面的特性。一个波包可以用四个参数来描述,即起音(Attack)、衰减(Attenuation)、延音(Sustain)和释音(Release),这四个也就是俗称的“ADSR”。在Tone中,Envelope是一个ADSR包络发生器。Envelope输出可以连接到AudioParam或Tone.Signal的信号。triggerAttack/triggerReleasetriggerAttack启动音符(振幅上升),而triggerRelease是振幅回到0时(即音符关闭)。constsynth=newTone.Synth().toDestination();constnow=Tone.now()//立即触发攻击synth.triggerAttack("C4",now)//等待一秒钟再触发释放synth.triggerRelease(now+1)triggerAttackReleasetriggerAttackRelease是triggerAttack和triggerRelease的组合音符的第一个参数可以是赫兹频率(例如440)或“音高八度”符号(例如“d#2”)。第二个参数是音符的持续时间。该值可以以秒为单位或作为时间相对值。triggerAttackRelease的第三个(可选)参数是音符应在AudioContext时间内播放多长时间。它可以用来计划未来的事件。constsynth=newTone.Synth().toDestination();constnow=Tone.now()synth.triggerAttackRelease("C4","8n",now)synth.triggerAttackRelease("E4","8n",现在+0.5)synth.triggerAttackRelease("G4","8n",now+1)TimeTimingWebAudio具有先进的采样精确调度功能。AudioContextTime是WebAudioAPI用于安排事件的时间,从页面加载时的0开始,以秒为单位计算。获取当前AudioContext时间setInterval(()=>console.log(Tone.now()),100);Tone.js抽象了AudioContext时间。任何以时间为参数的方法都可以接受一个数字或一个字符串,而不是定义所有以秒为单位的值。例如,“4n”是四分音符,“8t”是八分音符三连音,“1m”是小节。启动音频启动音频浏览器将不会播放任何音频,直到用户单击某些内容(例如播放按钮)。仅在从由用户操作(例如“单击”或“按键”)触发的事件侦听器调用Tone.start()之后运行您的Tone.js代码。Tone.start()返回一个承诺,并且在该承诺得到解决之前音频不会准备好。在AudioContext运行之前安排或播放音频将导致无声或不正确的安排。document.querySelector('button')?.addEventListener('click',async()=>{awaitTone.start()console.log('audioisready')})调度调度TransportTone.Transport是主要的计时工具.与AudioContext时钟不同,它可以启动、停止、循环和动态调整。您可以将其视为DAW中的排列视图或跟踪器中的通道。可以在传输过程中安排和同步多个事件和部分。Tone.Loop是一种创建循环回调的简单方法,可以安排开始和停止。//创建两个单音合成器constsynthA=newTone.FMSynth().toDestination();constsynthB=newTone.AMSynth().toDestination();//每四分音符播放一个音符constloopA=newTone.Loop(time=>{synthA.triggerAttackRelease("C2","8n",time);},"4n").start(0);//每隔四分音符播放另一个音符,通过启动它"8n"constloopB=newTone.Loop(time=>{synthB.triggerAttackRelease("C4","8n",time);},"4n").start("8n");//传输启动时循环开始Transport.start()//在10秒内加速到800bpmTone.Transport.bpm.rampTo(800,10);由于Javascript回调的定时不精确,将事件的精确采样时间传递给回调函数。使用此时间值调度事件。乐器有许多合成器可供选择,包括Tone.FMSynth、Tone.AMSynth和Tone.NoiseSynth。所有这些乐器都是单音的,这意味着它们一次只能演奏一个音符。要创建复音合成器,请使用Tone.PolySynth,它接受单音合成器作为其第一个参数并自动处理音符分配,以便您可以传入多个音符。该API类似于单音合成,除了必须为triggerRelease提供音符或音符数组。constsynth=newTone.PolySynth(Tone.Synth).toDestination();constnow=Tone.now()synth.triggerAttack("D4",now);synth.triggerAttack("F4",now+0.5);合成器.triggerAttack("A4",现在+1);synth.triggerAttack("C5",现在+1.5);synth.triggerAttack("E5",现在+2);synth.triggerRelease(["D4","F4","A4","C5","E5"],now+4);SamplesSampler声音生成不仅限于合成声音,还可以加载样本并以多种方式播放。Tone.Player是一种加载和播放音频文件的方法。constplayer=newTone.Player("https://tonejs.github.io/audio/berklee/gong_1.mp3").toDestination();Tone.loaded().then(()=>{player.start();});Tone.loaded()返回一个promise,当所有的音频文件都被加载时,这个promise就会被解析。这是一个有用的速记,而不是等待每个音频缓冲区的onload事件来解决。Tone.Sampler多个采样器也可以组合成一台乐器。如果您的音频文件是按音符、音调组织的。采样器使用音高偏移样本填充音符之间的间隙。例如,如果您只有钢琴上每3个音符的样本,您可以将其变成完整的钢琴样本。与其他合成器不同,Tone.Sampler是多通道的,因此无需传递给Tone.PolySynthconstsampler=newTone.Sampler({urls:{"C4":"C4.mp3","D#4":"Ds4.mp3","F#4":"Fs4.mp3","A4":"A4.mp3",},发布:1,baseUrl:"https://tonejs.github.io/audio/salamander/",}).toDestination();Tone.loaded().then(()=>{sampler.triggerAttackRelease(["Eb4","G4","Bb4"],4);})效果在上面的例子中,源总是直接连接到目标,但合成器的输出也可以通过一个(或多个)效果路由到扬声器。constplayer=newTone.Player({url:"https://tonejs.github.io/audio/berklee/gurgling_theremin_1.mp3",loop:true,autostart:true,})//创建失真效果constdistortion=newTone.Distortion(0.4).toDestination();//将播放器连接到失真播放器.connect(distortion);连接路由非常灵活。连接可以串行或并行运行。constplayer=newTone.Player({url:"https://tonejs.github.io/audio/drum-samples/loops/ominous.mp3",autostart:true,});constfilter=newTone.Filter(400,'lowpass').toDestination();constfeedbackDelay=newTone.FeedbackDelay(0.125,0.5).toDestination();//将播放器连接到并行播放器中的反馈延迟和过滤器.connect(过滤器);播放器。连接(反馈延迟);多个节点可以连接到同一个输入,使音源可以共享效果。Tone.Gain是一个非常有用的实用节点,可用于创建复杂的路由。信号与底层的WebAudioAPI一样,Tone.js是为几乎所有东西构建的音频速率信号控制。这是一个强大的功能,可以实现样本精确同步和参数调度。信号属性有一些用于创建自动化曲线的内置方法。例如,振荡器上的频率参数是一个信号,因此您可以创建从一个频率到另一个频率的平滑斜坡。constosc=newTone.Oscillator().toDestination();//从“C4”开始2);//启动振荡器2秒sosc.start().stop("+3");AudioContext音频上下文js在加载时创建一个AudioContext并使用规范化的音频上下文填充它以实现最大的浏览器兼容性。AudioContext可以在Tone.context中访问。或者使用Tone.setContext(AudioContext)来设置你自己的AudioContext。MIDI文件要使用MIDI文件,您首先需要将它们转换为JSON格式,以便Tone.js可以读取它们。