public static void SpeechSynthesizeWithPool() { var speechConfig = SpeechConfig.FromSubscription(subscriptionKey, region); var pool = new SynthesizerPool(() => new SpeechSynthesizer(speechConfig, null)); var latencyList = new List <double>(); var processingTimeList = new List <double>(); for (var turn = 0; turn < 3; turn++) { Console.WriteLine("turn: {0}", turn); Parallel.For(0, 64, (i) => { var start = DateTime.Now; var synthesizer = pool.Get(); bool first = true; void SynthesizingEvent(object sender, SpeechSynthesisEventArgs eventArgs) { // receive streaming audio here. if (!first) { return; } Console.WriteLine("First byte latency: {0}", DateTime.Now - start); first = false; if (turn > 0) { latencyList.Add((DateTime.Now - start).TotalMilliseconds); } } synthesizer.Synthesizing += SynthesizingEvent; var result = synthesizer.SpeakTextAsync($"today is a nice day. {turn}{i}").Result; if (result.Reason == ResultReason.SynthesizingAudioCompleted) { if (turn > 0) { processingTimeList.Add((DateTime.Now - start).TotalMilliseconds); } synthesizer.Synthesizing -= SynthesizingEvent; pool.Put(synthesizer); } else { var err = SpeechSynthesisCancellationDetails.FromResult(result); Console.WriteLine(err.ToString()); synthesizer.Dispose(); } }); Thread.Sleep(2000); } latencyList.Sort(); Console.WriteLine("Average latency {0} ms", latencyList.Average()); Console.WriteLine("Max latency {0} ms", latencyList.Max()); Console.WriteLine("Min latency {0} ms", latencyList.Min()); Console.WriteLine("90% latency {0} ms", latencyList[Convert.ToInt32(latencyList.Count * 0.9)]); Console.WriteLine("95% latency {0} ms", latencyList[Convert.ToInt32(latencyList.Count * 0.95)]); processingTimeList.Sort(); Console.WriteLine("\nAverage processing time {0} ms", processingTimeList.Average()); Console.WriteLine("Max processing time {0} ms", processingTimeList.Max()); Console.WriteLine("Min processing time {0} ms", processingTimeList.Min()); Console.WriteLine("90% processing time {0} ms", processingTimeList[Convert.ToInt32(processingTimeList.Count * 0.9)]); Console.WriteLine("95% processing time {0} ms", processingTimeList[Convert.ToInt32(processingTimeList.Count * 0.95)]); Console.WriteLine("Press the Enter key to exit."); Console.ReadLine(); }
public void Synthesize(string text) { var start = DateTime.Now; var synthesizer = pool.Get(); var ssml = GenerateSsml("en-US", "Female", speechConfig.SpeechSynthesisVoiceName, text); bool first = true; void SynthesizingEvent(object sender, SpeechSynthesisEventArgs eventArgs) { // receive streaming audio here. if (!first) { return; } Console.WriteLine("First byte latency: {0}", DateTime.Now - start); first = false; latencyList.Add((DateTime.Now - start).TotalMilliseconds); } void SynthesizerSynthesisCanceled(object sender, SpeechSynthesisEventArgs e) { var cancellation = SpeechSynthesisCancellationDetails.FromResult(e.Result); Console.WriteLine($"CANCELED: Reason={cancellation.Reason}"); if (cancellation.Reason == CancellationReason.Error) { Console.WriteLine($"CANCELED: ErrorCode={cancellation.ErrorCode}"); Console.WriteLine($"CANCELED: ErrorDetails=[{cancellation.ErrorDetails}]"); Console.WriteLine($"CANCELED: Did you update the subscription info?"); } } synthesizer.Synthesizing += SynthesizingEvent; synthesizer.SynthesisCanceled += SynthesizerSynthesisCanceled; var result = synthesizer.StartSpeakingSsmlAsync(ssml).Result; try { if (result.Reason == ResultReason.SynthesizingAudioStarted) { uint totalSize = 0; using (var audioDataStream = AudioDataStream.FromResult(result)) { // buffer block size can be adjusted based on scenario byte[] buffer = new byte[4096]; uint filledSize = 0; // read audio block in a loop here // if it is end of audio stream, it will return 0 // if there are error happening, the cancel event will be called. while ((filledSize = audioDataStream.ReadData(buffer)) > 0) { // Here you can save the audio or send the data to another pipeline in your service. Console.WriteLine($"{filledSize} bytes received. Handle the data buffer here"); totalSize += filledSize; } } if (totalSize > 0) { processingTimeList.Add((DateTime.Now - start).TotalMilliseconds); } synthesizer.Synthesizing -= SynthesizingEvent; synthesizer.SynthesisCanceled -= SynthesizerSynthesisCanceled; pool.Put(synthesizer); } } catch (Exception) { synthesizer.SynthesisCanceled -= SynthesizerSynthesisCanceled; synthesizer.Synthesizing -= SynthesizingEvent; synthesizer.Dispose(); } finally { } }