p5.js:sound(音乐)可视化,动画显示音频高低变化
本文通过4个案例介绍了使用 p5.js 进行音乐可视化的实践,包括将音频振幅转化为图形、生成波形图。
承上一篇:vite:初学 p5.js demo 画圆圈
cd p5-demo
copy .\node_modules\p5\lib\p5.min.js .
copy .\node_modules\p5\lib\addons\p5.sound.min.js .
在 p5.js 里,FFT() 是 p5.FFT 类的构造函数,p5.FFT 是 p5.sound 库中的一个重要类,它代表快速傅里叶变换(Fast Fourier Transform,FFT)。FFT 是一种在信号处理领域广泛使用的算法,主要用于将时域信号转换为频域信号,通过它能够分析信号在不同频率上的能量分布情况。
作用
在音频可视化的场景中,p5.FFT 可把音频信号从时域转换为频域,让你能获取音频在不同频率下的振幅信息,进而根据这些信息实现音频可视化效果,比如绘制频谱图、波形图等。
用法
在使用 p5.FFT 时,一般先创建一个 p5.FFT 对象,然后在 draw() 函数中调用其 analyze() 方法来获取音频频谱数据。
编写 p5_audio_vis.html 如下
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>p5.js Audio Visualization</title><script src="p5.min.js"></script><script src="p5.sound.min.js"></script>
</head>
<body><script>let song; // 音乐let fft; // 快速傅里叶变换//1.预读器(新建函数用来读取音频文件)function preload() {// 请替换为你自己的音频文件路径song = loadSound('your_audio_file.mp3');}//2.初始化function setup() {createCanvas(400, 400);fft = new p5.FFT();// 图形一般由填充色和边框两部分组成;noStroke()函数可以关闭边框的绘制noStroke();}//3.开始绘制function draw() {background(0); // spectrum 波谱、频谱let spectrum = fft.analyze();noStroke();fill(255, 0, 255);for (let i = 0; i < spectrum.length; i++) {let x = map(i, 0, spectrum.length, 0, width);let h = -height + map(spectrum[i], 0, 255, height, 0);rect(x, height, width / spectrum.length, h);}}//4.点击按钮播放/停止function mousePressed(){if (song.isPlaying()){song.pause();} else {song.play();}}</script>
</body>
</html>
运行 npm run dev
访问 http://localhost:5173/p5_audio_vis.html , 鼠标点击一下就播放音乐。
在 p5.js 中,下面这两行代码的含义如下:
fft = new p5.FFT();
这行代码创建了一个 p5.FFT 对象。p5.FFT 是 p5.sound 库中的一个类,它代表快速傅里叶变换(Fast Fourier Transform,FFT)。快速傅里叶变换是一种高效的算法,能够将时域信号转换为频域信号。在音频处理和可视化的场景中,使用 p5.FFT 对象可以分析音频信号在不同频率上的能量分布情况。这里没有给 p5.FFT 的构造函数传入参数,所以它会使用默认的参数设置,默认平滑度(smoothing)为 0.8,默认频率区间数量(bins)为 1024。
waveform = fft.waveform();
这行代码调用了 p5.FFT 对象的 waveform() 方法,并将返回值赋给变量 waveform。waveform() 方法的作用是获取当前音频信号的波形数据。波形数据是音频信号在时域上的表示,它记录了音频信号在不同时间点的振幅值。waveform() 方法返回一个数组,数组中的每个元素代表了音频信号在某个时间点的振幅,取值范围通常在 -1 到 1 之间。
编写 p5_waveform.html 如下
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>p5 audio necklace demo</title><script src="p5.min.js"></script><script src="p5.sound.min.js"></script>
</head>
<body>
<script>
let song;
let fft; // 快速傅里叶变换
let waveform; // 波形数据function preload() {// 请替换为你自己的音频文件路径song = loadSound('your.mp3');
}function setup() {createCanvas(400, 400);fft = new p5.FFT();
}function draw() {background(0);waveform = fft.waveform();stroke(255);strokeWeight(2);noFill();beginShape();for (let i = 0; i < waveform.length; i++) {let x = map(i, 0, waveform.length, 0, width);let y = map(waveform[i], -1, 1, 0, height);vertex(x, y);}endShape();
}function mousePressed(){if (song.isPlaying()){song.pause();} else {song.play();}
}
</script>
</body>
</html>
运行 npm run dev
访问 http://localhost:5173/p5_waveform.html , 鼠标点击一下就播放音乐。
编写 p5_audio_necklace.html 如下
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>p5 audio necklace demo</title><script src="p5.min.js"></script><script src="p5.sound.min.js"></script>
</head>
<body>
<script>
const soundPaths = ["your.mp3"];
let fft; // 快速傅里叶变换
let waveform; // 波形
let stars = [];
function preload()
{sound = loadSound(soundPaths);
}function setup()
{createCanvas(640,480,WEBGL); // 创建三维画板colorMode(HSB); // 颜色体系切换fft = new p5.FFT();waveform = fft.waveform();sound.amp(0.8); // 控制音量
}function draw()
{background(255);orbitControl();waveform = fft.waveform(); // 计算每一次刷新的音乐段振幅rotateX(PI/3);let r = width * 0.3;for(let a = 0;a < 2 * PI;a += PI/25){let index = int(map(a, 0, 2*PI, 0, 1024));let curH = abs(300 * waveform[index])// 需要注意图像绘制原点在电脑屏幕正中央let x = r * cos(a);let y = r * sin(a);push();translate(x,y,curH/2);rotateX(PI/2);let c1 = color(150,200,200);let c2 = color(200,100,160);let rate = map(a, 0, 2*PI, 0, 0.9);let col = lerpColor(c1,c2,rate);stroke(col);cylinder(10, 5 + curH); // 基于圆柱基础高度5pop();for(let k = 0; k < 10; k++){// 振幅越小,创建粒子的概率就会越小// 粒子运动的速度和圆柱的高度大小正相关,即振幅越大,粒子运动速度越快if(random(0.01,1) < waveform[index]) {// console.log(waveform[index]);stars.push(new star(x, y, 5 + curH, col));}}}for(let i = 0; i < stars.length; i++){stars[i].move();stars[i].show();// console.log(stars[i].z);if (stars[i].z > 500){stars.splice(i,1); // 让粒子到一定时间慢慢被删除}}
}function star(x, y, z, col)
{this.x = x + random(-2,2);this.y = y + random(-2,2);this.z = z;this.col = col;this.life = 500;this.speedX = random(-0.3,0.3);this.speedY = random(-0.3,0.3);this.speedZ = 0.05 + (z - 5) / 15;this.move = function(){this.z += this.speedZ;this.x += this.speedX;this.y += this.speedY;this.life -= 1;};this.show = function(){push();let a = map(this.life, 0, 500, 0, 1);stroke(hue(this.col), saturation(this.col),brightness(this.col));strokeWeight(1);point(this.x, this.y, this.z);pop()};}function mousePressed(){if (sound.isPlaying()){sound.pause();} else {sound.play();}
}
</script>
</body>
</html>
运行 npm run dev
访问 http://localhost:5173/p5_audio_necklace.html , 鼠标点击一下就播放音乐。

