the script 'forced_alignment_novo.py' which is to run novo_api on Python 3.6 environment is added.

This commit is contained in:
yemaozi88
2018-12-26 23:49:28 +01:00
parent 0777735979
commit b87a81eb9d
30 changed files with 1258 additions and 32 deletions

View File

@ -0,0 +1,4 @@
#!/usr/bin/env python
from .segments import Segmentation
from .praat import seg2tg

View File

@ -0,0 +1,77 @@
#!/usr/bin/env python
# (c) 2015--2018 NovoLanguage, author: David A. van Leeuwen
import codecs
def print_header(output, begin, end, nr_tiers):
print >> output, 'File type = "ooTextFile"'
print >> output, 'Object class = "TextGrid"'
print >> output, ''
print >> output, 'xmin = %s' % begin
print >> output, 'xmax = %s' % end
print >> output, 'tiers? <exists>'
print >> output, 'size = %d' % nr_tiers
print >> output, 'item []:'
def print_info_tier(output, title, begin, end, label):
print >> output, '\titem [%d]:' % 0
print >> output, '\t\tclass = "IntervalTier"'
print >> output, '\t\tname = "%s"' % title
print >> output, '\t\txmin = %s' % begin
print >> output, '\t\txmax = %s' % end
print >> output, '\t\tintervals: size = %d' % 1
print >> output, '\t\tintervals [1]:'
print >> output, '\t\t\txmin = %s' % begin
print >> output, '\t\t\txmax = %s' % end
print >> output, '\t\t\ttext = "%s"' % label
#def print_tier(output, title, begin, end, segs, (format, formatter)):
def print_tier(output, title, begin, end, segs, format, formatter):
print >> output, '\titem [%d]:' % 0
print >> output, '\t\tclass = "IntervalTier"'
print >> output, '\t\tname = "%s"' % title
print >> output, '\t\txmin = %s' % begin
print >> output, '\t\txmax = %s' % end
print >> output, '\t\tintervals: size = %d' % len(segs)
count = 1
for seg in segs:
#print seg
print >> output, '\t\tintervals [%d]:' % count
print >> output, '\t\t\txmin = %s' % repr(int(seg['begin']) / 100.0)
print >> output, '\t\t\txmax = %s' % repr(int(seg['end']) / 100.0)
string = '\t\t\ttext = "' + format + '"'
print >> output, string % formatter(seg['label'])
count += 1
def seg2tg(fname, segments):
if not segments:
return
output = codecs.open(fname, "w", encoding="utf-8")
confidences = []
word_labels = []
phones = []
for s in segments:
conf = s.llh if hasattr(s, "llh") else s.score
confidences.append({'begin': s.begin, 'end': s.end, 'label': conf})
word_labels.append({'begin': s.begin, 'end': s.end, 'label': s.label})
for p in s.phones:
phones.append({'begin': p.begin, 'end': p.end, 'label': p.label})
begin = repr(int(segments[0].begin) / 100.0)
end = repr(int(segments[-1].end) / 100.0)
nr_tiers = 3
print_header(output, begin, end, nr_tiers)
print_tier(output, "confidence", begin, end, confidences, ('%.3f', lambda x: x))
print_tier(output, "words", begin, end, word_labels, ('%s', lambda x: x))
print_tier(output, "phones", begin, end, phones, ('%s', lambda x: x))
output.close()

View File

@ -0,0 +1,99 @@
#!/usr/bin/env python
# (c) 2015--2018 NovoLanguage, author: David A. van Leeuwen
## These classes can be initialized with dictionaries, as they are returned by the python spraaklab recognition system.
class Segment(object):
def __init__(self, segment):
self.begin = segment["begin"]
self.end = segment["end"]
self.begintime = segment.get("beginTime", self.begin / 100.0)
self.endtime = segment.get("endTime", self.end / 100.0)
self.label = segment["label"]
self.score = segment["score"]
if "llh" in segment:
self.llh = segment["llh"]
if "phones" in segment:
self.type = "word"
self.phones = Segmentation(segment["phones"], ["sil"])
if hasattr(self.phones[0], "llh"):
self.minllh = min([s.llh for s in self.phones]) ## the current word llh for error detection
else:
self.type = "phone"
def __repr__(self):
res = "%8.3f -- %8.3f score %8.3f " % (self.begintime, self.endtime, self.score)
if hasattr(self, "llh"):
res += "llh %8.3f " % self.llh
res += self.label.encode("utf8")
return res
def export(self):
r = {"begin": self.begin, "end": self.end, "label": self.label, "score": self.score, "type": self.type}
if hasattr(self, "llh"):
r["llh"] = self.llh
if hasattr(self, "phones"):
r["phones"] = self.phones.export()
return r
class Segmentation(object):
def __init__(self, segments, sils=["<s>", "</s>", "!sil"]):
"""Create a segmentation from a spraaklab recognition structure.
segments: an array of words (or phones), represented by a dict with
"begin", "end", "label", "score", and "llh" keys. Words can also have
"phones" which is another array of segments."""
self.segments = [Segment(s) for s in segments]
if self.segments:
self.type = self.segments[0].type
else:
self.type = None
self.sils = sils
self.orig = segments ## in case we want to have access to the original recognition structure
def __getitem__(self, item):
return self.segments[item]
def __repr__(self):
ns = len(self.segments)
res = "Segmentation with %d %s%s" % (ns, self.type, "" if ns==1 else "s")
for seg in self.segments:
res += "\n " + repr(seg)
return res
def __len__(self):
return len(self.segments)
def score(self, skip=None):
if not skip:
skip = self.sils
s = 0.0
for seg in self.segments:
if seg.label not in skip:
s += seg.score
return s
def llhs(self, skip=None):
if not skip:
skip = self.sils
return [seg.llh for seg in self.segments if hasattr(seg, "llh") and seg.label not in skip]
def llh(self, skip=None):
return sum(self.llhs(skip))
def minllh(self, skip=None):
llhs = self.llhs(skip)
if llhs:
return min(llhs)
else:
return None
def labels(self, skip=None):
if not skip:
skip = self.sils
return [seg.label for seg in self.segments if seg.label not in skip]
def sentence(self, skip=None):
return " ".join(self.labels(skip))
def export(self):
return [seg.export() for seg in self.segments]