Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 16 additions & 23 deletions tts/tts-dotnet-quickstart/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ class Program

private static string? _apiKey;
private static HumeClient? _client;
private static string? _outputDir;

static async Task RunExamplesAsync()
{
Expand All @@ -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();
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -242,7 +235,6 @@ static async Task Example3Async()

/// <summary>
/// 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.
/// </summary>
private static async Task StreamAudioToPlayerAsync<T>(
IAsyncEnumerable<T> snippetStream,
Expand Down Expand Up @@ -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);
}
Expand All @@ -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();
}
Expand All @@ -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();
Expand Down Expand Up @@ -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}");
}

}
2 changes: 1 addition & 1 deletion tts/tts-dotnet-quickstart/tts-csharp-quickstart.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Hume" Version="0.2.1" />
<PackageReference Include="Hume" Version="0.2.3" />
<PackageReference Include="DotNetEnv" Version="3.1.1" />
<PackageReference Include="OneOf" Version="3.0.271" />
<PackageReference Include="OneOf.Extended" Version="3.0.271" />
Expand Down