/// <summary> /// Create domain index file. /// </summary> /// <param name="scriptFile">Script file.</param> /// <param name="domainList">Domain list.</param> /// <param name="uif">Name indexed unit features.</param> public void Create(XmlScriptFile scriptFile, DomainConfigList domainList, UnitIndexingFile uif) { // Parameters Validation if (scriptFile == null) { throw new ArgumentNullException("scriptFile"); } if (domainList == null) { throw new ArgumentNullException("domainList"); } if (uif == null) { throw new ArgumentNullException("uif"); } Dictionary<string, DomainIndexItem> items = new Dictionary<string, DomainIndexItem>(StringComparer.Ordinal); _language = scriptFile.Language; _tag = domainList.FontTag; Phoneme phoneme = Localor.GetPhoneme(_language); SliceData sliceData = Localor.GetSliceData(_language); foreach (ScriptItem scriptItem in scriptFile.Items) { if (!domainList.Contains(scriptItem.Id)) { continue; } Collection<TtsUnit> itemUnits = scriptItem.GetUnits(phoneme, sliceData); Collection<ScriptWord> allPronouncedNormalWords = scriptItem.AllPronouncedNormalWords; for (int i = 0; i < allPronouncedNormalWords.Count; i++) { ScriptWord word = allPronouncedNormalWords[i]; string text; if (domainList.Domain == ScriptDomain.Number) { text = GetNumberDomainWordText(word, scriptItem.Id, i, (domainList as NumberDomainConfigList).Digitals); } else if (domainList.Domain == ScriptDomain.Acronym) { text = GetAcronymDomainWordText(word, scriptItem.Id, i, (domainList as AcronymDomainConfigList).Acronyms); } else if (domainList.Domain == ScriptDomain.Letter) { // Use pronunciation phone ids as key text = GetPhoneIds(word); } else { text = word.Grapheme.ToUpperInvariant(); } if (items.ContainsKey(text) && domainList.Domain != ScriptDomain.Letter) { // Skip duplicate word, except Letter domain continue; } DomainIndexItem item = null; if (!items.ContainsKey(text)) { item = new DomainIndexItem(); item.Word = text; } else { item = items[text]; } bool skipped = false; Collection<TtsUnit> wordUnits = word.GetUnits(phoneme, sliceData); for (int wordUnitIndex = 0; wordUnitIndex < wordUnits.Count; wordUnitIndex++) { TtsUnit unit = wordUnits[wordUnitIndex]; FeatureDataItem featureItem = new FeatureDataItem(); int indexOfNonSilence = itemUnits.IndexOf(unit); Debug.Assert(indexOfNonSilence >= 0 && indexOfNonSilence < itemUnits.Count); int unitOffset = uif.SearchCandidateOffset(unit.MetaUnit.Name, scriptItem.Id, (uint)indexOfNonSilence); if (unitOffset == -1) { // Skip this word skipped = true; break; } if (item.FeatureItems.Count == wordUnitIndex) { featureItem.UnitIndexes.Add(unitOffset); item.FeatureItems.Add(featureItem); // [].UnitIndexes.Add(unitOffset); } else { item.FeatureItems[wordUnitIndex].UnitIndexes.Add(unitOffset); } } if (!skipped && !items.ContainsKey(item.Word)) { items.Add(item.Word, item); } } } _items = BuildHashTable(items.Values); }
/// <summary> /// Load feature data. /// </summary> /// <param name="data">Feature data bytes.</param> /// <param name="offset">Start offset in feature data chunck.</param> public void LoadFeatureData(byte[] data, int offset) { if (data == null) { throw new ArgumentNullException("data"); } uint count = BitConverter.ToUInt32(data, offset); checked { offset += sizeof(uint); } for (int i = 0; i < count; i++) { FeatureDataItem item = new FeatureDataItem(); // Number of Unit Indexes ushort unitCount = BitConverter.ToUInt16(data, offset); checked { offset += sizeof(ushort); } // UnitIndexes (uint) item.UnitIndexes.Clear(); for (ushort unitIndex = 0; unitIndex < unitCount; unitIndex++) { int index = BitConverter.ToInt32(data, offset); item.UnitIndexes.Add(index); checked { offset += sizeof(int); } } _featureItems.Add(item); } }