参考:基于p5.js和ml5.js库的“音乐可视化+手势交互控制”创意网页制作
编写 p5_sound_vis.html 如下
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>p5.js Sound Visualization</title><script src="p5.min.js"></script><script src="p5.sound.min.js"></script>
</head>
<body>
<script>//定义变量let song; // 声音let amplitude; // 振幅//1.预读器(新建函数用来读取音频文件)function preload(){// 请替换为你自己的音频文件路径song = loadSound('your.ogg');}//2.初始化function setup(){ createCanvas(400,400);amplitude = new p5.Amplitude();//noStroke()函数可以关闭边框的绘制noStroke();}//3.开始绘制function draw(){ background(0.5);//自由填充颜色fill(255,random(255),random(255));//映射振幅,并转换成图形let level = amplitude.getLevel();//振幅是0-1的,画布为400x400,振幅最高不能超过400let r = map(level,0,1, 0,400);ellipse(width/2, height/2, r, r);}//4.点击按钮播放/停止function mousePressed(){ if(song.isPlaying()){ song.pause();} else { song.play();}}
</script>
</body>
</html>
运行 npm run dev
访问 http://localhost:5173/p5_sound_vis.html , 鼠标点击一下就播放音乐。
参阅:p5.js 交互应用实战 —— 音乐可视化(案例)
相关文章:
p5.js:sound(音乐)可视化,动画显示音频高低变化
本文通过4个案例介绍了使用 p5.js 进行音乐可视化的实践,包括将音频振幅转化为图形、生成波形图。 承上一篇:vite:初学 p5.js demo 画圆圈 cd p5-demo copy .\node_modules\p5\lib\p5.min.js . copy .\node_modules\p5\lib\addons\p5.soun…...
HAL库常用函数
一、通用函数 系统初始化: HAL_Init(): 初始化HAL库和系统时钟(调用前需配置系统时钟源)。 HAL_Delay(uint32_t Delay): 毫秒级阻塞延时(基于SysTick定时器)。 HAL_GetTick(): 获取系统运行时间(毫秒计数…...
【Zinx】Day5-Part3:Zinx 的连接管理
目录 Day5-Part3:Zinx 的连接管理创建连接管理模块将连接管理模块集成到 Zinx 当中将 ConnManager 集成到 Server 当中在 Connection 的工厂函数中将连接添加到 ConnManagerServer 中连接数量的判断连接的删除 补充:连接的带缓冲发包方式补充:…...
C语言:6.20字符型数据练习题
编写程序,输人一行数字字符(用回车结束),每个数字字符 的前后都有空格。 把这一行中的数字转换成一个整数。 例如,若输入(<CR>代表 Enter键):2 4 8 3<CR>则输出 整数:2483。 #include <stdio.h>int main() {char ch;int number 0;printf("请输入一行…...
SpringBoot Test详解
目录 spring-boot-starter-test 1、概述2、常用注解 2.1、配置类型的注解2.2、Mock类型的注解2.3、自动配置类型的注解2.4、启动测试类型的注解2.5、相似注解的区别和联系 3、SpringBootTest和Junit的使用 3.1、单元测试3.2、集成测试 4、MockMvc 4.1、简单示例4.2、自动配置4…...
CDefView::_GetPIDL函数分析之ListView_GetItem函数的参数item的item.mask 为LVIF_PARAM
CDefView::_GetPIDL函数分析之ListView_GetItem函数的参数item的item.mask 为LVIF_PARAM 第一部分: 1: kd> t SHELL32!CDefView::_GetPIDL: 001b:77308013 55 push ebp 1: kd> dv this 0x00000015 i 0n21 …...
Android Retrofit 框架注解定义与解析模块深度剖析(一)
一、引言 在现代 Android 和 Java 开发中,网络请求是不可或缺的一部分。Retrofit 作为 Square 公司开源的一款强大的类型安全的 HTTP 客户端,凭借其简洁易用的 API 和高效的性能,在开发者社区中广受欢迎。Retrofit 的核心特性之一便是通过注…...
项目上传到Gitee过程
在gitee上新建一个仓库 点击“克隆/下载”获取仓库地址 电脑上要装好git 在电脑本地文件夹右键“Git Bash Here” 依次执行如下命令 git init git remote add origin https://gitee.com/qlexcel/stm32-simple.git git pull origin master git add . git commit -m ‘init’…...
DeepSeek R1在医学领域的应用与技术分析(Discuss V1版)
DeepSeek R1作为一款高性能、低成本的国产开源大模型,正在深刻重塑医学软件工程的开发逻辑与应用场景。其技术特性,如混合专家架构(MoE)和参数高效微调(PEFT),与医疗行业的实际需求紧密结合,推动医疗AI从“技术驱动”向“场景驱动”转型。以下从具体业务领域需求出发,…...
数学之快速幂-数的幂次
题目描述 给定三个正整数 N,M,P,求 输入描述 第 1 行为一个整数 T,表示测试数据数量。 接下来的 T 行每行包含三个正整数 N,M,P。 输出描述 输出共 T 行,每行包含一个整数,表示答案。 输入输出样例 示例 1 输入 3 2 3 7 4…...
git subtree管理的仓库怎么删除子仓库
要删除通过 git subtree 管理的子仓库,可以按照以下步骤操作: 1. 确认子仓库路径 首先确认要删除的子仓库的路径,假设子仓库路径为 <subtree-path>。 2. 从主仓库中移除子仓库目录 使用 git rm 命令删除子仓库的目录: …...
学习资料电子版 免费下载的网盘网站(非常全!)
我分享一个私人收藏的电子书免费下载的网盘网站(学习资料为主): link3.cc/sbook123 所有资料都保存在网盘了,直接转存即可,非常的便利! 包括了少儿,小学,初中,中职&am…...
SpringMVC-全局异常处理
文章目录 1. 全局异常处理2. 项目异常处理方案2.1 异常分类2.2 异常解决方案2.3 异常解决方案具体实现 1. 全局异常处理 问题:当我们在SpingMVC代码中没有对异常进行处理时,三层架构的默认处理异常方案是将异常抛给上级调用者。也就是说Mapper层报错会将…...
基于Spring Boot的宠物健康顾问系统的设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
【Linux内核系列】:深入理解缓冲区
🔥 本文专栏:Linux 🌸作者主页:努力努力再努力wz ★★★ 本文前置知识: 文件系统以及相关系统调用接口 输入以及输出重定向 那么在此前的学习中,我们了解了文件的概念以及相关的系统调用接口,并…...
Python开发Scikit-learn面试题及参考答案
目录 如何用 SimpleImputer 处理数据集中的缺失值? 使用 StandardScaler 对数据进行标准化的原理是什么?与 MinMaxScaler 有何区别? 如何用 OneHotEncoder 对类别型特征进行编码? 解释特征选择中 SelectKBest 与 VarianceThreshold 的应用场景。 如何通过 PolynomialFe…...
~(取反)在算法竞赛中的常见用法和注意事项
在算法竞赛中,取反符号 ~ 主要用于按位取反操作,其功能是对整数的二进制表示逐位取反(0 变 1,1 变 0)。以下是 ~ 在算法竞赛中的常见用法和注意事项: 1. 按位取反的基本用法 ~ 对整数的二进制表示进行取反…...
C++ MySQL 常用接口(基于 MySQL Connector/C++)
C MySQL 常用接口(基于 MySQL Connector/C) 1. 数据库连接 接口: sql::mysql::MySQL_Driver *driver; sql::Connection *con;作用: 用于创建 MySQL 连接对象。 示例: driver sql::mysql::get_mysql_driver_insta…...
本地部署 OpenManus 保姆级教程(Windows 版)
一、环境搭建 我的电脑是Windows 10版本,其他的没尝试,如果大家系统和我的不一致,请自行判断,基本上没什么大的出入啊。 openManus的Git地址:https://github.com/mannaandpoem/OpenManus 根据官网的两种安装推荐方式如…...
【Pandas】pandas Series compare
# Pandas2.2 Series ## Computations descriptive stats |方法|描述| |-|:-------| |Series.compare(other[, align_axis, ...])|用于比较两个 Series| ### pandas.Series.compare pandas.Series.compare 方法用于比较两个 Series,并返回一个包含差异的 DataFram…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
MySQL体系架构解析(三):MySQL目录与启动配置全解析
MySQL中的目录和文件 bin目录 在 MySQL 的安装目录下有一个特别重要的 bin 目录,这个目录下存放着许多可执行文件。与其他系统的可执行文件类似,这些可执行文件都是与服务器和客户端程序相关的。 启动MySQL服务器程序 在 UNIX 系统中,用…...
41道Django高频题整理(附答案背诵版)
解释一下 Django 和 Tornado 的关系? Django和Tornado都是Python的web框架,但它们的设计哲学和应用场景有所不同。 Django是一个高级的Python Web框架,鼓励快速开发和干净、实用的设计。它遵循MVC设计,并强调代码复用。Django有…...
精益数据分析(98/126):电商转化率优化与网站性能的底层逻辑
精益数据分析(98/126):电商转化率优化与网站性能的底层逻辑 在电子商务领域,转化率与网站性能是决定商业成败的核心指标。今天,我们将深入解析不同类型电商平台的转化率基准,探讨页面加载速度对用户行为的…...
