kaldi sre16/v1中local/make_mx6_mic.pl的解释

主要是将各种来源的声音文件降采样到8K,并检查各种需要prepare的文件。

#!/usr/bin/perl
use warnings; #sed replacement for -w perl parameter
# Copyright 2017   David Snyder
# Apache 2.0
# Prepares Mixer 6 (LDC2013S03) speech from a specified microphone and
# downsamples it to 8k.

if (@ARGV != 3) {
  print STDERR "Usage: $0 <path-to-LDC2013S03> <channel> <path-to-output>\n";
  print STDERR "e.g. $0 /export/corpora5/LDC/LDC2013S03 02 data/\n";
  exit(1);
}
($db_base, $ch, $out_dir) = @ARGV;
# 接收参数

@bad_channels = ("01", "03", "14");
# 创建数组

if (/$ch/i ~~ @bad_channels) {
  print STDERR "Bad channel $ch\n";
  exit(1);
}

# 如果文件夹不存在
if (! -d "$db_base/mx6_speech/data/pcm_flac/CH$ch/") {
  print STDERR "Directory $db_base/mx6_speech/data/pcm_flac/CH$ch/ doesn't exist\n";
  exit(1);
}

#如果在创建输出文件夹时候出错
$out_dir = "$out_dir/mx6_mic_$ch";
if (system("mkdir -p $out_dir")) {
  print STDERR "Error making directory $out_dir\n";
  exit(1);
}

if (system("mkdir -p $out_dir") != 0) {
  print STDERR "Error making directory $out_dir\n";
  exit(1);
}


# 打开5个文件,如果打不开就输出die 后面跟的提示,die有点类似warning
open(SUBJECTS, "<$db_base/mx6_speech/docs/mx6_subjs.csv") || die "cannot open $$db_base/mx6_speech/docs/mx6_subjs.csv";
open(SPKR, ">$out_dir/utt2spk") || die "Could not open the output file $out_dir/utt2spk";
open(GNDR, ">$out_dir/spk2gender") || die "Could not open the output file $out_dir/spk2gender";
open(WAV, ">$out_dir/wav.scp") || die "Could not open the output file $out_dir/wav.scp";
open(META, "<$db_base/mx6_speech/docs/mx6_ivcomponents.csv") || die "cannot open $db_base/mx6_speech/docs/mx6_ivcomponents.csv";

# 之前一直以为chomp函数只是去掉字符串末尾的\n
# chomp的真正作用是去除字符串末尾的$/,只是因为默认情况下$/为\n,造成chomp就是去除\n的假象;
# @_ 是函数传参时放置参数的数组,可以从中取实参
# $_ 是默认参数的意思,指的是在不指定的情况下,程序处理的上一个变量
# 比如,某个例子是打开一个文本文件,读取每一行,在没有指定参数的情况下,$_指向了从文件中读取的每一行
# Perl中uc和lc函数,两个函数都是把转换之后的字符串作为返回的值,uc是大写,表示upper convert,lc是小写,表示lower convert

while (<SUBJECTS>) {
  chomp;
  $line = $_;
  @toks = split(",", $line);  # 创建数组
  $spk = $toks[0];            # 创建标量
  $gender = lc $toks[1];
  if ($gender eq "f" or $gender eq "m") {
    print GNDR "$spk $gender\n";
  }
}

$num_good_files = 0;
$num_bad_files = 0;
while (<META>) {
  chomp;
  $line = $_;
  @toks = split(",", $line);
  $flac = "$db_base/mx6_speech/data/pcm_flac/CH$ch/$toks[0]_CH$ch.flac";
  $t1 = $toks[7];
  $t2 = $toks[8];
  @toks2 = split(/_/, $toks[0]);    # 创建数组
  $spk = $toks2[3];
  $utt = "${spk}_MX6_$toks2[0]_$toks2[1]_$ch";    # 这个应该是字符串拼接吧
  if (-f $flac) {      # 判断是否普通文件
    print SPKR "${utt} $spk\n";         # SPKR 代表一个文件啊,utt2spk,是一个变量名
    print WAV "${utt} sox -t flac $flac -r 8k -t wav - trim $t1 =$t2 |\n";     # 这句话使用sox 将音频转采样率为8K,https://blog.csdn.net/PeeNut/article/details/81176000
    $num_good_files++;   # 采样到8K成功的话就是一个good file
  } else {
    print STDERR "File $flac doesn't exist\n";
    $num_bad_files++;    # 记录不能采样到8K的文件个数
  }
}

print STDERR "Processed $num_good_files utterances; $num_bad_files had missing flac data.\n";
# 输出good files和bad files的数量

