44// 2013-2014 Johns Hopkins University (Author: Daniel Povey)
55// 2014 Guoguo Chen
66// 2014 IMSL, PKU-HKUST (author: Wei Shi)
7+ // 2018 Zhehuai Chen
78
89// See ../../COPYING for clarification regarding multiple authors
910//
@@ -68,7 +69,7 @@ void LatticeFasterOnlineDecoder::InitDecoding() {
6869 active_toks_[0 ].toks = start_tok;
6970 toks_.Insert (start_state, start_tok);
7071 num_toks_++;
71- ProcessNonemitting (config_.beam );
72+ ProcessNonemittingWrapper (config_.beam );
7273}
7374
7475// Returns true if any kind of traceback is available (not necessarily from
@@ -84,8 +85,8 @@ bool LatticeFasterOnlineDecoder::Decode(DecodableInterface *decodable) {
8485 while (!decodable->IsLastFrame (NumFramesDecoded () - 1 )) {
8586 if (NumFramesDecoded () % config_.prune_interval == 0 )
8687 PruneActiveTokens (config_.lattice_beam * config_.prune_scale );
87- BaseFloat cost_cutoff = ProcessEmitting (decodable); // Note: the value returned by
88- ProcessNonemitting (cost_cutoff);
88+ BaseFloat cost_cutoff = ProcessEmittingWrapper (decodable); // Note: the value returned by
89+ ProcessNonemittingWrapper (cost_cutoff);
8990 }
9091 FinalizeDecoding ();
9192
@@ -763,8 +764,8 @@ void LatticeFasterOnlineDecoder::AdvanceDecoding(DecodableInterface *decodable,
763764 PruneActiveTokens (config_.lattice_beam * config_.prune_scale );
764765 }
765766 // note: ProcessEmitting() increments NumFramesDecoded().
766- BaseFloat cost_cutoff = ProcessEmitting (decodable);
767- ProcessNonemitting (cost_cutoff);
767+ BaseFloat cost_cutoff = ProcessEmittingWrapper (decodable);
768+ ProcessNonemittingWrapper (cost_cutoff);
768769 }
769770}
770771
@@ -861,6 +862,7 @@ BaseFloat LatticeFasterOnlineDecoder::GetCutoff(Elem *list_head, size_t *tok_cou
861862}
862863
863864
865+ template <typename FstType>
864866BaseFloat LatticeFasterOnlineDecoder::ProcessEmitting (
865867 DecodableInterface *decodable) {
866868 KALDI_ASSERT (active_toks_.size () > 0 );
@@ -883,6 +885,7 @@ BaseFloat LatticeFasterOnlineDecoder::ProcessEmitting(
883885
884886 BaseFloat cost_offset = 0.0 ; // Used to keep probabilities in a good
885887 // dynamic range.
888+ const FstType &fst = dynamic_cast <const FstType&>(fst_);
886889
887890 // First process the best token to get a hopefully
888891 // reasonably tight bound on the next cutoff. The only
@@ -891,15 +894,13 @@ BaseFloat LatticeFasterOnlineDecoder::ProcessEmitting(
891894 StateId state = best_elem->key ;
892895 Token *tok = best_elem->val ;
893896 cost_offset = - tok->tot_cost ;
894- for (fst::ArcIterator<fst::Fst<Arc> > aiter (fst_ , state);
897+ for (fst::ArcIterator<FstType> aiter (fst , state);
895898 !aiter.Done ();
896899 aiter.Next ()) {
897- Arc arc = aiter.Value ();
900+ const Arc & arc = aiter.Value ();
898901 if (arc.ilabel != 0 ) { // propagate..
899- arc.weight = Times (arc.weight ,
900- Weight (cost_offset -
901- decodable->LogLikelihood (frame, arc.ilabel )));
902- BaseFloat new_weight = arc.weight .Value () + tok->tot_cost ;
902+ BaseFloat new_weight = arc.weight .Value () + cost_offset -
903+ decodable->LogLikelihood (frame, arc.ilabel ) + tok->tot_cost ;
903904 if (new_weight + adaptive_beam < next_cutoff)
904905 next_cutoff = new_weight + adaptive_beam;
905906 }
@@ -919,8 +920,8 @@ BaseFloat LatticeFasterOnlineDecoder::ProcessEmitting(
919920 // loop this way because we delete "e" as we go.
920921 StateId state = e->key ;
921922 Token *tok = e->val ;
922- if (tok->tot_cost <= cur_cutoff) {
923- for (fst::ArcIterator<fst::Fst<Arc> > aiter (fst_ , state);
923+ if (tok->tot_cost <= cur_cutoff) {
924+ for (fst::ArcIterator<FstType> aiter (fst , state);
924925 !aiter.Done ();
925926 aiter.Next ()) {
926927 const Arc &arc = aiter.Value ();
@@ -951,12 +952,35 @@ BaseFloat LatticeFasterOnlineDecoder::ProcessEmitting(
951952 return next_cutoff;
952953}
953954
955+ template BaseFloat LatticeFasterOnlineDecoder::
956+ ProcessEmitting<fst::ConstFst<fst::StdArc>>(DecodableInterface *decodable);
957+ template BaseFloat LatticeFasterOnlineDecoder::
958+ ProcessEmitting<fst::VectorFst<fst::StdArc>>(DecodableInterface *decodable);
959+ template BaseFloat LatticeFasterOnlineDecoder::
960+ ProcessEmitting<fst::Fst<fst::StdArc>>(DecodableInterface *decodable);
961+
962+ BaseFloat LatticeFasterOnlineDecoder::ProcessEmittingWrapper (
963+ DecodableInterface *decodable) {
964+ if (fst_.Type () == " const" ) {
965+ return LatticeFasterOnlineDecoder::
966+ ProcessEmitting<fst::ConstFst<Arc>>(decodable);
967+ } else if (fst_.Type () == " vector" ) {
968+ return LatticeFasterOnlineDecoder::
969+ ProcessEmitting<fst::VectorFst<Arc>>(decodable);
970+ } else {
971+ return LatticeFasterOnlineDecoder::
972+ ProcessEmitting<fst::Fst<Arc>>(decodable);
973+ }
974+ }
975+
976+ template <typename FstType>
954977void LatticeFasterOnlineDecoder::ProcessNonemitting (BaseFloat cutoff) {
955978 KALDI_ASSERT (!active_toks_.empty ());
956979 int32 frame = static_cast <int32>(active_toks_.size ()) - 2 ;
957980 // Note: "frame" is the time-index we just processed, or -1 if
958981 // we are processing the nonemitting transitions before the
959982 // first frame (called from InitDecoding()).
983+ const FstType &fst = dynamic_cast <const FstType&>(fst_);
960984
961985 // Processes nonemitting arcs for one frame. Propagates within toks_.
962986 // Note-- this queue structure is is not very optimal as
@@ -988,7 +1012,7 @@ void LatticeFasterOnlineDecoder::ProcessNonemitting(BaseFloat cutoff) {
9881012 // but since most states are emitting it's not a huge issue.
9891013 tok->DeleteForwardLinks (); // necessary when re-visiting
9901014 tok->links = NULL ;
991- for (fst::ArcIterator<fst::Fst<Arc> > aiter (fst_ , state);
1015+ for (fst::ArcIterator<FstType> aiter (fst , state);
9921016 !aiter.Done ();
9931017 aiter.Next ()) {
9941018 const Arc &arc = aiter.Value ();
@@ -1013,6 +1037,26 @@ void LatticeFasterOnlineDecoder::ProcessNonemitting(BaseFloat cutoff) {
10131037 } // while queue not empty
10141038}
10151039
1040+ template void LatticeFasterOnlineDecoder::
1041+ ProcessNonemitting<fst::ConstFst<fst::StdArc>>(BaseFloat cutoff);
1042+ template void LatticeFasterOnlineDecoder::
1043+ ProcessNonemitting<fst::VectorFst<fst::StdArc>>(BaseFloat cutoff);
1044+ template void LatticeFasterOnlineDecoder::
1045+ ProcessNonemitting<fst::Fst<fst::StdArc>>(BaseFloat cutoff);
1046+
1047+ void LatticeFasterOnlineDecoder::ProcessNonemittingWrapper (
1048+ BaseFloat cost_cutoff) {
1049+ if (fst_.Type () == " const" ) {
1050+ return LatticeFasterOnlineDecoder::
1051+ ProcessNonemitting<fst::ConstFst<Arc>>(cost_cutoff);
1052+ } else if (fst_.Type () == " vector" ) {
1053+ return LatticeFasterOnlineDecoder::
1054+ ProcessNonemitting<fst::VectorFst<Arc>>(cost_cutoff);
1055+ } else {
1056+ return LatticeFasterOnlineDecoder::
1057+ ProcessNonemitting<fst::ConstFst<Arc>>(cost_cutoff);
1058+ }
1059+ }
10161060
10171061void LatticeFasterOnlineDecoder::DeleteElems (Elem *list) {
10181062 for (Elem *e = list, *e_tail; e != NULL ; e = e_tail) {
0 commit comments