System.Speech Voice Recognition not working - c#

I am using c# system.speech , and i have limited number of sentences that i wants to recognize. Here is code
SpeechRecognitionEngine recognizer = new SpeechRecognitionEngine();
String[] Sentences = File.ReadAllLines(samplePath);
Choices sentences = new Choices();
sentences.Add(Sentences);
GrammarBuilder gBuilder = new GrammarBuilder(sentences);
Grammar g = new Grammar(gBuilder);
g.Enabled = true;
recognizer.LoadGrammar(g);
try
{
recognizer.SetInputToWaveFile(filePath);
RecognitionResult result = recognizer.Recognize();
String ret = result.Text;
recognizer.Dispose();
return ret;
}
catch (InvalidOperationException exception) { }
return "";
This code throws exception when I give it some wav file and reason of exception is it can't find match in sample sentences. Can I force it so it must select on sentence?

You are getting NullReferenceException because the format of your .wav file's format is different than how System.Speech.Recognition.SpeechRecognitionEngine is trying to analyse .wav files by default when using the SetInputToWaveFile method.
In order to change the read format you should use the SetInputToAudioStream method instead:
using (FileStream stream = new FileStream("C:\\3.wav", FileMode.Open))
{
recognizer.SetInputToAudioStream(stream, new SpeechAudioFormatInfo(5000, AudioBitsPerSample.Sixteen, AudioChannel.Stereo));
RecognitionResult result = recognizer.Recognize();
string ret = result.Text;
}
This way it reads your .wav file as a stereo file, at 16bps and with 5000 samples per second as your .wav file is really encoded.
Note: this solved the problem for me ON YOUR FILE

Related

Convert Postscript to Text file using ghostscript

my client wants me to do one task. which is whenever I print ctrl+P from the browser it will go automatically that contents to the database which is sql.
Now, Let me explain what I have tried to achieve this. Usually printerPlusPlus which is third party tool. Which adds virtual printer and prints the files PS to the temp directory than I can read the contents of that postscript file and save it to the database.
My real question is there anything from which I can convert this post script files to text or read them and save the texts to the database?
Or is there any better way to achieve this task?
Ghostscript is the alternate and ow-some feature to convert the postscripts to the text or pdf. But, I am completely clueless about the documentation and how to execute their commands.
_viewer.Interpreter.RunFile("C:\\PrinterPlusPlus\\Temp\\ankit_SONY-VAIO_sony_20151227_185020_3.ps");
GhostscriptPngDevice dev = new GhostscriptPngDevice(GhostscriptPngDeviceType.Png16m);
dev.GraphicsAlphaBits = GhostscriptImageDeviceAlphaBits.V_4;
dev.TextAlphaBits = GhostscriptImageDeviceAlphaBits.V_4;
dev.ResolutionXY = new GhostscriptImageDeviceResolution(96, 96);
dev.InputFiles.Add(#"C:\\PrinterPlusPlus\\Temp\\ankit_SONY-VAIO_sony_20151227_185020_3.ps");
dev.OutputPath = #"C:\\PrinterPlusPlus\\Temp\\ankit_SONY-VAIO_sony_20151227_185020_3.txt";
dev.Process();
_preview.Activate();
I tried this but this seems to be not working and adding ASCII text to the txt file.
I found ghostscript little confusing. But, I found the solution from here
string inputFile = #"E:\gss_test\test_postscript.ps";
GhostscriptPipedOutput gsPipedOutput = new GhostscriptPipedOutput();
// pipe handle format: %handle%hexvalue
string outputPipeHandle = "%handle%" + int.Parse(gsPipedOutput.ClientHandle).ToString("X2");
using (GhostscriptProcessor processor = new GhostscriptProcessor())
{
List<string> switches = new List<string>();
switches.Add("-empty");
switches.Add("-dQUIET");
switches.Add("-dSAFER");
switches.Add("-dBATCH");
switches.Add("-dNOPAUSE");
switches.Add("-dNOPROMPT");
switches.Add("-sDEVICE=pdfwrite");
switches.Add("-o" + outputPipeHandle);
switches.Add("-q");
switches.Add("-f");
switches.Add(inputFile);
try
{
processor.StartProcessing(switches.ToArray(), null);
byte[] rawDocumentData = gsPipedOutput.Data;
//if (writeToDatabase)
//{
// Database.ExecSP("add_document", rawDocumentData);
//}
//else if (writeToDisk)
//{
// File.WriteAllBytes(#"E:\gss_test\output\test_piped_output.pdf", rawDocumentData);
//}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
gsPipedOutput.Dispose();
gsPipedOutput = null;
}
}
This reads the postscript files easily :)

Handle setting up WaveFormat for mp3 memory stream in NAudio

