Skip to content

Commit

Permalink
add partial clip callback
Browse files Browse the repository at this point in the history
  • Loading branch information
StephenHodgson committed Oct 26, 2023
1 parent e3dbfe4 commit 534c9d7
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 4 deletions.
24 changes: 22 additions & 2 deletions ElevenLabs-DotNet/TextToSpeech/TextToSpeechEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,13 @@ public TextToSpeechEndpoint(ElevenLabsClient api) : base(api) { }
/// 4 - max latency optimizations, but also with text normalizer turned off for even more latency savings
/// (best latency, but can mispronounce eg numbers and dates).
/// </param>
/// <param name="partialClipCallback">
/// Optional, Callback to enable streaming audio as it comes in.<br/>
/// Returns partial <see cref="VoiceClip"/>s who's <see cref="VoiceClip.ClipData"/> overwritten with the next chunk of data.
/// </param>
/// <param name="cancellationToken">Optional, <see cref="CancellationToken"/>.</param>
/// <returns><see cref="VoiceClip"/>.</returns>
public async Task<VoiceClip> TextToSpeechAsync(string text, Voice voice, VoiceSettings voiceSettings = null, Model model = null, OutputFormat outputFormat = OutputFormat.MP3_44100_128, int? optimizeStreamingLatency = null, CancellationToken cancellationToken = default)
public async Task<VoiceClip> TextToSpeechAsync(string text, Voice voice, VoiceSettings voiceSettings = null, Model model = null, OutputFormat outputFormat = OutputFormat.MP3_44100_128, int? optimizeStreamingLatency = null, Func<VoiceClip, Task> partialClipCallback = null, CancellationToken cancellationToken = default)
{
if (text.Length > 5000)
{
Expand Down Expand Up @@ -90,7 +94,23 @@ public async Task<VoiceClip> TextToSpeechAsync(string text, Voice voice, VoiceSe

try
{
await responseStream.CopyToAsync(memoryStream, cancellationToken).ConfigureAwait(false);
if (partialClipCallback == null)
{
await responseStream.CopyToAsync(memoryStream, cancellationToken).ConfigureAwait(false);
}
else
{
int bytesRead;
var buffer = new byte[8192];

while ((bytesRead = await responseStream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false)) > 0)
{
var segment = new ReadOnlyMemory<byte>(buffer, 0, bytesRead);
await partialClipCallback(new VoiceClip(clipId, text, voice, segment)).ConfigureAwait(false);
await memoryStream.WriteAsync(segment, cancellationToken).ConfigureAwait(false);
}
}

clipData = memoryStream.ToArray();
}
finally
Expand Down
4 changes: 2 additions & 2 deletions ElevenLabs-DotNet/VoiceClip.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ namespace ElevenLabs
{
public sealed class VoiceClip
{
internal VoiceClip(string id, string text, Voice voice, byte[] clipData)
internal VoiceClip(string id, string text, Voice voice, ReadOnlyMemory<byte> clipData)
{
Id = id;
Text = text;
Voice = voice;
TextHash = $"{id}{text}".GenerateGuid().ToString();
ClipData = new ReadOnlyMemory<byte>(clipData);
ClipData = clipData;
}

public string Id { get; }
Expand Down

0 comments on commit 534c9d7

Please sign in to comment.