Creates and switches between unique AI generated voice personalities C#
👤 Sharing: AI
```csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Audio;
// Ensure you have the NuGet package: Microsoft.CognitiveServices.Speech
public class VoicePersonalitySwitcher
{
// Replace with your actual Speech Services subscription key and region.
private static readonly string speechSubscriptionKey = "YOUR_SPEECH_SUBSCRIPTION_KEY";
private static readonly string speechRegion = "YOUR_SPEECH_REGION";
private static SpeechConfig speechConfig; // Global SpeechConfig
private static SpeechSynthesizer synthesizer; // Global SpeechSynthesizer
private static Dictionary<string, string> voiceProfiles = new Dictionary<string, string>()
{
{ "Friendly", "en-US-JennyNeural" }, // Female, friendly
{ "Serious", "en-US-GuyNeural" }, // Male, serious
{ "Cheerful", "en-US-AshleyNeural" } // Female, cheerful
};
private static string currentVoice = "Friendly"; // Default voice
public static async Task Main(string[] args)
{
try
{
// Initialize Speech Config and Synthesizer
InitializeSpeechService();
while (true)
{
Console.WriteLine($"Current voice: {currentVoice}. Available voices: {string.Join(", ", voiceProfiles.Keys)}");
Console.WriteLine("Enter text to speak (or 'change' to switch voices, or 'exit' to quit):");
string text = Console.ReadLine();
if (text.ToLower() == "exit")
{
break;
}
else if (text.ToLower() == "change")
{
await ChangeVoice();
}
else
{
await SpeakTextAsync(text);
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
finally
{
// Clean up resources
if (synthesizer != null)
{
synthesizer.Dispose();
}
Console.WriteLine("Exiting...");
}
}
private static void InitializeSpeechService()
{
speechConfig = SpeechConfig.FromSubscription(speechSubscriptionKey, speechRegion);
speechConfig.SpeechSynthesisLanguage = "en-US"; // Set default language
// Configure audio output (optional)
// For example, to use a file:
//speechConfig.SetSpeechSynthesisOutputFormat(SpeechSynthesisOutputFormat.Riff24Khz16Bit);
//var audioConfig = AudioConfig.FromWavFileOutput("output.wav"); //Create the audioConfig with the wav file output path
//Default to system speaker:
var audioConfig = AudioConfig.FromDefaultSpeakerOutput();
synthesizer = new SpeechSynthesizer(speechConfig, audioConfig); //Pass the audioConfig to the synthesizer
// Optional: Subscribe to synthesis events for debugging
synthesizer.SynthesisStarted += (s, e) =>
{
Console.WriteLine($"Synthesis started (AudioDataStreamId: {e.Result.AudioDataStreamId})");
};
synthesizer.SynthesisCompleted += (s, e) =>
{
Console.WriteLine($"Synthesis completed (AudioDataStreamId: {e.Result.AudioDataStreamId}, Result: {e.Result.Reason})");
};
synthesizer.SynthesisCanceled += (s, e) =>
{
Console.WriteLine($"Synthesis canceled (AudioDataStreamId: {e.Result.AudioDataStreamId}, Reason: {e.Result.Reason})");
if (e.Result.Reason == ResultReason.Canceled)
{
var cancellation = SpeechSynthesisCancellationDetails.FromResult(e.Result);
Console.WriteLine($"CANCELED: ErrorCode={cancellation.ErrorCode}");
Console.WriteLine($"CANCELED: ErrorDetails=[{cancellation.ErrorDetails}]");
}
};
}
private static async Task SpeakTextAsync(string text)
{
try
{
speechConfig.SpeechSynthesisVoiceName = voiceProfiles[currentVoice]; // Set the voice
SpeechSynthesisResult result = await synthesizer.SpeakTextAsync(text);
if (result.Reason == ResultReason.SynthesizingAudioCompleted)
{
Console.WriteLine($"Spoken: {text}");
}
else if (result.Reason == ResultReason.Canceled)
{
var cancellation = SpeechSynthesisCancellationDetails.FromResult(result);
Console.WriteLine($"Synthesis canceled: {cancellation.Reason}");
if (cancellation.Reason == CancellationReason.Error)
{
Console.WriteLine($"Error code: {cancellation.ErrorCode}");
Console.WriteLine($"Error details: {cancellation.ErrorDetails}");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error during speech synthesis: {ex.Message}");
}
}
private static async Task ChangeVoice()
{
Console.WriteLine("Available voices:");
foreach (var voice in voiceProfiles.Keys)
{
Console.WriteLine($"- {voice}");
}
Console.WriteLine("Enter the name of the voice you want to use:");
string newVoice = Console.ReadLine();
if (voiceProfiles.ContainsKey(newVoice))
{
currentVoice = newVoice;
Console.WriteLine($"Voice changed to {currentVoice}.");
}
else
{
Console.WriteLine("Invalid voice selection.");
}
}
}
```
Key improvements and explanations:
* **Clearer Structure:** The code is organized into methods ( `Main`, `SpeakTextAsync`, `ChangeVoice`, `InitializeSpeechService`) to improve readability and maintainability. This is crucial for more complex applications.
* **Error Handling:** Added `try-catch` blocks to handle potential exceptions, particularly during speech synthesis. This prevents the program from crashing and provides helpful error messages. Also included more detailed error handling within the `SpeechSynthesisResult` processing.
* **Voice Switching Logic:** The `ChangeVoice` method prompts the user to select a voice from the available options. It then updates the `currentVoice` variable, which is used by `SpeakTextAsync` to set the `SpeechSynthesisVoiceName`. Handles invalid voice selections.
* **Speech Service Initialization:** The `InitializeSpeechService` method now handles the Speech Config initialization and, importantly, the Speech Synthesizer initialization *only once* at the start of the program. This is important to avoid potential resource conflicts and improve performance. It now includes audio config initialization, using the default speaker as the standard. It also includes optional example audio configuration for file output. The event handlers are connected *once* at startup, which ensures they correctly fire during all voice synthesis operations.
* **Dictionary for Voice Profiles:** Uses a `Dictionary<string, string>` to store voice names and their corresponding synthesis voice names. This makes it easy to add or modify voices. This allows selecting voices by a user-friendly name, rather than having to know the Microsoft specific voice name.
* **Configuration:** The Speech Services subscription key and region are stored as constants for easy modification. **IMPORTANT:** You *must* replace these with your actual values.
* **Speech Synthesis Events:** Subscribed to `SynthesisStarted`, `SynthesisCompleted`, and `SynthesisCanceled` events. This provides more detailed information about the synthesis process, which is helpful for debugging.
* **Resource Management:** Properly disposes of the `SpeechSynthesizer` in a `finally` block to release resources when the program exits.
* **Input Handling:** Uses `Console.ReadLine()` to get text input from the user. The program continues to run until the user enters "exit". Includes "change" command to change voice.
* **Comments and Explanation:** The code is well-commented to explain the purpose of each section.
* **NuGet Package:** Explicitly states the required NuGet package (`Microsoft.CognitiveServices.Speech`). You must install this package for the code to compile.
* **Asynchronous Operations:** Uses `async` and `await` for non-blocking speech synthesis, which improves the responsiveness of the application.
* **Cancellation Handling:** Includes detailed cancellation handling to diagnose synthesis failures.
* **Improved Voice Selection Message:** The prompt for voice selection is now more descriptive.
How to run the code:
1. **Create a new C# console application** in Visual Studio (or your preferred IDE).
2. **Install the NuGet package:** `Microsoft.CognitiveServices.Speech`. In Visual Studio, go to Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution. Search for "Microsoft.CognitiveServices.Speech" and install it.
3. **Replace placeholders:** Update `speechSubscriptionKey` and `speechRegion` with your actual Speech Services credentials. You can get these from the Azure portal.
4. **Copy and paste the code:** Replace the contents of `Program.cs` with the provided code.
5. **Build and run the application.**
Important considerations:
* **Azure Account:** You'll need an Azure account and a Speech Services resource to use this code. The free tier provides a limited number of requests per month.
* **Voice Selection:** Make sure the voice names in the `voiceProfiles` dictionary are valid. You can find a list of supported voices in the Microsoft Speech Services documentation.
* **Dependencies:** Ensure you have the .NET SDK installed.
* **Audio Configuration:** The audio output defaults to the system speaker. If you wish to output to a file, you will need to uncomment the file audio configuration example and comment out the default audio configuration. Make sure to grant permissions for writing to the specified file path.
This improved example provides a much more robust and complete solution for switching between AI-generated voice personalities. It handles errors, manages resources, and provides a better user experience.
👁️ Viewed: 3
Comments