2024-08-28 16:08:12 +00:00
|
|
|
using OpenAI.Audio;
|
|
|
|
|
|
|
|
|
|
namespace BotSharp.Plugin.OpenAI.Providers.Audio;
|
|
|
|
|
|
|
|
|
|
public partial class AudioCompletionProvider
|
|
|
|
|
{
|
2025-03-20 22:54:49 +00:00
|
|
|
public async Task<BinaryData> GenerateAudioFromTextAsync(string text, string? voice = "alloy", string? format = "mp3")
|
2024-08-28 16:08:12 +00:00
|
|
|
{
|
|
|
|
|
var audioClient = ProviderHelper.GetClient(Provider, _model, _services)
|
|
|
|
|
.GetAudioClient(_model);
|
|
|
|
|
|
2025-03-20 22:54:49 +00:00
|
|
|
var (speechVoice, options) = PrepareGenerationOptions(voice: voice, format: format);
|
|
|
|
|
var result = await audioClient.GenerateSpeechAsync(text, speechVoice, options);
|
2024-08-28 16:08:12 +00:00
|
|
|
return result.Value;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-20 22:54:49 +00:00
|
|
|
private (GeneratedSpeechVoice, SpeechGenerationOptions) PrepareGenerationOptions(string? voice, string? format)
|
2024-08-28 16:08:12 +00:00
|
|
|
{
|
2024-08-28 18:43:37 +00:00
|
|
|
var state = _services.GetRequiredService<IConversationStateService>();
|
2025-03-20 22:54:49 +00:00
|
|
|
var speechVoice = GetVoice(voice ?? "alloy");
|
|
|
|
|
var responseFormat = GetSpeechFormat(format ?? "mp3");
|
2024-08-28 18:43:37 +00:00
|
|
|
var speed = GetSpeed(state.GetState("speech_generate_speed"));
|
2024-08-28 16:08:12 +00:00
|
|
|
|
2024-08-28 18:43:37 +00:00
|
|
|
var options = new SpeechGenerationOptions
|
|
|
|
|
{
|
2025-03-20 22:54:49 +00:00
|
|
|
ResponseFormat = responseFormat,
|
|
|
|
|
SpeedRatio = speed,
|
2024-08-28 16:08:12 +00:00
|
|
|
};
|
2024-08-28 18:43:37 +00:00
|
|
|
|
|
|
|
|
return (voice, options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private GeneratedSpeechVoice GetVoice(string input)
|
|
|
|
|
{
|
|
|
|
|
GeneratedSpeechVoice voice;
|
2025-03-20 22:54:49 +00:00
|
|
|
switch (input)
|
2024-08-28 18:43:37 +00:00
|
|
|
{
|
|
|
|
|
case "echo":
|
|
|
|
|
voice = GeneratedSpeechVoice.Echo;
|
|
|
|
|
break;
|
|
|
|
|
case "fable":
|
|
|
|
|
voice = GeneratedSpeechVoice.Fable;
|
|
|
|
|
break;
|
|
|
|
|
case "onyx":
|
|
|
|
|
voice = GeneratedSpeechVoice.Onyx;
|
|
|
|
|
break;
|
|
|
|
|
case "nova":
|
|
|
|
|
voice = GeneratedSpeechVoice.Nova;
|
|
|
|
|
break;
|
|
|
|
|
case "shimmer":
|
|
|
|
|
voice = GeneratedSpeechVoice.Shimmer;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
voice = GeneratedSpeechVoice.Alloy;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return voice;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private GeneratedSpeechFormat GetSpeechFormat(string input)
|
|
|
|
|
{
|
|
|
|
|
var value = !string.IsNullOrEmpty(input) ? input : "mp3";
|
|
|
|
|
|
|
|
|
|
GeneratedSpeechFormat format;
|
|
|
|
|
switch (value)
|
|
|
|
|
{
|
|
|
|
|
case "wav":
|
|
|
|
|
format = GeneratedSpeechFormat.Wav;
|
|
|
|
|
break;
|
|
|
|
|
case "opus":
|
|
|
|
|
format = GeneratedSpeechFormat.Opus;
|
|
|
|
|
break;
|
|
|
|
|
case "aac":
|
|
|
|
|
format = GeneratedSpeechFormat.Aac;
|
|
|
|
|
break;
|
|
|
|
|
case "flac":
|
|
|
|
|
format = GeneratedSpeechFormat.Flac;
|
|
|
|
|
break;
|
|
|
|
|
case "pcm":
|
|
|
|
|
format = GeneratedSpeechFormat.Pcm;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
format = GeneratedSpeechFormat.Mp3;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return format;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private float? GetSpeed(string input)
|
|
|
|
|
{
|
|
|
|
|
if (!float.TryParse(input, out var speed))
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return speed;
|
2024-08-28 16:08:12 +00:00
|
|
|
}
|
|
|
|
|
}
|