No output in using wav file input with Microsoft SAPI 5.4 Api - sapi

I am working on a project where i need to use speech recognition to convert a wav file input speech ( conversation ) to text. After trying CMUSPhinx for a while, with terrible results, i am considering using Microsoft SAPI (Speech API) 5.4
I am coding as a Visual basic windows application from visual studio. Here is my code snippet :
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
' Dim SAPI
' SAPI = CreateObject("sapi.spvoice")
' SAPI.Speak(TextBox1.Text)
' Create new recognizer
Dim Recognizer As New SpInprocRecognizer
' create input file stream
InputFile = New SpFileStream
' Defaults to open for read-only, and DoEvents false
InputFile.Open(MY_WAVE_AUDIO_FILENAME)
' connect wav audio input to speech recognition engine
Recognizer.AudioInputStream = InputFile
' create recognition context
RecoContext = Recognizer.CreateRecoContext
' AddHandler RecoContext.Recognition, AddressOf RecoContext_Recognition
' create grammar
Grammar = RecoContext.CreateGrammar
' ... and load dictation
Grammar.DictationLoad()
' start dictating
Grammar.DictationSetState(SGDSActive)
End Sub
In the MY_WAVE_AUDIO_FILENAME, i have given the filename with full path. When i run this code on click of the button, i dont get any output. I have used the following recognition method :
Private Sub RecoContext_Recognition(ByVal StreamNumber As Long, ByVal StreamPosition As Object, ByVal RecognitionType As SpeechRecognitionType, ByVal Result As ISpeechRecoResult)
' Log/Report recognized phrase/information
Console.WriteLine("Reached here......")
TextBox1.Text = "Text should change"
End Sub
When i debug the application, flow is not reaching the RecoContext_Recognition method. The input file is a wav file with 16 bits per sample, 30 sec long conversation.
I am using the code mentioned in this link :
http://msdn.microsoft.com/en-us/library/ee431813(v=vs.85).aspx
How can i check for the issue ? I had read somewhere that dictation needs training to be given to Speech Recognition engine, if its required in my case too then how can i do that? Also in the link it is mentioned that we need to specify the length of the input file in order to do
this, am not sure how to do this as well. Help needed.

The sample code is missing a few steps that need to be addressed.
1) Inproc recognizers need to bind an engine before they will do any recognitions at all;
2) The inproc recognizer needs to be set active before it will start processing audio.
You should also consider adding handlers for other events, in particular SPEI_START_SR_STREAM, SPEI_SOUND_START, SPEI_SOUND_END, and SPEI_PHRASE_START to verify that the SR engine is processing audio at all and that it's trying to do some recognition.

Related

Windows CE Generate Log on Barcode Scan

