Introduction
This code is a simple command line program to announce the currently logged in user Display Name. The concept is fairly simple, but could easily be extended to announce dynamically passed in data and more complex logic. Many examples show using TTS in a Windowed app, but few showing CLI pattern.
Using the Code
I created this as follows using Visual Studio 2013 Community Edition on WIndows 10.
In Visual Studio:
- Create a New Project called
SayIt
- In Solution Explorer, Add References for:
System.Speech
System.DirectoryServices.AccountManagement
- Add the contents below to SayIt.cs file.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Speech.Synthesis;
using System.DirectoryServices.AccountManagement;
namespace SayIt
{
class SayIt
{
static void Main(string[] args)
{
const string voiceArg = "v:";
const string loudArg = "l:";
const string rateArg = "r:";
IEnumerable<string> parsedArgsVoice = from str in args
where str.IndexOf(voiceArg) >= 0
select str.Substring(2);
IEnumerable<int> parsedArgsLoud = from str in args
where str.IndexOf(loudArg) >= 0
select Int32.Parse(str.Substring(2));
IEnumerable<int> parsedArgsRate = from str in args
where str.IndexOf(rateArg) >= 0
select Int32.Parse(str.Substring(2));
SpeechSynthesizer synth = new SpeechSynthesizer();
List<string> voiceList = new List<string>();
foreach (var voice in synth.GetInstalledVoices())
{
voiceList.Add(voice.VoiceInfo.Name);
}
synth.SelectVoice(parsedArgsVoice.Count() > 0
? parsedArgsVoice.ElementAt(0)
: voiceList.ElementAt(0));
synth.Volume = parsedArgsLoud.Count() > 0
? parsedArgsLoud.ElementAt(0)
: 100;
synth.Rate = parsedArgsRate.Count() > 0
? parsedArgsRate.ElementAt(0)
: 1;
synth.Speak("Hello " + UserPrincipal.Current.DisplayName);
}
}
}
The code above is fairly straight forward and broken down in a few basic steps:
- Set up known CLI argument prefixes as
const string
s
- Use Linq to parse known command line arguments in a manner that allows the ordering of them to be specific. There is a lot of type validation code left out here to focus on the main logic!
- Create a new
SpeechSynthesizer
instance
- Use the
SpeechSynthesizer
instance to obtain installed voices and store them in a list
- Select a Voice, set the volume, and set the rate on the
SpeechSynthesizer
instance.
- Use the conditional ternary operator to set the voice, rate, and loudness to either a passed in CLI argument or a default if not passed as an argument.
- Passed in
Voice
must match an installed voice exactly - TTS settings in Control Panel will list installed voices
- Volume/Loudness valid range is 0 to 100
- Rate valid range is 0 to 10
- Call the
Speak
method on the SpeechSynthesizer
instance passing the string Hello
with the UserPrincipal.Current.DisplayName
(currently logged in user's DisplayName
) appended.
- If wishing to use just the
username
, then append Environment.UserName
instead of UserPrincipal.Current.DisplayName
.
- Also the
System.DirectoryServices.AccountManagement
reference and using
statement can be removed.
- Using
Environment.UserName
also seems to be much faster.
After building the solution, open a command prompt and change directory to where the SayIt.exe is output and type some of the following commands:
SayIt
- Announces user name in default voice, rate, and loudness
SayIt l:60
- Announces user name in default voice, rate, and loudness of 60
SayIt r:5 l:70
- Announces user name in default voice, rate of 5, and loudness of 70
SayIt l:90 r:2 "v:Microsoft Zira Desktop"
- Announces user name in using Microsoft Zira Desktop
voice, rate of 2, and loudness of 90
Points of Interest
I am using this with a Kinect V2 on Windows setup with the Windows Hello face recognition for login. I setup a Task that executes this program upon login. So my kids sit down in front of the computer, Windows Hello recognizes them and automatically logs them in, and when logged in, the computer TTS voice announces Hello Robert
. They get a kick out of it. When using the Environment.UserName
, which is faster, it usually announces while the login screen is still in progress, which is cool too.
History
- 2016-04-09 - Initial post