@@ -27,13 +27,15 @@ int main(int argc, char *argv[]) {
2727
2828 const char *usage =
2929 " Compute cepstral mean and variance normalization statistics\n "
30- " Per-utterance by default, or per-speaker if spk2utt option provided\n "
31- " Usage: compute-cmvn-stats [options] feats-rspecifier stats-wspecifier\n " ;
32-
30+ " If wspecifier provided: per-utterance by default, or per-speaker if\n "
31+ " spk2utt option provided; if wxfilename: global\n "
32+ " Usage: compute-cmvn-stats [options] feats-rspecifier (stats-wspecifier|stats-wxfilename)\n " ;
33+
3334 ParseOptions po (usage);
3435 std::string spk2utt_rspecifier;
36+ bool binary = false ;
3537 po.Register (" spk2utt" , &spk2utt_rspecifier, " rspecifier for speaker to utterance-list map" );
36-
38+ po. Register ( " binary " , &binary, " write in binary mode (applies only to global CMN/CVN) " );
3739 po.Read (argc, argv);
3840
3941 if (po.NumArgs () != 2 ) {
@@ -42,45 +44,66 @@ int main(int argc, char *argv[]) {
4244 }
4345
4446 std::string rspecifier = po.GetArg (1 );
45- std::string wspecifier = po.GetArg (2 );
47+ std::string wspecifier_or_wxfilename = po.GetArg (2 );
48+
49+ if (ClassifyWspecifier (wspecifier_or_wxfilename, NULL , NULL , NULL )
50+ != kNoWspecifier ) { // writing to a Table: per-speaker or per-utt CMN/CVN.
51+ std::string wspecifier = wspecifier_or_wxfilename;
4652
47- DoubleMatrixWriter writer (wspecifier);
53+ DoubleMatrixWriter writer (wspecifier);
4854
49- if (spk2utt_rspecifier != " " ) {
50- SequentialTokenVectorReader spk2utt_reader (spk2utt_rspecifier);
51- RandomAccessBaseFloatMatrixReader feat_reader (rspecifier);
52- for (; !spk2utt_reader.Done (); spk2utt_reader.Next ()) {
53- std::string spk = spk2utt_reader.Key ();
54- const std::vector<std::string> &uttlist = spk2utt_reader.Value ();
55- bool is_init = false ;
56- Matrix<double > stats;
57- for (size_t i = 0 ; i < uttlist.size (); i++) {
58- std::string utt = uttlist[i];
59- if (!feat_reader.HasKey (utt))
60- KALDI_WARN << " Did not find features for utterance " << utt;
61- else {
62- const Matrix<BaseFloat> &feats = feat_reader.Value (utt);
63- if (!is_init) {
64- InitCmvnStats (feats.NumCols (), &stats);
65- is_init = true ;
55+ if (spk2utt_rspecifier != " " ) {
56+ SequentialTokenVectorReader spk2utt_reader (spk2utt_rspecifier);
57+ RandomAccessBaseFloatMatrixReader feat_reader (rspecifier);
58+ for (; !spk2utt_reader.Done (); spk2utt_reader.Next ()) {
59+ std::string spk = spk2utt_reader.Key ();
60+ const std::vector<std::string> &uttlist = spk2utt_reader.Value ();
61+ bool is_init = false ;
62+ Matrix<double > stats;
63+ for (size_t i = 0 ; i < uttlist.size (); i++) {
64+ std::string utt = uttlist[i];
65+ if (!feat_reader.HasKey (utt))
66+ KALDI_WARN << " Did not find features for utterance " << utt;
67+ else {
68+ const Matrix<BaseFloat> &feats = feat_reader.Value (utt);
69+ if (!is_init) {
70+ InitCmvnStats (feats.NumCols (), &stats);
71+ is_init = true ;
72+ }
73+ AccCmvnStats (feats, NULL , &stats);
6674 }
67- AccCmvnStats (feats, NULL , &stats);
6875 }
76+ if (stats.NumRows () == 0 )
77+ KALDI_WARN << " No stats accumulated for speaker " << spk;
78+ else
79+ writer.Write (spk, stats);
80+ }
81+ } else { // per-utterance normalization
82+ SequentialBaseFloatMatrixReader feat_reader (rspecifier);
83+ for (; !feat_reader.Done (); feat_reader.Next ()) {
84+ Matrix<double > stats;
85+ const Matrix<BaseFloat> &feats = feat_reader.Value ();
86+ InitCmvnStats (feats.NumCols (), &stats);
87+ AccCmvnStats (feats, NULL , &stats);
88+ writer.Write (feat_reader.Key (), stats);
6989 }
70- if (stats.NumRows () == 0 )
71- KALDI_WARN << " No stats accumulated for speaker " << spk;
72- else
73- writer.Write (spk, stats);
7490 }
75- } else { // per-utterance normalization
91+ } else { // accumulate global stats
92+ std::string wxfilename = wspecifier_or_wxfilename;
93+ bool is_init = false ;
94+ Matrix<double > stats;
7695 SequentialBaseFloatMatrixReader feat_reader (rspecifier);
7796 for (; !feat_reader.Done (); feat_reader.Next ()) {
78- Matrix<double > stats;
7997 const Matrix<BaseFloat> &feats = feat_reader.Value ();
80- InitCmvnStats (feats.NumCols (), &stats);
98+ if (!is_init) {
99+ InitCmvnStats (feats.NumCols (), &stats);
100+ is_init = true ;
101+ }
81102 AccCmvnStats (feats, NULL , &stats);
82- writer.Write (feat_reader.Key (), stats);
83103 }
104+ Matrix<float > fstats (stats);
105+ Output ko (wxfilename, binary);
106+ fstats.Write (ko.Stream (), binary);
84107 }
85108 return 0 ;
86109 } catch (const std::exception& e) {
0 commit comments