
音频处理前端【免费下载链接】Tone.jsA Web Audio framework for making interactive music in the browser.项目地址https://gitcode.com/gh_mirrors/to/Tone.js点击查看免费下载Tone.js 是一个构建在 Web Audio API 之上的浏览器音频框架专为在浏览器中创作交互式音乐而设计其架构同时面向音乐人与音频程序员。本文以仓库根目录的 README.md 为骨架结合 Tone/ 目录下的核心源码与 examples/ 目录中的可运行示例系统讲解从安装引入、单音合成器控制、时间系统、音频启动约束到 Transport 全局调度、复音合成器、采样回放、效果器路由、信号自动化与 AudioContext 管理的完整实战路径。读完本文你将能够独立搭建一个可交互的浏览器音乐应用并理解每个 API 背后的源码级原理。一、Tone.js 是什么面向音乐人与程序员的 Web Audio 框架Tone.js 的核心定位在 README.md 的开篇描述中非常明确它是一个用于在浏览器中创建交互式音乐的 Web Audio 框架。其架构设计有两个目标读者音乐人开箱即用地获得 DAW数字音频工作站级别的能力如全局 Transport用于同步与调度事件的时间轴、预置合成器synths与效果器effects音频程序员获得高性能的底层构建块用于自行搭建合成器、效果器与复杂的控制信号control signals。从源码结构看这一高低兼顾的设计在仓库目录中体现得非常清晰见 Tone/ 目录树Tone/source/音频源包括振荡器族Oscillator、OmniOscillator、FatOscillator、FMOscillator等与采样回放Player、Players、Sampler等Tone/instrument/乐器层包括Synth、MonoSynth、FMSynth、AMSynth、PolySynth等Tone/effect/效果器层包括失真、滤波、延迟、混响等Tone/component/可组合的组件包络、滤波器、通道处理等Tone/signal/信号层这是整个框架一切皆信号能力的根基Tone/core/核心设施包括 Context、Transport、时间类型系统、工具类。以Tone.Synth为例其实现见 Tone/instrument/Synth.ts只做了两件事一个OmniOscillator路由经过一个AmplitudeEnvelope这正是预置乐器 底层构建块的组合这一哲学的直接体现。二、安装与引入npm 与 CDN 两种方式根据 README.md 的 Installation 一节与 package.json 中的发布配置Tone.js 支持两种引入方式。方式一npm 本地安装npm install tone // 安装最新稳定版 npm install tonenext // 或者使用 next 预发布版本说明tonenext对应仓库 dev 分支的持续构建产物详见下文测试与版本一节。当前仓库 package.json 中name为tonetype为modulemain指向build/esm/index.js说明安装后可通过 ES Module 方式引入。安装完成后使用 JavaScript 的import语法引入import * as Tone from tone;方式二unpkg CDN 直接挂载Tone.js 同时托管在 unpkg.com可在 HTML 文档中直接以script标签引入只要保证它出现在任何项目脚本之前script srchttp://unpkg.com/tone/script这一用法的完整可运行示例见仓库中的 examples/simpleHtml.html它展示了最简单的组合页面一个按钮点击时创建Tone.Synth并播放一个音符script srchttps://unpkg.com/tone/script script function playNote() { // create a synth const synth new Tone.Synth().toDestination(); // play a note from that synth synth.triggerAttackRelease(C4, 8n); } /script ... button onclickplayNote()Click me to play note!/button注意这个示例将音符触发放在按钮点击回调内——这正是下文启动音频一节所强调的浏览器自动播放策略约束下的标准写法。三、Hello Tone第一段声音README 给出的入门示例只有三行却是理解 Tone.js 对象模型的钥匙// create a synth and connect it to the main output (your speakers) const synth new Tone.Synth().toDestination(); // play a middle C for the duration of an 8th note synth.triggerAttackRelease(C4, 8n);关键动作拆解new Tone.Synth()创建合成器实例。从源码看Tone/instrument/Synth.ts构造函数内部创建了OmniOscillator与AmplitudeEnvelope并通过this.oscillator.chain(this.envelope, this.output)将振荡器串联包络后接入输出.toDestination()把合成器的输出接到主输出扬声器。这是 Tone.js 连接系统的便捷方法等价于手动connect到DestinationtriggerAttackRelease(C4, 8n)以音符音高 时值的方式触发一个完整音符。3.1 Tone.Synth 的组成与默认参数Tone.Synth是一个振荡器 一个 ADSR 包络的基本合成器。其默认参数在 Tone/instrument/Synth.ts 的getDefaults()中定义oscillator默认type: triangle三角波envelope默认attack: 0.005秒、decay: 0.1、sustain: 0.3、release: 1继承自Monophonic的detune: 0、portamento: 0、onsilence空回调见 Tone/instrument/Monophonic.ts。这些默认值构成了按一下就有声的实用起点也解释了为什么上面的入门示例无需任何配置即可发声。3.2 triggerAttack / triggerRelease手动控制音符起止triggerAttack开始音符幅度上升triggerRelease使幅度回落到 0即note off。README 给出的分离控制示例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);从源码层面看Tone/instrument/Monophonic.ts两个方法都会先把时间参数经this.toSeconds()换算为 AudioContext 秒然后分别调用内部钩子_triggerEnvelopeAttack(seconds, velocity)与_triggerEnvelopeRelease(seconds)。在Synth的实现中Tone/instrument/Synth.tsattack 时envelope.triggerAttack(time, velocity)启动包络同时oscillator.start(time)启动振荡器若sustain 0会在 attackdecay 之后自动停止振荡器release 时envelope.triggerRelease(time)触发释放并在release时长结束后停止振荡器。triggerAttack还支持第三个可选参数velocity0–1 的力度例如synth.triggerAttack(C4, 0.5, 0.5)表示半秒后以一半力度起音见 Tone/instrument/Monophonic.ts 中的源码示例注释。3.3 triggerAttackRelease起止一体triggerAttackRelease是triggerAttack与triggerRelease的组合也是日常最常用的方法。README 对其三个参数给出了精确定义第一个参数音符。可以是赫兹频率如440也可以是音高-八度记法如D#2第二个参数音符保持的时长。可以是秒数也可以是拍速相对值如8n详见下文时间系统一节第三个可选参数音符在 AudioContext 时间轴上播放的时刻用于在未来调度事件。README 的排程示例以八分音符间隔依次触发 C 大三和弦的三音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);四、时间系统从 AudioContext 秒到音乐时值Web Audio 具备采样级精度的调度能力。AudioContext 时间从页面加载时开始计数、以秒为单位递增是 Web Audio API 调度事件所使用的时间基准。4.1 Tone.now()获取当前 AudioContext 时间Tone.now()返回 AudioContext 的当前时间。README 示例用setInterval周期性打印setInterval(() console.log(Tone.now()), 100);Tone.js 将 AudioContext 时间做了抽象任何接受时间作为参数的方法既可以传数字秒也可以传字符串音乐时值。例如4n四分音符quarter-note8t八分音符三连音eighth-note triplet1m一个小节one measure。4.2 时间解析的源码实现这套时间编码体系的实现位于 Tone/core/type/Time.ts核心是TimeClass。从源码可以看到两类重要的表达式解析相对时间以开头表示从现在起多少正则regexp: /^\(.)/例如1表示一秒后、4n表示一个四分音符后量化时间以开头表示量化到下一个指定细分正则regexp: /^(.)/例如4n表示对齐到下一个四分音符边界。TimeClass还提供quantize(subdiv, percent)方法可把任意时间值按给定细分量化例如Tone.Time(0.6).quantize(4n, 0.5)返回0.55源码注释示例见 Tone/core/type/Time.ts。这些能力使得将事件精确对齐到音乐网格成为可能。五、启动音频浏览器自动播放策略务必遵守重要约束浏览器在用户产生点击等交互行为之前不会播放任何音频。必须把 Tone.js 代码放在由用户动作如click、keydown触发的事件监听器中执行并先调用Tone.start()。Tone.start()返回一个 Promise只有在该 Promise resolve 之后音频才真正就绪。在 AudioContext 运行之前进行调度或播放将导致静音或错误的调度结果。README 的标准写法//attach a click listener to a play button document.querySelector(button)?.addEventListener(click, async () { await Tone.start(); console.log(audio is ready); });这一约束同样解释了仓库示例中为何几乎所有可运行页面如 examples/simpleSynth.html、examples/simpleHtml.html都把发声动作封装在按钮回调里。六、调度Transport 与 Loop6.1 TransportDAW 式全局时间轴Tone.getTransport()返回全局主时间管理器。与 AudioContext 时钟不同它可以被启动、停止、循环并在运行中调整速度——可以把它想象成 DAW 中的编排视图arrangement view。从源码看Tone/core/clock/Transport.tsTransport 支持速度曲线与拍速变化并且与浏览器计时器setInterval、requestAnimationFrame不同回调会收到被调度事件的精确时间参数同时会发出start、stop、pause、loop等事件。多个事件与部件可以沿着 Transport 排布并同步。Tone.Loop是一种创建可调度启停的循环回调的简单方式。README 的经典示例——两个合成器交替演奏、整体速度斜坡加速// 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); // all loops start when the Transport is started Tone.getTransport().start(); // ramp up to 800 bpm over 10 seconds Tone.getTransport().bpm.rampTo(800, 10);这段代码同时展示了两个关键机制回调时间参数(time) {...}中的time是采样级精确的事件时间必须用它来调度事件——因为 JavaScript 回调本身不是精确定时的偏移启动loopB.start(8n)以八分音符为偏移启动使两个循环形成错拍off quarter-note的切分效果bpm 是信号Tone.getTransport().bpm.rampTo(800, 10)说明拍速本身是可平滑自动化的信号量10 秒内从默认 120 BPM 斜坡到 800 BPM。Transport 的更多能力scheduleRepeat、scheduleOnce、事件系统、loop 区间等可进一步阅读 Tone/core/clock/Transport.ts 与配套测试 Tone/core/clock/Transport.test.ts。七、乐器单音合成器与复音 PolySynth7.1 可选合成器README 列举了多个可直接选用的合成器Tone.FMSynth、Tone.AMSynth、Tone.NoiseSynth加上前文详述的Tone.Synth。它们对应的源码分别位于 Tone/instrument/FMSynth.ts、Tone/instrument/AMSynth.ts、Tone/instrument/NoiseSynth.ts。所有这些乐器默认都是单音monophonic的即同一时刻只能演奏一个音符。7.2 PolySynth一键获得复音能力要创建**复音polyphonic**合成器使用Tone.PolySynth。它接受一个单音乐器作为第一个参数自动处理音符分配voice allocation因此可以同时传入多个音符。其 API 与单音乐器类似区别在于triggerRelease必须传入一个音符或音符数组。从源码看Tone/instrument/PolySynth.tsPolySynth 本身并不是合成器它只是管理另一种合成器类型的声音实例voice并支持maxPolyphony最大复音数等选项以及通过synth.set({ detune: -1200 })跨所有 voice 批量设置参数。README 的琶音示例——依次叠加 D 大调五声音阶的五个音最后统一释放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);注意triggerRelease接收了包含全部五个音符的数组一次性释放整个和弦。八、采样回放Tone.Player 与 Tone.Sampler声音生成不限于合成。Tone.js 也支持加载并回放音频采样文件。8.1 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在所有音频文件加载完成后 resolve。它是等待每个音频 buffer 的onload事件的便捷替代。仓库 examples/player.html 展示了 Player 的完整可交互用法。8.2 Tone.Sampler按音符组织的采样乐器多个采样可以组合成一件乐器。如果音频文件按音符组织Tone.Sampler会对采样做变调pitch shift以填补音符之间的空缺——例如只采样了钢琴每三个音就能补全成一架完整钢琴。与其他合成器不同Sampler 天生是复音的无需再包一层 PolySynth。README 示例使用 Salamander 钢琴采样库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); });参数说明urls音符名到采样文件名的映射键为音符名如C4、D#4注意升号写法Ds4.mp3是文件命名上的转义release释放时长秒baseUrl所有urls中文件名的公共基础路径用于拼接完整 URL播放时同样支持传入音符数组这里是 E 大三和弦[Eb4, G4, Bb4]与时长4 秒。九、效果器与灵活的路由系统前面所有示例都把声源直接连到Destination但合成器的输出同样可以先经过一个或多个效果器再进扬声器。9.1 串联一个效果器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);这里Tone.Distortion(0.4)的 0.4 是失真强度NormalRange 0–1对应源码 Tone/effect/Distortion.ts。player.connect(distortion)将声源路由进效果器效果器再输出到主输出。9.2 并联多个效果器连接路由是灵活的既可以串联也可以并联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.Filter(400, lowpass)创建截止频率 400 Hz 的低通滤波器Tone.FeedbackDelay(0.125, 0.5)创建延迟时间 0.125 秒、反馈量 0.5 的反馈延迟。两者并联Player 的输出同时进入滤波器和反馈延迟得到干湿并行的混合效果。9.3 共享效果与 Gain 工具节点多个节点可以连接到同一个输入使多个声源共享效果器。Tone.Gain是构建复杂路由时非常有用的工具节点。这一设计理念在仓库中有大量实例——例如 examples/buses.html 展示了总线式路由examples/mixer.html 展示了混音台式的多轨路由。十、信号一切皆可音频速率自动化与底层 Web Audio API 一脉相承Tone.js 几乎所有参数都由音频速率audio-rate的信号控制。这意味着参数的采样级精确同步与调度成为可能也是 Tone.js 与普通setValue 一次性赋值式音频库的核心区别。Signal属性自带若干用于创建自动化曲线的内建方法。README 用振荡器频率做例子——Oscillator的frequency参数就是一个 Signalconst 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);要点osc.frequency.value C4直接给频率信号赋一个音符值时间系统会自动换算为 Hzosc.frequency.rampTo(C2, 2)在 2 秒内从 C4 平滑斜降到 C2指数斜坡符合音高感知osc.start().stop(3)立即启动、三秒后停止前缀即前文提到的相对时间表达式。信号系统在仓库中的实现位于 Tone/signal/ 目录包含Signal、Add、Multiply、Scale、WaveShaper等一系列可组合的信号算子见 Tone/signal/index.ts测试覆盖见 Tone/signal/Signal.test.ts。Transport 的bpm.rampTo(800, 10)正是这一体系的又一实例。十一、AudioContext 管理Tone.js 在加载时会自动创建一个 AudioContext并通过 standardized-audio-context 对其进行 shim以最大化浏览器兼容性——这一依赖声明在 package.json 中可以看到standardized-audio-context: ^25.3.70。获取Tone.getContext()返回当前 AudioContext 封装自定义Tone.setContext(audioContext)可注入你自己的 AudioContext。从源码看Tone/core/context/Context.tsContext类封装了原生BaseAudioContext并额外管理 Ticker可靠的定时回调、常量 AudioBufferSourceNode 缓存、超时事件时间线以及每个 Context 专属的 Transport / Listener / Destination / Draw 单例。Context也支持Offline渲染模式离线音频处理见 Tone/core/context/Offline.ts 与 examples/offline.html可用于离线渲染与测试。十二、MIDI、性能与测试MIDI要使用 MIDI 文件需先用工具将其转换为 Tone.js 可理解的 JSON 格式。仓库本身并不直接解析.mid二进制文件而是依赖转换后的 JSON 结构相关类型支持见 Tone/core/type/Midi.tsMIDI 音符到频率的转换与 Tone/core/type/Midi.test.ts。性能Tone.js 大量使用原生 Web Audio 节点如 GainNode、WaveShaperNode完成所有信号处理这一设计使它在桌面与移动浏览器上都能良好运行。README 建议关注性能相关的 wiki 文章以获得最佳实践。测试与版本仓库使用 mocha 与 chai 运行大规模测试套件宣称接近 100% 覆盖率。dev 分支通过构建的产物会发布到 npm 的tonenext。在 package.json 中可以找到对应的脚本npm test运行 TypeScript 编译检查与 web-test-runner 测试套件配置见 test/web-test-runner.config.jsnpm test:examples、npm test:html、npm test:integrations、npm test:readme分别验证示例页面、HTML 页面、各打包方式集成与 README 代码块的可运行性npm run linttsc --noEmit ESLint 静态检查。测试辅助代码与音频对比文件位于 test/ 目录例如 test/helper/CompareToFile.ts 实现了与参考 WAV 逐采样对比的回归测试机制参考音频存放在 test/audio/compare/。十三、快速开始清单从零到可交互音乐应用综合全文搭建一个最小可用的 Tone.js 交互应用需要以下步骤引入npm 安装后import * as Tone from tone或通过 unpkg CDN 在 HTML 中引入参考 examples/simpleHtml.html等待用户手势在 click / keydown 回调中await Tone.start()之后音频才可用创建声源如new Tone.Synth().toDestination()或Tone.Player/Tone.Sampler加载采样加载完成可依赖Tone.loaded()可选路由效果器用player.connect(effect)串联/并联Tone.Filter、Tone.FeedbackDelay、Tone.Distortion等效果器复杂路由可用Tone.Gain调度单音用triggerAttack/triggerRelease/triggerAttackRelease时间参数支持秒或8n等音乐时值循环事件用Tone.LoopTone.getTransport().start()精确对齐用Tone.now()作为基准时刻自动化利用 Signal 能力如osc.frequency.rampTo(C2, 2)或Tone.getTransport().bpm.rampTo(800, 10)。每一步的完整可运行参考都可在 examples/ 目录找到对应页面如 examples/simpleSynth.html、examples/player.html、examples/stepSequencer.html 等它们共同构成了阅读源码 Tone/ 之前最直观的实践入口。赞分享音频处理前端【免费下载链接】Tone.jsA Web Audio framework for making interactive music in the browser.项目地址https://gitcode.com/gh_mirrors/to/Tone.js点击查看免费下载相关推荐Visdom 回调事件往返链路解析从浏览器交互到 Python 回调的完整路由指南Visdom 回调事件往返链路解析从浏览器交互到 Python 回调的完整路由指南 本文是 Visdom 回调Callback与事件往返Event Ro数据可视化前端Tone.js完全指南Web Audio框架如何重塑浏览器音乐交互体验Tone.js完全指南Web Audio框架如何重塑浏览器音乐交互体验 你是否曾想过在网页中创建互动音乐体验却被复杂的Web Audio API挡在门外T音频处理前端如何用Tone.js打造浏览器音乐应用从入门到创意实现的完整指南如何用Tone.js打造浏览器音乐应用从入门到创意实现的完整指南 Tone.js是一个强大的Web Audio框架专为在浏览器中创建交互式音乐体验而设计。无音频处理前端上一篇Cosmos 仓库 Dice Simulation 动态规划题解基于三维 DP 记忆化搜索的连续次数约束计数下一篇Shields 徽章服务退役RetiredService完整实践指南当上游服务关闭时如何优雅下线徽章创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考