Passer au contenu principal
A

dsh-soundcheck

alittlelov/dsh-soundcheck

Analyse un fichier audio local et fournit un bref avis en langage clair sur le tempo, la tonalité, la dynamique, l’écrêtage et la structure de l’arrangement. Les mesures brutes restent dans un bloc séparé ; l’audio ne quitte jamais la machine.

Installer

dsh plugin --profile web add github:alittlelov/dsh-soundcheck

README

dsh-soundcheck

给 DeepSeek Harness 加本地音乐分析能力 —— 让文本模型能回答关于一首歌的问题。

分析在本机:音频不出本机、不上传、不调用云端推理 · Windows 专用 · CPU 可跑,不需要 GPU 安装或补装组件时需要联网:按所选组件下载依赖与模型,完整安装约 570 MB。装完后日常分析在本机执行,不访问网络、不上传音频


这是什么

一个 DSH 插件。装上之后直接在对话里问「这首歌多快」「有没有人唱」「哪段最炸」, 模型会调它给出的四个工具,拿回实测数据再回答。

它尽量给可追溯的测量依据;预测与听写都有局限,证据不足时会明说,而不是补一个看起来合理的数字。

干什么用

能回答怎么答
多长、多快时长;BPM 两层(如 78 / 156),不替你挑哪层是「真速」
什么调Krumhansl 模板 + Top3 候选 + 歧义分类
多响、有没有削波真峰值、整体 RMS、贴顶采样数、整合响度 LUFS
能量怎么走16 秒块 RMS 走势、最满在哪、最大反差、怎么收尾
有没有人唱分轨占比 + 人声段(哪几段在唱)+ 相对电平
各轨占多少4 轨(人声 / 鼓 / 贝斯 / 其他)或 6 轨(再加吉他 / 钢琴)
歌词机器听写的候选段 —— 是候选,不是精确歌词
音高音域、趋势、有声占比、最长连续秒数
某一段怎么回事指定 [start, end] 单独分析

测不到什么(工具会直接说,不会硬编):

  • 具体乐器名 —— 中文民乐基本没有(实测会把唢呐报进没有唢呐的曲子)
  • 情绪、氛围、场景、语义联想
  • 音符级旋律 —— 音高只有轮廓

安装

dsh plugin add ALittleLov/dsh-soundcheck

第一次分析之前先装引擎:

/audio-install

它建 venv、装 librosa + onnxruntime、下载模型(约 570 MB)。

分轨与歌词听写是可选组件,不装也能用其余全部能力;缺组件时工具会明说缺什么。

都有什么

四个工具

工具作用参数
audio_analyze分析整首音频path format brief detail blocks stems preview preview_asr asr async
audio_section只分析一段path start end format brief detail blocks
audio_bands分频段诊断path start end
audio_provision装引擎stems asr

常用参数:

参数作用
format: json结构化输出(给程序用)
brief: true配合 json,只留结论级字段,约 130 token
detail: true输出完整测量明细
stems: 4s | 6s分轨(可选组件,首次 60–90 秒,之后读缓存)
asr: tiny | base | small歌词听写(可选组件,默认关闭)
preview: true快速预览,6–40 秒选段,约 8 秒;不跑分轨 / ASR
preview_asr: tiny | base | small仅配合 preview:对选中片段听写一句,约 +17 秒
async: true后台任务,立即返回 job id(分轨 / 听写建议开)

audio_bands 是分频段诊断:把频谱切 5 段(30–250 / 250–800 / 800–2500 / 2500–6000 / 6000–12000 Hz), 给每段的能量占比、打击密度、间隔规律性 cv。用来判断「这是音乐还是野外录音」、 验证某一层打击到底在不在。内部诊断用,不进主报告。

两个命令

命令作用
/audio-status看引擎状态(Python 环境 / 脚本 / 模型 / 安装标记)
/audio-install一键装引擎,返回装了什么、走了哪个镜像

怎么用

直接用自然语言问:

帮我看看 D:\Music\track.flac 这首歌什么情况
这首 2:40 那一段是怎么回事
这首有没有人唱?哪几段在唱?

要细节就加一句:

用 detail 看完整测量明细
只看 1:30 到 2:10,给我 json

装不上或想手动跑,命令行也能用:

cd <插件目录>/engine
export PYTHONUTF8=1          # Windows 上必须,否则中文输出会崩
python analyze.py "<音频路径>"
python analyze.py "<音频路径>" --detail
python analyze.py "<音频路径>" --json --brief
python analyze.py "<音频路径>" --start 1:30 --end 2:10
python analyze.py "<音频路径>" --stems 6s
python analyze.py "<音频路径>" --asr base
python analyze.py "<音频路径>" --pitch
python analyze.py "<音频路径>" --preview --preview-asr tiny

输出长什么样

