/// <summary> /// Parse XML document for Lexicon Schema File path. /// </summary> /// <param name="dom">XML configuration document.</param> /// <param name="nsmgr">Namespace.</param> private void ParseLexiconSchema(XmlDocument dom, XmlNamespaceManager nsmgr) { LexiconSchemaFile = ParseFilePath(dom, nsmgr, LexiconSchemaFileItem); if (!Helper.FileValidExists(LexiconSchemaFile)) { throw new FileNotFoundException( string.Format(CultureInfo.InvariantCulture, "Lexicon schema file \"{0}\" not found", LexiconSchemaFile)); } LexicalAttributeSchema attributeSchema = new LexicalAttributeSchema(FontLanguage); attributeSchema.Load(LexiconSchemaFile); attributeSchema.Validate(); if (attributeSchema.ErrorSet.Contains(ErrorSeverity.MustFix)) { attributeSchema.ErrorSet.Export(Console.Error); throw new InvalidDataException( string.Format(CultureInfo.InvariantCulture, "Please fix the error of lexicon schema file \"{0}\"", LexiconSchemaFile)); } PosSet = TtsPosSet.LoadFromSchema(LexiconSchemaFile); }
/// <summary> /// Save schema (with feature set and it's value group, mean, variance). /// </summary> /// <param name="language">The language.</param> /// <param name="schemaFile">The schema File.</param> /// <param name="phoneToIdIndexes">Phone To Id Indexes.</param> /// <param name="writer">Writer.</param> /// <param name="stringPool">String pool.</param> /// <returns>Size of bytes written out.</returns> public uint WriteSchema(Language language, string schemaFile, Dictionary<string, string> phoneToIdIndexes, DataWriter writer, StringPool stringPool) { Helper.ThrowIfFileNotExist(schemaFile); Helper.ThrowIfNull(phoneToIdIndexes); Helper.ThrowIfNull(writer); Helper.ThrowIfNull(stringPool); Helper.ThrowIfNull(language); uint size = 0; LexicalAttributeSchema schema = new LexicalAttributeSchema(language); schema.Load(schemaFile); List<string> stateFeatureList = new List<string>(); List<string> featureList = new List<string>(); int stateFeatureCount = 0; for (int i = 0; i < schema.Categories.Count; i++) { string name = schema.Categories[i].Name.ToLower(); if (name.IndexOf("state") >= 0) { stateFeatureCount++; if (!stateFeatureList.Contains(name)) { stateFeatureList.Add(name); } } if (!featureList.Contains(name)) { featureList.Add(name); } } // write state feature count. size += writer.Write((uint)stateFeatureList.Count); size += writer.Write((uint)stateFeatureCount); // write total feature count. size += writer.Write((uint)featureList.Count()); Dictionary<string, uint> featureIndex = new Dictionary<string, uint>(); uint index = 0; foreach (string feature in featureList) { size += writer.Write((uint)stringPool.Length); stringPool.PutString(feature); featureIndex.Add(feature, index++); } // write feature category size += writer.Write((uint)schema.Categories.Count); for (int i = 0; i < schema.Categories.Count; i++) { string featureName = schema.Categories[i].Name.ToLower(); // feature index size += writer.Write((uint)featureIndex[featureName]); // mean size += writer.Write(schema.Categories[i].Mean); // invStdDev size += writer.Write(schema.Categories[i].InvStdDev); // value count size += writer.Write((uint)schema.Categories[i].Values.Count); for (int k = 0; k < schema.Categories[i].Values.Count; k++) { string valueName = schema.Categories[i].Values[k].Name.ToLower(); string id = string.Empty; if (phoneToIdIndexes.ContainsKey(valueName) && featureName.IndexOf("phoneidentity") >= 0) { id = phoneToIdIndexes[valueName]; } else { id = valueName; } try { size += writer.Write(uint.Parse(id)); } catch (System.FormatException) { continue; } } } Debug.Assert(size % sizeof(uint) == 0, "Data must be 4-byte aligned."); return size; }
/// <summary> /// Validate language data files. /// </summary> /// <param name="language">Language of the data files.</param> /// <returns>Error set.</returns> public ErrorSet ValidateLanguageData(Language language) { ErrorSet errorSet = new ErrorSet(); if (!IsEmpty()) { if (!string.IsNullOrEmpty(_phoneSet)) { TtsPhoneSet ttsPhoneSet = new TtsPhoneSet(); ttsPhoneSet.Load(PhoneSet); if (ttsPhoneSet.Language != language) { errorSet.Add(new Error(VoiceCreationLanguageDataError.MismatchLanguage, Localor.LanguageToString(language), Localor.LanguageToString(ttsPhoneSet.Language), Localor.PhoneSetFileName, PhoneSet)); } } if (!string.IsNullOrEmpty(_unitTable)) { SliceData sliceData = new SliceData(); sliceData.Language = language; sliceData.Load(UnitTable); if (sliceData.IsEmpty()) { errorSet.Add(new Error(VoiceCreationLanguageDataError.EmptyLanguageDataFile, Localor.LanguageToString(language), Localor.UnitTableFileName, UnitTable)); } } if (!string.IsNullOrEmpty(_lexicalAttributeSchema)) { LexicalAttributeSchema lexicalAttributeSchema = new LexicalAttributeSchema(); lexicalAttributeSchema.Load(LexicalAttributeSchema); if (lexicalAttributeSchema.Language != language) { errorSet.Add(new Error(VoiceCreationLanguageDataError.MismatchLanguage, Localor.LanguageToString(language), Localor.LanguageToString(lexicalAttributeSchema.Language), Localor.PhoneSetFileName, LexicalAttributeSchema)); } } if (!string.IsNullOrEmpty(_truncateRule)) { TruncateRuleData truncateRuleData = new TruncateRuleData(); truncateRuleData.Load(TruncateRule); if (truncateRuleData.Language != language) { errorSet.Add(new Error(VoiceCreationLanguageDataError.MismatchLanguage, Localor.LanguageToString(language), Localor.LanguageToString(truncateRuleData.Language), Localor.TruncateRulesFileName, TruncateRule)); } } if (!string.IsNullOrEmpty(_ttsToSapiVisemeId)) { PhoneMap phoneMap = PhoneMap.CreatePhoneMap(TtsToSapiVisemeId); if (phoneMap.Language != language) { errorSet.Add(new Error(VoiceCreationLanguageDataError.MismatchLanguage, Localor.LanguageToString(language), Localor.LanguageToString(phoneMap.Language), Localor.TtsToSapiVisemeIdFileName, TtsToSapiVisemeId)); } } if (!string.IsNullOrEmpty(_ttsToSrPhone)) { PhoneMap phoneMap = PhoneMap.CreatePhoneMap(TtsToSrPhone); if (phoneMap.Language != language) { errorSet.Add(new Error(VoiceCreationLanguageDataError.MismatchLanguage, Localor.LanguageToString(language), Localor.LanguageToString(phoneMap.Language), Localor.TtsToSrPhoneFileName, TtsToSrPhone)); } } if (!string.IsNullOrEmpty(_ttsToIpaPhone)) { PhoneMap phoneMap = PhoneMap.CreatePhoneMap(TtsToIpaPhone); if (phoneMap.Language != language) { errorSet.Add(new Error(VoiceCreationLanguageDataError.MismatchLanguage, Localor.LanguageToString(language), Localor.LanguageToString(phoneMap.Language), Localor.TtsToIpaPhoneFileName, TtsToIpaPhone)); } } if (!string.IsNullOrEmpty(_fontMeta)) { PhoneMap phoneMap = PhoneMap.CreatePhoneMap(FontMeta); if (phoneMap.Language != language) { errorSet.Add(new Error(VoiceCreationLanguageDataError.MismatchLanguage, Localor.LanguageToString(language), Localor.LanguageToString(phoneMap.Language), Localor.FontMetaFileName, FontMeta)); } } } else { Trace.WriteLine("Using stocked language data with tools..."); } return errorSet; }
/// <summary> /// Load Lexicon Attribute Schema Data object. /// </summary> /// <param name="errorSet">ErrorSet.</param> /// <returns>Lexicon Attribute Schema Data object.</returns> internal override object LoadDataObject(ErrorSet errorSet) { if (errorSet == null) { throw new ArgumentNullException("errorSet"); } LexicalAttributeSchema schema = new LexicalAttributeSchema(); schema.Load(this.Path); schema.Validate(); errorSet.Merge(schema.ErrorSet); if (schema.ErrorSet.Contains(ErrorSeverity.MustFix)) { schema = null; } return schema; }
/// <summary> /// Get Lexicon specific language. /// </summary> /// <param name="language">The language.</param> /// <returns>The lexical attribute schema.</returns> public static LexicalAttributeSchema GetLexicalAttributeSchema(Language language) { LexicalAttributeSchema schema = null; if (_ttsLexicalAttributeSchemaMap.ContainsKey(language)) { schema = _ttsLexicalAttributeSchemaMap[language]; } else { using (StreamReader reader = Localor.LoadResource(language, Localor.LexicalAttributeSchemaFileName)) { if (reader != null) { schema = new LexicalAttributeSchema(language); schema.Load(reader); _ttsLexicalAttributeSchemaMap[language] = schema; } } } return schema; }