Skip to content

linnn-nb/audio-qc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

audio-qc · 音频自动质检工具

把"音频投稿 / 训练数据是否合格"的判断,拆成可自动计算、可解释、可复现的指标, 为每个音频生成一张多维记分卡,并用三层漏斗(PASS / REVIEW / REJECT)给出审核结论。

适用场景:UGC 音频投稿初筛、音乐/音效训练数据清洗、批量素材质检。


一、四维评价体系

每个音频从 4 个维度评价。前 3 维各 0–5 分并按权重汇总成总分;版权维度本版本仅占位、不计权

维度 权重 是否全自动 说明
音质 0.4 ✅ 全自动 LUFS 响度 / 削波 / 波峰因数(动态) / 本底噪声 / 采样率,纯波形计算,稳定可复现
音乐性(客观代理) 0.3 ⚠️ 仅客观代理 多个信号处理可直接算的代理子分量取平均(动态 / 节奏 / 频谱织体 / 声场 / 段落对比),不是真实音乐性评价
场景 0.3 ◐ 半自动 时长适配 +(可选)申报标签真实性校验(申报 BPM/调性 vs 实测)
版权 ❌ 未接入 本版本占位,标注"未接入";接口已在 fingerprint.py 预留

诚实边界说明

  • 音质完全自动、客观,可直接信任。
  • 音乐性只是客观代理:动态起伏大、节拍稳、频谱不噪声化、有声场展宽、段落对比强,都不等于"好听"。这些只是可由信号处理稳定复现的代理量,真实音乐性需专门模型 + 人工听审,本工具只提供数值供参考。

音乐性子分量(各 0–5,取平均得维度分;单声道时跳过"声场"不计入平均)

子分量 用到的客观特征 含义 / 评分逻辑
动态 dynamic_variation 帧级 RMS(dB) 标准差;越大=音量起伏越明显,过平铺扣分
节奏 tempo_stability + onset_density 节拍稳定性 = 1/(1+拍间隔变异系数CV)(0–1,越稳越高);节奏密度=onset数/时长,落在理想窗 [0.5, 8] 次/秒满分,过稀疏/过密扣分
频谱织体 spectral_flatness + spectral_centroid_hz 频谱平坦度过高(≥0.5)判为噪声化扣分;频谱质心(音色明暗)落在 [500, 6000]Hz 满分,过闷/过尖锐扣分
声场 stereo_width 左右声道相关系数 corr,宽度=clip(1−corr,0,1);单声道返回 0 且跳过不计入平均
段落对比 section_contrast 三段 MFCC 均值两两欧氏距离均值;越大=主歌/副歌/桥段对比越强

另含辅助客观特征 spectral_balance(低 <250Hz / 中 250–4000Hz / 高 >4000Hz 三段能量占比 low_ratio/mid_ratio/high_ratio),随特征一并输出到 JSON,便于追溯频段分布,但不直接参与上面子分量打分。

以上阈值均在 config.jsonmusicality 段,可经 --config 覆盖。这些仍是客观代理,边界同上。

  • 场景在无申报标签时只能按时长粗判,精确场景匹配需要更多业务信息(用途、目标平台等)。
  • 版权 / 曲风分类未接入:版权需指纹库(Chromaprint/AcoustID),曲风需分类模型,均为后续工作。

二、三层漏斗

        ┌─────────────────────────────────────────────┐
输入 ──▶ │ ① 否决门:时长越界 / 近全静音 / 严重削波       │ ──命中──▶ REJECT
        └─────────────────────────────────────────────┘
                          │ 未命中
                          ▼
        ┌─────────────────────────────────────────────┐
        │ ② 三维打分 → 加权总分(版权不计权)            │
        └─────────────────────────────────────────────┘
                          │
                          ▼
        ┌─────────────────────────────────────────────┐
        │ ③ 结论:总分 ≥4.0 PASS / 2.5–4.0 REVIEW       │
        │          / <2.5 REJECT                        │
        └─────────────────────────────────────────────┘

否决门(命中任一直接 REJECT)

  • 时长不在 [5s, 600s]
  • 有效声音占比 active_ratio < 0.05(近乎全静音)
  • 削波采样占比 clipped_ratio > 0.01(严重削波失真)

三、安装与用法

