Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

中西方乐器动态音色空间系统

把乐器音频转成可计算、可解释的「动态音色空间」:提取声学特征 → 可视化音色轨迹 → 在主观感知维度上做相关性验证 → 归档案档。

本项目由 3 个脚本重构而来:

原始文件 重构后的位置
project2.py timbre_space/(config / audio / features / trajectory / users / storage / pipeline / ui)+ app.py
visualize copy 2.py 其独有的完整特征集(带宽 / 滚降 / 对比度 / 平坦度 / pyin 基频 / hpss 谐波分离)并入 timbre_space/features.py、audio.py
relitu3.py timbre_space/perception.py + scripts/plot_perception_heatmap.py

目录结构

timbre_app/
├── app.py                        # Web 界面入口
├── requirements.txt
├── timbre_space/                 # 主包
│   ├── config.py                 #   配置:路径 / 音频 / 绘图参数
│   ├── fonts.py                  #   跨平台中英文字体解析
│   ├── audio.py                  #   音频加载、预处理、波形与频谱图
│   ├── features.py               #   全局汇总特征 + 逐帧特征
│   ├── trajectory.py             #   轨迹样条平滑 + 3D/2D 可视化
│   ├── perception.py             #   感知相关性热力图
│   ├── users.py                  #   用户注册与登录
│   ├── storage.py                #   历史任务归档
│   ├── pipeline.py               #   流程调度(界面与 CLI 共用,不依赖 gradio)
│   └── ui.py                     #   Gradio 界面
├── scripts/
│   ├── plot_perception_heatmap.py  # 出热力图(relitu3.py 的 CLI 版)
│   └── analyze_audio.py            # 批量提特征 + 出轨迹图
├── tests/
│   ├── test_smoke.py               # 离线自检(不需要 librosa)
│   └── test_pipeline_e2e.py        # 端到端(需要真实音频)
├── data/samples/                 # 示例数据
│   ├── 感知相关性.csv
│   └── 感知不相似度矩阵.xlsx
└── runtime/                      # 运行产物(自动创建,已 gitignore)
    ├── user_data/                #   users.json + 每用户目录
    ├── history/                  #   history.json + 每任务结果目录
    └── temp/                     #   中间文件与可下载 CSV

安装

cd timbre_app
python -m venv .venv
.venv\Scripts\activate        # Windows
pip install -r requirements.txt

依赖:librosa / numpy / pandas / scipy / matplotlib / seaborn / openpyxl / gradio。 界面层对 Gradio 5 与 6 都做了兼容(Gradio 6 把 css、theme 从 Blocks() 移到了 launch(),Dataframe 的 height 改成了 max_height,timbre_space/ui.py 里已自动探测)。

自检

python tests/test_smoke.py          # 离线:字体 / 热力图 / 轨迹 / 用户 / 归档
python tests/test_pipeline_e2e.py   # 端到端:需要 librosa + 一个真实音频

test_pipeline_e2e.py 默认从项目上一级的乐器库里自动挑一个音频,也可以指定:

set TIMBRE_TEST_AUDIO=D:\some\place\sample.wav
python tests/test_pipeline_e2e.py

使用

1. Web 界面

python app.py                            # 默认 127.0.0.1:7860,自动开浏览器
python app.py --port 8000
python app.py --host 0.0.0.0 --share     # 生成临时公网链接
python app.py --runtime-dir D:/data/timbre_runtime

界面分 5 页:用户管理 → 音频上传 → 特征提取 → 动态可视化 → 历史记录。 分析产物会落到 runtime/history/<任务ID>/,包含波形频谱图、3D/2D 轨迹图、 逐帧特征 CSV、全局特征 CSV。

2. 感知相关性热力图

python scripts/plot_perception_heatmap.py
python scripts/plot_perception_heatmap.py \
  --input data/samples/感知相关性.csv \
  --output 图/感知相关性_热力图.png
python scripts/plot_perception_heatmap.py \
  --input data/samples/感知不相似度矩阵.xlsx

默认按论文级排版:宋体中文 + Times New Roman 西文(与原 relitu3.py 一致),600 dpi。

配色会按矩阵类型自动切换:

输入 判定依据 配色
感知相关性.csv(有负值) 出现负相关 vlag 发散色,色心锁 0:正相关偏红、负相关偏蓝、0 为白
感知不相似度矩阵.xlsx(全非负) 距离矩阵没有负值 单向色阶 YlOrRd,否则整张图会挤在色带一侧读不出层次

Excel 的表头行会自动定位。感知不相似度矩阵.xlsx 的第 0 行是合并标题、 第 1 行才是 乐器声音样本 | 古筝 | 中胡 | ...,原脚本按第 0 行切会直接报错。

3. 批量分析音频

python scripts/analyze_audio.py "某个音频.wav"
python scripts/analyze_audio.py --instrument-dir "D:/YCHEN/timbre_space/audioclassification/flute" --limit 30
python scripts/analyze_audio.py --glob "D:/.../**/*.wav" --summary 特征汇总.csv
python scripts/analyze_audio.py <多个文件> --no-plots      # 只提特征,批量时更快

4. 在代码 / notebook 里调用

from timbre_space import TimbrePipeline, settings

