# appMusic **Repository Path**: jsy96/app-music ## Basic Information - **Project Name**: appMusic - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-12 - **Last Updated**: 2026-08-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # appMusic 一个纯前端网页应用,用于选择不同情感词,基于 `tension` 和 `brightness` 两个浮点参数自动匹配和弦进行,生成简谱音级,并通过浏览器 Web Audio API 连续演奏。 ## 功能 - 情感词选择:内置 24 种情感词,每种情感包含 `tension` 和 `brightness` 两个 0~1 浮点参数。 - 自动和弦匹配:内置 26 组和弦搭配库,系统会根据情感参数选择最接近的和弦进行。 - 选择根音 / 调性:支持 C 到 B 的 12 个半音,情感和弦进行会自动按所选根音移调。 - 手动和弦选择:支持大三、小三、减三、增三、sus2、sus4、属七、大七、小七、半减七、六、小六、九、add9、maj9、m9、7b9、7#5、maj7#11、dim7、mMaj7 等和弦。 - 进行 → 手动联动:在「情感和弦进行」中点击任一和弦名,会自动把该和弦的根音与和弦类型同步到「根音 / 调性」和「手动和弦类型」两个下拉,载入到「当前和弦」并试听一声;随后即可用「播放当前和弦 / 琶音」在该和弦上单独探索或修改(情感进行显示保持不变)。 - 输出简谱:当前和弦和情感和弦进行都会显示对应简谱音级,播放时会实时显示并高亮当前播放到的简谱音。 - 播放声音:支持播放当前和弦(整块齐奏)、当前和弦琶音(逐音依次响)、完整情感和弦进行(跟随顶部「节奏」BPM 与鼓点);每次点击播放后会自动重复播放,并在 30 秒后停止。 - 情感进行采用和弦式齐奏:每个和弦的所有音同时发声(与「播放当前和弦」一致),每个音延续到下一个和弦切换前(满拍连奏)。播放时**与涂鸦旋律共享同一节拍栅格**——以顶部「节奏」的 BPM 为准,把 2 小节(32 步)均分给当前情感进行的每个和弦(4 和弦时各占 8 步 / 2 拍),和弦切换点严格对齐节奏栅格;勾选「节拍鼓点」时情感进行也会叠加同样的鼓点。「琶音时长」滑块只负责「播放当前和弦琶音」的逐音间隔。 - 调整琶音时长:可通过滑块调整当前和弦琶音的每个音间隔。 - 实例片段:每个情感和弦进行配 1~3 个使用了相似进行或类似色彩的真实音乐作品作为参考,并可点击「演奏示范」用 Web Audio 合成一段贴合该进行的原创示范旋律(旋律声 + 柔和和弦垫),旋律简谱会随播放实时高亮。示范旋律根据和弦根音 + 旋律风格(抒情慢板 / 跳跃活泼 / 流动连贯 / 紧张半音)从和弦音派生,纯原创、不引用具体歌曲旋律;切换根音/调性时旋律会自动移调。 - 涂鸦旋律:新增「涂鸦旋律」画板,在框里用颜色任意涂鸦——**颜色(色相)映射到当前调性的五声音阶 5 个音级**(红 / 绿 / 青 / 紫 / 品红 → 1 2 3 5 6 或 1 b3 4 5 b7),**垂直位置决定八度**(上 1/3 高八度、中 1/3 中音区、下 1/3 低八度),**涂抹密度决定力度**,**空列即休止**。画板按时间轴离散成 32 步(= 8 拍 = 2 个 4/4 小节,恰好让情感进行的 4 个和弦各占 8 步 / 2 拍),抬起笔即把画面翻译成旋律简谱并实时显示。点「播放涂鸦旋律」会把旋律(正弦)叠在当前「情感和弦进行」之上,并按所选「节奏」循环演奏 30 秒,旋律简谱随播放逐音高亮;大小调(五声音阶)随当前情感 `brightness` 自动切换(< 0.5 用小调五声)。 - 节奏:在「根音 / 调性」旁新增「节奏」下拉,内置 6 种预设(流行中板 96 / 抒情慢板 70 / 轻快快板 124 / 摇摆爵士 104 / 电子律动 120 / 无鼓自由 84 BPM),每种带 BPM、摇摆比例(swing)与鼓点风格。涂鸦旋律与情感进行都按所选 BPM 把每步定为一个 16 分音符、共享同一 2 小节(32 步)节拍栅格;勾选「节拍鼓点」后两者都会叠加底鼓 / 军鼓 / 镲(噪声 + 低频正弦纯 Web Audio 合成)的 2 小节鼓点 pattern,摇摆预设还会让偶数 16 分步延后半步产生 swing feel。 - 音频情感识别:在「音频情感识别」卡片上传一段音频(wav / mp3 / m4a / ogg 等),系统在浏览器本地完成全部分析(纯前端,不上传服务器)。实现方式:用迭代 radix-2 FFT 对分帧信号做频谱分析,提取频谱重心(→ brightness)、频谱平坦度 / 能量 / 过零率(→ tension),并用 Krumhansl–Schmuckler 调性轮廓估计主音与大小调(小调额外增加 tension)。把特征映射到 `tension / brightness` 后,按与情感词相同的距离度量自动匹配最接近的情感词、刷新「情感和弦进行」与「实例片段」。为避免长音频阻塞主线程,仅分析前 30 秒。该结果为启发式估算,仅供参考。 - 音频播放 / 录音 / 保存:「音频情感识别」卡片除上传文件外,支持直接用浏览器录音(`getUserMedia` + `MediaRecorder`,最长 30 秒、到时自动停止)。录音或载入文件后可点「播放音频」用 Web Audio 试听、点「保存为 WAV」把当前音频(文件或录音)编码为 16-bit PCM WAV 下载到本地;录音完成会自动走与文件相同的本地频谱分析流程直接识别。所有音频处理均在浏览器本地完成,不上传任何服务器。 - 旋律格网导出 MIDI:「旋律格网」卡片的「导出 MIDI」按钮把当前格网(旋律 + 和弦行 + 所选节奏鼓点)编码为标准 MIDI 文件(SMF format 1,480 PPQN,4/4 拍,每步 = 16 分音符,32 步 = 2 小节)下载到本地,可直接拖入 DAW / 钢琴卷帘编辑、换音色、改速度。旋律轨为 Acoustic Grand Piano(channel 0),和弦垫轨为 String Ensemble(channel 1,每段 8 步 / 2 拍连奏),鼓点轨为 GM 打击乐(channel 9,36 底鼓 / 38 军鼓 / 42 闭合踩镲,仅在勾选「节拍鼓点」时导出);swing 节奏的奇数步延迟也一并还原。 ## 项目结构 ```text appMusic/ ├── index.html # 页面结构 ├── styles.css # 页面样式 ├── app.js # 情感数据、和弦库、简谱生成、Web Audio 播放逻辑 ├── start.bat # Windows 一键启动本地静态服务器(serve.py,禁用缓存)并自动打开浏览器 ├── serve.py # 禁用缓存的本地静态服务器(http.server + no-cache 头,配合 start.bat) ├── vercel.json # Vercel 静态部署配置(零构建) └── README.md # 项目说明 ``` ## 使用方式 **Windows 一键启动**:双击 `start.bat`,或在 cmd 里运行: ```bat start.bat ``` 脚本会自动定位项目目录、用 uv 启动本地静态服务器(默认端口 8000),并在 2 秒后用默认浏览器打开页面。需要指定端口时传入参数: ```bat start.bat 9000 ``` 停止服务器:在命令行窗口按 `Ctrl+C`。脚本依赖本机已安装的 [uv](https://docs.astral.sh/uv/)(若未安装会提示并退出)。 **手动启动**:也可以直接用浏览器打开 `index.html`,或在项目目录自行启动静态文件服务器: ```bash uv run --no-project -m http.server 8000 ``` 然后在浏览器访问 `http://localhost:8000`。 ## 部署到 Vercel 本项目是纯静态站点(无构建步骤),已附带 `vercel.json`(开启 `cleanUrls`,让 `/` 干净命中 `index.html`)。 **方式一:Vercel CLI(推荐,无需 GitHub)** 本机已安装 Vercel CLI(`vercel --version` 可用)。在项目目录依次执行: ```bash vercel login # 首次:浏览器登录 Vercel 账号 vercel --prod # 部署到生产;首次会询问项目名 / 范围,回车用默认即可 ``` 部署成功后终端会输出一个 `https://.vercel.app` 的线上地址。之后每次代码更新,再次运行 `vercel --prod` 即可重新部署。 > 注意:本仓库的 git remote 是 Gitee,而 Vercel 的 git 自动部署集成仅支持 GitHub / GitLab / Bitbucket。因此用 CLI 直接上传是最省事的方式;若希望 push 后自动部署,可把仓库再镜像一份到 GitHub,并在 Vercel 控制台 Import 该 GitHub 仓库(此时无需 `vercel.json` 之外的额外配置)。 **方式二:Vercel 控制台手动上传** 也可以在 [vercel.com/new](https://vercel.com/new) 页面直接把项目文件夹拖进去(New Project → 拖拽目录),零配置完成部署。 ## 情感参数逻辑 - `brightness` 越高,越倾向于明亮、开放的和弦色彩,例如 major、6、add9、maj7、maj9。 - `brightness` 越低,越倾向于阴暗、低沉的和弦色彩,例如 minor、m7、m6、m7b5、dim。 - `tension` 越高,越倾向于紧张、不稳定的和弦色彩,例如 sus4、7、9、7b9、7#5、dim7。 - `tension` 越低,越倾向于稳定、舒展的和弦色彩,例如 major、6、add9、maj7。 ## 界面设计 - 整体风格:深邃午夜底色 + 缓慢流动的彩色光斑,金 / 品红 / 紫三色渐变作为强调色,所有面板使用毛玻璃(backdrop-filter)效果。 - 统一且紧凑的卡片风格:所有内容卡片(当前和弦 / 情感和弦进行 / 音频情感识别 / 实例片段 / 参考资料)的标题风格完全一致——都只有标题文字 + 右侧 `card-tag` 标签,不再出现「有的带数字徽章、有的不带」的不一致;操作顺序交由 Hero 顶部的三步流程指引承担。同时整体间距收紧(面板内边距、区块间距、网格间距、按钮 / 下拉内边距统一调小),页面更紧凑。 - 就近播放按钮:播放按钮与它控制的对象放在一起——「播放当前和弦 / 播放当前和弦琶音 / 停止」在「当前和弦」卡片内;「情感和弦进行」卡片内含「播放情感进行」+「停止」(停止位于播放按钮右侧,随时中断)。 - 就近参数控件:参数控件与它控制的对象放在一起——「情感词」在「情感和弦进行」卡片内(决定进行),「手动和弦类型」+「琶音时长」在「当前和弦」卡片内(决定当前和弦与琶音);全局的「根音 / 调性」放在 Hero 顶部(决定全局调性,同时影响下方两个卡片)。 - 渐变标题:Hero 大标题与「当前和弦」的和弦名都用渐变色文字呈现。 - 自定义控件:下拉框使用自定义箭头,琶音时长滑块的轨道会按当前值实时填充金→品红渐变进度。 - 参数可视化:每个情感词卡片和当前情感统计区都会用迷你进度条分别显示 `tension`(金→玫红)和 `brightness`(靛→青)两个参数的强弱。 - 播放反馈:进入播放时 `` 会加上 `is-playing` 类标记状态;和弦齐奏(播放当前和弦 / 情感进行里的每个和弦)时,对应卡片里该和弦的所有简谱音会同时高亮,与同时发声的声音保持同步;琶音与示范旋律则保持逐音高亮。 - 简谱音符:每个简谱音是独立胶囊,播放命中时会渐变高亮、上浮放大并发光。 - 实例片段卡片:每个示例显示作品名、相似进行说明、旋律风格标签,以及原创旋律的简谱(每个和弦小节之间用「|」分隔,方便看清每个节奏;带八度点,高音上方加圆点、低音下方加圆点),播放时当前音渐变高亮上浮。 - 旋律格网卡片:参考 HookTheory TheoryTab 的格网——上方「和弦行」4 段彩色和弦块(每段 8 步 = 2 拍,按音级 1–7 上色,点击弹出 1–7 浮层选择音级、自动得该音级的自然三和弦;点外部 / Esc / 换调自动关闭);下方「旋律格」14 行(两个八度 × 7 个调式音级,越上越高)× 32 列(时间步),点击放 / 删音、同行横向拖拽画长音(跨多步),空列即休止;颜色对应 Hookpad 音级色(1红 2橙 3黄 4绿 5蓝 6紫 7粉);播放时当前列与和弦段同步高亮。另含 7 色音级图例(点击预听)、清空旋律、随机旋律。 - 参考资料 grouping:底部三个静态清单(情感词参数 / 和弦搭配库 / 已支持和弦)统一归入「参考资料」组标题之下,作为查阅区与上方交互区清晰分隔。 - 响应式:980px 以下控件改两列、网格改单列;720px 以下 Hero、控件、页脚全部纵向堆叠。同时遵循 `prefers-reduced-motion`,关闭光斑动画。 ## 页面结构(自上而下) ```text 顶部品牌栏 └─ Hero:标题 + 简介 + 三步流程指引 + 根音 / 调性 + 节奏 + 节拍鼓点(全局,影响下方卡片与旋律格网) └─ 音频情感识别:选择音频文件 或 麦克风录音 → 播放 / 保存为 WAV → 本地频谱分析 → 自动匹配情感(刷新下方进行与实例片段) └─ 旋律格网:7 色音级图例(Hookpad 色,点击预听)+ 和弦行(4 段,点击弹 1-7 浮层选音级、自动得自然三和弦)+ 旋律格(14 行=两八度×7 音级、32 列=时间,点击放/删音 + 拖拽画长音)+ 清空 / 随机旋律 + 播放格网 / 停止 / 导出 MIDI └─ 生成结果(两栏网格) ├─ 当前和弦:手动和弦类型 + 琶音时长 + 和弦名 + 简谱 + 音名 + 播放当前和弦 / 播放当前和弦琶音 / 停止 └─ 情感和弦进行:情感词 + 参数统计 + 和弦芯片 + 小节简谱 + 播放情感进行 / 停止 └─ 实例片段:真实作品参考 + 原创示范旋律 └─ 参考资料:情感词参数列表 / 26 组和弦搭配库 / 已支持和弦 └─ 页脚 ``` ## 技术说明 - 页面不依赖构建工具或第三方前端框架。 - 声音播放使用浏览器内置的 Web Audio API。 - 音频情感识别完全在浏览器本地完成:`AudioContext.decodeAudioData` 解码上传文件,自实现的迭代 radix-2 FFT 做分帧频谱分析,提取频谱重心 / 平坦度 / RMS / 过零率与 chroma,再用 Krumhansl–Schmuckler 轮廓估计调式;音频数据不会离开本机。 - 录音 / 保存:录音使用 `MediaRecorder` + `getUserMedia`(最长 30 秒、到时自动停止);录音或载入文件后可点「播放音频」用 Web Audio 试听,点「保存为 WAV」把当前 `AudioBuffer` 编码为 16-bit PCM WAV 下载到本地;录音完成后自动走与文件相同的本地频谱分析流程直接识别。 - 旋律格网:格网状态为 `melodyGrid[32]`(每步 `null` 或 `{deg, oct}`)+ `chordRow[4]`(每段音级 0–6);旋律音与和弦都按「调式音级」(大调 / 自然小调七音)+ Hookpad 七色映射,`degreeToFrequency` / `degreeToChord` 随根音与大小调(emotion brightness<0.5 为小调)联动;换情感时和弦行从当前情感进行吸附到最近调内音级重新初始化。鼓点用预生成的 1 秒白噪声 `AudioBuffer` 经 `BiquadFilter`(军鼓 bandpass / 镲 highpass)+ 指数衰减包络合成,底鼓用正弦 150→50 Hz 下扫;所有节点登记到统一的播放队列,停止时一并 `stop()`。 - 首次播放需要由用户点击按钮触发,这是现代浏览器对音频自动播放的限制。 - 旋律格网导出 MIDI:手写 Standard MIDI File 编码器(format 1,480 PPQN),按当前节奏把每步映射为 16 分音符(120 ticks)、32 步 = 2 小节 4/4。旋律 / 和弦垫 / 鼓点分别成轨:旋律用 `rowToDegreeOctave` + `degreeToFrequency` 换算音高、`freqToMidiNote`(A4=69)转 MIDI 音号,持续 len 步;和弦垫用 `degreeToChord` 取三和弦音、每段 8 步连奏;鼓点用 GM 打击乐(36/38/42)。swing 的奇数步延迟换算成 ticks 一并写入。所有 delta-time 用变长量编码,末尾加 End Of Track,最终拼成 `Uint8Array` → `Blob`(`audio/midi`)触发下载。