At the moment, I am currently faced with a small project as to update a current bar-code system so that it will store a log file on scan. However, I'm not provided with any source code for the current system. So I was thinking maybe I can develop a small .exe to run and it's job is just to store the ID scanned as well as the current timestamp to a text file named log.txt.
Here's all I'm provided with:
A small touchscreen device running on windows CE with a built-in bar-code
scanner (imager) and few other ports including a USB port.
A memory stick containing the object codes (exe, dll, pdb, bat and
xml) and other multimedia files.
SDK CD containing an SDK platform installer (.msi) requiring VS2005
SP1 to be installed.
Now I'm just confused on how to get the job done. I've been spending the past 3 days researching about this. One of my Google findings suggest that the bar-code scanner works just like a keyboard input? Hence, I made a simple VB6 application with a textbox to store the contents of it and reset the textbox at the same time when a 10-digit ID is inputted. The application is not executable in the device though (I found out that VB6 exe is not executable in winCE, sadly).
Furthermore, I tried to open MS WordPad in the device and attempted to scan the bar-code. Nothing is copied to the WordPad though. I thought bar-code scanner works identically like a keyboard input? My mistake? Any clarification will be highly appreciated.
I'm actually new to bar-code and winCE development and if it helps, I'm familiar with the following languages (in-order): C#, VB6, VB.Net, C, Java. Any suggestion on the quickest way to get the job done? I believe it's not a hectic job, but I'm stuck on where to begin.
Just tell me in case any further clarification is needed. Thanks in advance!
Edit#1:
Here's what I tried so far (Assuming Barcode Scan works just like keyboard input):
(Using VB.Net for Windows CE 5.0 Device under VS2005)
Private Sub barcodeTB_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles barcodeTB.TextChanged
If (Len(barcodeTB.Text) = 10) Then 'If 10 digits ID have been scanned..
Using writer As IO.StreamWriter = New IO.StreamWriter("log.txt", True)
writer.WriteLine(barcodeTB.Text & " " & DateTime.Now)
End Using
barcodeTB.Text = "" 'reset TextBox
End If
End Sub
It works just fine when I input the code manually. But nil when I tried to scan my bar-code.
Edit#2:
There are several PDFs provided in their website: http://www.scantech-id.com/en/support/download.php?pin=42676d021abeff1e479180ffeb4240e5
I'm perfectly sure that the scanner is installed in COM3 port if it helps! Still trying to figure this out.
Edit#3:
So this is my last attempt: To read it directly via the DataReceived from COM3 Port.
I set a timer so that it sends the data transmitted every 1 second if there's any. It works nicely as the textbox only get updated when I scan my bar-code. However, the output is not in a desirable format. What am I doing wrong? See below:
And here's the code:
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, _
ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
Handles SerialPort1.DataReceived
Q.Enqueue(SerialPort1.ReadExisting())
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
SyncLock Q
While Q.Count > 0
receivedTB.Text &= Chr(13) & Chr(10) & Q.Dequeue
End While
End SyncLock
End Sub

Copy File on Modification FIleSystemWatcher, Visual Basic (VS 2012 V11)