pipeline = TimbrePipeline()
features, plots = pipeline.analyze_once("audio.wav")
print(features.global_features)
print(plots)

配置

所有配置集中在 timbre_space/config.py,路径全部基于文件位置推导,与启动时的工作目录无关。

配置项 默认值 说明
AudioConfig.target_sr 22050 重采样目标采样率
AudioConfig.max_duration 10.0 每段音频最长处理秒数
AudioConfig.n_mfcc 20 MFCC 维数
PlotConfig.dpi 300 CLI / 归档出图 dpi
PlotConfig.app_dpi 200 界面内出图 dpi(兼顾速度)
PlotConfig.heatmap_dpi 600 热力图 dpi(印刷级)

可用环境变量覆盖路径:

  • TIMBRE_RUNTIME_DIR:运行产物目录
  • TIMBRE_DATA_ROOT:乐器音频库所在根目录(默认取项目上一级,即 D:\YCHEN\timbre_space)

相比原始脚本的改动

功能增强

  • 特征集取两者之长:保留 visualize copy 2.py 的频谱带宽 / 滚降 / 对比度 / 平坦度、 20 维 MFCC、pyin 基频、hpss 谐波与打击乐分离,同时采用 project2.py 的模块边界。 单段音频实测输出 34 项全局特征。
  • 新增谐波能量占比、浊音占比、频谱质心标准差等衍生特征。
  • 逐帧特征做 min-max 归一化,避免 3D 轨迹被量纲最大的频谱质心完全支配。
  • 热力图配色按矩阵类型自动切换,Excel 表头行自动定位(详见上一节)。
  • 命令行支持批量与通配符,--no-plots 可跳过出图只提特征,适合跑数据集。

Bug 修复

问题 原状 现状
3D 图文件名硬编码 visualize copy 2.py 写死 '小提琴_dynamic_3d.png',分析任何乐器都覆盖同一文件 文件名由音频文件名派生
历史记录未做归属校验 visualize copy 2.py 的 load_history_task 不校验用户 HistoryStore.get 强制按用户名过滤
task_id 冲突 秒级/整数时间戳,同秒两次分析互相覆盖;毫秒级在紧循环里仍会碰 毫秒时间戳 + 4 位随机后缀
JSON 索引写坏 seek(0) 后 dump,新内容更短时尾部残留旧字节 → JSON 损坏 临时文件 + os.replace 原子替换
登录态串号 current_user 挂在全局单例,多窗口互相顶掉 gr.State(Session()) 每会话独立
密码强度 无盐 MD5 PBKDF2-HMAC-SHA256(随机盐 + 20 万次迭代),旧 MD5 记录可登录并自动升级
中文乱码 字体路径写死 Linux 服务器 /hdd/.../simsun.ttc,Windows 上中文变方块 按操作系统探测候选字体
论文图字体降级 — 衬线中文(宋体)与黑体系分开解析,论文图仍用宋体
样条插值崩溃 make_interp_spline 直接调用,时间轴重复/非单调时抛异常 先排序去重,再按点数降阶
Excel 表头误判 按第 0 行切列名,遇到带标题行的表直接报错 在前若干行里自动定位表头
相对路径漂移 数据目录相对 cwd,换目录启动就找不到 全部基于 Path(__file__) 推导
删除越界 清空历史时直接 rmtree(record['save_dir']) 校验目标必须是 history 目录的子目录
界面兼容性 只适用于 Gradio 4/5 探测并兼容 Gradio 5 / 6

原始数据说明

感知相关性.csv 是 16 个主观听觉形容词与 3 个 UMAP 维度的相关系数矩阵。 从数值可以读出三条几乎正交的语义轴:

维度 语义轴 正向代表 负向代表
维度 1 明亮度 明亮 +0.85 / 尖锐 +0.84 / 清脆 +0.79 暗淡 −0.88 / 单薄 −0.46
维度 2 厚实度 浑厚 +0.73 / 厚实 +0.71 / 丰满 +0.68 单薄 −0.77 / 干瘪 −0.63
维度 3 粗糙度 粗糙 +0.84 / 混浊 +0.76 清脆 −0.44

互为反义的词对在同一条轴上符号相反(明亮/暗淡、丰满/单薄、清脆/混浊), 说明客观声学特征空间与主观感知维度是对齐的——这正是本课题的核心论点。


验证情况

重构后已实际运行并全部通过(Windows / Python 3.13 / librosa 1.0.0 / gradio 6.27.0):

检查项 结果
python -m py_compile(14 个 .py) 通过
tests/test_smoke.py 9 / 9 通过
tests/test_pipeline_e2e.py(真实大提琴音频) 25 / 25 通过
scripts/analyze_audio.py 输出 37 列汇总表 + 2 张轨迹图
scripts/plot_perception_heatmap.py CSV 与 xlsx 两条分支均出图,与原 感知相关性_热力图.png 数值一致
Gradio 界面构建 72 个组件,无异常
界面实际启动 HTTP 200,标题与自定义 CSS 均正常注入

runtime/ 目录是运行产物(用户库、历史记录、临时文件),已在 .gitignore 中, 可随时整个删掉;下次启动会自动重建。

About

中西方乐器动态音色空间系统:乐器音频声学特征提取、音色轨迹可视化与感知相关性分析(Gradio 界面 + 命令行工具)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages