コード例 #1
0
        /// <summary>
        /// Get the normal phones' names.
        /// </summary>
        /// <param name="phoneSet">Phone set.</param>
        /// <param name="errors">Errors is having.</param>
        /// <returns>The pohne names.</returns>
        public Collection<string> GetNormalPhoneNames(TtsPhoneSet phoneSet, ErrorSet errors)
        {
            if (phoneSet == null)
            {
                throw new ArgumentNullException("phoneSet");
            }

            if (errors == null)
            {
                throw new ArgumentNullException("errors");
            }

            errors.Clear();
            Collection<string> names = new Collection<string>();
            foreach (ScriptSentence sentence in Sentences)
            {
                ErrorSet sentenceErrors = new ErrorSet();
                foreach (string name in sentence.GetNormalPhoneNames(phoneSet, sentenceErrors))
                {
                    names.Add(name);
                }

                errors.Merge(sentenceErrors);
            }

            return names;
        }
コード例 #2
0
        /// <summary>
        /// Load.
        /// </summary>
        /// <param name="filePath">FilePath.</param>
        /// <param name="phoneSet">PhoneSet.</param>
        /// <returns>ErrorSet.</returns>
        public ErrorSet Load(string filePath, TtsPhoneSet phoneSet)
        {
            // This validation is needed by Fxcop checking parameters.
            if (phoneSet == null)
            {
                phoneSet = null;
            }

            if (string.IsNullOrEmpty(filePath))
            {
                throw new ArgumentNullException("filePath");
            }

            if (!File.Exists(filePath))
            {
                throw Helper.CreateException(typeof(FileNotFoundException), filePath);
            }

            if (!Helper.IsUnicodeFile(filePath))
            {
                throw new InvalidDataException(Helper.NeutralFormat(
                    "Polyphony rule file [{0}] is not unicode.", filePath));
            }

            ErrorSet errorSet = new ErrorSet();
            _keyTypes.Clear();
            bool finishReadHead = false;
            bool firstKeyString = true;
            PolyphonyRule polyphonyWord = null;

            int lineNum = 0;
            string domain = DomainItem.GeneralDomain;
            foreach (string line in Helper.FileLines(filePath, Encoding.Unicode, false))
            {
                lineNum++;
                string trimedLine = line.Trim();
                if (string.IsNullOrEmpty(trimedLine))
                {
                    continue;
                }

                if (IsComment(trimedLine))
                {
                    continue;
                }

                if (IsDomainTag(trimedLine))
                {
                    ParseDomainKey(trimedLine, ref domain);
                    continue;
                }

                ErrorSet parseErrorSet = new ErrorSet();
                if (!finishReadHead)
                {
                    bool isKeyDeclear = TryParseKeyDeclear(trimedLine,
                        ref firstKeyString, parseErrorSet);
                    AddParseError(errorSet, lineNum, parseErrorSet);
                    if (isKeyDeclear)
                    {
                        continue;
                    }
                    else
                    {
                        finishReadHead = true;
                    }
                }

                PolyruleKeys.Instance.KeyTypes = _keyTypes;

                parseErrorSet.Clear();
                bool isKeyLine = TryParseKeyLine(trimedLine,
                    ref polyphonyWord, parseErrorSet, domain);

                domain = DomainItem.GeneralDomain;
                AddParseError(errorSet, lineNum, parseErrorSet);
                if (isKeyLine)
                {
                    continue;
                }

                parseErrorSet.Clear();
                bool isConditionLine = TryParseConditionLine(trimedLine, phoneSet,
                    polyphonyWord, parseErrorSet);
                AddParseError(errorSet, lineNum, parseErrorSet);
                if (isConditionLine)
                {
                    continue;
                }

                errorSet.Add(PolyRuleError.InvalidLineFormat,
                    lineNum.ToString(CultureInfo.InvariantCulture), trimedLine);
            }

            if (polyphonyWord != null)
            {
                _polyphonyWords.Add(polyphonyWord);
            }

            if (string.IsNullOrEmpty(_keyString))
            {
                errorSet.Add(PolyRuleError.MissPrimaryKey,
                    filePath);
            }

            errorSet.AddRange(CheckDupWordDefinitions());

            foreach (PolyphonyRule rule in _polyphonyWords)
            {
                errorSet.AddRange(rule.CheckDupRuleConditions());
            }

            return errorSet;
        }