After looking through many sites and some tutorial videos, I'm still stumped on this one. I'm finishing up a program and I need to add one last bit of functionality.
The program works this way. The user specifies a file in textbox1 and then specifies a directory in textbox2. The user sets how often they want the file to by copied in textbox3. The user hits run and the program copies the file to the new location, adding a number to the file name each time it is copied (to avoid overwrites). That all works fine, but I want the user to have the choice to either copy the file by time or when the file is modified.
How can I use the FileSystemWatcher to look for modification in the directory (given in textbox1) and then call the statement that copies the specified directory to the target destination (specified in textbox 2)?
Additional Note:
In one tutorial the FileSystemWatcher path was set up by doing this
Dim watched As String = System.IO.Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), "Pictures")
Dim fsw As New FileSystemWatcher(watched)
The path that the code directs to is "C:\Users[User Name]\Pictures" .
I can't find a resource online that shows what variables ".GetEnvironmentVariable" accepts or even what the variables mean. This is one of many reasons why I am having trouble with this last bit code.
GetEnvironmentVariable returns the value for the specified environment for the current process.
In the case of your example, USERPROFILE is the path to the folder for the current user. For example, on my laptop USERPROFILE is C:\Users\Tim.
The output of System.IO.Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), "Pictures") would be the USERPROFILE path plus "Pictures" - to continue with my example, it would be C:\Users\Tim\Pictures - which is the physical path to the My Pictures folder for my user account.
To get a list of all your environment variables, if you're curious, go to the DOS prompt and type in SET and hit return.
To answer your original question, you need to handle the FileSystemWatcher.Changed Event.
For example:
Private Shared Sub OnChanged(source As Object, e As RenamedEventArgs)
' Do your copy here
End Sub
You can hook the event handler up to your FileWatcher like this:
AddHandler fsw.Changed, AddressOf OnChanged
However, pay attention to this warning from the MSDN docs.
Common file system operations might raise more than one event. For example, when a file is moved from one directory to another, several OnChanged and some OnCreated and OnDeleted events might be raised. Moving a file is a complex operation that consists of multiple simple operations, therefore raising multiple events. Likewise, some applications (for example, antivirus software) might cause additional file system events that are detected by FileSystemWatcher.
This is the code I used it does what I want it to.
Option Explicit On
Option Strict On
Imports System.IO
Imports Microsoft.VisualBasic ' I don't know this one, but the code worked without this.
Imports System.Security.Permissions ' I don't know the exactly what this does but the
' http://msdn.microsoft.com/ site did this, I assume it'f to allow for permission to
' watch files? The code still worked for me without this
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.Load
Dim directoryPath As String = Path.GetDirectoryName(TextBox1.Text)
Dim varFileSystemWatcher As New FileSystemWatcher()
varFileSystemWatcher.Path = directoryPath
varFileSystemWatcher.NotifyFilter = (NotifyFilters.LastWrite)
varFileSystemWatcher.Filter = Path.GetFileName(TextBox1.Text) ' I know this
' limits what's being watched to one file, but right now this is
' what I want the program to do.
AddHandler varFileSystemWatcher.Changed, AddressOf OnChanged
varFileSystemWatcher.EnableRaisingEvents = True
End Sub
Private Sub OnChanged(source As Object, ByVal e As FileSystemEventArgs)
My.Computer.FileSystem.CopyFile(e.FullPath, TextBox2.Text & "\" & e.Name, True)
End Sub

Using Visual Basic to Select a Google Search Result in Internet Explorer

I have VB code that goes to Google, fills in the search bar, and hits the search button. Is there a way to have my program select a particular result after my search? ie. I search for "cheese", I would like for my program to select the 2nd to last result (in this case, it is wwww.chuckecheese.com)
I ended up using Sendkeys to emulate the tab and down arrow keys on the keyboard. You can then navigate to your desired search results using these 2 keys
Or you can bypass using an API and avoid ads or cost using speech recognition to improve your Dictation searches. Programming isn't programming if you aren't thinking outside the box and innovating your own solutions.
Coding comes with creativity and you won't know what that is if you don't try. This site is excellent for this very purpose and many have contributed to innovation in coding.
You will have to add a text file to your project and call it whatever you want, then change the path below in the code to your own path. The text file stays blank. The program will write your spoken search to file and then execute the search, constantly over-writing itself.
For some odd reason, this method greatly improves the fusion of speech recognition and dictation. You can speak an entire phrase and it will conduct the search. A good mic is a must and speaking clearly without background disturbances.
Imports System.Speech.Recognition
'Declarations:
Private ReadOnly Drone As New SpeechRecognitionEngine()
Private ReadOnly Qa As New DictationGrammar()
Private Sub Form1_Load(sender As Object,
e As EventArgs) Handles MyBase.Load
'Dictation Mode | Google Engine
Drone.LoadGrammarAsync(Qa)
Drone.RequestRecognizerUpdate()
Drone.SetInputToDefaultAudioDevice()
Drone.InitialSilenceTimeout = TimeSpan.FromSeconds(2.5)
Drone.BabbleTimeout = TimeSpan.FromSeconds(1.5)
Drone.EndSilenceTimeout = TimeSpan.FromSeconds(1.2)
Drone.EndSilenceTimeoutAmbiguous = TimeSpan.FromSeconds(1.5)
AddHandler Drone.SpeechRecognized, AddressOf Drone_SpeechRecognized
Drone.RecognizeAsync(RecognizeMode.Multiple)
End Sub
Private Sub Drone_SpeechRecognized(sender As Object, e As SpeechRecognizedEventArgs)
Dim google As String = e.Result.Text.ToString
Select Case (google)
Case google
If google <> "+" Then
'This section will take spoken word, write to file then execute search.
Dim sb As New StringBuilder
'Be sure to change the text file path below to your path if you are new to this program.
sb.AppendLine(google)
'Add your own path below here. you can also change google to youtube and conduct youtube searches
File.WriteAllText("C:\Users\justin.ross\source\repos\ScarlettCenturium\Scarlett Centurium\Scarlett Centurium\File.txt", sb.ToString())
google = "https://www.google.com/search?q=" & Uri.EscapeUriString(google)
Dim proc As New Process()
Dim startInfo As New ProcessStartInfo(google)
proc.StartInfo = startInfo
proc.Start()
'This sendkey will close out previous tab on new search
SendKeys.Send($"^{{w}}")
Return
End If
End Select
End Sub
well you can use google api for that
goto http://code.google.com/p/google-api-for-dotnet/
download GoogleSearchAPI_0.4_alpha.zip
extract it and add reference to the dll file in your project ( in folder .net 2)
and you can use it like this
first import the library
Imports Google.API.Search
then in a sub or function put your code as
Dim rf As String = "http://www.google.com"
Dim v As New Google.API.Search.GwebSearchClient(rf)
Dim result = v.Search(TextBox1.Text, 40)
' number (40) is the amount of fetched results ( change it if you want )
For Each item In result
If item.Url.Contains("chuckecheese") Then
' your code goes here
End If
Next

Converting C# to VB.net is not working

I have translated some code from C# to VB.net for the purpose of getting Folder Browser functionality. The link to the code is here.....
http://www.codeproject.com/KB/aspnet/DirectoryBrowsing.aspx
My issue is that I have not been able to correcly translate these two lines of code to VB.net.
TreeView1.TreeNodeExpanded +=new TreeNodeEventHandler(TreeView1_TreeNodeExpanded);
TreeView1.SelectedNodeChanged += new EventHandler(TreeView1_SelectedNodeChanged);
Every translator I have used has simply dropped the semicolon from the end of each line. But the editor still does not like them.
I could some help with this as it seems this effects the refresh of the selected folder in the tree view control.
I don't get to see the C drive folder unless I type the path in the text box, and the folder will still not expand.
thank you,
Use this:
AddHandler TreeView1.TreeNodeExpanded, AddressOf TreeView1_TreeNodeExpanded
AddHandler TreeView1.SelectedNodeChanged, AddressOf TreeView1_SelectedNodeChanged
Edit:
A different way to do this would be to apply it at the method level:
Protected Sub TreeView1_TreeNodeExpanded(ByVal sender as Object, ByVal e as TreeNodeEventArgs) Handles TreeView1.TreeNodeExpanded
' Some code
End Sub
Protected Sub TreeView1_SelectedNodeChanged(ByVal sender as Object, ByVal e as EventArgs) Handles TreeView1.SelectedNodeChanged
' Some code
End Sub
You should run this in debug to find out what exactly is going on. I find a lot of times when events of this nature are run in asp.net, you have a conflicting event that "resets" the controls you are attempting to change.

VB.NET - DirectX.AudioVideoPlayback gives incorrect frame size?

Hey, making a media player and need to know something.
I have a menu which reads file info, but for some reason, when I open a video that I KNOW is 1280x720, the width and height come up as 1292x758.
Edit:
When I open a video which is 640x480, it says it's 656x518
That, and an extra preview box pops up due to:
labFR.Text = "Frame rate: " & Strings.FormatNumber((1 / AudioVideoPlayback.Video.FromFile(labinput.text, True).AverageTimePerFrame), 3)
This needs to be playing so I can get the frame rate, but how to I close it once I have the frame rate?
Working in VB.NET Framework 4.0. (VS2010)
Answers to either of these problems are highly appreciated.
Got it. I have to Dim the Video outside of all the modules with autoplay set to false, then I can grab all the properties from the video without constantly opening the video on several threads over and over.
Dim openerfile As Video
Public Sub btnInputBrowse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnInputBrowse.Click
openerfile = Video.FromFile(labinputfile.Text, False) 'labinputfile is a textbox which is given the path of an openfiledialog
End Sub
Then all I have to do is use "openerfile" and its properties for what I wish.