# DeClicker **Repository Path**: LXP-Never/de-clicker ## Basic Information - **Project Name**: DeClicker - **Description**: 嘀嗒声消除 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-06-26 - **Last Updated**: 2026-06-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # declicker — Click/Pop 消除器 复现 Adobe Audition Click/Pop Eliminator 的检测与修复。依赖 numpy + scipy。 ## 效果 ### 频谱对比 三面板频谱图:原始(click 可见为垂直亮线)→ 修复后(亮线消失)→ 差异(仅移除了 click)。 ![频谱对比](docs/comparison_spectrogram.png) ### 波形对比 原始波形 vs 修复后波形,红色虚线标注 5 个用户确认的 click 位置。 ![波形对比](docs/comparison_waveform.png) ### 检测修复分布 6 个 click 被检测并修复,共 3484 个样本修改,非 click 区域零漂移。 ![检测分布](docs/detection_map.png) ## 快速开始 ```python from declicker import declick_file declick_file('input.wav') ``` 命令行: ```bash python pipeline.py ``` ## 架构 ``` [输入] → [STFT 逐频段偏离检测] → [脉冲衰减验证] → [per-bin gain gate 修复] → [输出] ``` ### 检测:STFT 逐频段偏离 + 脉冲衰减验证 | 步骤 | 方法 | 作用 | |------|------|------| | 1 | STFT 计算时频矩阵 | fft_size=256, hop=8 | | 2 | 逐频率 bin 计算当前帧/双向背景中值偏离比 | 前后各 50 帧背景,排除当前帧 | | 3 | 取所有 bin 最大偏离为帧异常度 | 宽带瞬态检测 | | 4 | 对数空间 4σ 离群点检测 | threshold 自适应,无硬编码 | | 5 | 脉冲衰减验证 | decay_ratio < 0.2,基于阻尼指数衰减模型 | ### 修复:per-bin gain gate + 局部窗口混合 | 步骤 | 方法 | 作用 | |------|------|------| | 1 | 逐 click 取局部窗口 | click 两侧各 8*fft_size 上下文 | | 2 | 局部 STFT | 幅度谱 + 相位谱 | | 3 | 坏帧逐 bin gain = min(1, expected/actual) | 只压低膨胀 bin,不放大,保留相位 | | 4 | 局部 ISTFT 重建 | OLA 加窗合成 | | 5 | 只在 click ± hop 范围混合 | 远离 click 的区域零漂移 | ## 关键设计决策 ### 为什么用 STFT 偏离检测而不是能量比或 AR 预测误差? - **能量比法**检测"能量突变",会误报所有音乐瞬态(鼓点、辅音起始) - **AR 预测误差法**检测"不符合信号模型的异常点",但对工频干扰型 click 不敏感 - **STFT 偏离法**直接对应频谱图上的视觉特征,能检测所有类型的宽带瞬态 ### 为什么用双向背景窗口? 背景中值应包含 click 前后的正常信号。单向(只看过去)窗口在 click 后面会因背景偏低而误判正常音频。双向窗口(前后各 50 帧,排除当前帧)从物理上避免了这个问题,语音误报自动消失。 ### 为什么用 per-bin gain gate 而不是整帧中值替换? - **整帧中值替换**会替换整个 STFT 帧的幅度,包括正常的频率 bin,导致频谱细节丢失 - **per-bin gain gate** 只压低膨胀的频率 bin,正常 bin 不受影响 - 增益永远 ≤ 1,不会放大噪声 - 保留原始相位,无相位抵消导致的"水声感" - 局部窗口策略:只在 click ± hop 范围混合,远离 click 的区域零漂移 ### 阈值为什么自适应? - **离群点检测**:max_dev 在对数空间近似高斯分布,用 MAD 鲁棒估计 σ,threshold = median + 4σ。4σ 置信度 ~6e-5,不依赖任何绝对数值 - **衰减比**:click 是脉冲响应,τ << T_window → 残留能量 e^(-T/τ) → 0;持续信号衰减比 → 1。decay_ratio < 0.2 对应 τ < T/1.6 ## 瞬态噪声仿真器(NN 训练数据增强) `simulate/` 覆盖 6 大类 20 种瞬态噪声,每个函数返回 `(noisy, events)` 供监督学习使用。所有幅度默认自适应(基于信号 RMS)。 ### 6 大类覆盖 | 类别 | 函数 | 模拟场景 | |------|------|---------| | ① 单点冲击 | `add_click`, `add_spike`, `adc_dac_glitch` | 静电/接口冲击、ADC 饱和恢复 | | ② 短时突变 | `add_pop`, `clipping_burst`, `bit_crash` | 电流冲击、瞬时削顶、缓冲区错误 | | ③ 丢失中断 | `dropout_burst`, `packet_loss` | frame drop、网络丢包 | | ④ 比特损坏 | `bit_flip` | 存储/传输 bit 错误(单 bit XOR 翻转) | | ⑤ 频谱瞬态 | `add_crackle`, `vinyl_crackle`, `emi_spike`, `clock_noise`, `impulse_train` | vinyl 噪点、电磁干扰、时钟串扰 | | ⑥ 物理建模 | `dc_offset_jump`, `damped_oscillation`, `mic_pop`, `relay_bounce`, `codec_artifact`, `resample_glitch` | 电容充放电、阻尼振荡、喷麦、继电器弹跳、编解码预回声、重采样不连续 | ### 用法 ```python from simulate import TransientNoiseAugment, events_to_mask augment = TransientNoiseAugment(p=0.8) noisy, events = augment(clean_audio, sr) # X = noisy, Y = clean_audio mask = events_to_mask(events, len(noisy)) # 1=受污染样本,用于 loss masking ``` ### 稀疏分布设计 真实 click 分布是稀疏的,组合器默认不同时全开,每种噪声独立概率: | 噪声类型 | 默认概率 | |---------|---------| | click | 0.30 | | pop | 0.20 | | 其余 18 种 | 0.05~0.10 | ### 自适应幅度 绝大多数函数支持 `amplitude=None`(默认),按 `signal_rms × amp_ratio` 自动计算,适配任意幅度输入(归一化语音到低幅度粉噪均可)。 ## 文件结构 ``` declicker/ ├── __init__.py # 导出 declick, declick_file, 仿真增强函数 ├── detect.py # STFT 偏离检测 + 脉冲衰减验证 ├── lsar.py # per-bin gain gate 修复 + 局部窗口混合 ├── pipeline.py # 主管线:检测 → 修复 → 输出 ├── simulate/ # 瞬态噪声仿真器(6 大类 20 种,NN 训练数据增强) │ ├── augment.py # 20 种噪声 + 组合器 │ ├── README.md # 仿真器文档 │ └── samples/ # 样例 wav(基于 pink_noise 生成) ├── cc_test/ # 测试和分析脚本 ├── docs/ # 效果图 │ ├── comparison_spectrogram.png # 频谱对比图 │ ├── comparison_waveform.png # 波形对比图 │ └── detection_map.png # 检测分布图 └── uploaded/ # 测试音频 ``` ## 依赖 - Python ≥ 3.8 - numpy - scipy ## 参数 | 参数 | 默认值 | 说明 | |------|--------|------| | fft_size | 256 | STFT 窗长 | | hop | 8 | 检测 STFT 帧移 | | context_frames | 100 | 双向背景窗口总帧数 | | outlier_sigma | 4.0 | 离群点检测 σ 倍数(对数空间) | | decay_ratio_max | 0.2 | 脉冲衰减判据上限 | | min_duration_ms | 5.0 | 最短 click 持续时间 | ## 已知局限 - 窄 click(<3ms)检测能力有限——STFT 窗长 256 对 1-10 样本的尖峰灵敏度不足 - 16kHz 采样率下频谱分辨率低,部分频域判据不可靠 - 未在 44.1kHz 高采样率下验证 ## 版本历程 | 版本 | 关键改进 | |------|---------| | v1.0 | STFT 频谱偏离检测 + 频谱替换修复 | | v1.1 | 阈值基于物理原理自适应(4σ 离群点 + 衰减比) | | v1.2 | 双向背景窗口(语音误报自动消失,检测 12→6) | | v1.3 | 瞬态噪声仿真器(6 大类 20 种,NN 训练数据增强,全部自适应幅度) |