If you fancy a quick, fun, muck-around style project in C# then having a play with the System.Speech.SpeechSynthesizer class is definitely a good bet. Below is pretty much the most basic example of using this class which involves simply passing a string to the SpeechSythesizer Speak or SpeakAsync methods. More complicated variations are possible by using a PromptBuilder object instead which allows fine-tuned control over the content being spoken (i.e. pronunciation of parts of the content and getting a firm grip on the start of sentences and paragraphs within the content as a whole).
Start by adding a reference to the System.Speech assembly within your project:

Here’s a very basic code implementation (using a C# Console Application):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Speech.Synthesis; //To gain access to the SpeechSynthesizer Class (add a reference to System.Speech)
using System.Diagnostics; //For the debugging
namespace SpeechSynthTestApp
{
/// <summary>
/// Program Class Definition.
/// </summary>
class Program
{
#region Private Static Data Fields
//Static SpeechSynthesizer object (initialised fully within the PrepareSpeechSynthObject method)
private static SpeechSynthesizer speechSynth;
#endregion Private Static Data Fields
#region Constructor
/// <summary>
/// SpeechSynthTestApp Program Class Constructor.
/// </summary>
/// <param name="args">Incoming arguments for this Console Application from external sources (if supplied).</param>
static void Main(string[] args)
{
//Prepare the static SpeechSynthesizer object ready to receive input from the user (for speech) and then start the main application loop
PrepareSpeechSynthObject();
RunApplication();
}
#endregion Constructor
#region Private Static Methods
/// <summary>
/// Private static method that prepares the private SpeechSynthesizer object
/// ready for the user to start interacting with.
/// </summary>
private static void PrepareSpeechSynthObject()
{
//Initialise the speechSynth object
speechSynth = new SpeechSynthesizer();
//For testing purposes tie up some of the SpeechSynthesizer classes event handlers (in this instance to retrieve debug information)
speechSynth.SpeakStarted += ((sender, e) =>
{
SpeechSynthesizer synth = sender as SpeechSynthesizer;
if (synth != null)
{
Debug.WriteLine("Speech Synth object has started talking with the voice '{0}' at volume '{1}'.",
synth.Voice.Description, synth.Volume);
}
});
speechSynth.SpeakProgress += ((sender, e) =>
{
SpeechSynthesizer synth = sender as SpeechSynthesizer;
if (synth != null)
{
Debug.WriteLine("Speech Progressing. Saying '{0}'; Char Count '{1}'; Audio Pos '{2}'; Voice '{3}'; Volume '{4}'.",
e.Text, e.CharacterCount, e.AudioPosition, synth.Voice.Description, synth.Volume);
}
});
speechSynth.SpeakCompleted += ((sender, e) =>
{
SpeechSynthesizer synth = sender as SpeechSynthesizer;
if (synth != null)
{
Debug.WriteLine("Speech completed. Voice '{0}'; Volume '{1}'.", synth.Voice.Description, synth.Volume);
}
});
}
/// <summary>
/// Private static method that represents the main application loop (which
/// consists of gathering user input and calling a method to make a
/// SpeechSynthesizer object do it's thing!).
/// </summary>
private static void RunApplication()
{
//Just keep a' loopin'
while (true)
{
//Gather user input
Console.Write("Type something for the SpeechSynthesizer to say then press enter ('E' to exit): ");
string userInput = Console.ReadLine();
//If a user types 'E' (case insensitive) then exit the loop and the application
if (userInput.Equals("E", StringComparison.InvariantCultureIgnoreCase))
{
//As we are calling SpeakAsync we have to cancel any code still being executed/to be executed asynchronously to prevent exceptions
speechSynth.SpeakAsyncCancelAll();
break; //Exit
}
//SPEAK!
Speak(userInput);
}
}
/// <summary>
/// Take in the users input and talk talk talk!!!
/// </summary>
/// <param name="userInput">The users input from the Console.</param>
private static void Speak(string userInput)
{
/*
Speak based on the users input (handle null, empty or whitespace input). We could create a more complicated PromptBuilder object here but
passing a string serves as a suitable, basic example
*/
speechSynth.SpeakAsync(string.IsNullOrWhiteSpace(userInput) ? "You need to type something next time." : userInput);
}
#endregion Private Static Methods
}
}
In addition to the content being spoken you’ll also be able to access additional details via the event hookups (as specified in the code snippet above). A wee example looks like this:

I guarantee that, within about 30 seconds, you’ll be typing all sorts of swear words just to see how funny they sound. Enjoy!