I'm trying to set up the WaveStream so that it uses the same format as the mp3 data passed in. I get the format by reading a frame, but when I try to actually create the new conversion stream using the new format I get an "AcmNotPossible calling AcmStreamOpen" exception.
Here's where I'm trying to set the new format:
Mp3Frame f = Mp3Frame.LoadFromStream(ms);
WaveFormat targetFormat = new Mp3WaveFormat(f.SampleRate, f.ChannelMode == ChannelMode.Mono ? 1 : 2, f.FrameLength, f.BitRate);
WaveFormatConversionStream conversionStream;
try
{
using (WaveStream blockAlignedStream =
new BlockAlignReductionStream(conversionStream = new WaveFormatConversionStream(targetFormat,
new Mp3FileReader(ms))))
{
using (WaveOut waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))
{
waveOut.Init(blockAlignedStream);
waveOut.Play();
I'm not sure if I even need to convert anything if I set up the wave stream to match the format of the mp3 data.
NOTE: I tried using WaveFormatStream.CreatePcmStream but I was getting 'static/white noise' for some mp3's. They appeared to be 16bit 44,100 stereo, but were being labeled as Version 1, Layer 1, as opposed to version 1, layer 3 which plays back correctly.
This code sample seems to have come from a long time back. You don;t need the BlockAlignReductionStream or the WaveFormatConversionStream, and you should stay away from function callbacks in WaveOut. This should be sufficient to play from a memory stream:
var reader = new Mp3FileReader(ms)
var waveOut = new WaveOutEvent();
waveOut.Init(reader);
waveOut.Play();

C# How Can I Play A Video From A Memory Stream Using DirectShow(quartz.dll)?

I have a C# Visual Studio WinForms .NET app that plays video using the QuartzTypeLib (quartz.dll). With the code I've written, I can play any video file from the hard drive.
Here's the code at the top that executes when the app starts:
public const int WS_CHILD = 0x40000000;
public const int WS_CLIPCHILDREN = 0x2000000;
public QuartzTypeLib.IMediaControl mc;
public QuartzTypeLib.IVideoWindow videoWindow = null;
IMediaPosition mp = null;
And here's the code that opens the video file:
private void openMediaToolStripMenuItem_Click(object sender, EventArgs e)
{
// Open a media file.
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Video Files|*.mpg;*.avi;*;*.wmv;*.mov";
ofd.FilterIndex = 1;
if (DialogResult.OK == ofd.ShowDialog())
{
// Stop the playback for the current movie if a video is currently playing.
if (mc != null)
mc.Stop();
if (pbVideoDisplay.Image != null)
pbVideoDisplay.Image = null;
// Load the movie file.
FilgraphManager graphManager = new FilgraphManager();
graphManager.RenderFile(ofd.FileName);
mp = graphManager as IMediaPosition;
mc = (IMediaControl)graphManager;
tsbtnPlay.Enabled = tsbtnPause.Enabled = tsbtnStop.Enabled = true;
// Attach the view to the picture box (pbVideoDisplay) on frmMain.
try
{
videoWindow = (IVideoWindow)graphManager;
videoWindow.Owner = (int)pbVideoDisplay.Handle;
videoWindow.WindowStyle = WS_CHILD | WS_CLIPCHILDREN;
videoWindow.SetWindowPosition(
pbVideoDisplay.ClientRectangle.Left,
pbVideoDisplay.ClientRectangle.Top,
pbVideoDisplay.ClientRectangle.Width,
pbVideoDisplay.ClientRectangle.Height);
}
catch //(Exception Ex)
{
// I'll write code for this when I have a need to.
}
// Now we convert the video to a byte array.
FileStream fs = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read);
try
{
// Here we convert the video to Base 64.
VideoInBytes = new byte[fs.Length];
VideoInBytes = System.Text.Encoding.UTF8.GetBytes(ofd.FileName);
VideoInBase64 = Convert.ToBase64String(VideoInBytes);
}
catch //(Exception Ex)
{
//throw new Exception("Error in base64Encode" + Ex.Message);
}
}
}
Notice that I have code that converts the video to a Base64 string. This string will obviously have to be loaded into a memory stream. I'd like to add code that will allow me to play a video from a memory stream. Is that even possible with DirectShow and if so, what code would I need to add and where would I put it?
The DirectShow way is to create a special so-called filter (source filter) that outputs video data and then add it to the graph chain.
Usually a filter is written in C++. Of course almost any code that can be written in C++ can be rewritten in C#. It could take a lot of work, for instance look at this article:
http://www.codeproject.com/Articles/421167/Pure-NET-DirectShow-Filters-in-Csharp
Another way is file emulation. In this case you would need 3rd party solution like BoxedApp.
The idea is to intercept some file functions like SetFilePointer and ReadFile, to provide data as it is written from a real file (but in fact it is read from memory).

I want change wav file 16 kHz 16 bit to 8 kHz 16 bit mono C# NAudio

Code not working, please check out and sey me what i wrong writing?! please help.
openFileDialog openFileDialog = new openFileDialog();
openFileDialog.Filter = ("Wave Files (*.wav)|*.wav|All Files (*.*)|*.*");
openFileDialog.FilterIndex = 1;
WaveFileReader reader = new NAudio.Wave.WaveFileReader(dpmFileDestPath);
WaveFormat newFormat = new WaveFormat(8000, 16, 1);
WaveFormatConversionStream str = new WaveFormatConversionStream(newFormat, reader);
try
{
WaveFileWriter.CreateWaveFile("C:\\Konvertierten_Dateien.wav", str);
}
catch (Exception ex)
{
MessageBox.Show(String.Format("{0}", ex.Message));
}
finally
{
str.Close();
}
MessageBox.Show("Konvertieren ist Fertig!");
}
this is a code and not working.
If you are trying to change channel count and sample rate at the same time, do it in two steps. E.g. first go stereo to mono, then go 44.1kHz to 8kHz. Without seeing the WaveFormat of your incoming file though or the exception you get, I can't say exactly what the issue is.

