diff --git a/tts/tts-dotnet-quickstart/Program.cs b/tts/tts-dotnet-quickstart/Program.cs index 76f40c87..3e3ac9a4 100644 --- a/tts/tts-dotnet-quickstart/Program.cs +++ b/tts/tts-dotnet-quickstart/Program.cs @@ -22,7 +22,6 @@ class Program private static string? _apiKey; private static HumeClient? _client; - private static string? _outputDir; static async Task RunExamplesAsync() { @@ -39,12 +38,6 @@ static async Task RunExamplesAsync() _client = new HumeClient(_apiKey); - // Create an output directory in the temporary folder - _outputDir = Path.Combine(Path.GetTempPath(), "hume-audio"); - Directory.CreateDirectory(_outputDir); - - Console.WriteLine($"Results will be written to {_outputDir}"); - await Example1Async(); await Example2Async(); await Example3Async(); @@ -199,7 +192,7 @@ static async Task Example3Async() { Console.WriteLine("Example 3: Bidirectional streaming..."); - using var streamingTtsClient = new StreamingTtsClient(_apiKey!); + using var streamingTtsClient = new StreamingTtsClient(_apiKey!, enableDebugLogging: true); await streamingTtsClient.ConnectAsync(); // Use buffered mode for bidirectional streaming to handle irregular chunk arrival timing @@ -242,7 +235,6 @@ static async Task Example3Async() /// /// Helper method to stream audio chunks from a TTS response to an audio player. - /// Handles SDK compatibility by working with both TtsOutput and OneOf types. /// private static async Task StreamAudioToPlayerAsync( IAsyncEnumerable snippetStream, @@ -313,10 +305,12 @@ public Task StartStreamingAsync() { try { + int chunkCount = 0; foreach (var audioBytes in _audioBuffer.GetConsumingEnumerable(_bufferCts.Token)) { - if (_audioProcess?.StandardInput?.BaseStream != null) + if (_audioProcess?.StandardInput?.BaseStream != null && !_audioProcess.HasExited) { + chunkCount++; await _audioProcess.StandardInput.BaseStream.WriteAsync(audioBytes, _bufferCts.Token); await _audioProcess.StandardInput.BaseStream.FlushAsync(_bufferCts.Token); } @@ -335,18 +329,24 @@ public Task StartStreamingAsync() public Task SendAudioAsync(byte[] audioBytes) { - if (!_isStreaming) return Task.CompletedTask; + if (!_isStreaming) + { + return Task.CompletedTask; + } + + if (audioBytes.Length == 0) + { + return Task.CompletedTask; + } try { if (_useBuffering && _audioBuffer != null) { - // Buffered mode: add to queue for background task to process _audioBuffer.Add(audioBytes); } else if (_audioProcess?.HasExited == false) { - // Direct mode: write immediately to ffplay _audioProcess?.StandardInput.BaseStream.Write(audioBytes, 0, audioBytes.Length); _audioProcess?.StandardInput.BaseStream.Flush(); } @@ -373,9 +373,11 @@ public async Task StopStreamingAsync() { await _bufferTask; } + + await Task.Delay(TimeSpan.FromSeconds(5)); } - // Close ffplay process + // Close ffplay process input stream - ffplay will finish playing all buffered audio then exit if (_audioProcess != null && !_audioProcess.HasExited) { _audioProcess.StandardInput.Close(); @@ -458,13 +460,4 @@ private static StreamingAudioPlayer StartAudioPlayer() return new StreamingAudioPlayer(); } - private static async Task WriteResultToFile(string base64EncodedAudio, string filename, string outputDir) - { - var filePath = Path.Combine(outputDir, $"{filename}.wav"); - // Decode the base64-encoded audio data - var audioData = Convert.FromBase64String(base64EncodedAudio); - await File.WriteAllBytesAsync(filePath, audioData); - Console.WriteLine($"Wrote {filePath}"); - } - } diff --git a/tts/tts-dotnet-quickstart/tts-csharp-quickstart.csproj b/tts/tts-dotnet-quickstart/tts-csharp-quickstart.csproj index 71c56715..08a58e0e 100644 --- a/tts/tts-dotnet-quickstart/tts-csharp-quickstart.csproj +++ b/tts/tts-dotnet-quickstart/tts-csharp-quickstart.csproj @@ -10,7 +10,7 @@ - +