默认一段判断,数字只在依据里:

[判断]  一段人能直接读的结论:时长 / 速度层级 / 调性 / 母带 / 结构重心 / 最大反差 / 收尾
[依据]  判断背后的数字:峰值、RMS、起音、调性、拍速
[可信]  beat / 调性 / 根音 的适用性分数(0-1)
[听不到] 这类分析听不出来的东西

装了可选组件才会出现的段:

[分轨]  各轨能量占比 + 人声判定
[时间线] 逐块的变化事件(哪些轨变了、变了多少、持续多久)
[钩子]  能量与起音同时出现峰值的位置,不等同于副歌或歌曲中的 Hook
[听写]  只输出通过可信度筛选的候选段;没有可信段时只给状态与计数,不给正文
[标签]  模型预测标签,仅作辅助参考
[音高]  音域 / 趋势 / 有声占比 / 最长连续秒数

[时间线] 长这样:

[时间线]
   0:16.0  编曲加码(能量 -31→-21 dB、起音 20→38);人声变响 56 dB,该状态持续 64 秒
   3:12.0  编曲加码(能量 -18→-15 dB、起音 52→42);贝斯变响 6 dB,该状态持续 48 秒
   6:40.0  动态收缩(能量 -15→-22 dB、起音 56→44)
   8:16.0  动态收缩(能量 -13→-74 dB、起音 52→4),该状态持续 41 秒

它不说「这是副歌」,只说「哪个时刻、哪条轨、变了多少、维持了多久」。段落角色还是要人听。

已知限制

  • 片段 BPM 不等于全曲 BPM:短片段会锁到别的拍层级,输出里会警告

  • 和弦只到根音级:七度、挂四、转位在混音里分不出来

  • 歌词是候选:音对字错是常态;非中文人声只给音译,不翻词义

  • 中文乐器识别不可靠:所以判断里不写配器行

  • 音高是轮廓不是音符:给不了调式、旋律走向的名字

  • 人声证据不足时会跳过听写:判据是人声轨与混音之间的相对电平差(不是人声轨单独的 dBFS), 分三档:

    • ≤ -20 dB → 不跑 ASR,状态 skipped_low_vocal_evidence
    • -20 ~ -15 dB(不含两端) → 灰区,同样不跑 ASR,状态 withheld_ambiguous_vocal_evidence
    • ≥ -15 dB → 允许跑 ASR,但结果仍须通过可信段筛选

    两个阈值是初始工程参数,没有用人工标注样本校准过。这是测量证据不足, 不是「已判定为纯器乐」——个别纯器乐仍可能因分轨泄漏跑到 ASR,反之轻声吟唱也可能被挡下

  • 没有可靠歌词时不给降级稿:如果 ASR 跑了但没有任何一段通过可信度筛选, 只报数量、不提供正文——把没验证过的文字交给下游模型,它仍会当成歌词用

关于仓库历史

这个仓库于 2026-10-23 进行过迁移和重建:旧提交合并为一次提交,旧 Release 也已重新发布。

这带来三个表现:

  • 看不到逐版本提交:完整版本记录见 CHANGELOG.md
  • 提交时间集中在同一天
  • 旧 Release 页面仍在,但里面打包的代码都是当前版本,不是该版本的原始代码

代码没有混淆、没有压缩。音频分析在本机执行,不上传音频或用户数据; 需要联网的只有安装与补装组件时的下载。 engine/analyze.py 是全文可读的。

下载文件的 sha256 校验值

插件下载的模型与配置文件都会校验 sha256。哈希写死在代码里(lib/index.js 的 CHECKSUMS), 不是运行时从网上取——否则镜像站可以把文件和哈希一起换掉,校验就失效了。

下载后校验不通过会拒绝写入并换下一个源;全部失败就报错停下,不会拿一个来路不明的文件去推理。

文件sha256
yamnet.onnx04e27fca08e7a3aea2630d1a63a51e6b437c803e0ff6e26399f80870ac251dda
musicnn.onnxa4d64c1dac195bdb118e789ddd38115c68028d26ad692448f5a8748e39490df6
beat-this-final0.onnxe5e37b7d1802895e42559c5a1ced7619b1601d257a5c8e167c9d45de37c1b078
frontend.json7b2ba71db92b79cb33f45feb21854161de329b86a7e6ea686c3fec51ce85eb9f
htdemucs_fp16weights.onnxd05c269d0178d2a72ad484b10b11dd370193fc923201c3b27a99f848745db70a
htdemucs_6s_fp16weights.onnx7ce55792e2231c93fbf92de95f5fd5b3a5e6c89f7db690dfd693e8f1dce56869

想自己核对已经装好的模型:

sha256sum yamnet.onnx musicnn.onnx
# Windows: certutil -hashfile yamnet.onnx SHA256

许可

MIT

Plugins associés