NAudio to split mp3 file

I am very new to audio or mp3 stuff, was looking for a way to have a feature to split an mp3 file in C#, asp.net. After googling for a good 3-day without much of a great help, I am hoping that somebody here can point me to a right direction.
Can I use NAudio to accomplish this? Is there any sample code for that? Thanks in advance.
My final solution to split mp3 file in c# is to use NAudio. Here is a sample script for that, hope it helps someone in the community:
string strMP3Folder = "<YOUR FOLDER PATH>";
string strMP3SourceFilename = "<YOUR SOURCE MP3 FILENAMe>";
string strMP3OutputFilename = "<YOUR OUTPUT MP3 FILENAME>";
using (Mp3FileReader reader = new Mp3FileReader(strMP3Folder + strMP3SourceFilename))
{
int count = 1;
Mp3Frame mp3Frame = reader.ReadNextFrame();
System.IO.FileStream _fs = new System.IO.FileStream(strMP3Folder + strMP3OutputFilename, System.IO.FileMode.Create, System.IO.FileAccess.Write);
while (mp3Frame != null)
{
if (count > 500) //retrieve a sample of 500 frames
return;
_fs.Write(mp3Frame.RawData, 0, mp3Frame.RawData.Length);
count = count + 1;
mp3Frame = reader.ReadNextFrame();
}
_fs.Close();
}
Thanks to Mark Heath's suggestion for this.
The namespace required is NAudio.Wave.
An MP3 File is made up of a sequence of MP3 frames (plus often ID3 tags on the beginning and end). The cleanest way to split an MP3 file then is to copy a certain number of frames into a new file (and optionally bring the ID3 tags along too if that is important).
NAudio's MP3FileReader class features a ReadNextFrame method. This returns an MP3Frame class, which contains the raw data as a byte array in the RawData property. It also includes a SampleCount property which you can use to accurately measure the duration of each MP3 Frame.
The previous answers helped me get started. NAudio is the way to go.
For my PodcastTool I needed to to split podcasts at 2 minute intervals to make seeking to a specific place faster.
Here's the code to split an mp3 every N seconds:
var mp3Path = #"C:\Users\ronnie\Desktop\mp3\dotnetrocks_0717_alan_dahl_imagethink.mp3";
int splitLength = 120; // seconds
var mp3Dir = Path.GetDirectoryName(mp3Path);
var mp3File = Path.GetFileName(mp3Path);
var splitDir = Path.Combine(mp3Dir,Path.GetFileNameWithoutExtension(mp3Path));
Directory.CreateDirectory(splitDir);
int splitI = 0;
int secsOffset = 0;
using (var reader = new Mp3FileReader(mp3Path))
{
FileStream writer = null;
Action createWriter = new Action(() => {
writer = File.Create(Path.Combine(splitDir,Path.ChangeExtension(mp3File,(++splitI).ToString("D4") + ".mp3")));
});
Mp3Frame frame;
while ((frame = reader.ReadNextFrame()) != null)
{
if (writer == null) createWriter();
if ((int)reader.CurrentTime.TotalSeconds - secsOffset >= splitLength)
{
// time for a new file
writer.Dispose();
createWriter();
secsOffset = (int)reader.CurrentTime.TotalSeconds;
}
writer.Write(frame.RawData, 0, frame.RawData.Length);
}
if(writer != null) writer.Dispose();
}
these would be helpful Alvas Audio (commercial) and ffmpeg
If you want to split podcasts, copy the tracks to an audio device (swimming headers in my case) and include a little audio header made from the Text To Speech service from Google to identify the tracks. (e.g. "History of the world in a hundred objects. Episode 15. Track 1 of 4") you could check a little bash script https://github.com/pulijon/cpodcast/blob/main/cutpodcast.bash
It is prepared to add the audio header in Spanish. For other languages you should change the option -l and the string of header
gtts-cli "Corte $((10#$ntrack)) de $((10#$numtracks)). $5 " -l es --output pre_$track

Categories