def reorg_noncollapsed(f): padding = 0.1 print(f) tg_path = os.path.join(noncollapsed_dir, f) tg = TextGrid() tg.read(tg_path) new_tg = TextGrid(maxTime=tg.maxTime) new_tg_path = tg_path.replace(noncollapsed_dir, data_dir) for tier in tg.tiers: new_tier = IntervalTier(name=tier.name, maxTime=tg.maxTime) for i in tier: new_mark = sub_pattern.sub(' ', i.mark).strip() if not new_mark: continue new_begin = i.minTime - padding if new_begin < 0: new_begin = 0 new_end = i.maxTime + padding if new_end > tg.maxTime: new_end = tg.maxTime try: new_tier.add(new_begin, new_end, new_mark) except ValueError: new_tier[-1].maxTime = new_end new_tier[-1].mark += ' ' + new_mark print(len(new_tier)) new_tg.append(new_tier) new_tg.write(new_tg_path)
def guess_textgrid_format(path): """ Given a directory, tries to guess what format the textgrids are in Parameters ---------- path : str the path of the directory containing the textgrids Returns ------- str or None textgrid format or None if file is not textgrid and directory doesn't contain textgrids """ from .inspect import inspect_labbcat, inspect_mfa, inspect_fave if os.path.isdir(path): counts = {'mfa': 0, 'labbcat': 0, 'fave': 0, None: 0} for root, subdirs, files in os.walk(path): for f in files: if not f.lower().endswith('.textgrid'): continue tg_path = os.path.join(root, f) tg = TextGrid() try: tg.read(tg_path) except ValueError as e: raise (TextGridError( 'The file {} could not be parsed: {}'.format( tg_path, str(e)))) labbcat_parser = inspect_labbcat(tg_path) mfa_parser = inspect_mfa(tg_path) fave_parser = inspect_fave(tg_path) if labbcat_parser._is_valid(tg): counts['labbcat'] += 1 elif mfa_parser._is_valid(tg): counts['mfa'] += 1 elif fave_parser._is_valid(tg): counts['fave'] += 1 else: counts[None] += 1 return max(counts.keys(), key=lambda x: counts[x]) elif path.lower().endswith('.textgrid'): tg = TextGrid() tg.read(path) labbcat_parser = inspect_labbcat(path) mfa_parser = inspect_mfa(path) fave_parser = inspect_fave(path) if labbcat_parser._is_valid(tg): return 'labbcat' elif mfa_parser._is_valid(tg): return 'mfa' elif fave_parser._is_valid(tg): return 'fave' return None
def load_grid(story, grid_dir="data/grids"): """Loads the TextGrid for the given [story] from the directory [grid_dir]. The first file that starts with [story] will be loaded, so if there are multiple versions of a grid for a story, beward. """ gridfile = [os.path.join(grid_dir, gf) for gf in os.listdir(grid_dir) if gf.startswith(story)][0] return TextGrid(open(gridfile).read())
def load_5tier_grids_for_stories(stories, rootdir): grids = dict() for story in stories: storydir = os.path.join(rootdir, [sd for sd in os.listdir(rootdir) if sd.startswith(story)][0]) storyfile = os.path.join(storydir, [sf for sf in os.listdir(storydir) if sf.endswith("TextGrid")][0]) grids[story] = TextGrid(open(storyfile).read()) return grids
def check_integrity(f): """Check for the integrity""" gridobj = TextGrid(get_grid(f)) # Check if tiers are OK print "\tChecking proper tier names..." assert gridobj.tiers[0].nameid == 'diph' assert gridobj.tiers[1].nameid == 'point' assert gridobj.tiers[2].nameid == 'word' # Check number of words and diphthings print "\tChecking if the tiers contain 32 nonempty items..." diph, word = get_nonempty(gridobj.tiers[0]), get_nonempty(gridobj.tiers[2]) assert len(word) == 32 assert len(diph) == 32 print "\tChecking that the number of empty and nonempty tiers is the same..." assert len(gridobj.tiers[0].simple_transcript) == len( gridobj.tiers[2].simple_transcript) print "\tChecking if all tiers have valid text..." all_there(diph, 'diph') all_there(word, 'word') print "\tChecking if the diphthongs have pairs..." unique(diph) print "\tChecking if all words are present..." checkwords(word) print "\tChecking if the words and diphthongs match..." all_matches(diph, word) print "\tChecking if the number of intervals is 64..." intervals = gridobj.tiers[1].simple_transcript assert len(intervals) == 64 print "\tChecking if intervals match diphthongs..." check_intervals_match(diph, intervals)
def update_utterance_text(self, utterance, new_text): new_text = new_text.lower().strip() self.text_mapping[utterance] = new_text text_file_path = self.utt_text_file_mapping[utterance] if text_file_path.lower().endswith('.textgrid'): tg = TextGrid() found = False tg.read(text_file_path) print(utterance) speaker_name = utterance.split('_', maxsplit=1) wave_name, begin, end = self.segments[utterance].split(' ') begin = float(begin) end = float(end) if len(tg.tiers) == 1: for interval in tg.tiers[0]: if abs(interval.minTime - begin) < 0.01 and abs(interval.maxTime - end) < 0.01: interval.mark = new_text found = True break else: for tier in tg.tiers: if tier.name == speaker_name: for interval in tg.tiers[0]: if abs(interval.minTime - begin) < 0.01 and abs(interval.maxTime - end) < 0.01: interval.mark = new_text found = True break if found: tg.write(text_file_path) else: print('Unable to find utterance {} match in {}'.format(utterance, text_file_path)) else: with open(text_file_path, 'w', encoding='utf8') as f: f.write(new_text)
def export_segments(self, output_directory): from decimal import Decimal from textgrid import TextGrid, IntervalTier file_dict = {} for utt, segment in self.corpus.vad_segments.items(): filename, utt_begin, utt_end = segment utt_begin = Decimal(utt_begin) utt_end = Decimal(utt_end) if filename not in file_dict: file_dict[filename] = {} speaker = 'segments' text = 'speech' if speaker not in file_dict[filename]: file_dict[filename][speaker] = [] file_dict[filename][speaker].append([utt_begin, utt_end, text]) for filename, speaker_dict in file_dict.items(): try: speaker_directory = os.path.join( output_directory, self.corpus.file_directory_mapping[filename]) except KeyError: speaker_directory = output_directory os.makedirs(speaker_directory, exist_ok=True) max_time = self.corpus.get_wav_duration(filename) tg = TextGrid(maxTime=max_time) for speaker in sorted(speaker_dict.keys()): words = speaker_dict[speaker] tier = IntervalTier(name=speaker, maxTime=max_time) for w in words: if w[1] > max_time: w[1] = max_time tier.add(*w) tg.append(tier) tg.write(os.path.join(speaker_directory, filename + '.TextGrid'))
def ctm_to_textgrid(phone_ctm, out_directory, utt2dur, frameshift=0.01): textgrid_write_errors = {} frameshift = Decimal(str(frameshift)) if not os.path.exists(out_directory): os.makedirs(out_directory) utt2dur_mapping = generate_utt2dur(utt2dur) for i, (k, v) in enumerate(sorted(phone_ctm.items())): maxtime = Decimal(str(utt2dur_mapping[k])) try: tg = TextGrid(maxTime=maxtime) phonetier = IntervalTier(name='phones', maxTime=maxtime) for interval in v: if maxtime - interval[1] < frameshift: interval[1] = maxtime #remove B E I and stress (0,1) information from phoneme interval[2] = re.sub("\d+", "", interval[2].split('_')[0]) phonetier.add(*interval) tg.append(phonetier) outpath = os.path.join(out_directory, k + '.TextGrid') tg.write(outpath) except Exception as e: exc_type, exc_value, exc_traceback = sys.exc_info() textgrid_write_errors[k] = '\n'.join( traceback.format_exception(exc_type, exc_value, exc_traceback)) if textgrid_write_errors: error_log = os.path.join(out_directory, 'output_errors.txt') with io_open(error_log, 'w', encoding='utf-8') as f: f.write( u'The following exceptions were encountered during the ouput of the alignments to TextGrids:\n\n' ) for k, v in textgrid_write_errors.items(): f.write(u'{}:\n'.format(k)) f.write(u'{}\n\n'.format(v))
def convert_ctm_to_textgrid(ctm, textgrid): words = [] phonemes = [] with open(ctm, encoding='utf-8') as f: for l in f: tok = l.strip().split() text = tok[4] beg = float(tok[2]) dur = float(tok[3]) if tok[0][0] == '@': if besi.match(text): text = text[:-2] phonemes.append((text, beg, dur)) else: words.append((text, beg, dur)) tw = IntervalTier(name='words') tp = IntervalTier(name='phonemes') for seg in words: try: tw.add(round(seg[1], 2), round(seg[1] + seg[2], 2), seg[0]) except ValueError: print("Error in word seg: " + seg[0]) for seg in phonemes: try: tp.add(round(seg[1], 2), round(seg[1] + seg[2], 2), seg[0]) except ValueError: print("Error in phoneme seg: " + seg[0]) tg = TextGrid() tg.append(tw) tg.append(tp) tg.write(textgrid)
def load_textgrid(path): tg = TextGrid() try: tg.read(path) except ValueError as e: print('The file {} could not be parsed: {}'.format(path, str(e))) return tg
def from_ref_and_target(cls, ref_tg: BaseTextGridDocument, target_tg: BaseTextGridDocument): """Simply interweaves the ref and target into one tg for annotations merging""" # checking first if both TG have the same amount of tiers, and the same names ref_names = sorted(ref_tg.textgrid.getNames()) target_names = sorted(target_tg.textgrid.getNames()) if len(ref_names) != len(target_names): error_log.log_structural( "The reference and target annotator's textgrids don't have the same amount of Tiers " "(%i for the reference, %i for the target)" % (len(ref_names), len(target_names))) return if ref_names != target_names: # TODO: maybe make this more helpful error_log.log_structural("The names of some of the tiers in the reference and target textgrids don't match") return # TODO : add support for empty tiers deletion assert ref_tg.task == target_tg.task merged_tg = TextGrid(name=ref_tg.textgrid.name, minTime=ref_tg.textgrid.minTime, maxTime=ref_tg.textgrid.maxTime) for tier_name in ref_tg.textgrid.getNames(): ref_tier: IntervalTier = deepcopy(ref_tg.textgrid.getFirst(tier_name)) target_tier: IntervalTier = deepcopy(target_tg.textgrid.getFirst(tier_name)) ref_tier.name = tier_name + "-ref" target_tier.name = tier_name + "-target" merged_tg.append(ref_tier) merged_tg.append(target_tier) new_doc = cls.from_textgrid(merged_tg, ref_tg.creators + target_tg.creators, ref_tg.task) return new_doc
def load_textgrid(self, path): tg = TextGrid(strict=False) try: tg.read(path) new_tiers = [] dup_tiers_maxes = { k: 0 for k, v in Counter([t.name for t in tg.tiers]).items() if v > 1 } dup_tiers_inds = {k: 0 for k in dup_tiers_maxes.keys()} for i, t in enumerate(tg.tiers): if t.name in dup_tiers_maxes: if len(t) > dup_tiers_maxes[t.name]: dup_tiers_maxes[t.name] = len(t) dup_tiers_inds[t.name] = i for i, t in enumerate(tg.tiers): if t.name in dup_tiers_maxes: if i != dup_tiers_inds[t.name]: continue new_tiers.append(t) tg.tiers = new_tiers return tg except Exception as e: print('There was an issue parsing {}:'.format(path)) raise
def test_tier_duplication(): error_log.flush() tg = TextGrid() interval = IntervalTier("A", minTime=0, maxTime=10) tg.tiers = [interval] tg_doc = SingleAnnotatorTextGrid.from_textgrid(tg, [], None) tg_doc.check()
def check_times_merging(self): """Checks that paired tiers can be merged together. Outputs the partially merged textgrid as well as the merge conflicts.""" from .tasks.double import MergeResults merged_times_tg = TextGrid( name=self.textgrid.name, maxTime=self.textgrid.maxTime, minTime=self.textgrid.minTime) merge_results = MergeResults() for tier in self.checking_scheme.all_tiers_names: merged_tier_name = tier + self.TOP_GROUP_SUFFIX target_tier_name = tier + self.BOTTOM_GROUP_SUFFIX merged_tier = self.textgrid.getFirst(merged_tier_name) target_tier = self.textgrid.getFirst(target_tier_name) # in case either tier is not present, we just skip this merge if merged_tier is None or target_tier is None: continue times_merged_tier, tier_merge = self.merge_tiers(merged_tier, target_tier) merge_results.tiers_merges.append(tier_merge) times_merged_tier.name = tier merged_times_tg.append(times_merged_tier) # logging conflicts as errors that could be displayed to the # annotator (in case of merge attempt) for conflict in merge_results.to_merge_conflicts_errors(): error_log.log_merge(conflict) return merged_times_tg, merge_results
def get_intervals(textgrid_fn, tier_name): tg = TextGrid() tg.read(textgrid_fn) try: tier_i = tg.getNames().index(tier_name) except ValueError: raise TextGridError("Cannot find tier named " + tier_name) return tg[tier_i]
def gen_template_tg(self, duration: float, filename: str): new_tg = TextGrid(name=filename, minTime=0.0, maxTime=duration) for tier_name in self.tiers_specs.keys(): new_tier = IntervalTier(name=tier_name, minTime=0.0, maxTime=duration) new_tg.append(new_tier) return new_tg
def get_label(path): """ Used to load a TextGrid from disk and return the array representation of it. :param path: Path to the TextGrid :return: Array representation of the TextGrid. """ grid = TextGrid(name=path) grid.read(path, Fs=int(audio_sample_rate / window_size)) return grid.FsArrayCombined
def gop_feat_simple(gop_vals, textgrid_file): """ Calculate gop statistics on vowels, consonants and syllables :param gop_vals: gop values of one utterance extracted from gop files :param textgrid_file: textgrid file :return: """ textgrid = TextGrid() textgrid.read(textgrid_file) phn_seq = "" for intervals in textgrid.tiers[1]: if intervals.mark is not None: if intervals.mark != 'SIL' and intervals.mark != 'SPN': phn_seq += " " + intervals.mark language = syllabifier.English syllables = syllabifier.syllabify(language, str(phn_seq)) vowel_gop, consonants_gop, syllable_gop = [], [], [] syllable_idx = 0 # determine which syllable current phoneme is in phn_idx = 0 syllable_phn_gop = [] for intervals in textgrid.tiers[1]: # vowels and consonants if intervals.mark is not None: if intervals.mark != 'SIL' and intervals.mark != 'SPN': if intervals.mark in vowels: vowel_gop.append(gop_vals[phn_idx]) elif intervals.mark in consonants: consonants_gop.append(gop_vals[phn_idx]) else: continue # syllables if syllable_idx < len(syllables): current_syllable = syllables[syllable_idx][1] + syllables[syllable_idx][2] + syllables[syllable_idx][3] if intervals.mark is not None: if intervals.mark != 'SIL' and intervals.mark != 'SPN': if intervals.mark in current_syllable: syllable_phn_gop.append(gop_vals[phn_idx]) if intervals.mark == current_syllable[-1]: syllable_idx += 1 syllable_gop.append(np.mean(syllable_phn_gop)) syllable_phn_gop = [] if intervals.mark is not None: phn_idx += 1 if not vowel_gop: vowel_gop.append(1) if not consonants_gop: consonants_gop.append(1) if not syllable_gop: syllable_gop.append(1) return [np.mean(vowel_gop), np.mean(consonants_gop), np.mean(syllable_gop)], ["gop_avgV", "gop_avgC", "gop_avgSyl"]
def read_tg_from_str(tg_str, round_digits=DEFAULT_TEXTGRID_PRECISION): """ Read the tiers contained in the Praat-formatted string tg_str into a TextGrid object. Times are rounded to the specified precision. Adapted from TextGrid.read() """ source = StringIO(tg_str) tg = TextGrid() file_type, short = parse_header(source) if file_type != "TextGrid": raise ValueError("The file could not be parsed as a TextGrid as it is " "lacking a proper header.") tg.minTime = parse_line(source.readline(), short, round_digits) tg.maxTime = parse_line(source.readline(), short, round_digits) source.readline() # More header junk if short: m = int(source.readline().strip()) # Will be tg.n else: m = int(source.readline().strip().split()[2]) # Will be tg.n if not short: source.readline() for i in range(m): # Loop over grids if not short: source.readline() if parse_line(source.readline(), short, round_digits) == "IntervalTier": inam = parse_line(source.readline(), short, round_digits) imin = parse_line(source.readline(), short, round_digits) imax = parse_line(source.readline(), short, round_digits) itie = IntervalTier(inam, imin, imax) itie.strict = tg.strict n = int(parse_line(source.readline(), short, round_digits)) for j in range(n): if not short: source.readline().rstrip().split() # Header junk jmin = parse_line(source.readline(), short, round_digits) jmax = parse_line(source.readline(), short, round_digits) jmrk = get_mark(source, short) if jmin < jmax: # Non-null itie.addInterval(Interval(jmin, jmax, jmrk)) tg.append(itie) else: # PointTier inam = parse_line(source.readline(), short, round_digits) imin = parse_line(source.readline(), short, round_digits) imax = parse_line(source.readline(), short, round_digits) itie = PointTier(inam) n = int(parse_line(source.readline(), short, round_digits)) for j in range(n): source.readline().rstrip() # Header junk jtim = parse_line(source.readline(), short, round_digits) jmrk = get_mark(source, short) itie.addPoint(Point(jtim, jmrk)) tg.append(itie) return tg
def gen_template_tg(self, filename: str) -> SingleAnnotatorTextGrid: """Generates the template textgrid (pregenerated tiers and tg length) for that campaign""" audio_file = self.corpus.get_file(filename) if self.checking_scheme is None: tg = TextGrid(name=filename, maxTime=audio_file.duration) else: tg = self.checking_scheme.gen_template_tg(audio_file.duration, filename) return SingleAnnotatorTextGrid.from_textgrid(tg, [self.creator], None)
def ctm_to_textgrid(word_ctm, phone_ctm, out_directory, corpus, dictionary, frameshift=0.01): textgrid_write_errors = {} frameshift = Decimal(str(frameshift)) if not os.path.exists(out_directory): os.makedirs(out_directory, exist_ok=True) silences = {dictionary.optional_silence, dictionary.nonoptional_silence} for i, (filename, speaker_dict) in enumerate(sorted(word_ctm.items())): maxtime = corpus.get_wav_duration(filename) try: speaker_directory = os.path.join( out_directory, corpus.file_directory_mapping[filename]) tg = TextGrid(maxTime=maxtime) for speaker in corpus.speaker_ordering[filename]: words = speaker_dict[speaker] word_tier_name = '{} - words'.format(speaker) phone_tier_name = '{} - phones'.format(speaker) word_tier = IntervalTier(name=word_tier_name, maxTime=maxtime) phone_tier = IntervalTier(name=phone_tier_name, maxTime=maxtime) for w in words: word_tier.add(*w) for p in phone_ctm[filename][speaker]: if len(phone_tier) > 0 and phone_tier[ -1].mark in silences and p[2] in silences: phone_tier[-1].maxTime = p[1] else: if len(phone_tier) > 0 and p[2] in silences and p[ 0] < phone_tier[-1].maxTime: p = phone_tier[-1].maxTime, p[1], p[2] elif len(phone_tier) > 0 and p[2] not in silences and p[0] < phone_tier[-1].maxTime and \ phone_tier[-1].mark in silences: phone_tier[-1].maxTime = p[0] phone_tier.add(*p) tg.append(word_tier) tg.append(phone_tier) tg.write(os.path.join(speaker_directory, filename + '.TextGrid')) except Exception as e: exc_type, exc_value, exc_traceback = sys.exc_info() textgrid_write_errors[filename] = '\n'.join( traceback.format_exception(exc_type, exc_value, exc_traceback)) if textgrid_write_errors: error_log = os.path.join(out_directory, 'output_errors.txt') with open(error_log, 'w', encoding='utf8') as f: f.write( 'The following exceptions were encountered during the ouput of the alignments to TextGrids:\n\n' ) for k, v in textgrid_write_errors.items(): f.write('{}:\n'.format(k)) f.write('{}\n\n'.format(v))
def export_classification(self, output_directory): if self.cluster: self.cluster_utterances() else: self.get_classification_stats() from decimal import Decimal from textgrid import TextGrid, IntervalTier spk2utt_path = os.path.join(self.classify_directory, 'spk2utt') utt2spk_path = os.path.join(self.classify_directory, 'utt2spk') if self.corpus.segments: utt2spk = load_scp(utt2spk_path) file_dict = {} for utt, segment in self.corpus.segments.items(): filename, utt_begin, utt_end = segment.split(' ') utt_begin = Decimal(utt_begin) utt_end = Decimal(utt_end) if filename not in file_dict: file_dict[filename] = {} speaker = utt2spk[utt] text = self.corpus.text_mapping[utt] if speaker not in file_dict[filename]: file_dict[filename][speaker] = [] file_dict[filename][speaker].append([utt_begin, utt_end, text]) for filename, speaker_dict in file_dict.items(): try: speaker_directory = os.path.join( output_directory, self.corpus.file_directory_mapping[filename]) except KeyError: speaker_directory = output_directory max_time = self.corpus.get_wav_duration(filename) tg = TextGrid(maxTime=max_time) for speaker in sorted(speaker_dict.keys()): words = speaker_dict[speaker] tier = IntervalTier(name=speaker, maxTime=max_time) for w in words: if w[1] > max_time: w[1] = max_time tier.add(*w) tg.append(tier) tg.write( os.path.join(speaker_directory, filename + '.TextGrid')) else: spk2utt = load_scp(spk2utt_path) for speaker, utts in spk2utt.items(): speaker_dir = os.path.join(output_directory, speaker) os.makedirs(speaker_dir, exist_ok=True) with open(os.path.join(speaker_dir, 'utterances.txt'), 'w', encoding='utf8') as f: for u in utts: f.write('{}\n'.format(u))
def create_grid(wav_file: Path, text: str, tier_name: str, n_digits: int) -> TextGrid: assert wav_file.is_file() assert len(text) > 0 duration_s = get_wav_duration_s(wav_file) duration_s = round(duration_s, n_digits) result = TextGrid(None, 0, duration_s) tier = IntervalTier(tier_name, 0, duration_s) symbols = list(text) tier.intervals.extend(get_intervals(symbols, duration_s, n_digits)) result.append(tier) return result
def reorg_original(f): print(f) tg_path = os.path.join(noncollapsed_dir, f) tg = TextGrid() tg.read(tg_path) new_tg = TextGrid(maxTime=tg.maxTime) new_tg_path = tg_path.replace('_original.TextGrid', '.TextGrid') sentence_tier = tg.getFirst('Sentences') speaker_tier = tg.getFirst('Speakers') speaker_tiers = {} for i in speaker_tier: if i.mark == '': continue if ',' in i.mark: continue if i.mark == 'Tân.': continue speaker_tiers[i.mark] = IntervalTier(i.mark, maxTime=tg.maxTime) for i in sentence_tier: if not i.mark.strip(): continue duration = i.maxTime - i.minTime mid_point = i.minTime + duration / 2 speaker_int = speaker_tier.intervalContaining(mid_point) speaker = speaker_int.mark if speaker == 'Tân.': speaker = 'Tan' if speaker == '': continue if len(speaker_tiers[speaker] ) > 0 and speaker_tiers[speaker][-1].maxTime == i.minTime: speaker_tiers[speaker][-1].maxTime = i.maxTime speaker_tiers[speaker][ -1].mark = speaker_tiers[speaker][-1].mark + ' ' + i.mark else: speaker_tiers[speaker].addInterval(i) for k, v in sorted(speaker_tiers.items()): new_tg.append(v) print(speaker_tiers.keys()) new_tg.write(new_tg_path)
def main(text_grid_filename, output_label): if os.path.exists(text_grid_filename): t = TextGrid() t.read(text_grid_filename) onset = t._TextGrid__tiers[0]._IntervalTier__intervals[ 1]._Interval__xmin offset = t._TextGrid__tiers[0]._IntervalTier__intervals[ 1]._Interval__xmax f = open(output_label, 'w') onset_i = np.ceil(onset * 100 * 2) # extract every 5 ms offset_i = np.floor(offset * 100 * 2) # extract every 5 ms f.write('1 2\n') f.write(str(onset_i) + ' ' + str(offset_i) + '\n')
def fixTiers(source, tierlist, outfile): """Takes list of TextGrids, file with new tier orders, list of output file names, returns TextGrids with new tier order""" for line, tier, out in zip(source.readlines(), tierlist, outfile.readlines()): f = line.rstrip('\n') oldtg = TextGridFromFile(f) list_from_file = eval(tier) output = out.rstrip('\n') newtg = TextGrid('newtg') for n in list_from_file: ntier = oldtg.getFirst(n) newtg.append(ntier) newtg.write(output)
def get_word_set(corpus, include_bracketed=False): word_set = corpus.word_set decode_error_files = [] textgrid_read_errors = {} for file_path in corpus.transcriptions_without_wavs: if file_path.endswith('.lab'): try: text = load_text(file_path) except UnicodeDecodeError: decode_error_files.append(file_path) continue words = parse_transcription(text) word_set.update(words) else: tg = TextGrid() try: tg.read(file_path) except Exception as e: exc_type, exc_value, exc_traceback = sys.exc_info() textgrid_read_errors[file_path] = '\n'.join( traceback.format_exception(exc_type, exc_value, exc_traceback)) continue for i, ti in enumerate(tg.tiers): if ti.name.lower() == 'notes': continue if not isinstance(ti, IntervalTier): continue for interval in ti: text = interval.mark.lower().strip() words = parse_transcription(text) if not words: continue word_set.update(words) if decode_error_files: print( 'WARNING: The following files were not able to be decoded using utf8:\n\n' '{}'.format('\n'.join(decode_error_files))) if textgrid_read_errors: print( 'WARNING: The following TextGrid files were not able to be read:\n\n' '{}'.format('\n'.join(textgrid_read_errors.keys()))) print( 'Generating transcriptions for the {} word types found in the corpus...' .format(len(word_set))) if not include_bracketed: word_set = [x for x in word_set if not check_bracketed(x)] return word_set
def convert_textgrid(tg_old, sil): tg_new = TextGrid(tg_old.start, tg_old.end) phontier = Tier('phones', tg_old['PHONEMES'].start, tg_old['PHONEMES'].end, 'Interval', [Interval(x.start, x.end, convert_mark(x.mark, sil)) for x in tg_old['PHONEMES']]) wordtier = Tier('words', tg_old['WORDS'].start, tg_old['WORDS'].end, 'Interval', [Interval(x.start, x.end, convert_mark(x.mark, sil)) for x in tg_old['WORDS']]) tg_new.append_tier(wordtier) tg_new.append_tier(phontier) return tg_new
def gen_merged_times(self): """Merges times""" merged_times_tg, merge_results = self.check_times_merging() new_tg = TextGrid(name=merged_times_tg.name, maxTime=merged_times_tg.maxTime, minTime=merged_times_tg.minTime) for tier_name in self.checking_scheme.all_tiers_names: merged_tier: IntervalTier = deepcopy(merged_times_tg.getFirst(tier_name)) target_tier: IntervalTier = deepcopy(self.textgrid.getFirst(tier_name + "-target")) merged_tier.name = tier_name + "-merged" new_tg.append(merged_tier) new_tg.append(target_tier) return new_tg, merge_results
def read_textgrid(file, tier): tg = TextGrid() tg.read(file) if len(tg.tiers) <= tier: raise IOError('Texgrid file ' + file + ' doesn\'t have enough tiers to get tier: ' + str(tier)) if not hasattr(tg.tiers[tier], 'intervals'): raise IOError('The selected tier: ' + str(tier) + ' is not and IntervalTier in file: ' + file) ret = [] for seg in tg.tiers[tier].intervals: ret.append(Segment(seg.mark, seg.minTime, seg.duration())) return ret