diff --git a/src/chain/phone-topology.cc b/src/chain/phone-topology.cc new file mode 100644 index 00000000000..e0a3fb639b7 --- /dev/null +++ b/src/chain/phone-topology.cc @@ -0,0 +1,98 @@ +// chain/phone-topology.cc + +// Copyright 2015 Johns Hopkins University (author: Daniel Povey) +// 2015 Xingyu Na + +// See ../../COPYING for clarification regarding multiple authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED +// WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, +// MERCHANTABLITY OR NON-INFRINGEMENT. +// See the Apache 2 License for the specific language governing permissions and +// limitations under the License. + +#include "chain/phone-topology.h" + +namespace kaldi { +namespace chain { + + +const fst::VectorFst& PhoneTopolgy::TopologyForPhone (int32 phone) { + return fsts_[phone]; +} + +PhoneTopology::PhoneTopology (int32 num_phones) { + fsts_.clear(); + fsts_.resize(num_phones + 1); + for (int32 i = 1; i <= num_phones; i++) { + fst::VectorFst fst; + fst.AddState(); // state 0 + fst.SetStart(0); // set start state + fst.AddState(); // state 1 + fst.AddArc(0, StdArc(1, 1, 0.5, 1)); + fst.AddArc(1, StdArc(2, 2, 0.5, 1)); + fst.SetFinal(1); // set final state + fsts_[i] = fst; + } +} + +void PhoneTopology::Write(std::ostream &os, bool binary) const{ + WriteToken(os, binary, ""); + if (!binary) os << "\n"; + int num_phones = fsts_.size() - 1; + WriteToken(os, binary, ""); + WriteBasicType(os, binary, num_phones); + if (!binary) os << "\n"; + std::vector >::iterator fiter = fsts_.begin(), + fend = fsts_.end(); + for (++fiter; fiter != fend; ++fiter) + WriteFstKaldi(os, binary, *fiter); + WriteToken(os, binary, ""); +} + +void PhoneTopology::Read(std::istream &is, bool binary) const{ + ExpectToken(is, binary, ""); + int num_phones; + ExpectToken(is, binary, ""); + ReadBasicType(is, binary, &num_phones); + fsts_.resize(num_phones + 1); + std::vector >::iterator fiter = fsts_.begin(), + fend = fsts_.end(); + for (++fiter; fiter != fend; ++fiter) + ReadFstKaldi(os, binary, fiter); + ExpectToken(is, binary, ""); +} + +bool PhonoTopology::IsAlignable() { + std::vector >::iterator fiter = fsts_.begin(), + fend = fsts_.end(); + for (++fiter; fiter != fend; ++fiter) { + // Get start state symbles + unordered_set syms; + for (ArcIterator >aiter(*fiter, fiter->Start()); !aiter.Done(); aiter.Next()) { + const Arc &arc = aiter.Value(); + syms.insert(arc.ilabel); + } + for (StateIterator siter(*fiter); !siter.Done(); siter.Next()) { + typename Arc::StateId s = siter.Value(); + for (ArcIterator >aiter(*fiter, s); !aiter.Done(); aiter.Next()) { + const Arc &arc = aiter.Value(); + if (arc.nextstate == fiter->Start()) + return false; + if (s != fiter->Start() && syms.find(arc.ilabel) != syms.end()) + return false; + } + } + } + return true; +} + +} // namespace chain +} // namespace kaldi diff --git a/src/chain/phone-topology.h b/src/chain/phone-topology.h index 2eaec7d124a..cec7e28686d 100644 --- a/src/chain/phone-topology.h +++ b/src/chain/phone-topology.h @@ -78,14 +78,14 @@ class PhoneTopology { void Write(std::ostream &os, bool binary) const; - void Read(std::istream &is) const; + void Read(std::istream &is, bool binary) const; // returns true if all the phones' FSTs have the following properties: // - the symbols on arcs out of the start-state are disjoint from the // symbols on arcs out of other states. // - there are no arcs ending in the start state. bool IsAlignable(); - private: + private: void Check(); // index zero is not used.