コード例 #3
0
        /// <summary>
        /// Check whether a script item is valid
        /// We don't check schema here
        /// Validation conditions: 
        /// 1. Normal word should have pronunciation 
        /// 2. Pronunciation should be good
        /// 3. POS should be in POS set
        /// We could use some flag to control the validation conditions
        /// When we need flexible control.
        /// </summary>
        /// <param name="item">The item to be checked.</param>
        /// <param name="errors">Errors if item is invalid.</param>
        /// <param name="validateSetting">Validation data set.</param>
        /// <returns>True is valid.</returns>
        public static bool IsValidItem(ScriptItem item, ErrorSet errors, XmlScriptValidateSetting validateSetting)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            if (errors == null)
            {
                throw new ArgumentNullException("errors");
            }

            if (validateSetting == null)
            {
                throw new ArgumentNullException("validateSetting");
            }

            validateSetting.VerifySetting();

            XmlScriptValidationScope scope = validateSetting.ValidationScope;

            bool valid = true;
            errors.Clear();

            int sentIndex = 0;
            foreach (ScriptSentence sentence in item.Sentences)
            {
                int wordIndex = 0;
                foreach (ScriptWord word in sentence.Words)
                {
                    if ((scope & XmlScriptValidationScope.Pronunciation) == XmlScriptValidationScope.Pronunciation)
                    {
                        // check pronunciation
                        string pron = null;
                        if (word.WordType == WordType.Normal)
                        {
                            pron = word.GetPronunciation(validateSetting.PhoneSet);
                        }

                        if (!string.IsNullOrEmpty(pron))
                        {
                            ErrorSet pronErrors = Core.Pronunciation.Validate(pron, validateSetting.PhoneSet);
                            foreach (Error error in pronErrors.Errors)
                            {
                                errors.Add(ScriptError.PronunciationError, error, item.Id, word.Grapheme);
                            }
                        }
                        else if (word.WordType == WordType.Normal)
                        {
                            // Pronunciation is optional for normal word, will give warning if empty pronunciation for normal word.
                            errors.Add(ScriptError.EmptyPronInNormalWord, item.Id, word.Grapheme);
                        }
                    }

                    if ((scope & XmlScriptValidationScope.POS) == XmlScriptValidationScope.POS)
                    {
                        // check pos name
                        if (!string.IsNullOrEmpty(word.PosString) &&
                            !validateSetting.PosSet.Items.ContainsKey(word.PosString))
                        {
                            errors.Add(ScriptError.UnrecognizedPos, item.Id, word.Grapheme,
                                word.Pronunciation, word.PosString);
                        }
                    }

                    string nodePath = string.Format(CultureInfo.InvariantCulture, "Sentence[{0}].Word[{1}]",
                        sentIndex, wordIndex);
                    word.IsValid(item.Id, nodePath, scope, errors);

                    wordIndex++;
                }

                sentIndex++;
            }

            if ((scope & XmlScriptValidationScope.SegmentSequence) == XmlScriptValidationScope.SegmentSequence)
            {
                CheckSegments(item, errors);
            }

            if (errors.Count > 0)
            {
                valid = false;
            }

            return valid;
        }
コード例 #4
0
        /// <summary>
        /// Get the Phones of this item.
        /// </summary>
        /// <param name="phoneSet">Phone set.</param>
        /// <param name="errors">Errors if having invalid phone.</param>
        /// <returns>The phones.</returns>
        public Collection<Phone> GetPhones(TtsPhoneSet phoneSet, ErrorSet errors)
        {
            if (phoneSet == null)
            {
                throw new ArgumentNullException("phoneSet");
            }

            if (errors == null)
            {
                throw new ArgumentNullException("errors");
            }

            errors.Clear();
            Collection<Phone> phones = new Collection<Phone>();
            foreach (ScriptSentence sentence in Sentences)
            {
                ErrorSet sentenceErrors = new ErrorSet();
                foreach (Phone phone in sentence.GetPhones(phoneSet, sentenceErrors))
                {
                    phones.Add(phone);
                }

                errors.Merge(sentenceErrors);
            }

            return phones;
        }
