I want to write a simple Windows app in Visual C#/C++ that lets users input different segments of text, and then press a set of hotkeys to hear the various text segments in TTS at any time. The program should accept hotkeys while running in background or even when fullscreen applications have focus.
Example use case: user enters "hello world" and saves it as the first text segment, and then enters "stack overflow" and saves it as the second text segment. The user can switch to another program, then press hotkey CTRL-1 to hear the TTS say "hello world" or CTRL-2 to hear the TTS say "stack overflow." The program should of course be able to run entirely offline (just in case that affects any suggestions)
As a sidenote, I'm fairly new to programming in Visual whatever, but have a decent enough background in C#/C+, so even though I'm mainly looking for help on the TTS part, I'm open to suggestions of any kind if someone's done this kind of thing before.
if you want to talk something on C# use Introp.SpeechLib.dll
E.g:
private void ReadText()
{
int iCounter = 0;
while (Convert.ToInt32(numericUpDown1.Value) > iCounter)
{
SpVoice spVoice = new SpVoice();
spVoice.Speak("Hello World", SpeechVoiceSpeakFlags.SVSFPurgeBeforeSpeak);
spVoice.WaitUntilDone(Timeout.Infinite);
iCounter = iCounter + 1;
}
}
read this: Speech Technologies
Reference System.Speech.dll. You can instantiate a System.Speech.Synthesis.Synthesizer and call .Speak("TEXT HERE");
You have to use the Microsoft Speech SDK.
Have a look at this link for details:
http://dhavalshah.wordpress.com/2008/09/16/text-to-speech-in-c/
Related
I have a very basic problem, For a game (Dota 2) I want to write a little macro which opens the console, writes "setinfo name ".........................."" into it and then closes it, the hotkey for console is set to '#'. For this I wrote an application which listens for the key 'f' to be pressed, and then send
1) '#' (open the console)
2) "messag ebla bla b...."
3) '#' (close the console)
everything is working except that it will not open the console (but if the console is already open it will write #messagej.j....# into it when i press f just as wanted)
my code for sending the keys.
SendKeys.Send("#");
SendKeys.Send("my message for consol");
SendKeys.Send("#");
does anybody know why the hotkeys dont work by sending keys? I thought its an simulation of when the user presses F or Q.
First thing You should try is adding a "software" delay between keypresses.
string MSG = "#yourmessage#";
foreach (object c_loopVariable in MSG) {
c = c_loopVariable;
Sendkeys.Send(c);
sleep(20);
}
The other thing to consider - sendkeys do not emulate the keypress at the hardware layer - it is on windows API level, and the DirectX DirectInput., witch most games use for user input processing goes a level further. So it is possible You will not be able to do it this easy.
You should check out more of keybd_event. Ive had better luck using that - as i understand it goes a level deeper than just sendkeys.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646304(v=vs.85).aspx
Anyways, I hope u are not going to use this for some spamming in a great game! :)
I am writing a little application that is supposed to listen for user commands and send keystrokes to another program. I am using Speech Recognition Engine Class but my script doesn't work properly.
If I use a custom grammar (with very few words like "start" or "exit") the program will always recognize one of the my words even though I said something completely different.
For istance I say "stackoverflow" and the program recognizes "start".
With a default dictionary the program becomes almost impossible to use (I have to be 100% correct otherwise it won't understand).
The strange thing is that if I use Speech Recognizer instead of Speech Recognition Engine my program works perfect but ofcourse everytime I say something unrelated it messes up because Windows Speech Recognition handles the result and I don't want that to happen. That is the reason why I am using Speech Recognition Engine actually.
What am I doing wrong?
Choices c = new Choices(new string[] { "use", "menu", "map", "save", "talk", "esc" });
GrammarBuilder gb = new GrammarBuilder(c);
Grammar g = new Grammar(gb);
sr = new SpeechRecognitionEngine();
sr.LoadGrammar(g);
sr.SetInputToDefaultAudioDevice();
sr.SpeechRecognized += sr_SpeechRecognized;
Almost forgot, I don't know if that's relevant but I am using Visual Studio 11 Ultimate Beta.
For each speech recognition result detected you also receive the confidence for the recognition - a low confidence level would indicate that the engine is "not so sure" about the result and you might want to reject it, e.g.:
private void SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
if (e.Result.Confidence >= 0.7)
{
//high enough confidence, use result
}
else
{
//reject result
}
}
I've started using .NET speech-to-text library (SpeechRecognizer)
While googling and searching this site i found this code sample:
var c = new Choices();
for (var i = 0; i <= 100; i++)
c.Add(i.ToString());
var gb = new GrammarBuilder(c);
var g = new Grammar(gb);
rec.UnloadAllGrammars();
rec.LoadGrammar(g);
rec.Enabled = true;
Which helped me to start. I changed these 2 lines
for (var i = 0; i <= 100; i++)
c.Add(i.ToString());
to my need
c.Add("Open");
c.Add("Close");
But, when I say 'Close', the speech recognizer of windows closes my application!
In addition, Is there a better way to recognize speech than to create my own dictionary? I would like the user to say something like: "Write a note to myself" and then the user will speak and I'll write.
Sorry for asking 2 questions at the same question, both seem to be relevant to my one problem.
You are using the shared speech recognizer (SpeechRecognizer). When you instantiate
SpeechRecognizer you get a recognizer that can be shared by other applications and is typically used for building applications to control windows and applications running on the desktop.
It sounds like you want to use your own private recognition engine (SpeechRecognitionEngine). So instantiate a SpeechRecognitionEngine instead.
see SpeechRecognizer Class.
Disable built-in speech recognition commands? may also have some helpful info.
Microsoft's desktop recognizers include a special grammar called a dictation grammar that can be used to transcribe arbitrary words spoken by the user. You can use the dictation grammar to do transcription style recognition. See DictationGrammar Class and SAPI and Windows 7 Problem
I have a better answer....
Try adding a dictation Grammar to your recognizer... it seems to disable all built-in commands like select/delete/close etc..
You then need to use the speech recognized event and SendKeys to add text to the page. My findings so far indicate that you can't have your SAPI cake and eat it.
I think the solution above should work for you if you've not already solved it (or moved on).
What am I doing:
My main intent is to enable user friendly text to speech for personal use on Win 7. Approach should work in Google Chrome, VS and Eclipse.
Code example:
Following code creates global keyboard hook for ctrl + alt + space, called hookEvent. If event fires, it starts/stops speaking clipboard contents ( that can be updated with ctrl + c ).
/// <summary>
/// KeyboardHook from: http://www.liensberger.it/web/blog/?p=207
/// </summary>
private readonly KeyboardHook hook = new KeyboardHook();
private readonly SpeechSynthesizer speaker = //
new SpeechSynthesizer { Rate = 3, Volume = 100 };
private void doSpeaking(string text)
{
// starts / stops speaking, while not blocking UI
if (speaker.State != SynthesizerState.Speaking)
speaker.SpeakAsync(text);
else
speaker.SpeakAsyncCancelAll();
}
private void hookEvent(object sender, KeyPressedEventArgs e)
{
this.doSpeaking(Convert.ToString(Clipboard.GetText()));
}
public Form1()
{
InitializeComponent();
hook.KeyPressed += new EventHandler<KeyPressedEventArgs>(hookEvent);
hook.RegisterHotKey(ModifierKeysx.Control|ModifierKeysx.Alt, Keys.Space);
}
Question:
I would prefer not using the clipboard. Or at least, restoring the value after, something like:
[MethodImpl(MethodImplOptions.Synchronized)]
private string getSelectedTextHACK()
{
object restorePoint = Clipboard.GetData(DataFormats.UnicodeText);
SendKeys.SendWait("^c");
string result = Convert.ToString(Clipboard.GetText());
Clipboard.SetData(DataFormats.UnicodeText, restorePoint);
return result;
}
What are my options?
Edit:
To my surprise, I found that my clipboard reader is the best way to go. I created a notification area app, that responds to left click (speaking clipboard) and right click (menu opens up). In menu the user can chance speed, speak or create a audio file.
MS provide accessibility tools that do cover what you're trying to do. If you take a look at documents about screen scraping. In short, every component is accessible in some manner, if you use some of the windows debugging tools you can get to see the component names/structures within. You can then use that, however, its complicated as most times you would need to be very specific for each application you intend to scrape from.
If you manage to scrape you dont need to use the clipboard, as you can access the text property of the apps direct. Its not something I've had to do, hence, Ive no code to offer off the top of my head, but the term "screen scraping" should point you in the right direction.
If to expand a little on what Bugfinder said, Microsoft provider a UI Automation Framework to solve problems like the one you mentioned:
In particular you can use the TextSelectionChangedEvent of TextPattern:
The problem with this solution is that it only works on supported operating systems and applications - and not all support this.
Your clipboard solution is acceptable for applications that do not provide a good automation interface.
But for many applications the UI Automation Framework will work well and will provide you with a far better solution.
Basically I want to write an application which would display the current language as a tray icon. Mainly I can code C++ and C#. Guess Google would help me out but I would like to ask it here first, since the community, the knowledge here is something I trust.
(Never wrangled with such parts of the system so far. So that's why I would like to ask the community.)
Okay thanks to your help, I managed to discover two ways. Using the DllImport in C# (importing the user32.dll) and the InputLanguage.
Found a snippet:
public void SetNewCurrentLanguage() {
// Gets the default, and current languages.
InputLanguage myDefaultLanguage = InputLanguage.DefaultInputLanguage;
InputLanguage myCurrentLanguage = InputLanguage.CurrentInputLanguage;
textBox1.Text = "Current input language is: " + myCurrentLanguage.Culture.EnglishName + '\n';
textBox1.Text += "Default input language is: " + myDefaultLanguage.Culture.EnglishName + '\n';
// Changes the current input language to the default, and prints the new current language.
InputLanguage.CurrentInputLanguage = myDefaultLanguage;
textBox1.Text += "Current input language is now: " + myDefaultLanguage.Culture.EnglishName;
}
I applied this like the following:
InputLanguage myCurrentLanguage = InputLanguage.CurrentInputLanguage;
notifyIcon.Text = myCurrentLanguage.LayoutName + '\n' + myCurrentLanguage.Culture.DisplayName;
This displays it if you hover it above the icon. However, it won't update on switch, nor show the layout as text in the tray area. For that, I found a "Drawing in VB.NET" article, maybe this will help me working out this issue. About the switch detect, that's a good question.
To get the user's overall UI language, GetUserDefaultUILanguage.
To get the current thread's language, GetThreadUILanguage or GetThreadLocale.
To get the current keyboard input language, GetKeyboardLayout.
To display a notification area icon in Windows prior to Windows 7, Shell_NotifyIcon. In Windows 7 Shell_NotifyIcon might still work if the user sets appropriate options, but otherwise you have to find another way.
If you have more than one possible keyboard input language, Windows already displays the current keyboard input language in the language bar unless the user has disabled it. The user might put the language bar in the task bar, though it's not quite the same as being in the notification area.
If you want to receive notices when the user changes a language, WM_SETTINGCHANGE might let you know when you should call SystemParametersInfo to check. I'm not sure if there's a better way.