|
本帖最后由 shaoheshaohe 于 2019-1-17 10:07 编辑
这个脚本的输入参数有三个:1.data/mfcc/train 2.exp/make_mfcc/train 3.mfcc/train
1.data/mfcc/train中有数据预处理后的一些文件:phone.txt spk2utt text utt2spk wav.scp word.txt
2.exp/make_mfcc/train中应该是要保存程序运行的日志文件的
3.mfcc/train中是提取出的特征文件
1是输入目录,2,3是输出目录
#!/bin/bash
# Copyright 2012-2016 Johns Hopkins University (Author: Daniel Povey)
# Apache 2.0
# To be run from .. (one directory up from here)
# see ../run.sh for example
# Begin configuration section.
nj=4
cmd=run.pl
mfcc_config=conf/mfcc.conf
compress=true
write_utt2num_frames=false # if true writes utt2num_frames
# End configuration section.
# 打印这个脚本的名称以及所有的参数
echo "$0 $@" # Print the command line for logging
# 加载path.sh和parse_options.sh
if [ -f path.sh ]; then . ./path.sh; fi
. parse_options.sh || exit 1;
# 如果参数少于1或者大于3就提示使用脚本错误
if [ $# -lt 1 ] || [ $# -gt 3 ]; then
echo "Usage: $0 [options] <data-dir> [<log-dir> [<mfcc-dir>] ]";
echo "e.g.: $0 data/train exp/make_mfcc/train mfcc"
echo "Note: <log-dir> defaults to <data-dir>/log, and <mfccdir> defaults to <data-dir>/data"
echo "Options: "
echo " --mfcc-config <config-file> # config passed to compute-mfcc-feats "
echo " --nj <nj> # number of parallel jobs"
echo " --cmd (utils/run.pl|utils/queue.pl <queue opts>) # how to run jobs."
echo " --write-utt2num-frames <true|false> # If true, write utt2num_frames file."
exit 1;
fi
data=$1 # data=data/mfcc/train
if [ $# -ge 2 ]; then # 如果参数大于等于2
logdir=$2 # logdir=exp/make_mfcc/train
else
logdir=$data/log
fi
if [ $# -ge 3 ]; then # 如果参数大于等于3
mfccdir=$3 #mfccdir=mfcc/train
else
mfccdir=$data/data
fi
# make $mfccdir an absolute pathname.
mfccdir=`perl -e '($dir,$pwd)= @ARGV; if($dir!~m:^/:) { $dir = "$pwd/$dir"; } print $dir; ' $mfccdir ${PWD}`
# use "name" as part of name of the archive.
name=`basename $data` # data/mfcc/train输出train
# 创建mfcc特征文件夹和log文件夹
mkdir -p $mfccdir || exit 1;
mkdir -p $logdir || exit 1;
# 如果之前有执行过生成了特征信息文件则备份
if [ -f $data/feats.scp ]; then
mkdir -p $data/.backup
echo "$0: moving $data/feats.scp to $data/.backup"
mv $data/feats.scp $data/.backup
fi
scp=$data/wav.scp # 得到音频路径列表
required="$scp $mfcc_config"
for f in $required; do # 检测wav.scp和mfcc_config.sh文件是否存在
if [ ! -f $f ]; then
echo "make_mfcc.sh: no such file $f"
exit 1;
fi
done
# 使用validate_data_dir.sh 检测$data里的内容是否正确
utils/validate_data_dir.sh --no-text --no-feats $data || exit 1;
if [ -f $data/spk2warp ]; then
echo "$0 [info]: using VTLN warp factors from $data/spk2warp"
vtln_opts="--vtln-map=ark:$data/spk2warp --utt2spk=ark:$data/utt2spk"
elif [ -f $data/utt2warp ]; then
echo "$0 [info]: using VTLN warp factors from $data/utt2warp"
vtln_opts="--vtln-map=ark:$data/utt2warp"
fi
for n in $(seq $nj); do # 几个线程就分几个文件 .ark中存放音频mfcc特征
# the next command does nothing unless $mfccdir/storage/ exists, see
# utils/create_data_link.pl for more info.
utils/create_data_link.pl $mfccdir/raw_mfcc_$name.$n.ark
done
if $write_utt2num_frames; then
write_num_frames_opt="--write-num-frames=ark,t:$logdir/utt2num_frames.JOB"
else
write_num_frames_opt=
fi
if [ -f $data/segments ]; then # 如果存在segments文件则使用已有文件
echo "$0 [info]: segments file exists: using that."
split_segments=""
for n in $(seq $nj); do
split_segments="$split_segments $logdir/segments.$n"
done
utils/split_scp.pl $data/segments $split_segments || exit 1;
rm $logdir/.error 2>/dev/null
$cmd JOB=1:$nj $logdir/make_mfcc_${name}.JOB.log \
extract-segments scp,p:$scp $logdir/segments.JOB ark:- \| \
compute-mfcc-feats $vtln_opts --verbose=2 --config=$mfcc_config ark:- ark:- \| \
copy-feats --compress=$compress $write_num_frames_opt ark:- \
ark,scp:$mfccdir/raw_mfcc_$name.JOB.ark,$mfccdir/raw_mfcc_$name.JOB.scp \
|| exit 1;
else # 我使用的时候执行此分支
echo "$0: [info]: no segments file exists: assuming wav.scp indexed by utterance."
split_scps=""
for n in $(seq $nj); do
split_scps="$split_scps $logdir/wav_${name}.$n.scp"
# 后面是 exp/make_mfcc/train/wav_train.1.scp
done
utils/split_scp.pl $scp $split_scps || exit 1; # 使用脚本处理 scp=$data/wav.scp
# add ,p to the input rspecifier so that we can just skip over
# utterances that have bad wave data.
# 这里用run.pl提取特征开始
$cmd JOB=1:$nj $logdir/make_mfcc_${name}.JOB.log \
compute-mfcc-feats $vtln_opts --verbose=2 --config=$mfcc_config \
scp,p:$logdir/wav_${name}.JOB.scp ark:- \| \
copy-feats $write_num_frames_opt --compress=$compress ark:- \
ark,scp:$mfccdir/raw_mfcc_$name.JOB.ark,$mfccdir/raw_mfcc_$name.JOB.scp \
|| exit 1;
fi
#最后生成的应该就是mfcc/train 中的raw_mfcc_train.1.ark raw_mfcc_train.1.scp
if [ -f $logdir/.error.$name ]; then # 如果出现了错误则打印出log中最后的错误信息
echo "Error producing mfcc features for $name:"
tail $logdir/make_mfcc_${name}.1.log
exit 1;
fi
# concatenate the .scp files together.
for n in $(seq $nj); do
cat $mfccdir/raw_mfcc_$name.$n.scp || exit 1;
done > $data/feats.scp || exit 1 # 将所有的scp文件拼接起来输出到data/mfcc/train/feats.scp
if $write_utt2num_frames; then
for n in $(seq $nj); do
cat $logdir/utt2num_frames.$n || exit 1;
done > $data/utt2num_frames || exit 1
rm $logdir/utt2num_frames.*
fi
# 删除过程文件
rm $logdir/wav_${name}.*.scp $logdir/segments.* 2>/dev/null
nf=`cat $data/feats.scp | wc -l` # 输出文件的行数
nu=`cat $data/utt2spk | wc -l`
if [ $nf -ne $nu ]; then # 检测特征的数目与音频文件的数目是否相同
echo "It seems not all of the feature files were successfully processed ($nf != $nu);"
echo "consider using utils/fix_data_dir.sh $data"
fi
if [ $nf -lt $[$nu - ($nu/20)] ]; then
echo "Less than 95% the features were successfully generated. Probably a serious error."
exit 1;
fi
echo "Succeeded creating MFCC features for $name"
---------------------
作者:哪得小师弟
来源:CSDN
原文:https://blog.csdn.net/x603560617/article/details/83116484
版权声明:本文为博主原创文章,转载请附上博文链接!
|
|