/// <summary>
        /// Aoustic processing event handler.
        /// Do duration and F0 update after the right sub-level of acoustic prosody tagger.
        /// </summary>
        /// <param name="sender">Sender of the event handler.</param>
        /// <param name="e">Event argument object.</param>
        private void OnAcousticProcessed(object sender, TtsModuleEventArgs e)
        {
            if (e.ModuleType == TtsModuleType.TM_APT_DURATION && _sentenceMatch)
            {
                if (_config.UpdateNormalWordDuration || _config.UpdateF0 ||
                    _config.UpdateScriptSilenceDuration)
                {
                    try
                    {
                        GetPhonePosi(e.Utterance);

                        if (_config.UpdateNormalWordDuration || _config.UpdateF0)
                        {
                            CheckMatched(_curScriptSentence);
                        }

                        if (_config.UpdateNormalWordDuration || _config.UpdateScriptSilenceDuration)
                        {
                            DurationUpdate(e.Utterance, _curScriptSentence);
                        }

                        e.Utterance.Acoustic.RefreshFrameCount();
                    }
                    catch (InvalidDataException exception)
                    {
                        HandleException(exception);
                    }
                }
            }

            if (e.ModuleType == TtsModuleType.TM_APT_F0 && _sentenceMatch && _config.UpdateF0)
            {
                try
                {
                    F0Update(e.Utterance, _curScriptSentence);
                }
                catch (InvalidDataException exception)
                {
                    HandleException(exception);
                }
            }
        }
 /// <summary>
 /// Aoustic processing event handler.
 /// Call process of utterance extenders to process the utterance.
 /// </summary>
 /// <param name="sender">Sender of the event handler.</param>
 /// <param name="e">Event argument object.</param>
 private void OnAcousticProcessing(object sender, TtsModuleEventArgs e)
 {
     if (e.ModuleType == TtsModuleType.TM_APT_MODEL_FINDER)
     {
         foreach (IUtteranceExtender extender in _utteranceExtenders)
         {
             extender.Process(e.Utterance, _curScriptItem);
         }
     }
 }
 /// <summary>
 /// Service provider processed event handler.
 /// Do updates after the right process if necessary.
 /// </summary>
 /// <param name="sender">Sender of the event handler.</param>
 /// <param name="e">Event argument object.</param>
 private void OnProcessed(object sender, TtsModuleEventArgs e)
 {
     if (_sentenceMatch)
     {
         try
         {
             if (e.ModuleType == TtsModuleType.TM_UNIT_GENERATION)
             {
                 if (_config.UpdateToBIAccent)
                 {
                     UpdateToBIAccent(e.Utterance, _curScriptSentence);
                 }
             }
         }
         catch (InvalidDataException exception)
         {
             HandleException(exception);
         }
     }
 }
        /// <summary>
        /// Linguistic processing event handler.
        /// Do break, emphasis, boundary tone update after the right sub-level of acoustic prosody tagger.
        /// </summary>
        /// <param name="sender">Sender of the event handler.</param>
        /// <param name="e">Event argument object.</param>
        private void OnLinguisticProcessed(object sender, TtsModuleEventArgs e)
        {
            if (_sentenceMatch)
            {
                try
                {
                    if (e.ModuleType == SP.TtsModuleType.TM_LPT_BREAK)
                    {
                        if (_config.UpdateBreakLevel)
                        {
                            UpdateBreak(e.Utterance, _curScriptSentence);
                        }

                        if (_config.UpdateSilenceWord)
                        {
                            UpdateSilenceWords(e.Utterance, _curScriptSentence, _serviceProvider.Engine, _logger);
                        }
                    }

                    if (e.ModuleType == SP.TtsModuleType.TM_LPT_EMPHASIS)
                    {
                        if (_config.UpdateEmphasis)
                        {
                            UpdateEmphasis(e.Utterance, _curScriptSentence);
                        }
                    }

                    if (e.ModuleType == SP.TtsModuleType.TM_LPT_BOUNDARY_TONE)
                    {
                        if (_config.UpdateBoundaryTone)
                        {
                            UpdateBoundaryTone(e.Utterance, _curScriptSentence);
                        }
                    }
                }
                catch (InvalidDataException exception)
                {
                    HandleException(exception);
                }
            }
        }
 /// <summary>
 /// Service provider processing event handler.
 /// Do word update before linguist prosody tagger if necessary.
 /// </summary>
 /// <param name="sender">Sender of the event handler.</param>
 /// <param name="e">Event argument object.</param>
 private void OnLinguisticProcessing(object sender, TtsModuleEventArgs e)
 {
     if (e.ModuleType == TtsModuleType.TM_LPT_BREAK)
     {
         try
         {
             CheckConsistency(e.Utterance, _curScriptSentence, _config.ConsistencyCheckOption);
             _sentenceMatch = true;
             UpdateWords(e.Utterance, _curScriptSentence, _serviceProvider.Engine);
         }
         catch (InvalidDataException exception)
         {
             HandleException(exception);
         }
     }
 }
        /// <summary>
        /// Aoustic processed event handler for the receiver.
        /// Apply stored duration and/or f0 to receiver.
        /// </summary>
        /// <param name="sender">Sender of the event handler.</param>
        /// <param name="e">Event argument object.</param>
        private void OnReceiverAcousticProcessed(object sender, TtsModuleEventArgs e)
        {
            if (e.ModuleType == TtsModuleType.TM_APT_DURATION &&
                _config.DonateDuration)
            {
                if (!e.Utterance.Acoustic.Durations.DimensionIsMatched(_donatorDuration))
                {
                    ErrorLog("Number of phones don't match!");
                }
                else
                {
                    e.Utterance.Acoustic.Durations.CopyFrom(_donatorDuration);
                    e.Utterance.Acoustic.RefreshFrameCount();
                }
            }

            if (e.ModuleType == TtsModuleType.TM_APT_F0 &&
                _config.DonateF0)
            {
                if (!e.Utterance.Acoustic.F0s.DimensionIsMatched(_donatorF0))
                {
                    ErrorLog("Number of frames don't match!");
                }
                else
                {
                    e.Utterance.Acoustic.F0s.CopyFrom(_donatorF0);
                }
            }
        }
        /// <summary>
        /// Aoustic processed event handler for the donator.
        /// Store duration and/or f0 of donator locally.
        /// </summary>
        /// <param name="sender">Sender of the event handler.</param>
        /// <param name="e">Event argument object.</param>
        private void OnDonatorAcousticProcessed(object sender, TtsModuleEventArgs e)
        {
            if (e.ModuleType == TtsModuleType.TM_APT_DURATION &&
                _config.DonateDuration)
            {
                _donatorDuration = e.Utterance.Acoustic.Durations.ToArray();
            }

            if (e.ModuleType == TtsModuleType.TM_APT_F0 &&
                _config.DonateF0)
            {
                _donatorF0 = e.Utterance.Acoustic.F0s.ToArray();
            }

            if (e.ModuleType == TtsModuleType.TM_APT_LSF)
            {
                _receiver.SpeechSynthesizer.Speak(_curScriptSententence.Text);
            }
        }