kaldi的vad计算

vad.conf配置文件中可选参数

--vad-energy-threshold=5.0 # VAD 的能量阈值常数项,若小于这个值则为噪音,若大于则为语音信号
--vad-energy-mean-scale=0.5 # 如果设置为 s,设 m 为该音频所有帧的平均对数能量,则实际阈值 = s*m + vad-energy-threshold;
--vad-frames-context=0 # 中央帧每一侧的上下文帧数,在其能量被监控的窗口中
--vad-proportion-threshold=0.6 # 控制窗口内需要具有比阈值更多能量的帧比例的参数

计算代码

kaldi官网文档

#include "ivector/voice-activity-detection.h"
#include "matrix/matrix-functions.h"
namespace kaldi {
    void ComputeVadEnergy(const VadEnergyOptions &opts, const MatrixBase<BaseFloat> &feats, Vector<BaseFloat> *output_voiced) {
        int32 T = feats.NumRows(); // 帧数
        output_voiced->Resize(T);  // vad输出结果
        if (T == 0) {
            KALDI_WARN << "Empty features";
            return;
        }
        Vector<BaseFloat> log_energy(T); // 对数能量值
        log_energy.CopyColFromMat(feats, 0); // column zero is log-energy. 特征的第零列是对数能量。
        
        BaseFloat energy_threshold = opts.vad_energy_threshold; // vad判断阈值, 若小于这个值则为噪音,若大于则为语音信号
        if (opts.vad_energy_mean_scale != 0.0) { // 若vad_energy_mean_scale不为0,确保其不为负数
            KALDI_ASSERT(opts.vad_energy_mean_scale > 0.0);
            energy_threshold += opts.vad_energy_mean_scale * log_energy.Sum() / T;
        }
        
        KALDI_ASSERT(opts.vad_frames_context >= 0);
        KALDI_ASSERT(opts.vad_proportion_threshold > 0.0 && opts.vad_proportion_threshold < 1.0);
        for (int32 t = 0; t < T; t++) {
            const BaseFloat *log_energy_data = log_energy.Data();
            int32 num_count = 0, den_count = 0, context = opts.vad_frames_context;
            for (int32 t2 = t - context; t2 <= t + context; t2++) {
                if (t2 >= 0 && t2 < T) {
                    den_count++; // 包含帧数
                    if (log_energy_data[t2] > energy_threshold)
                        num_count++; // log能量大于阈值的帧数
                }
            }
            if (num_count >= den_count * opts.vad_proportion_threshold)
                (*output_voiced)(t) = 1.0;
            else
                (*output_voiced)(t) = 0.0;
        }
    }  
 
}

使用方法

sid/compute_vad_decision.sh --nj 1 --cmd "$train_cmd" --vad-config vad.conf文件路径 data目录路径 log目录路径 vad目录路径
utils/fix_data_dir.sh data目录路径

该脚本会从data目录路径中读取feats.scp文件,并根据vad.conf文件路径读取vad.conf配置文件;
然后会在vad中生成多个(根据nj值确定生成的文件数)vad.ark和vad.scp文件,并把log信息写入log文件保存在log目录下,最终会将所有vad.scp合并为一个总的vad.scp放在data目录下;


版权声明:本文为qq_38789531原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。