/// <summary>
        /// Do F0 update if given external F0s.
        /// </summary>
        /// <param name="intUtt">Internal utterance.</param>
        /// <param name="extSentence">External script sentence.</param>
        private void F0Update(SP.TtsUtterance intUtt, ScriptSentence extSentence)
        {
            int normalWordIndex = 0;
            TraceLog(_logger, true, "Updated F0 Position (Indicated by normal words index):");

            foreach (ScriptWord extWord in extSentence.PronouncedWords)
            {
                int syllableIndex = 0;
                IUpdateHelper f0Updater;
                foreach (ScriptSyllable extSyllable in extWord.Syllables)
                {
                    int phoneIndex = 0;
                    f0Updater = new SyllableUpdateHelper();
                    ProcessF0Update(f0Updater, intUtt, extSyllable, phoneIndex,
                        syllableIndex, normalWordIndex);

                    foreach (ScriptPhone extPhone in extSyllable.Phones)
                    {
                        f0Updater = new PhoneUpdateHelper();
                        ProcessF0Update(f0Updater, intUtt, extPhone, phoneIndex,
                            syllableIndex, normalWordIndex);

                        phoneIndex++;
                    }

                    syllableIndex++;
                }

                normalWordIndex++;
            }

            if (_config.FixF0NoConsistenceNum > 0)
            {
                FixF0NoConsistence(intUtt);
            }

            TraceLogLine(_logger);
        }
        /// <summary>
        /// Do duration update if given a external duration.
        /// </summary>
        /// <param name="intUtt">Internal utterance.</param>
        /// <param name="extSentence">External script sentence.</param>
        private void DurationUpdate(SP.TtsUtterance intUtt, ScriptSentence extSentence)
        {
            // The length of each frame in millisecond.
            float frameLength = _serviceProvider.Engine.Config.SamplesPerFrame * 1000 /
                (float)_serviceProvider.Engine.Config.SamplesPerSecond;

            int normalWordIndex = 0;
            IUpdateHelper durationUpdater;
            TraceLog(_logger, true, "Updated Duration Position (Indicated by normal words index):");
            for (int wordIndex = 0; wordIndex < extSentence.Words.Count; wordIndex++)
            {
                ScriptWord scriptThisWord = extSentence.Words[wordIndex];
                if (scriptThisWord.IsPronounced)
                {
                    if (_config.UpdateNormalWordDuration)
                    {
                        int syllableIndex = 0;

                        foreach (ScriptSyllable extSyllable in scriptThisWord.Syllables)
                        {
                            int phoneIndex = 0;
                            durationUpdater = new SyllableUpdateHelper();
                            ProcessDurationUpdate(durationUpdater, intUtt, extSyllable,
                                0, phoneIndex, syllableIndex, normalWordIndex, frameLength);

                            foreach (ScriptPhone extPhone in extSyllable.Phones)
                            {
                                durationUpdater = new PhoneUpdateHelper();
                                ProcessDurationUpdate(durationUpdater, intUtt, extPhone,
                                    0, phoneIndex, syllableIndex, normalWordIndex, frameLength);

                                durationUpdater = new StateUpdateHelper();
                                UpdateStateDuration(durationUpdater, intUtt, extPhone,
                                    phoneIndex, syllableIndex, normalWordIndex, frameLength);
                                phoneIndex++;
                            }

                            syllableIndex++;
                        }
                    }

                    normalWordIndex++;
                }
                else if (scriptThisWord.WordType == WordType.Silence && _config.UpdateScriptSilenceDuration)
                {
                    durationUpdater = new SilenceUpdateHelper();
                    ProcessDurationUpdate(durationUpdater, intUtt, scriptThisWord.Syllables[0],
                        NotUpdateState, 0, 0, normalWordIndex - 1, frameLength);

                    ProcessDurationUpdate(durationUpdater, intUtt, scriptThisWord.Syllables[0].Phones[0],
                        NotUpdateState, 0, 0, normalWordIndex - 1, frameLength);

                    UpdateStateDuration(durationUpdater, intUtt, scriptThisWord.Syllables[0].Phones[0],
                        0, 0, normalWordIndex - 1, frameLength);
                }
            }

            TraceLogLine(_logger);
        }