如何根据包含语音的单个音频文件估算 SNR? 我知道两种方法:
对数功率直方图百分位差(又名“NIST 快速方法”),此处描述:http://labrosa.ee.columbia.edu/~dpwe/tmp/nist/doc/stnr.txt
10*log10( (S-N)/N ), 其中
- S = sum{x[i]^2 * e[i]}
- N = 总和{x[i]^2 * (1-e[i])}
- e[i] 某种语音事件检测(语音/非语音指示器)
有没有更好的方法不需要立体数据(或干净和嘈杂版本的数据)?我还想避免 NIST 文档(请参阅 1.)中描述的“第二种方法”,该方法对分布做出了强有力的假设。
最佳答案
人声使用 300 Hz 到 3 kHz 的频率。这就是(旧的)电话系统正在使用的。人声永远不会同时使用所有这些频率,这就是为什么我们可以进行频率分析以找到本底噪声 - 无需任何引用或语音事件检测 e[i]:
计算频率分辨率为 ~ 10 - 20 Hz 的 FFT。 对于 48 kHz 的采样率,您将使用采样率/分辨率的 FFT 长度 = 4800 个样本,这应该四舍五入到最接近的 2 的幂,即 4096
确定保存 300 - 3000 赫兹结果的必要容器。 bin 索引 k 保存频率 k*samplerate/FFT_length 的结果。对于 48 kHz 以上的输入和 FFT 长度 4096,这是 k(300 Hz) = 300 * 4096/48000 ~= 25 和 k(3000 Hz) = 3000 * 4096/48000 ~= 250。
计算每个必需 bin 中的能量:E[k] = FFT[k].re ^2 + FFT[k].im ^2。这取决于您的 FFT 算法将实部和虚部写入“何处”。
N = min{ E[k=25..250] } * number_of_bins (=250-25+1)
S = sum{ E[k=25..250] }
SNR = (S-N)/N。电平为10*log10(SNR)
由于 SNR 随时间变化,返回步骤 1 使用一些新样本 - 可能有一些重叠
关于algorithm - 估计音频文件信噪比的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8150725/