## this script should be used only by Aki Kunikoshi. import os import numpy as np import pandas as pd import argparse import json from novoapi.backend import session import defaultfiles as default import convert_phoneset def load_novo70_phoneset(): #phonelist_novo70_ = pd.ExcelFile(default.phonelist_novo70_xlsx) #df = pd.read_excel(phonelist_novo70_, 'list') ## *_simple includes columns which has only one phone in. #for ipa, novo70 in zip(df['IPA_simple'], df['novo70_simple']): # if not pd.isnull(ipa): # print('{0}:{1}'.format(ipa, novo70)) # translation_key[ipa] = novo70 #phonelist_novo70 = np.unique(list(df['novo70_simple'])) novo70_phoneset = pd.read_csv(default.novo70_phoneset, delimiter='\t', header=None, encoding="utf-8") novo70_phoneset.rename(columns={0: 'novo70', 1: 'ipa', 2: 'description'}, inplace=True) #phoneset_ipa = [] #phoneset_novo70 = [] #with open(default.novo70_phoneset, "rt", encoding="utf-8") as fin: # lines = fin.read() # lines = lines.split('\n') # for line in lines: # words = line.split('\t') # if len(words) > 1: # novo70 = words[0] # ipa = words[1] # phoneset_ipa.append(ipa) # phoneset_novo70.append(novo70) # translation_key_ipa2novo70[ipa] = novo70 # translation_key_novo702ipa[novo70] = ipa # As per Nederlandse phoneset_aki.xlsx recieved from David # [ɔː] oh / ohr # from ipa->novo70, only oh is used. # [ɪː] ih / ihr # from ipa->novo70, only ih is used. # [iː] iy # [œː] uh # [ɛː] eh # [w] wv in IPA written as ʋ. extra_ipa = ['ɔː', 'ɪː', 'iː', 'œː', 'ɛː', 'ʋ'] extra_novo70 = ['oh', 'ih', 'iy', 'uh', 'eh', 'wv'] phoneset_ipa = list(novo70_phoneset['ipa']) phoneset_ipa.extend(extra_ipa) phoneset_ipa = [i.replace('ː', ':') for i in phoneset_ipa] phoneset_novo70 = list(novo70_phoneset['novo70']) phoneset_novo70.extend(extra_novo70) phoneset_novo70 = [i.replace('ː', ':') for i in phoneset_novo70] translation_key_ipa2novo70 = dict() translation_key_novo702ipa = dict() for ipa, novo70 in zip(phoneset_ipa, phoneset_novo70): #phoneset_ipa.append(ipa) #phoneset_novo70.append(novo70) translation_key_ipa2novo70[ipa] = novo70 translation_key_novo702ipa[novo70] = ipa translation_key_novo702ipa['ohr'] = 'ɔ:' translation_key_novo702ipa['ihr'] = 'ɪ:' phoneset_ipa = np.unique(phoneset_ipa) phoneset_novo70 = np.unique(phoneset_novo70) return phoneset_ipa, phoneset_novo70, translation_key_ipa2novo70, translation_key_novo702ipa def split_ipa(line): """ Split a line by IPA phones. If nasalized sound (such as ɛ̃ː) is included, it will give error. :param string line: one line written in IPA. :return string lineSeperated: the line splitted in IPA phone. """ phoneset_ipa, _, _, _ = load_novo70_phoneset() #multi_character_phones = [i for i in phoneset_ipa if len(i) > 1] #multi_character_phones.sort(key=len, reverse=True) #multi_character_phones = [ # # IPAs in CGN. # u'ʌu', u'ɛi', u'œy', u'aː', u'eː', u'iː', u'oː', u'øː', u'ɛː', u'œː', u'ɔː', u'ɛ̃ː', u'ɑ̃ː', u'ɔ̃ː', u'œ̃', u'ɪː' # ] #return [phone for phone in multi_character_tokenize(line.strip(), multi_character_phones)] return convert_phoneset.split_word(line, phoneset_ipa) def split_novo70(line): """ Split a line by novo70 phones. :param string line: one line written in novo70. :return string lineSeperated: the line splitted by novo70 phones. """ _, phoneset_novo70, _, _ = load_novo70_phoneset() #multi_character_phones = [p for p in phoneset_novo70 if len(p) > 1] #multi_character_phones = sorted(multi_character_phones, key=len, reverse=True) multi_character_phones = convert_phoneset.extract_multi_character_phones(phoneset_novo70) return ['sp' if phone == ' ' else phone for phone in multi_character_tokenize(line.strip(), multi_character_phones)] def novo702ipa(line): #pronunciation = [] _, _, _, translation_key = load_novo70_phoneset() #for phone in split_novo70(tokens): # pronunciation.append(translation_key.get(phone, phone)) #return ' '.join(pronunciation) return ' '.join(convert_phoneset.convert_phoneset(split_novo70(line), translation_key)) # numbering of novo70 should be checked. def ipa2novo70(line): #pronunciation = [] _, _, translation_key, _ = load_novo70_phoneset() #for phone in split_ipa(tokens): # pronunciation.append(translation_key.get(phone, phone)) #return ' '.join(pronunciation) return ' '.join(convert_phoneset.convert_phoneset(split_ipa(line), translation_key)) def make_grammar(word, pronunciation_ipa): """ Args: words pronunciation_ipa: list of pronunciation variants. """ #word = 'pauw' #pronunciation_ipa = ['pau', 'pɑu'] grammer_data_elements0_pronunciation = [] for id, ipa in enumerate(pronunciation_ipa): novo70 = ipa2novo70(ipa) grammer_data_elements0_pronunciation.append({ "phones": novo70.split(), "id": id }) grammar_data = { "kind": 'sequence', "elements": [{ "kind": "word", "pronunciation": grammer_data_elements0_pronunciation, "label": word }] } grammar = { "type": "confusion_network", "version": "1.0", "data": grammar_data, "return_objects": ["grammar"], "phoneset": "novo70" } return grammar def forced_alignment(wav_file, word, pronunciation_ipa): ### IMPORTANT ### # because of this function, this script should not be uploaded / shared. # username / password cannot be passed as artuments... p = argparse.ArgumentParser() p.add_argument("--user", default='martijn.wieling') p.add_argument("--password", default='xxxxxx') args = p.parse_args() rec = session.Recognizer(grammar_version="1.0", lang="nl", snodeid=101, user=args.user, password=args.password, keepopen=True) # , modeldir=modeldir) grammar = make_grammar(word, pronunciation_ipa) result = rec.setgrammar(grammar) #print "Set grammar result", res result = rec.recognize_wav(wav_file) return result.export() def result2pronunciation(result, word): result_ = [result[i] for i in range(len(result)) if result[i]['label'] == word] llh = result_[0]['llh'] phones = result_[0]['phones'] pronunciation_novo70 = [phone['label'] for phone in phones] pronunciation_ipa = [novo702ipa(phone) for phone in pronunciation_novo70] return pronunciation_ipa, pronunciation_novo70, llh def phones_not_in_novo70(ipa): """ extract phones which is not in novo70 phoneset. """ phoneset_ipa, _, _, _ = load_novo70_phoneset() # As per Nederlandse phoneset_aki.xlsx recieved from David # [ɔː] oh / ohr # [ɪː] ih / ihr # [iː] iy # [œː] uh # [ɛː] eh # [w] wv in IPA written as ʋ. david_suggestion = ['ɔː', 'ɪː', 'iː', 'œː', 'ɛː', 'w'] return [phone for phone in split_ipa(ipa) if not phone in phoneset_ipa and not phone in david_suggestion] if __name__ == 'main': pronunciation_ipa = ['rø:s', 'mɑn', 'mɑntsjə'] #grammar = make_grammar('reus', pronunciation_ipa) phoneset_ipa, phoneset_novo70, translation_key_ipa2novo70, translation_key_novo702ipa = load_novo70_phoneset()