ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

p5.js 音乐可视化:从振幅响应到 FFT 频谱的 4 个可运行实验

2026/9/5 21:54:11 拓冰建站 浏览量
p5.js 音乐可视化:从振幅响应到 FFT 频谱的 4 个可运行实验 p5.js 音乐可视化从振幅响应到 FFT 频谱的 4 个可运行实验【免费下载链接】p5.jsp5.js is a client-side JS platform that empowers artists, designers, students, and anyone to learn to code and express themselves creatively on the web. It is based on the core principles of Processing. Looking for p5.js 2.0? http://beta.p5js.org项目地址: https://gitcode.com/GitHub_Trending/p5/p5.js任务写一个页面本地音频的音量实时控制画布中一个圆的大小。用到的项目是 p5.js功能是音频可视化把声音变成可以逐帧读取的数据再把这些数据映射到画布坐标上。环境准备p5.js 与 p5.sound 的引入音频相关 API 全部在扩展库 p5.sound 里核心库 src/ 目录下没有。引入方式两种CDN两个 script 标签核心库在前p5.sound 在后。本地仓库内现成的lib/p5.js和lib/addons/p5.sound.js适合离线开发和国内网络环境。加载顺序是硬约束p5.sound 是挂载在 p5 上的扩展顺序写反会直接报 p5 is not defined。最小可运行页面如下script srclib/p5.js/script script srclib/addons/p5.sound.js/scriptlet soundFile; function preload() { soundFormats(mp3, ogg); // 声明文件备选格式 soundFile loadSound(assets/beat.mp3); } function setup() { createCanvas(800, 400); soundFile.loop(); // 循环播放可视化才有连续数据源 } function draw() { background(20); }第一个实验音量驱动圆的大小只用一个 APInew p5.Amplitude()。它返回当前混合音量getLevel()取 0–1 的浮点数相当于给整个音频流接了一个电平表。let soundFile, level; function preload() { soundFormats(mp3, ogg); soundFile loadSound(assets/beat.mp3); } function setup() { createCanvas(600, 600); noStroke(); fill(255, 180, 80); soundFile.loop(); level new p5.Amplitude(0.8); // 0.8 平滑系数值越大跳动越柔和 } function draw() { background(15); const vol level.getLevel(); // 当前音量范围 0–1 const d map(vol, 0, 1, 40, 420); // 映射为直径 ellipse(width / 2, height / 2, d); }关键 API 逐条说明p5.Amplitude(smoothing)构造参数是平滑系数 0–10.8 适合鼓点这种突变信号麦克风输入建议 0.2 左右。getLevel()返回 0–1。静音时接近 0不要期望它精确到 0。map(a, b, c, d)把数据域 0–1 换成画布域 40–420 像素这一步就是数据到像素的全部。数据怎么变成像素理解 p5.sound 的读取链路p5.sound 内部把 Web Audio API 的 AnalyserNode 包了一层p5.Amplitude读的是时域整体电平p5.FFT读的是频域分段强度。画布这边渲染管线按p5.Element→p5.Renderer→p5.Renderer2D/3D分层音频数据只是draw()里的普通变量走哪条渲染路径都行。进阶一FFT 频谱柱状图p5.FFT.analyze()返回 0–255 的 1024 个值默认采样数位置即频率索引 0 是最低频末尾是最高频。FFT 本质上就是把声音按频率拆成一段段强度值低频在左、高频在右。let fft; function setup() { createCanvas(800, 300); fft new p5.FFT(0.8, 1024); // 平滑 0.81024 个采样点 } function draw() { background(20); const bins fft.analyze(); // 1024 个 0–255 的值 for (let i 0; i bins.length; i) { const h map(bins[i], 0, 255, 0, height); fill(80, 200, 255); rect(i * (width / bins.length), height - h, width / bins.length - 1, h); } }只关心某个频段时不用自己切片直接fft.getEnergy(60, 250)取 60–250Hz 的能量值。进阶二低频能量驱动粒子扩散粒子系统只依赖一个数低频段的能量。音量越大粒子被推得越远。let fft, pts; function setup() { createCanvas(800, 800); fft new p5.FFT(); pts Array.from({ length: 400 }, () random(2 * TAU)); } function draw() { background(10); const low fft.getEnergy(60, 250); // 低音能量 for (const a of pts) { const r map(low, 0, 255, 60, 320); fill(255, 120, 60, 90); circle(width / 2 cos(a) * r, height / 2 sin(a) * r, 6); } }进阶三3D 频谱createCanvas(w, h, WEBGL)切到 WebGL 渲染器频谱变成一根根竖条鼠标可旋转查看。function setup() { createCanvas(800, 500, WEBGL); // 进入 WebGL 模式 fft new p5.FFT(0.8, 512); // 3D 下采样数减半性能更好 } function draw() { orbitControl(); // 鼠标拖拽旋转视角 background(12); const bins fft.analyze(); for (let i 0; i bins.length; i) { const h map(bins[i], 0, 255, 4, 200); fill(60, 220, 180); box(3, h, 3); translate(width / bins.length, 0, 0); } translate(-width, 0, 0); }四个高频坑自动播放限制 ⚠️浏览器策略下 AudioContext 默认挂起soundFile.loop()写在setup()里不保证出声。解法是在首次点击或按键回调里调一次userStartAudio()音频图会立即解锁。远程音频 CORSloadSound走 XHR远端服务器没有 CORS 头的音频文件会静默加载失败。要么本地化素材要么换允许跨域的源。绘制性能1024 个采样点每帧画 1024 次rect或上万条vertex低端设备会掉帧。降低 FFT 采样数、隔帧重绘或用noLoop()配合手动触发绘制。CDN 不稳定jsDelivr 等公共 CDN 在国内不可达时页面整体加载失败。把lib/p5.js和lib/addons/p5.sound.js拷进项目静态目录是最省事的兜底方案。继续深入的入口仓库的测试目录 test/manual-test-examples/addons/p5.sound/ 下有 30 多个可直接运行的示例覆盖波形、FFT 频段、麦克风、振荡器调制每个目录都是 index.html 加 sketch.js 的最小结构。音频 API 细节见 p5.sound 源码。跑通上面四个实验后再去看它们读起来会快很多。【免费下载链接】p5.jsp5.js is a client-side JS platform that empowers artists, designers, students, and anyone to learn to code and express themselves creatively on the web. It is based on the core principles of Processing. Looking for p5.js 2.0? http://beta.p5js.org项目地址: https://gitcode.com/GitHub_Trending/p5/p5.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考