コード例 #5
0
        /// <summary>
        /// Get the Phones of this sentence.
        /// </summary>
        /// <param name="phoneSet">Phone set.</param>
        /// <param name="errors">Errors if having invalid phone.</param>
        /// <returns>The phones.</returns>
        public Collection<Phone> GetPhones(TtsPhoneSet phoneSet, ErrorSet errors)
        {
            if (phoneSet == null)
            {
                throw new ArgumentNullException("phoneSet");
            }

            if (errors == null)
            {
                throw new ArgumentNullException("errors");
            }

            errors.Clear();
            Collection<Phone> phones = new Collection<Phone>();
            foreach (ScriptWord word in Words)
            {
                ErrorSet wordErrors = new ErrorSet();
                foreach (Phone phone in word.GetPhones(phoneSet, wordErrors))
                {
                    phones.Add(phone);
                }

                errors.Merge(wordErrors);
            }

            return phones;
        }
コード例 #6
0
        /// <summary>
        /// Get the normal phones' names.
        /// </summary>
        /// <param name="phoneSet">Phone set.</param>
        /// <param name="errors">Errors is having.</param>
        /// <returns>The pohne names.</returns>
        public Collection<string> GetNormalPhoneNames(TtsPhoneSet phoneSet, ErrorSet errors)
        {
            if (phoneSet == null)
            {
                throw new ArgumentNullException("phoneSet");
            }

            if (errors == null)
            {
                throw new ArgumentNullException("errors");
            }

            errors.Clear();
            Collection<Phone> phones = GetPhones(phoneSet, errors);
            Collection<string> names = new Collection<string>();
            if (errors.Count == 0)
            {
                foreach (Phone phone in phones)
                {
                    if (phone.IsNormal)
                    {
                        names.Add(phone.Name);
                    }
                }
            }

            return names;
        }
コード例 #7
0
        /// <summary>
        /// Get the Phones of this word.
        /// </summary>
        /// <param name="phoneSet">Phone set.</param>
        /// <param name="errors">Errors if having invalid phone.</param>
        /// <returns>The phones.</returns>
        public Collection<Phone> GetPhones(TtsPhoneSet phoneSet, ErrorSet errors)
        {
            if (phoneSet == null)
            {
                throw new ArgumentNullException("phoneSet");
            }

            if (errors == null)
            {
                throw new ArgumentNullException("errors");
            }

            errors.Clear();
            string pronunciation = GetPronunciation(phoneSet);
            Collection<Phone> phoneColl = new Collection<Phone>();

            // Note: for punctucations should return empty phone collection
            if (WordType == WordType.Normal)
            {
                Phone[] phones = Core.Pronunciation.SplitIntoPhones(pronunciation, phoneSet, errors);
                if (phones != null)
                {
                    phoneColl = new Collection<Phone>(phones);
                }
            }

            return phoneColl;
        }
コード例 #8
0
        /// <summary>
        /// Add one item to script file.
        /// This method will check whether the item is balid before adding.
        /// </summary>
        /// <param name="item">The item to be added.</param>
        /// <param name="errors">The errors if failed to add.</param>
        /// <param name="validate">Whether validate schema and content.</param>
        /// <param name="sort">Whether insert the script item in the sort position.</param>
        /// <returns>True if successfully added.</returns>
        public bool Add(ScriptItem item, ErrorSet errors, bool validate, bool sort)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            if (errors == null)
            {
                throw new ArgumentNullException("errors");
            }

            // check schema, should throw exception if invalid
            CheckSchema(item);

            bool added = true;
            errors.Clear();

            // content checking, should add to errors if invalid
            if (_itemDic.ContainsKey(item.Id))
            {
                errors.Add(ScriptError.DuplicateItemId, item.Id);
            }

            if (validate)
            {
                ErrorSet contentErrors = new ErrorSet();
                XmlScriptValidateSetting validateSetting = new XmlScriptValidateSetting(PhoneSet, PosSet);
                ScriptItem.IsValidItem(item, contentErrors, validateSetting);
                errors.Merge(contentErrors);
            }

            if (errors.Count > 0)
            {
                added = false;
            }

            if (added)
            {
                _itemDic.Add(item.Id, item);
                if (sort)
                {
                    bool inserted = false;
                    for (int i = 0; i < _items.Count; i++)
                    {
                        if (string.Compare(item.Id, _items[i].Id, StringComparison.OrdinalIgnoreCase) < 0)
                        {
                            _items.Insert(i, item);
                            inserted = true;
                            break;
                        }
                    }

                    if (!inserted)
                    {
                        _items.Add(item);
                    }
                }
                else
                {
                    _items.Add(item);
                }
            }

            return added;
        }
