public async Task SayAsync(string content) { using var logger = _logger.Action($"Say {content}"); try { var speech = await _renderSpeechService.RenderSpeechAsync(content).ConfigureAwait(false); _player.Stop(); speech.Seek(0, SeekOrigin.Begin); _player.Stream = speech; _player.Play(); } catch (RenderSpeechException ex) { logger.Failure(ex.Message); } }
/// <summary> /// Renders specified content into a stream of audio data ready for playback /// </summary> /// <param name="content">Speech to render into audio</param> /// <returns>A stream containing the audio data</returns> public async Task <Stream> RenderSpeechAsync(string content) { bool haveSource; TaskCompletionSource <Stream>?tcsStream; lock (_padlock) { if (_completedRenders.TryGetValue(content, out var existingStream)) { return(existingStream); } haveSource = _pendingRenders.TryGetValue(content, out tcsStream); } if (haveSource) { return(await tcsStream !.Task.ConfigureAwait(false)); } tcsStream = new TaskCompletionSource <Stream>(); lock (_padlock) { _pendingRenders[content] = tcsStream; } var stream = await _renderSpeechService.RenderSpeechAsync(content).ConfigureAwait(false); lock (_padlock) { _completedRenders[content] = stream; _pendingRenders.Remove(content); } tcsStream.SetResult(stream); return(stream); }