Ожидание преобразования текста в речь - PullRequest
0 голосов
/ 09 октября 2018

Я пытаюсь поиграть с Task, чтобы понять, как он работает, поэтому в моем игрушечном проекте я просто хотел начать преобразование текста в речь и распечатать время.Это мое усилие:

await Task.Factory.StartNew(
    ()    => System.Diagnostics.Debug.Print("START PLAYING {0}", 
                 System.DateTime.Now.ToString("HH:mm:ss"))).ContinueWith(

    (arg) => DependencyService.Get<ITextToSpeech>().Speak(s)).ContinueWith(

    (arg) => System.Diagnostics.Debug.Print("STOP  PLAYING {0}", 
                 System.DateTime.Now.ToString("HH:mm:ss"))
);

Код находится внутри обработчика событий async void Play_Clicked(object sender, System.EventArgs e), но, как я вижу, TTS не будет ждать завершения и сразу же напечатает время:

START PLAYING 11:22:44
START IMPLEMENTATION 11:22:44
STOP  IMPLEMENTATION 11:22:45
STOP  PLAYING 11:22:45

Реализация зависимости - это просто копирование / вставка из учебника Xamarin по TTS:

using Xamarin.Forms;
using AVFoundation;

[assembly: Dependency(typeof(Testers.iOS.TextToSpeechImplementation))]
namespace Testers.iOS
{
    public class TextToSpeechImplementation : ITextToSpeech
    {
        public TextToSpeechImplementation() { }

        public void Speak(string text)
        {
            System.Diagnostics.Debug.Print("START IMPLEMENTATION {0}", System.DateTime.Now.ToString("HH:mm:ss"));

            var speechSynthesizer = new AVSpeechSynthesizer();
            var speechUtterance = new AVSpeechUtterance(text)
            {
                Rate = AVSpeechUtterance.MaximumSpeechRate / 2.8f,
                Voice = AVSpeechSynthesisVoice.FromLanguage(App.current_lang),
                PreUtteranceDelay = 0.5f,
                PostUtteranceDelay = 0.0f,
                Volume = 0.5f,
                PitchMultiplier = 1.0f
            };

            speechSynthesizer.SpeakUtterance(speechUtterance);
            System.Diagnostics.Debug.Print("STOP  IMPLEMENTATION {0}", System.DateTime.Now.ToString("HH:mm:ss"));
        }
    }
}

с его интерфейсом, определенным как

using System;

namespace Testers
{
    public interface ITextToSpeech
    {
        void Speak(string text);
    }
}

Я до сих пор понимаювся эта концепция async / await, так что я, очевидно, здесь упускаю что-то важное.

Буду признателен за любую помощь!

1 Ответ

0 голосов
/ 09 октября 2018

Вы используете TaskCompletionSource вместе с обработчиком DidFinishSpeechUtterance, чтобы определить, когда закончится речевой вывод.

Примечание: Обработчик DidFinishSpeechUtterance автоматически назначает AVSpeechSynthesizerDelegate, поэтому вы можетепропустите оболочки обработчика Xamarin и напрямую создайте / используйте свой собственный делегат (который необходим для некоторых случаев использования)

Пример использования:

await speechSynthesizer.SpeakUtteranceAsync(speechUtterance, cancelToken);

Пример расширения:

public static class AClassyClass
{
    public static async Task SpeakUtteranceAsync(this AVSpeechSynthesizer synthesizer, AVSpeechUtterance speechUtterance, CancellationToken cancelToken)
    {
        var tcsUtterance = new TaskCompletionSource<bool>();
        try
        {
            synthesizer.DidFinishSpeechUtterance += OnFinishedSpeechUtterance;
            synthesizer.SpeakUtterance(speechUtterance);
            using (cancelToken.Register(TryCancel))
            {
                await tcsUtterance.Task;
            }
        }
        finally
        {
            synthesizer.DidFinishSpeechUtterance -= OnFinishedSpeechUtterance;
        }

        void TryCancel()
        {
            synthesizer?.StopSpeaking(AVSpeechBoundary.Word);
            tcsUtterance?.TrySetResult(true);
        }

        void OnFinishedSpeechUtterance(object sender, AVSpeechSynthesizerUteranceEventArgs args)
        {
            if (speechUtterance == args.Utterance)
                tcsUtterance?.TrySetResult(true);
        }
    }
}

Примечание: Xamarin.Essentials включает этот поток с помощью TaskCompletionSource и предоставляет TextToSpeech.SpeakAsync, обеспечивающий ту же функцию

Re: https://docs.microsoft.com/en-us/xamarin/essentials/text-to-speech

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...