Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions src/chain/phone-topology.cc
Original file line number Diff line number Diff line change
@@ -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<StdArc>& 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<StdArc> 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, "<PhoneTopology>");
if (!binary) os << "\n";
int num_phones = fsts_.size() - 1;
WriteToken(os, binary, "<NumPhones>");
WriteBasicType(os, binary, num_phones);
if (!binary) os << "\n";
std::vector<fst::VectorFst<StdArc> >::iterator fiter = fsts_.begin(),
fend = fsts_.end();
for (++fiter; fiter != fend; ++fiter)
WriteFstKaldi(os, binary, *fiter);
WriteToken(os, binary, "</PhoneTopology>");
}

void PhoneTopology::Read(std::istream &is, bool binary) const{
ExpectToken(is, binary, "<PhoneTopology>");
int num_phones;
ExpectToken(is, binary, "<NumPhones>");
ReadBasicType(is, binary, &num_phones);
fsts_.resize(num_phones + 1);
std::vector<fst::VectorFst<StdArc> >::iterator fiter = fsts_.begin(),
fend = fsts_.end();
for (++fiter; fiter != fend; ++fiter)
ReadFstKaldi(os, binary, fiter);
ExpectToken(is, binary, "</PhoneTopology>");
}

bool PhonoTopology::IsAlignable() {
std::vector<fst::VectorFst<StdArc> >::iterator fiter = fsts_.begin(),
fend = fsts_.end();
for (++fiter; fiter != fend; ++fiter) {
// Get start state symbles
unordered_set<int> syms;
for (ArcIterator<Fst<Arc> >aiter(*fiter, fiter->Start()); !aiter.Done(); aiter.Next()) {
const Arc &arc = aiter.Value();
syms.insert(arc.ilabel);
}
for (StateIterator<StdFst> siter(*fiter); !siter.Done(); siter.Next()) {
typename Arc::StateId s = siter.Value();
for (ArcIterator<Fst<Arc> >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
4 changes: 2 additions & 2 deletions src/chain/phone-topology.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down