コード例 #9
0
        private ErrorSet CompileLexicon(Stream outputStream)
        {
            if (outputStream == null)
            {
                throw new ArgumentNullException("outputStream");
            }

            ErrorSet errorSet = new ErrorSet();

            ErrorSet subErrorSet = new ErrorSet();
            LexicalAttributeSchema schema = (LexicalAttributeSchema)GetObject(
                RawDataName.LexicalAttributeSchema, subErrorSet);
            MergeDependencyError(errorSet, subErrorSet, _schemaFullName);

            subErrorSet.Clear();
            TtsPhoneSet phoneSet = (TtsPhoneSet)GetObject(RawDataName.PhoneSet, subErrorSet);
            MergeDependencyError(errorSet, subErrorSet, RawDataName.PhoneSet);

            if (!errorSet.Contains(ErrorSeverity.MustFix))
            {
                Microsoft.Tts.Offline.Core.Lexicon lexicon = (Microsoft.Tts.Offline.Core.Lexicon)GetObject(RawDataName.Lexicon, errorSet);
                errorSet.Merge(lexicon.ErrorSet);

                // Change to case insensitive lexicon
                MemoryStream lexiconStream = new MemoryStream();
                using (XmlWriter xmlWriter = XmlWriter.Create(lexiconStream))
                {
                    Microsoft.Tts.Offline.Core.Lexicon.ContentControler lexiconControler = 
                        new Microsoft.Tts.Offline.Core.Lexicon.ContentControler();
                    lexiconControler.IsCaseSensitive = true;
                    lexicon.Save(xmlWriter, lexiconControler);
                }

                lexiconStream.Seek(0, SeekOrigin.Begin);
                Microsoft.Tts.Offline.Core.Lexicon caseInsensitiveLexicon = new Microsoft.Tts.Offline.Core.Lexicon();
                using (StreamReader sr = new StreamReader(lexiconStream))
                {
                    caseInsensitiveLexicon.Load(sr);
                }

                if (caseInsensitiveLexicon != null && !errorSet.Contains(ErrorSeverity.MustFix))
                {
                    caseInsensitiveLexicon.LexicalAttributeSchema = schema;

                    caseInsensitiveLexicon.PhoneSet = phoneSet;
                    caseInsensitiveLexicon.Validate();

                    // Set severity of errors only in case-insensitive lexicon to NoError for they're not treated as real error
                    caseInsensitiveLexicon.ErrorSet.SetSeverity(ErrorSeverity.NoError);

                    string vendorLexiconPath = Helper.GetTempFileName();

                    caseInsensitiveLexicon.SaveToVendorLexicon(vendorLexiconPath);

                    string toolFileName = ToolName.BldVendor2;
                    string binaryLexiconPath = Helper.GetTempFileName();

                    string compilingArguments = Helper.NeutralFormat("-v {0} V2 \"{1}\" \"{2}\" \"{3}\" TTS",
                        (int)_language, _dataHandlerList.Datas[RawDataName.LexicalAttributeSchema].Path,
                        vendorLexiconPath, binaryLexiconPath);
                    string toolPath = Path.Combine(ToolDir, toolFileName);

                    CheckToolExists(toolPath, errorSet);
                    if (!errorSet.Contains(ErrorSeverity.MustFix))
                    {
                        HandleCommandLine(ModuleDataName.Lexicon, toolPath, compilingArguments,
                            binaryLexiconPath, outputStream, errorSet);
                    }

                    File.Delete(vendorLexiconPath);

                    errorSet.Merge(caseInsensitiveLexicon.ErrorSet);
                }
                else if (lexicon == null)
                {
                    errorSet.Add(DataCompilerError.RawDataError, "Lexicon");
                }
                else
                {
                    errorSet.Merge(caseInsensitiveLexicon.ErrorSet);
                }
            }

            return errorSet;
        }