首页 / 资讯中心 / 文章详情

九个旋钮、零采样:folia-major 的 Web Audio 效果链如何把干净信号调出复古听感

九个旋钮、零采样:folia-major 的 Web Audio 效果链如何把干净信号调出复古听感 ★ FEATURED ARTICLE
九个旋钮、零采样folia-major 的 Web Audio 效果链如何把干净信号调出复古听感【免费下载链接】folia-major专注于绚丽的歌词动画效果的本地音乐/navidrome/第三方多平台在线音乐播放器项目地址: https://gitcode.com/GitHub_Trending/fo/folia-majorfolia-major 是播放本地与多平台在线音乐的播放器它的复古听感不靠任何采样文件本文拆解这条浏览器原生 Web Audio 效果链——接线顺序、九个旋钮的节点映射与零素材生成读完能画出整条音频图。信号主链一行写死的接线顺序与九个旋钮的落点decks → mix → equaliser → effects → volume → fade → analyser → out这是播放图里信号走的完整顺序写死在 playbackGraph.ts 的一个函数里。注释说顺序重要到值得单独拿出来——它从 React hook 搬进可独立测试的接线函数让顺序本身可以被断言。automix 的两个 deck 先落在同一个混音点上EQ 与 analyser 因此各只存在一份、看到的是混合后的总和crossfade 期间音色不打嗝歌词可视化画的是真正被听见的波形。主路上九个旋钮依次接线highpass → lowpass → drive → crush → wow 延迟线 → M/S 拓宽 → 压缩器 → makeup 增益noise黑胶噪声与 space混响是两条旁支直接混进链的输出。主路上游是十段 EQ31、62、125、250、500 Hz 与 1k、2k、4k、8k、16k每段 ±12 dB、Q 1.4频段定义在 audioEqualizer.ts。audioEqualizerGraph.ts 在播放源生命周期内只建一次这串十滤波器链之后 UI 更新只调 apply 函数用setTargetAtTime把增益写进已有节点时间常数 15 ms——React 状态不进音频处理路径。为什么从这条链切入效果链的所有取舍都发生在顺序上。节点摆在什么位置决定旋钮控制的是什么节点如何更新决定有没有咔哒声。音量推子挪到效果链之后三组 dBFS 实测支撑的取舍结论先行音量节点必须放在效果链之后而不是它最初的混音点位置。九个效果里有三种是“绝对值”行为——按满量程或固定阈值计算而不是相对输入电平。如果推子留在它们上游会怎样用 OfflineAudioContext 把同一串链在搬动前后各测一遍playbackGraph.ts 的注释块记录了全部数据黑胶噪声噪声分支混在链的输出端上游推子根本碰不到。音量 1.00、0.50、0.25 三档读出的爆裂声都是 -51.9 dBFS音乐每调小一半噪声相对抬升 6 dB没有任何档位能压住它。挪到下游后三档变成 -51.8 / -57.9 / -64.0 dBFS随音量正常衰减。比特碎化量化阶梯按满量程划分输入被调小后阶梯占比反而变大。一个 -12 dBFS 测试音音量 1.00 时信噪比 38.2 dB0.25 时跌到 25.8 dB——等效位深凭空掉两位动的只是音量推子。挪到下游后所有档位稳定在 38.2 dB。punch 压缩器阈值固定输入变安静后直接够不到阈值效果整个消失。对照组干净全部效果关闭时两种接线顺序测得一致信噪比都是 82.6 dB不开效果的用户听不出差别。反事实也清楚推子留在混音点改音量就等于改效果的“行为”——爆裂声压不住、位深掉两位、压缩器在安静段落失效。该文件还在启动时把接线顺序打印出来注释明说顺序就是修复如果哪天“音量”又排在“效果”前面噪声就不再听音量旋钮的话了。️ 五处反直觉实现4x 过采样、开方映射与延迟释放drive 段开 4x 过采样effectNodes.ts 给饱和节点设oversample 4x这是 WaveShaperNode 可用的最高档。注释给出原因软削波产生的谐波会越过奈奎斯特频率混叠谐波正是波形整形听起来“发毛”而不是“温暖”的来源。代价是这个节点按 4 倍采样成本运算。响度匹配的饱和曲线推 drive 只加谐波不加音量。effectSources.ts 的measureSaturationCompensation先测 0.5 幅度参考正弦过 tanh 曲线后 RMS 抬升了多少再反向乘回去量程顶端峰值电平信号约 20% THD典型预设值停在 5% 附近。crush 按开方映射位深位深 16 − √amount × 12即 4~16 bit。不开方时听得出来的 8~10 bit 段会被挤到滑杆最末端开方后落在中段最“脆”的段落留给末端同在 effectSources.ts。wow 调的是延迟线不是采样率wowBranch.ts 用 0.7 Hz 慢 wow 与 6.8 Hz 快 flutter 两个振荡器同时调制一条基准 12 ms 延迟线的 delayTime。磁带的音高漂移不用变速实现而用延迟调制和磁带机的 wow 同源。800 ms 延迟释放ConvolverNode、噪声源、LFO 都是昂贵节点关闭后先淡出、800 ms 后才拆。effectBranchRelease.ts 只排一个定时器窗口内重新打开则节点原封不动避免反复创建带来的爆音reverb、noise、wow 三个分支共用这套协议。代价与边界这套效果链在哪里不成立单条 per-listener 链没有 per-track 效果混音点下游全部属于听者automix 两个 deck 共用同一组九个旋钮。做不到给 A 轨挂 lofi、B 轨保持干燥crossfade 也穿过同一条链。噪声底是 3 秒循环黑胶噪声缓冲只生成一次且source.loop true咔嗒模式每 3 秒重复一遍增益按amount^1.4 × 0.55映射滑杆低端变化很平。hall 是一个固定房间脉冲响应 2.2 s 长、(1−t)^2.8 衰减分支创建时生成一次space 旋钮只改 wet/dry 比例wet amount×0.75dry 1 − amount×0.2不改房间大小。六个预设 id 是对外契约audioPresets.ts 的注释写明 flat/lofi/radio/hall/vocal/bass 承诺给 mod 系统Folium 1.x 的folium.equalizer.setMode必须继续接受退役预设只能把旧 id 指到最近的继任者预设参数因此被兼容性锁住。源码阅读地图从接线到分支的半小时路径先读 playbackGraph.ts接线加实测注释块约 10 分钟把“音量在效果之后”的顺序立住再读 effectChain.ts 的 apply 函数约 10 分钟看完九个旋钮如何一次写进全部节点参数最后并行读 reverbBranch.ts、noiseBranch.ts、wowBranch.ts 与 effectBranchRelease.ts再 10 分钟。主链是一个函数分支共用一个协议整条阅读路径半小时足够走完。【免费下载链接】folia-major专注于绚丽的歌词动画效果的本地音乐/navidrome/第三方多平台在线音乐播放器项目地址: https://gitcode.com/GitHub_Trending/fo/folia-major创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?
咨询建站