安装(推荐虚拟环境)

cd audio-qc
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

依赖:numpy soundfile pyloudnorm librosa scipy。处理 mp3/m4a 等压缩格式需系统装有 ffmpegbrew install ffmpeg)。

用法

# 单文件
python screen.py samples/normal.wav

# 整个目录(递归扫描 .wav .mp3 .flac .m4a .ogg)+ 写出 JSON
python screen.py samples/ -o report.json

# 自定义阈值/权重
python screen.py samples/ --config config.json -o report.json

# 带申报标签做"标签真实性"校验
python screen.py samples/ --labels labels.json -o report.json

--labels JSON 形如(按文件名匹配):

{ "track01.wav": { "bpm": 120, "key": "A minor" } }

四、记分卡输出示例

控制台(每文件一行 + 结论原因 + 汇总):

================================================================================================
音频质检报告 (audio-qc)
================================================================================================
文件                  结论       总分  音质  音乐  场景    BPM  调性
------------------------------------------------------------------------------------------------
normal.wav            REVIEW    3.2   4.5   1.5   3.8     120  A minor
    └ 结论: 加权总分 3.2 处于 [2.5,4.0),建议人工复核
clipped.wav           REJECT     -     -     -     -        -  unknown
    └ 结论: 命中否决门:削波采样占比 0.42(>0.01),严重削波失真
------------------------------------------------------------------------------------------------
汇总
  文件总数 : 4
  结论分布 : {'REVIEW': 1, 'REJECT': 3}
  通过率   : 0.0%
  ...

JSON(report.json,每文件含各维度分数 + 逐条中文理由 + 原始指标快照):

{
  "summary": { "total_files": 4, "verdict_counts": {...}, "pass_rate": 0.0, "bpm_distribution": {...}, "key_distribution": {...} },
  "results": [
    {
      "file": "samples/normal.wav",
      "verdict": "REVIEW",
      "total_score": 3.2,
      "dimensions": {
        "音质":   { "score": 4.5, "weight": 0.4, "reasons": ["响度 -13.8 LUFS 处于目标窗内", ...] },
        "音乐性": { "score": 1.5, "weight": 0.3, "reasons": ["说明:以下为客观代理评分...", ...] },
        "场景":   { "score": 3.8, "weight": 0.3, "reasons": [...] },
        "版权":   { "score": null, "status": "未接入", "reasons": ["版权指纹检测未接入(本版本跳过)..."] }
      },
      "metrics": { "lufs": -13.8, "clipped_ratio": 0.0, ... },
      "features": {
        "bpm": 120.0, "key": "A minor", "key_confidence": 0.84,
        "dynamic_variation": 10.2, "section_contrast": 83.5,
        "tempo_stability": 0.94, "onset_density": 1.05,
        "spectral_flatness": 0.001, "spectral_centroid_hz": 1205.0,
        "low_ratio": 0.85, "mid_ratio": 0.14, "high_ratio": 0.003,
        "stereo_width": 0.26
      }
    }
  ]
}

五、项目结构

audio-qc/
├── audioqc/
│   ├── probe.py        # 解码与格式探测 -> Audio
│   ├── quality.py      # 音质客观指标 -> QualityMetrics
│   ├── features.py     # 音乐性客观代理特征(含节拍稳定性/频谱/声场等) -> MusicFeatures
│   ├── rules.py        # 否决门 + 三维评分 + 结论 -> 记分卡
│   ├── report.py       # 记分卡整理 / 批量汇总 / 控制台打印
│   └── fingerprint.py  # 版权指纹占位(接口预留)
├── screen.py           # 命令行入口(批量)
├── config.json         # 默认阈值/权重(可被 --config 覆盖)
└── requirements.txt

六、未接入 / 后续工作

  • 版权指纹检测:接入 Chromaprint fpcalc + AcoustID 数据库(fingerprint.py 已留接口与接入备忘)。
  • 曲风 / 情绪分类:需训练或接入分类模型。
  • 真实音乐性评价:当前为客观代理,后续可接专门模型并结合人工听审。

About

音频自动质检工具:四维记分卡(音质/音乐性/场景/版权)+三层漏斗(PASS/REVIEW/REJECT),为音乐投稿/训练数据做可解释、可复现的自动初筛

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages