/// <summary> /// Get word text for number domain. /// </summary> /// <param name="word">Given ScriptWord.</param> /// <param name="sentenceId">Sentence Id.</param> /// <param name="wordIndex">Word index.</param> /// <param name="digitals">Digital words.</param> /// <returns>Word text.</returns> private static string GetNumberDomainWordText(ScriptWord word, string sentenceId, int wordIndex, Dictionary<string, DigitalWordItem> digitals) { string text = word.Grapheme.ToUpperInvariant(); string key = DigitalWordItem.GetKey(sentenceId, wordIndex); if (digitals.ContainsKey(key)) { text += "@" + digitals[key].Group.ToString(System.Globalization.CultureInfo.InvariantCulture); } else { if (word.Break > TtsBreak.Word) { text += "#3"; } else { text += "#1"; } } return text; }
/// <summary> /// Calculate PosInSentence feature for a given word /// Change it to public for code re-use in script sentence. /// </summary> /// <param name="preWord">Previous word of target word to calculate.</param> /// <param name="word">Target word to calculate.</param> /// <returns>PosInSentence feature.</returns> public static PosInSentence CalculatePosInSentence(ScriptWord preWord, ScriptWord word) { int row = (int)((preWord == null) ? TtsBreak.Sentence : preWord.Break) - (int)TtsBreak.Word; int column = (int)word.Break - (int)TtsBreak.Word; // #0, a word is connected with the word following it. Like the liason in French // Here treat it as word boundary column = column < 0 ? 0 : column; row = row < 0 ? 0 : row; PosInSentence pis = _posInSentenceTrans[row][column]; return pis; }
/// <summary> /// Get script words from utterance. /// </summary> /// <param name="utt">Utterance.</param> /// <param name="isOovWord">Return whether each word is oov.</param> /// <returns>Script words.</returns> public Collection<ScriptWord> GetScriptWords(SP.TtsUtterance utt, Collection<bool> isOovWord) { if (utt == null) { throw new ArgumentNullException("utt"); } Collection<ScriptWord> words = new Collection<ScriptWord>(); for (int i = 0; i < utt.Words.Count; ++i) { SP.TtsWord word = utt.Words[i]; if (IsCommonWord(word)) { ScriptWord scriptWord = new ScriptWord(); // Currently runtime will append a punctuation word for the sentence that has no // punctuation at the end. if (string.IsNullOrEmpty(word.WordText) && (i == utt.Words.Count - 1) && word.WordType == SP.TtsWordType.WT_PUNCTUATION) { // Don't add the word to keep consistence with original input text. continue; } scriptWord.Grapheme = word.WordText; if (!string.IsNullOrEmpty(word.Pronunciation)) { scriptWord.Pronunciation = word.Pronunciation.ToLowerInvariant(); } ushort posTaggerPos = _engine.PosTable.GetPOSTaggerPOS(checked((ushort)word.Pos)); scriptWord.PosString = _engine.PosTable.IdToString(posTaggerPos); scriptWord.DetailedPosString = _engine.PosTable.IdToString(checked((ushort)word.Pos)); scriptWord.NETypeText = word.NETypeText; scriptWord.OffsetInString = (int)word.TextOffset; scriptWord.LengthInString = (int)word.TextLength; scriptWord.PronSource = (TtsPronSource)word.PronSource; scriptWord.RegularText = word.WordRegularText; switch (word.WordType) { case SP.TtsWordType.WT_NORMAL: case SP.TtsWordType.WT_SPELLOUT: scriptWord.WordType = WordType.Normal; break; case SP.TtsWordType.WT_PUNCTUATION: scriptWord.WordType = WordType.Punctuation; break; } switch (word.Emphasis) { case SP.TtsEmphasis.EMPH_YES: scriptWord.Emphasis = TtsEmphasis.Yes; break; case SP.TtsEmphasis.EMPH_NONE: scriptWord.Emphasis = TtsEmphasis.None; break; } switch (word.BreakLevel) { case SP.TtsBreakLevel.BK_IDX_SYLLABLE: scriptWord.Break = TtsBreak.Syllable; break; case SP.TtsBreakLevel.BK_IDX_INTERM_PHRASE: scriptWord.Break = TtsBreak.InterPhrase; break; case SP.TtsBreakLevel.BK_IDX_INTONA_PHRASE: scriptWord.Break = TtsBreak.IntonationPhrase; break; case SP.TtsBreakLevel.BK_IDX_SENTENCE: scriptWord.Break = TtsBreak.Sentence; break; } if (word.ToBIFinalBoundaryTone != (uint)TtsTobiBoundary.NoBoundaryTone) { Offline.TtsTobiBoundaryToneSet boundarySet = new Offline.TtsTobiBoundaryToneSet(); scriptWord.TobiFinalBoundaryTone = TobiLabel.Create(boundarySet.IdItems[(uint)word.ToBIFinalBoundaryTone]); } words.Add(scriptWord); isOovWord.Add(IsOov(word)); } } return words; }
/// <summary> /// Dump the data in the words. /// </summary> /// <param name="sentence">The script sentence which to store the data dumped from the words.</param> /// <param name="utt">The utterance.</param> /// <param name="ttsEngine">The object ttsEngine to help to convert the Pos and get sentence id.</param> /// <param name="scriptLanguage">The language of the script.</param> private static void DumpWords(ScriptSentence sentence, SP.TtsUtterance utt, SP.TtsEngine ttsEngine, Language scriptLanguage) { Debug.Assert(sentence != null, "Sentence should not be null"); Debug.Assert(utt != null, "Utt should not be null"); Debug.Assert(ttsEngine != null, "ttsEngine should not be null"); // Phone index to mark the phone in the Utt.Phones int phoneIndex = 0; // F0 index to mark the start position in the Utt.Sccoustic.F0s int f0StartIndex = 0; // Unit index to mark the unit in the Utt.Units int unitIndex = 0; // Word index to mark the position in the Utt.Words int wordIndex = 0; foreach (SP.TtsWord word in utt.Words) { if (word.WordText != null) { ScriptWord scriptWord = new ScriptWord(); // Tag the language to the word level if there is not single language in the utt. // The major language (the most word count with this language) will be tag on the // script level, others tag on the word level. if ((Language)word.LangId != scriptLanguage) { scriptWord.Language = (Language)word.LangId; } // According to the schema, if the word is "silence", there should be not // value in the scriptWord pronunciation. Means: <w v="" if (word.WordType != TtsWordType.WT_SILENCE) { scriptWord.Grapheme = word.WordText; } if (!string.IsNullOrEmpty(word.Pronunciation)) { scriptWord.Pronunciation = word.Pronunciation.ToLowerInvariant(); } scriptWord.WordType = ConvertWordType(word); // Dump the Part-Of-Speech. // If the word is "sil", the word text is " ", the pos id is 65535, out of boundary. // In this case, will not dump the pos. if (!string.IsNullOrEmpty(word.WordText.Trim())) { scriptWord.PosString = ttsEngine.PosTable.IdToString(word.Pos); } scriptWord.Break = (TtsBreak)word.BreakLevel; scriptWord.Emphasis = (TtsEmphasis)word.Emphasis; scriptWord.TobiFinalBoundaryTone = ConvertTobiFBT(word.ToBIFinalBoundaryTone); scriptWord.PronSource = (TtsPronSource)word.PronSource; scriptWord.OffsetInString = (int)word.TextOffset; scriptWord.LengthInString = (int)word.TextLength; DumpSyllables(scriptWord, utt, word, ref phoneIndex, ref unitIndex, ref f0StartIndex, ttsEngine); sentence.Words.Add(scriptWord); } else { string message = Helper.NeutralFormat("The word text of word [{0}]: \"{1}\" in the" + "utterance is empty.", wordIndex, word.WordText); throw new InvalidDataException(message); } wordIndex++; } }
/// <summary> /// Syllabify one tts word entry. /// </summary> /// <param name="word">Word to syllabify.</param> /// <returns>Sliced word pronunciation.</returns> public string SliceWord(ScriptWord word) { if (word == null) { throw new ArgumentNullException("word"); } if (string.IsNullOrEmpty(word.Grapheme)) { string message = string.Format(CultureInfo.InvariantCulture, "word.Grapheme should not be null or empty."); throw new ArgumentNullException("word", message); } string pron = word.GetPronunciation(_phoneSet); string slicePron = string.Empty; if (!string.IsNullOrEmpty(pron)) { slicePron = RewritePhones2Units(_sliceData, pron); if (!string.IsNullOrEmpty(slicePron)) { slicePron = Regex.Replace(slicePron, @"\.\s+\.", "."); } } return slicePron; }
/// <summary> /// Appends a punctuation word in the end of given utterance. /// </summary> /// <param name="utterance"> /// The given utterance. /// </param> /// <param name="scriptWord"> /// The script word. /// </param> /// <returns> /// The phoneme count of the given word. /// </returns> /// <exception cref="InvalidDataException"> /// Exception. /// </exception> private int AppendPunctuationWord(TtsUtterance utterance, ScriptWord scriptWord) { TtsWord word = utterance.AppendNewWord(); word.LangId = (ushort)scriptWord.Language; word.BreakLevel = (TtsBreakLevel)scriptWord.Break; word.Emphasis = (TtsEmphasis)scriptWord.Emphasis; word.WordText = scriptWord.Grapheme; word.NETypeText = scriptWord.NETypeText; word.WordType = TtsWordType.WT_PUNCTUATION; // There is no phoneme for punctuation word. return 0; }
/// <summary> /// Read and parse word data from the XML text reader to utterance. /// </summary> /// <param name="reader">XML text reader to read data from.</param> /// <param name="utterance">Target utterance to save result words.</param> private static void ProcessWord(XmlTextReader reader, TtsUtterance utterance) { ScriptWord word = new ScriptWord(utterance.Script.Language); word.Grapheme = reader.GetAttribute("val"); if (reader.GetAttribute("p") != null) { word.Pronunciation = reader.GetAttribute("p"); } if (reader.GetAttribute("pos") != null) { word.Pos = (PartOfSpeech)Enum.Parse(typeof(PartOfSpeech), reader.GetAttribute("pos")); } if (reader.GetAttribute("emphasis") != null) { word.Emphasis = (TtsEmphasis)Enum.Parse(typeof(TtsEmphasis), reader.GetAttribute("emphasis")); } if (reader.GetAttribute("break") != null) { word.Break = (TtsBreak)Enum.Parse(typeof(TtsBreak), reader.GetAttribute("break")); } if (reader.GetAttribute("type") != null) { word.WordType = (WordType)Enum.Parse(typeof(WordType), reader.GetAttribute("type")); } utterance.Script.Words.Add(word); reader.Skip(); }
/// <summary> /// Build syllable collection for a given word. /// </summary> /// <param name="word">Word to process.</param> private static void BuildSyllables(ScriptWord word) { if (word == null) { throw new ArgumentNullException("word"); } if (word.Pronunciation == null) { throw new ArgumentException("word.Pronunciation is null"); } word.Syllables.Clear(); string[] syllableTexts = Core.Pronunciation.SplitIntoSyllables(word.Pronunciation); for (int syllableIndex = 0; syllableIndex < syllableTexts.Length; syllableIndex++) { ScriptSyllable syllable = new ScriptSyllable(); syllable.Text = syllableTexts[syllableIndex]; syllable.TtsBreak = (syllableIndex == syllableTexts.Length - 1) ? word.Break : TtsBreak.Syllable; syllable.Stress = Core.Pronunciation.GetStress(syllable.Text); syllable.TtsEmphasis = (syllable.Stress != TtsStress.None) ? word.Emphasis : TtsEmphasis.None; word.Syllables.Add(syllable); } }
/// <summary> /// Load the attributes for a given word. /// </summary> /// <param name="word">ScriptWord.</param> /// <param name="reader">XmlTextReader.</param> /// <param name="scriptLanguage">The language of the script.</param> private static void LoadWordAttributes(ScriptWord word, XmlTextReader reader, Language scriptLanguage) { Debug.Assert(word != null); Debug.Assert(reader != null); string wordLanguage = reader.GetAttribute("language"); if (!string.IsNullOrEmpty(wordLanguage) && Localor.StringToLanguage(wordLanguage) != scriptLanguage) { word.Language = Localor.StringToLanguage(wordLanguage); } word.Grapheme = reader.GetAttribute("v"); string pron = reader.GetAttribute("p"); if (!string.IsNullOrEmpty(pron)) { word.Pronunciation = pron; } word.AcceptGrapheme = reader.GetAttribute("av"); string acceptPron = reader.GetAttribute("ap"); if (!string.IsNullOrEmpty(acceptPron)) { word.AcceptPronunciation = acceptPron; } string type = reader.GetAttribute("type"); if (!string.IsNullOrEmpty(type)) { word.WordType = ScriptWord.StringToWordType(type); } if (word.Grapheme == null || word.Grapheme.Length == 0) { if (word.WordType != WordType.Silence && word.WordType != WordType.Punctuation) { throw new InvalidDataException(Helper.NeutralFormat( "Line [{0}]: only silence word, prosody boundary or punctuation can have null/empty word grapheme", reader.LineNumber)); } } else { if (word.WordType == WordType.Silence) { throw new InvalidDataException(Helper.NeutralFormat( "Line [{0}]: silence word or prosody boundary should have empty word grapheme", reader.LineNumber)); } } string pos = reader.GetAttribute("pos"); if (!string.IsNullOrEmpty(pos)) { word.PosString = pos; } string expansion = reader.GetAttribute("exp"); if (!string.IsNullOrEmpty(expansion)) { word.Expansion = expansion; } string emphasis = reader.GetAttribute("em"); if (!string.IsNullOrEmpty(emphasis)) { word.Emphasis = ScriptWord.StringToEmphasis(emphasis); } string breakLevel = reader.GetAttribute("br"); if (!string.IsNullOrEmpty(breakLevel)) { word.Break = ScriptWord.StringToBreak(breakLevel); } string breakAskLevel = reader.GetAttribute("bra"); if (!string.IsNullOrEmpty(breakAskLevel)) { word.BreakAsk = ScriptWord.StringToBreak(breakAskLevel); } else { word.BreakAsk = ScriptWord.UndefinedBreakAsk; } string breakProb = reader.GetAttribute("brp"); if (!string.IsNullOrEmpty(breakProb)) { word.BreakProb = float.Parse(breakProb, CultureInfo.InvariantCulture); } else { word.BreakProb = ScriptWord.DefaultProbability; } string wordTone = reader.GetAttribute("wt"); if (!string.IsNullOrEmpty(wordTone)) { word.WordTone = ScriptWord.StringToWordTone(wordTone); } string tobiibt = reader.GetAttribute("tobiibt"); if (!string.IsNullOrEmpty(tobiibt)) { word.TobiInitialBoundaryTone = new TobiLabel(tobiibt); } string tobifbt = reader.GetAttribute("tobifbt"); if (!string.IsNullOrEmpty(tobifbt)) { word.TobiFinalBoundaryTone = new TobiLabel(tobifbt); } string domain = reader.GetAttribute("domain"); if (!string.IsNullOrEmpty(domain)) { word.AcousticDomainTag = domain; } string nusTag = reader.GetAttribute("nus"); if (!string.IsNullOrEmpty(nusTag)) { word.NusTag = nusTag; } string regularText = reader.GetAttribute("regularText"); if (!string.IsNullOrEmpty(regularText)) { word.RegularText = regularText; } string sp = reader.GetAttribute("sp"); if (!string.IsNullOrEmpty(sp)) { word.ShallowParseTag = sp; } string tcgppScore = reader.GetAttribute("tcgppScore"); if (!string.IsNullOrEmpty(tcgppScore)) { word.TcgppScores = tcgppScore; } string pronSource = reader.GetAttribute("pronSource"); if (!string.IsNullOrEmpty(pronSource)) { word.PronSource = ScriptWord.StringToPronSource(pronSource); } string netype = reader.GetAttribute("netype"); if (!string.IsNullOrEmpty(netype)) { word.NETypeText = netype; } if (word.WordType != WordType.Silence) { string offset = reader.GetAttribute("offset"); if (!string.IsNullOrEmpty(offset)) { word.OffsetInString = int.Parse(offset); } string length = reader.GetAttribute("length"); if (!string.IsNullOrEmpty(length)) { word.LengthInString = int.Parse(length); } } }
/// <summary> /// Load one script word from the xmltextreader. /// </summary> /// <param name="reader">XmlTextReader.</param> /// <param name="contentController">ContentControler.</param> /// <param name="language">The language of the script.</param> /// <returns>ScriptWord that read.</returns> public static ScriptWord LoadWord(XmlTextReader reader, object contentController, Language language) { Debug.Assert(reader != null); ContentControler scriptContentController = new ContentControler(); if (contentController is ContentControler) { scriptContentController = contentController as ContentControler; } else if (contentController != null) { throw new ArgumentException("Invalid contentController type"); } ScriptWord word = new ScriptWord(language); // load attributes LoadWordAttributes(word, reader, language); // load syllables // remember that word can have no syllable list if (!reader.IsEmptyElement) { while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element && reader.Name == "syls") { while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element && reader.Name == "syl") { ScriptSyllable syllable = LoadSyllable(reader, language); syllable.Word = word; word.Syllables.Add(syllable); } else if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "syls") { break; } } } else if (reader.NodeType == XmlNodeType.Element && reader.Name == "acoustics") { word.Acoustics = new ScriptAcoustics(); word.Acoustics.ParseFromXml(reader); } else if (reader.NodeType == XmlNodeType.Element && reader.Name == "comments") { if (scriptContentController.LoadComments) { word.TtsXmlComments.Parse(reader); word.TtsXmlComments.Tag = word; } else { reader.Skip(); } } else if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "w") { break; } } } return word; }
/// <summary> /// Sync word text to item text. /// </summary> /// <param name="scriptWord">Script word to be synced.</param> public static void SyncWordChangesToItem(ScriptWord scriptWord) { if (scriptWord == null) { throw new ArgumentNullException("scriptWord"); } if (scriptWord.Sentence == null) { throw new ArgumentException("scriptWord.Sentence is null"); } if (scriptWord.Sentence.ScriptItem == null) { throw new ArgumentException("scriptWord.Sentence.ScriptItem is null"); } SyncItemTextFromWordList(scriptWord.Sentence.ScriptItem); }
/// <summary> /// Scritp word to be displayed. /// </summary> /// <param name="word">Script word.</param> /// <returns>String.</returns> public static string BuildDisplayedWordText(ScriptWord word) { if (word == null) { throw new ArgumentNullException("word"); } if (string.IsNullOrEmpty(word.Grapheme)) { throw new ArgumentException("word.Grapheme"); } StringBuilder displayedWordText = new StringBuilder(); displayedWordText.AppendFormat("{0}", word.Grapheme); if (word.Emphasis == TtsEmphasis.Yes) { displayedWordText.Append(" *"); } string breakString = ScriptWord.BreakToString(word.Break); if (!string.IsNullOrEmpty(breakString)) { if (word.Break == TtsBreak.Syllable) { displayedWordText.Append(" _"); } else { displayedWordText.Append(" #"); } displayedWordText.Append(breakString); } return displayedWordText.ToString(); }
/// <summary> /// Get word text for acronym domain. /// </summary> /// <param name="word">Given ScriptWord.</param> /// <param name="sentenceId">Sentence Id.</param> /// <param name="wordIndex">Word index.</param> /// <param name="acronyms">Acronym words.</param> /// <returns>Word text.</returns> private static string GetAcronymDomainWordText(ScriptWord word, string sentenceId, int wordIndex, Dictionary<string, AcronymWordItem> acronyms) { string key = AcronymWordItem.GetKey(sentenceId, wordIndex); string text = acronyms[key].Word.ToUpperInvariant(); text += "@" + acronyms[key].Group.ToString(System.Globalization.CultureInfo.InvariantCulture); return text; }
/// <summary> /// Find previos word, which is normal word /// Change it to public for code re-use in script sentence. /// </summary> /// <param name="words">Word collection to search.</param> /// <param name="word">Word to find previous word for.</param> /// <returns>Found word.</returns> public static ScriptWord FindPreviousWord(Collection<ScriptWord> words, ScriptWord word) { if (words == null) { throw new ArgumentNullException("words"); } if (word == null) { throw new ArgumentNullException("word"); } int index = words.IndexOf(word); if (index == -1) { throw new ArgumentOutOfRangeException("word"); } while (index - 1 >= 0) { if (words[index - 1].WordType == WordType.Normal) { return words[index - 1]; } --index; } return null; }
/// <summary> /// Converts one word instance to script named entity. /// </summary> /// <param name="word">The word instance to convert.</param> /// <returns>The converted script named entity instance.</returns> private ScriptNamedEntity ToScriptNamedEntity(ScriptWord word) { Helper.ThrowIfNull(word); if (string.IsNullOrEmpty(word.NamedEntityTypeString)) { throw new InvalidDataException(Helper.NeutralFormat( "The type of the named entity [{0}] should not be empty.", word.NamedEntityTypeString)); } ScriptNamedEntity entity = new ScriptNamedEntity(); entity.Text = word.Grapheme; entity.PosString = word.PosString; entity.Type = word.NamedEntityTypeString; entity.Start = word.SubWords[0]; entity.End = word.SubWords[word.SubWords.Count - 1]; return entity; }
/// <summary> /// Fix the ending punctuation of the sentence, this is, to make sure /// The sentence end with Period punctuation. /// </summary> /// <param name="words">Word collection of the sentence.</param> /// <param name="language">Language of the sentence.</param> private static void FixEndingPunctuation(Collection<ScriptWord> words, Language language) { if (words.Count > 0) { ScriptWord lastWord = words[words.Count - 1]; if (lastWord.WordType == WordType.Normal) { ScriptWord word = new ScriptWord(language); word.Grapheme = "."; word.WordType = WordType.Period; word.Break = Localor.MapWordType2Break(word.WordType); words.Add(word); } else if (lastWord.WordType == WordType.OtherPunctuation) { // upgrade this word break level lastWord.WordType = WordType.Period; lastWord.Break = Localor.MapWordType2Break(lastWord.WordType); } } }
/// <summary> /// Converts one named entity to script word instance. /// </summary> /// <param name="entity">The named entity instance to convert.</param> /// <returns>The converted word instance.</returns> private ScriptWord ToScriptWord(ScriptNamedEntity entity) { Helper.ThrowIfNull(entity); if (string.IsNullOrEmpty(entity.Type)) { throw new InvalidDataException(Helper.NeutralFormat( "The type of the named entity [{0}] should not be empty.", entity.Text)); } ScriptWord word = new ScriptWord(entity.Start.Language); word.Break = entity.End.Break; word.Grapheme = entity.Text; word.PosString = entity.PosString; if (word.PosString == ScriptNamedEntity.DefaultEmptyPosString) { word.PosString = ScriptNamedEntity.DefaultEntityPosString; } word.NamedEntityTypeString = entity.Type; word.Sentence = entity.Start.Sentence; word.SubWords = new Collection<ScriptWord>(); StringBuilder pronunciation = new StringBuilder(); for (int i = Words.IndexOf(entity.Start); i <= Words.IndexOf(entity.End); i++) { word.SubWords.Add(Words[i]); if (!string.IsNullOrEmpty(Words[i].Pronunciation)) { if (pronunciation.Length != 0) { pronunciation.AppendFormat(" {0} ", Pronunciation.WordPronBoundaryString); } pronunciation.Append(Words[i].Pronunciation); } } word.Pronunciation = pronunciation.ToString(); return word; }
/// <summary> /// Previos word building, process one token of word. /// </summary> /// <param name="words">Result word list.</param> /// <param name="language">Language of the sentence.</param> /// <param name="tokenMatch">Token matched.</param> /// <param name="wordIndex">Word index of current word.</param> /// <returns>Word index of next word.</returns> private int PreBuildWord(Collection<ScriptWord> words, Language language, Match tokenMatch, int wordIndex) { bool tagged = true; // 0 is the whole "((\S+)/(\S+))|(\S+)" // 1 is "((\S+)/(\S+))|" // 2 is "(\S+)/" // 3 is "/(\S+)" // 4 is "|(\S+)" string content = tokenMatch.Groups[1].Value; if (string.IsNullOrEmpty(content)) { tagged = false; content = tokenMatch.Groups[4].Value; } else { content = tokenMatch.Groups[2].Value; } Match breakMatch = Regex.Match(content, @"^#([0|1|2|3|4])([FfcRr]?)$"); Match wordToneMatch = Regex.Match(content, @"^#([FfcRr])$"); Match emphasisMatch = Regex.Match(content, @"^\*[234]?$"); Match puncMatch = Regex.Match(content, @"^" + PunctuationPattern + "$"); if (emphasisMatch.Success) { if (wordIndex >= 0) { words[wordIndex].Emphasis = TtsEmphasis.Yes; words[wordIndex].EmphasisTag = content; } } else if (wordToneMatch.Success) { if (wordIndex >= 0) { words[wordIndex].WordTone = ScriptItem.LabelToWordTone(wordToneMatch.Groups[1].Value); words[wordIndex].WordToneTag = content; } } else if (breakMatch.Success) { if (wordIndex >= 0) { // Upgrade one level for #1 for word break level. words[wordIndex].Break = (TtsBreak)(int.Parse(breakMatch.Groups[1].Value, CultureInfo.InvariantCulture) + 1); words[wordIndex].BreakTag = content; if (!string.IsNullOrEmpty(breakMatch.Groups[2].Value)) { words[wordIndex].WordTone = ScriptItem.LabelToWordTone(breakMatch.Groups[2].Value); words[wordIndex].WordToneTag = content; } } } else if (puncMatch.Success) { ScriptWord word = new ScriptWord(language); word.Grapheme = content; word.WordType = Localor.MapPunctuation(puncMatch.Groups[1].Value, PunctuationPattern); word.Break = Localor.MapWordType2Break(word.WordType); if (tagged) { word.PosTag = tokenMatch.Groups[3].Value; } words.Add(word); } else { ScriptWord word = new ScriptWord(language); word.Grapheme = content; if (tagged) { word.PosTag = tokenMatch.Groups[3].Value; } word.AccessingUnits += delegate { RefreshUnits(); }; words.Add(word); wordIndex = words.Count - 1; } return wordIndex; }
/// <summary> /// Get intonation phrase of the word. /// </summary> /// <param name="word">Script word.</param> /// <returns>Intonation phrase.</returns> public ScriptIntonationPhrase GetIntonationPhrase(ScriptWord word) { ScriptIntermediatePhrase intermediatePhrase = GetIntermediatePhrase(word); return intermediatePhrase == null ? null : intermediatePhrase.IntonationPhrase; }
/// <summary> /// Insert silence word to script. /// </summary> /// <param name="scriptSentence">Script sentence.</param> /// <param name="wordIndex">To be insert word's position.</param> /// <param name="phoneme">The phoneme string.</param> public static void InsertSilenceWord(ScriptSentence scriptSentence, int wordIndex, string phoneme) { Debug.Assert(Phoneme.IsSilenceFeature(phoneme), "The phoneme should have silence feature"); ScriptWord silenceWord = new ScriptWord(); silenceWord.WordType = WordType.Silence; silenceWord.Pronunciation = Phoneme.ToRuntime(phoneme); silenceWord.Sentence = scriptSentence; ScriptSyllable silenceSyllable = new ScriptSyllable(); silenceSyllable.Word = silenceWord; silenceWord.Syllables.Add(silenceSyllable); ScriptPhone silencePhone = new ScriptPhone(phoneme); silencePhone.Syllable = silenceSyllable; silenceWord.Syllables[0].Phones.Add(silencePhone); scriptSentence.Words.Insert(wordIndex, silenceWord); }
/// <summary> /// Get intermediate phrase. /// </summary> /// <param name="word">Script word.</param> /// <returns>Intermediate phrase.</returns> public ScriptIntermediatePhrase GetIntermediatePhrase(ScriptWord word) { ScriptIntermediatePhrase intermediatePhrase = null; foreach (ScriptIntonationPhrase phrase in IntonationPhrases) { intermediatePhrase = phrase.GetIntermediatePhrase(word); if (intermediatePhrase != null) { break; } } return intermediatePhrase; }
/// <summary> /// Appends a normal word in the end of given utterance. /// </summary> /// <param name="utterance"> /// The given utterance. /// </param> /// <param name="scriptWord"> /// The script word. /// </param> /// <returns> /// The phoneme count of the given word. /// </returns> /// <exception cref="InvalidDataException"> /// Exception. /// </exception> private int AppendNormalWord(TtsUtterance utterance, ScriptWord scriptWord) { TtsWord word = utterance.AppendNewWord(); word.LangId = (ushort)scriptWord.Language; word.BreakLevel = (TtsBreakLevel)scriptWord.Break; word.Emphasis = (TtsEmphasis)scriptWord.Emphasis; word.WordText = scriptWord.Grapheme; word.NETypeText = scriptWord.NETypeText; word.WordRegularText = scriptWord.RegularText; word.WordType = TtsWordType.WT_NORMAL; word.AcousticDomain = DomainExtension.MapToEnum(scriptWord.AcousticDomainTag); word.WordExpansion = scriptWord.Expansion; word.ReadablePronunciation = scriptWord.Pronunciation; if (!string.IsNullOrEmpty(scriptWord.Pronunciation)) { word.PhoneIds = Phoneme.PronunciationToPhoneIds(Pronunciation.RemoveUnitBoundary(scriptWord.Pronunciation)); } if (NeedPos) { // Checks pos. if (string.IsNullOrEmpty(scriptWord.PosString)) { throw new InvalidDataException( Helper.NeutralFormat("No POS found in sentence \"{0}\" for word \"{1}\"", scriptWord.Sentence.ScriptItem.Id, scriptWord.Grapheme)); } // Sets pos value. word.Pos = (ushort)PosSet.Items[scriptWord.PosString]; string taggingPos = PosSet.CategoryTaggingPOS[scriptWord.PosString]; word.POSTaggerPos = (ushort)PosSet.Items[taggingPos]; } // Gets the normal phoneme count. ErrorSet errorSet = new ErrorSet(); int count = scriptWord.GetNormalPhoneNames(PhoneSet, errorSet).Count; if (errorSet.Count > 0) { throw new InvalidDataException( Helper.NeutralFormat("Invalid phone found in sentence \"{0}\" for word \"{1}\"", scriptWord.Sentence.ScriptItem.Id, scriptWord.Grapheme)); } word.TextOffset = (uint)scriptWord.OffsetInString; word.TextLength = (uint)scriptWord.LengthInString; return count; }
/// <summary> /// Delete word from the sentence. /// For example: A, B, C, D, E. /// Current status: C, and D have been deleted.then word after word dict store: C->D, D->E. /// After deleting B, then deleted word after word will store: B->C, C->D, D->E. /// </summary> /// <param name="scriptWord">Word to be deleted.</param> /// <returns>Deleted word position.</returns> public int DeleteWord(ScriptWord scriptWord) { if (scriptWord == null) { throw new ArgumentNullException("scriptWord"); } int position = _words.IndexOf(scriptWord); if (position >= 0) { _words.Remove(scriptWord); _needBuildUnits = true; } return position; }
/// <summary> /// Generate script item from raw text(only generate to word level). /// </summary> /// <param name="text">Plain text.</param> /// <returns>ScriptItem.</returns> public ScriptItem GenerateScriptItem(string text) { if (string.IsNullOrEmpty(text)) { throw new ArgumentNullException("text"); } // this function should contain "ProcessMode.TextProcess" if ((_mode & ProcessMode.TextProcess) == 0) { throw new InvalidOperationException("Process mode can only be ProcessMode.TextProcess"); } ScriptItem item = new ScriptItem(); item.Text = text; foreach (SP.TtsUtterance utt in EspUtterances(text)) { using (utt) { if (utt.Words.Count == 0) { continue; } ScriptSentence sentence = new ScriptSentence(); foreach (SP.TtsWord word in utt.Words) { if (!string.IsNullOrEmpty(word.WordText)) { ScriptWord scriptWord = new ScriptWord(); scriptWord.Grapheme = word.WordText; if (!string.IsNullOrEmpty(word.Pronunciation)) { scriptWord.Pronunciation = word.Pronunciation.ToLowerInvariant(); } scriptWord.WordType = WordType.Normal; if (word.WordType == SP.TtsWordType.WT_PUNCTUATION) { scriptWord.WordType = WordType.Punctuation; } scriptWord.PronSource = (TtsPronSource)word.PronSource; sentence.Words.Add(scriptWord); } } sentence.Text = sentence.BuildTextFromWords(); item.Sentences.Add(sentence); } } return item; }
/// <summary> /// Insert word to the position. /// </summary> /// <param name="scriptWord">Word to be insert.</param> /// <param name="position">Position to be inserted.</param> public void InsertWord(ScriptWord scriptWord, int position) { if (scriptWord == null) { throw new ArgumentNullException("scriptWord"); } if (position < 0 || position > _words.Count) { throw new ArgumentException(Helper.NeutralFormat( "Invalid position {0}, should between 0 and {1}.", position, _words.Count)); } _words.Insert(position, scriptWord); scriptWord.Sentence = this; _needBuildUnits = true; }
/// <summary> /// Dump the data in the syllable. /// </summary> /// <param name="scriptWord">The script word to store the data dumped from the syllables.</param> /// <param name="utt">The utterance.</param> /// <param name="word">The word which contains the these syllables.</param> /// <param name="phoneIndex">Phone index to mark the phone in the Utt.Phones.</param> /// <param name="unitIndex">Unit index to mark the unit in the Utt.Units.</param> /// <param name="f0StartIndex">F0 index to mark the start position in the F0s.</param> /// <param name="ttsEngine">The object ttsEngine to help to convert the Pos and get sentence id.</param> private static void DumpSyllables(ScriptWord scriptWord, SP.TtsUtterance utt, SP.TtsWord word, ref int phoneIndex, ref int unitIndex, ref int f0StartIndex, SP.TtsEngine ttsEngine) { Debug.Assert(scriptWord != null, "ScriptWord should not be null"); Debug.Assert(utt != null, "Utt should not be null"); Debug.Assert(word != null, "Word should not be null"); Debug.Assert(phoneIndex >= 0, "PhoneIndex should not be less than 0"); Debug.Assert(f0StartIndex >= 0, "f0StartIndex should not be less than 0"); Debug.Assert(ttsEngine != null, "ttsEngine should not be null"); // Go through each syllable in the word. SP.TtsSyllable syllable = word.FirstSyllable; while (syllable != null) { ScriptSyllable scriptSyllable = new ScriptSyllable(); TtsTobiAccentSet tobiAccentSet = new TtsTobiAccentSet(); if (syllable.ToBIAccent != SP.TtsTobiAccent.K_NOACC) { scriptSyllable.TobiPitchAccent = TobiLabel.Create(tobiAccentSet.IdItems[(uint)syllable.ToBIAccent]); } scriptSyllable.Stress = (TtsStress)syllable.Stress; DumpPhones(scriptSyllable, utt, syllable, ref phoneIndex, ref unitIndex, ref f0StartIndex, ttsEngine); scriptWord.Syllables.Add(scriptSyllable); if (syllable == word.LastSyllable) { break; } syllable = syllable.Next; } }
/// <summary> /// Get pronunciation id string for letter domain. /// </summary> /// <param name="word">Given ScriptWord.</param> /// <returns>Pronunciation id string.</returns> private static string GetPhoneIds(ScriptWord word) { Phoneme phoneme = Localor.GetPhoneme(word.Language); string[] phones = word.Pronunciation.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); StringBuilder phoneIds = new StringBuilder(); foreach (string phone in phones) { if (phone == TtsUnit.UnitDelimiter) { continue; } if (phoneme.TtsPhoneIds.ContainsKey(phone)) { phoneIds.Append((char)phoneme.TtsPhoneIds[phone]); } } return phoneIds.ToString(); }