|
来历:知乎
Tone.js 是一个Web Audio框架,用于在阅读器中建立交互式音乐。Tone.js旨在使音乐家和基于Web Audio 利用法式的音频法式员都能熟悉利用。在利用层,Tone.js 供给了常见的DAW(数字音频工作站)功用,如用于同步和调剂事务的全局传输,以及预构建的分解器和音效。此外,Tone.js 供给高性能的构建模块,以建立您自己的分解器、音效和复杂的控制信号。
安装
安装最新稳定版本
npm install tone大概安装最新next版本
npm install tone@next导入Tone.js
import * as Tone from 'tone'Hello Tone
//建立一个synth并将其毗连到主输出装备(您的扬声器)
const synth = new Tone.Synth().toDestination();
//播放中 'C' 调在8个音符的延续时候内
synth.triggerAttackRelease("C4", "8n");
Tone.Synth
Tone.Synth 是一个具有单振荡器和ADSR Envelope (波封)的根基分解器。
波封(Envelope)是指将一种音色波形的大致表面描画出来用以暗示出该音色在音量变化上的特征的参数。 一个波封可以用4种参数来描写,别离是Attack(起音)、Decay(衰减)、Sustain(延持)、与Release(释音),这四者也就是一般称的“ADSR”。
Tone中,Envelope是ADSR信封天生器。信封输出一个信号,可以毗连到AudioParam或Tone.Signal。 triggerAttack / triggerRelease
triggerAttack启动音符(振幅在上升),而triggerRelease是当振幅回到0(即音符封闭)。
const synth = new Tone.Synth().toDestination();
const now = Tone.now()
// trigger the attack immediately
synth.triggerAttack("C4", now)
// wait one second before triggering the release
synth.triggerRelease(now + 1)
triggerAttackRelease
triggerAttackRelease是triggerAttack和triggerRelease的组合
音符的第一个参数可所以赫兹频次(如440)或“音高-八度”标记(如“d# 2”)。
第二个参数是音符的延续时候。该值可以以秒为单元,也可以作为一个时候相对值。
triggerAttackRelease的第三个(可选)参数是音符在AudioContext时候内应当播放的时候。它可以用于计划未来事务。
const synth = new Tone.Synth().toDestination();
const now = Tone.now()
synth.triggerAttackRelease("C4", "8n", now)
synth.triggerAttackRelease("E4", "8n", now + 0.5)
synth.triggerAttackRelease("G4", "8n", now + 1)
Time 时候
Web Audio具有先辈的,样本切确调剂功用。AudioContext时候是Web Audio API用来放置事务的时候,随当页面加载时从0起头,以秒为单元停止计数。
获得当前AudioContext时候
setInterval(() => console.log(Tone.now()), 100);
Tone.js 笼统了AudioContext时候。任何以时候为参数的方式都可以接管数字或字符串,而不是以秒为单元界说一切值。例如,“4n”是四分音符,“8t”是八分音符三连音,“1m”是一个小节。
Starting Audio 启动音频
阅读器不会播听任何音频,直到用户点击某些工具(如播放按钮)。只要在处置务监听器中挪用Tone.start()以后,才能运转你的Tone.js代码,该事务监听器是由用户操纵(如“单击”或“按下键”)触发的。
Tone.start()返回一个许诺,只要在该许诺被处理后,音频才会预备好。在AudioContext运转之前调剂或播放音频将致使寂静或不正确的调剂。
document.querySelector('button')?.addEventListener('click', async () => {
await Tone.start()
console.log('audio is ready')
})
Scheduling 调剂
Transport
Tone.Transport是首要的计时工具。与AudioContext时钟分歧的是,它可以启动、停止、循环和静态调剂。你可以把它设想成数字音频工作站中的排列视图或跟踪器中的通道。
多个事务和部分可以沿着传输放置和同步。Tone.Loop是一种建立循环回调的简双方式,可以计划启动和停止。
// create two monophonic synths
const synthA = new Tone.FMSynth().toDestination();
const synthB = new Tone.AMSynth().toDestination();
//play a note every quarter-note
const loopA = new Tone.Loop(time => {
synthA.triggerAttackRelease("C2", "8n", time);
}, "4n").start(0);
//play another note every off quarter-note, by starting it "8n"
const loopB = new Tone.Loop(time => {
synthB.triggerAttackRelease("C4", "8n", time);
}, "4n").start("8n");
// the loops start when the Transport is started
Tone.Transport.start()
// ramp up to 800 bpm over 10 seconds
Tone.Transport.bpm.rampTo(800, 10);
由于Javascript回调的时候不切确,事务的采样切确时候被传递到回调函数中。利用此时候值调剂事务。
Instruments 乐器
这里有很多分解器可供挑选,包括 Tone.FMSynth, Tone.AMSynth and Tone.NoiseSynth.
一切这些乐器都是单声道(单声道),这意味着它们一次只能演奏一个音符。
要建立一个复音分解器,请利用Tone.PolySynth,它接管单音分解器作为它的第一个参数,并自动处置音符分派,以便您可以传入多个音符。该API类似于单音分解,只是必须给triggerRelease一个音符或音符数组。
const synth = new Tone.PolySynth(Tone.Synth).toDestination();
const now = Tone.now()
synth.triggerAttack("D4", now);
synth.triggerAttack("F4", now + 0.5);
synth.triggerAttack("A4", now + 1);
synth.triggerAttack("C5", now + 1.5);
synth.triggerAttack("E5", now + 2);
synth.triggerRelease(["D4", "F4", "A4", "C5", "E5"], now + 4);
Samples 采样器
声音天生并不范围于分解声音,还可以加载一个示例并以多种方式回放它。Tone.Player是一种加载和播放音频文件的方式。
const player = new Tone.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.PolySynth
const sampler = new Tone.Sampler({
urls: {
"C4": "C4.mp3",
"D#4": "Ds4.mp3",
"F#4": "Fs4.mp3",
"A4": "A4.mp3",
},
release: 1,
baseUrl: "https://tonejs.github.io/audio/salamander/",
}).toDestination();
Tone.loaded().then(() => {
sampler.triggerAttackRelease(["Eb4", "G4", "Bb4"], 4);
})
Effects 音效
在上面的例子中,音源总是间接毗连到Destination,但synth的输出也可以经过一个(或多个)结果路由到扬声器。
const player = new Tone.Player({
url: "https://tonejs.github.io/audio/berklee/gurgling_theremin_1.mp3",
loop: true,
autostart: true,
})
//create a distortion effect
const distortion = new Tone.Distortion(0.4).toDestination();
//connect a player to the distortion
player.connect(distortion);
毗连路由很是灵活。毗连可以串交运转,也可以并交运转。
const player = new Tone.Player({
url: "https://tonejs.github.io/audio/drum-samples/loops/ominous.mp3",
autostart: true,
});
const filter = new Tone.Filter(400, 'lowpass').toDestination();
const feedbackDelay = new Tone.FeedbackDelay(0.125, 0.5).toDestination();
// connect the player to the feedback delay and filter in parallel
player.connect(filter);
player.connect(feedbackDelay);
多个节点可以毗连到不异的输入,使音源同享结果。对于建立复杂的路由,Tone.Gain是很是有用的适用节点。
Signals 信号
和底层的Web Audio API一样,Tone.js构建时几近一切内容都有音频速度信号控制。这是一个功用强大的特征,可以实现样本切确的同步和参数调剂。
信号属性有一些用于建立自动化曲线的内置方式。
例如,振荡器上的频次参数是一个信号,是以您可以建立从一个频次到另一个频次的平滑斜坡。
const osc = new Tone.Oscillator().toDestination();
// start at "C4"
osc.frequency.value = "C4";
// ramp to "C2" over 2 seconds
osc.frequency.rampTo("C2", 2);
// start the oscillator for 2 seconds
osc.start().stop("+3");
AudioContext 音频高低文
js在加载时建立一个AudioContext,并利用标准化的audio-context添补它以获得最大的阅读器兼容性。AudioContext可以在Tone.context中拜候。大概利用Tone.setContext(AudioContext)设备自己的AudioContext。
MIDI 文件
要利用MIDI文件,首先需要将它们转换成JSON格式,使得Tone.js可以读取。
接待来我的小我博客走走~
原文地址:https://zhuanlan.zhihu.com/p/601627353
免责声明:
1、文章部分图片源于收集,均为表示图;
2、一切文章、图片、音频视频文件等材料版权归版权一切人一切;
3、因非原创文章及图片等内容没法和版权者联系,如原作者或编辑以为作品不宜上网供阅读,或不应无偿利用,请实时告诉我们,以敏捷采纳适当办法,避免给双方形成不需要的经济损失;
4、本页面内容由爬虫法式自动收集于互联网,如无意中加害了媒体或小我的常识产权,请电邮【E-Mail:cb@yoyodoc.com】告之,我们将于24小时内删除。 |
|