# 下面关闭5个文件
close(SUBJECTS) || die;
close(GNDR) || die;
close(SPKR) || die;
close(WAV) || die;
close(META) || die;

# 利用utt2spk,自动生成spk2utt文件
if (system(
  "utils/utt2spk_to_spk2utt.pl $out_dir/utt2spk >$out_dir/spk2utt") != 0) {
  die "Error creating spk2utt file in directory $out_dir";
}

# utils/fix_data_dir.sh是干什么的呢?
# 看看下面的注释:
# This script makes sure that only the segments present in
# all of "feats.scp", "wav.scp" [if present], segments [if present]
# text, and utt2spk are present in any of them.
# It puts the original contents of data-dir into
# data-dir/.backup

# This script helps ensure that the various files in a data directory are correctly sorted and filtered, 
# for example removing utterances that have no features (if feats.scp is present)
# 应该是减少不必要的计算,节约算力,utterances的总数有可能减少

system("utils/fix_data_dir.sh $out_dir");

# utils/validate_data_dir.sh是干什么的呢?
# 先看看下面:
=pod 注释
这是一个perl的多行注释
echo "Usage: $0 [--no-feats] [--no-text] [--no-wav] [--no-spk-sort] <data-dir>"
echo "The --no-xxx options mean that the script does not require "
echo "xxx.scp to be present, but it will check it if it is present."
echo "--no-spk-sort means that the script does not require the utt2spk to be "
echo "sorted by the speaker-id in addition to being sorted by utterance-id."
echo "By default, utt2spk is expected to be sorted by both, which can be "
echo "achieved by making the speaker-id prefixes of the utterance-ids"
echo "e.g.: $0 data/train"
=cut

# 就是说validate_data_dir.sh,可以有4个布尔型(true or false)的默认参数,no-feats,no-text,no-wav,no-spk-sort,
# 但有一个参数是文件夹地址,<data-dir>,是一定要给的,这个sh文件主要是对该文件夹下面的各种文件进行检查
# 如果你不设置的话,这4个参数默认都是false,也就是不检查这几个文件,不管它是否存在
# 如果你设置谁为true,就意味着有这么一个文件,那它就会检查一下

# spk-sort,是说,对文件utt2spk,除了按照utterance-id排序之外,还要不要按照speaker-id进行排序
# 默认情况下,文件utt2spk,是要按照这两个规则排序的,把speaker-id变成utterance-id的前缀就可以了

# validate_data_dir.sh,还检查了utt2spk这个文件是否有正确的format,应该有且仅有两列
# 还检查了spk2utt这个文件的行数,如果只有一行,意味着只有一个说话人,就会报错
# 还会检查utt2spk,spk2utt文件中的每行是否有序,是否重复,是否有无效的行,某一行的数据是否有缺失
# 检查两文件utt2spk,spk2utt的行数是否相等,是否match

# 如果设置no_text=true,还会检查这个text文件是否存在,会执行validate_text.pl,会检查text文件是否有序,重复,会检查text 是否含有 illegal symbol
# 会比较utterance lists extracted from utt2spk and text是否长度不一样

# 如果参数no_wav设置为true,但是却没有这个文件,也会报错
# 如果wav.scp存在,会检查有没有对应的segments,会检查wav.scp文件是否有序,重复
# 会检查:Please do not use tilde (~) in your wav.scp
# 如果segments存在,会检查该文件是否有序,重复,会检查它是否是4列,每列数据formant是否正确,否则会报错:Bad line in segments file或者badly formatted segments file
# 会比较segments_len和utt2spk中的num_utts是否一致
# 会从segments中抽取recording-ids与wav.scp比较,是否一致

# 如果reco2file_and_channel,这个文件存在的话,也会对它进行各种与上面类似检查

# 如果no_feats设置为true,代表有这个文件,也会对文件是否存在进行检查,并对文件本身的内容进行各种与上面类似的检查,
# 如check_sorted_and_uniq,比较utterance-ids extracted from utt2spk and features

# 如果下面文件存在的话:cmvn.scp,spk2gender,spk2warp,utt2warp,vad.scp ,utt2lang ,utt2uniq,utt2dur,reco2dur,
# 也会对文件本身的内容进行各种与上面类似的检查,不存在当然不用检查啦

# 最后成功的标志是出现:Successfully validated data-directory

# system后面括号中的字符串是一个命令,如果返回值非0,则表示在执行该命令的过程中出错,则显示die后面的字符串
# system()会调用fork()产生子进程,由子进程来执行参数string字符串所代表的命令。此命令执行完后随即返回原调用的进程。

if (system("utils/validate_data_dir.sh --no-text --no-feats $out_dir") != 0) {
  die "Error validating directory $out_dir";
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值