recording microphone audio using NAudio in a console application - c#

my code runs and creates a test.wav but this file dosent contain aything. i am trying to run this code in a console application. please help
using System;
using System.Media;
using NAudio;
using NAudio.Wave;
class sound
{
public static void Main()
{
WaveInCapabilities deviceInfo = WaveIn.GetCapabilities(0);
Console.WriteLine("Now recording...");
WaveInEvent waveSource = new WaveInEvent();
waveSource.DeviceNumber = 0;
waveSource.WaveFormat = new WaveFormat(16000, deviceInfo.Channels);
//waveSource.DataAvailable += new EventHandler<WaveInEventArgs>(waveSource_DataAvailable);
string tempFile = (#"C:\Users\user\Desktop\test1.wav");
WaveFileWriter waveFile = new WaveFileWriter(tempFile, waveSource.WaveFormat);
waveSource.StartRecording();
}
//void waveInStream_DataAvailable(object sender, WaveInEventArgs e)
//{
// wavefile.WriteData(e.Buffer, 0, e.BytesRecorded);
//}
}
and can someone please explain what do the lines which are commented mean. i am a beginner in programming.
when i compile the program it gives 2 errors:
Error 1: An object reference is required for the non-static field, method, or property 'sound.waveSource_DataAvailable(object, NAudio.Wave.WaveInEventArgs)' C:\Users\user\Documents\Visual Studio 2008\Projects\sound\sound\Program.cs 18 49 sound
Error 2 The name 'wavefile' does not exist in the current context C:\Users\user\Documents\Visual Studio 2008\Projects\sound\sound\Program.cs 28 21 sound

Apparently the StartRecording methods start some capture loops that periodically raises the DataAvailable event to allow the user collecting the recorded data. In your example code the event handle properly append the recorded data to the file tempFile. Both the function waveInStream_DataAvailable and the waveFile must be declared as static.

Try this:
using System;
using System.Media;
using NAudio;
using NAudio.Wave;
class sound
{
static WaveFileWriter waveFile;
public static void Main()
{
//WaveInCapabilities deviceInfo = WaveIn.GetCapabilities(0);
Console.WriteLine("Now recording...");
WaveInEvent waveSource = new WaveInEvent();
//waveSource.DeviceNumber = 0;
waveSource.WaveFormat = new WaveFormat(44100, 1);
waveSource.DataAvailable += new EventHandler<WaveInEventArgs>(waveSource_DataAvailable);
string tempFile = (#"C:\Users\user\Desktop\test1.wav");
waveFile = new WaveFileWriter(tempFile, waveSource.WaveFormat);
waveSource.StartRecording();
Console.WriteLine("Press enter to stop");
Console.ReadLine();
waveSource.StopRecording();
waveFile.Dispose();
}
static void waveSource_DataAvailable(object sender, WaveInEventArgs e)
{
waveFile.WriteData(e.Buffer, 0, e.BytesRecorded);
}
}

Related

Naudio and Syn speech null reference error when reading from memory stream

I'm pretty sure i'm doing this right but I can't seem to figure out what is causing this error or how to fix it. Any help would be appreciated. The code is below with the error below that.
Code. I posted all of it since I do not know what is relevant for this error.
public class voiceStuff
{
public WaveInEvent waveInStream;
private static StreamSpeechRecognizer _recognizer;
WaveFileWriter writer;
private MemoryStream mem;
public void record()
{
waveInStream.NumberOfBuffers = 2;
waveInStream.StartRecording();
recognize();
}
public void recognize()
{
Console.ReadKey();
waveInStream.StopRecording();
}
public voiceStuff()
{
Logger.LogReceived += Logger_LogReceived;
waveInStream = new WaveInEvent();
waveInStream.NumberOfBuffers =2;
waveInStream.WaveFormat = new WaveFormat(16000, 1);
mem = new MemoryStream();
writer = new WaveFileWriter(mem, waveInStream.WaveFormat);
waveInStream.DataAvailable += onDataAvailable;
var modelPath = Path.Combine(Directory.GetCurrentDirectory(), "model/en-us");
var dictionaryPath = Path.Combine(modelPath, "cmudict-en-us.dict");
var languageModelPath = Path.Combine(modelPath, "en-us.lm.dmp");
var configuration = new Configuration
{
AcousticModelPath = modelPath,
DictionaryPath = dictionaryPath,
LanguageModelPath = languageModelPath,
UseGrammar = true,
GrammarPath = "Models",
GrammarName = "hello"
};
_recognizer = new StreamSpeechRecognizer(configuration);
waveInStream.StartRecording();
Console.ReadKey();
waveInStream.StopRecording();
Thread.Sleep(50);
_recognizer.StartRecognition(mem, new TimeFrame(mem.Length));
SpeechResult result = _recognizer.GetResult();
_recognizer.StopRecognition();
Console.WriteLine("result: " + result?.GetHypothesis());
//syn speech
}
public void onDataAvailable(object sender, WaveInEventArgs e)
{
writer.Write(e.Buffer, 0, e.BytesRecorded);
}
static void Logger_LogReceived(object sender, LogReceivedEventArgs e)
{
Console.WriteLine(e.Message);
}
}
Error
9/12/2016 9:55:42 PM Error StreamSpeechRecognizer System.NullReferenceException: Object reference not set to an instance of an object.
at Syn.Speech.Linguist.Dictionary.TextDictionary.Allocate()
at Syn.Speech.Linguist.Language.Grammar.Grammar.Allocate()
at Syn.Speech.Linguist.Flat.FlatLinguist.Allocate()
at Syn.Speech.Decoders.Search.SimpleBreadthFirstSearchManager.Allocate()
at Syn.Speech.Recognizers.Recognizer.Allocate()
at Syn.Speech.Api.StreamSpeechRecognizer.StartRecognition(Stream stream, TimeFrame timeFrame)
9/12/2016 9:55:42 PM Error StreamSpeechRecognizer Syn.Speech.Helper.IllegalStateException: Expected state Ready actual state Allocating
at Syn.Speech.Recognizers.Recognizer.CheckState(State desiredState)
at Syn.Speech.Recognizers.Recognizer.Recognize(String referenceText)
at Syn.Speech.Api.AbstractSpeechRecognizer.GetResult()
9/12/2016 9:55:42 PM Error StreamSpeechRecognizer Syn.Speech.Helper.IllegalStateException: Expected state Ready actual state Allocating
at Syn.Speech.Recognizers.Recognizer.CheckState(State desiredState)
at Syn.Speech.Recognizers.Recognizer.Deallocate()
at Syn.Speech.Api.StreamSpeechRecognizer.StopRecognition()
At the very least you will need to Dispose your WaveFileWriter in order to finalise the WAV file structure. However, beware of disposing the memory stream as well. I usually wrap it in NAudio's utility class IgnoreDisposeStream
Then you need to rewind your MemoryStream to the start before passing it on to the speech recognition.

Unexpected Error: An unhandled exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll

I'm building a windows forms program on Visual Studio 2013 (C#) which reads data from Serial Port (in my case - Arduino) and use it to change a picture. The Arduino returns an 8-bit string of 0's and 1's, which indicates what picture to change. For example - if the string is 10001001 the program should change the 1'st, 5'th and 8'th picture. The program is able to get the correct string from the Serial Port (via Serial Communication), but when I added a method that makes the picture to change, it sometimes gives me this error:
An unhandled exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
and point that line on Program.cs:
Application.Run(new Form1());
(My form name is "form1.cs" and the namespace is serial_read)
Here's what the program looks like:
And here's my form1.cs code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
namespace Serial_receive
{
public partial class Form1 : Form
{
SerialPort serialPort1 = new SerialPort(); //Defines Serial Port
public Form1()
{
InitializeComponent();
serialPort1.BaudRate = 9600;
serialPort1.DtrEnable = true;
foreach (string port in SerialPort.GetPortNames()) {comboBox1.Items.Add(port);} //Gives a list of the available ports
serialPort1.DataReceived += serialPort1_DataReceived;
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string line = serialPort1.ReadLine(); //The serial string
this.BeginInvoke(new LineReceivedEvent(LineReceived), line);
}
private delegate void LineReceivedEvent(string line);
//Change image to a different image
private void changeColor(PictureBox ob, string line, int l) //ob = PictureBox, line = the serial string, l = number of PictureBox
{
if (int.Parse(line.Substring(l, 1)) == 1)
ob.Image = Serial_receive.Properties.Resources.red;
}
private void LineReceived(string line)
{
label1.Text = line;
changeColor(l1, line, 0); //Picture 1
changeColor(l2, line, 1); //Picture 2
changeColor(l3, line, 2); //Picture 3
changeColor(l4, line, 3); //Picture 4
changeColor(l5, line, 4); //Picture 5
changeColor(l6, line, 5); //Picture 6
changeColor(l7, line, 6); //Picture 7
changeColor(l8, line, 7); //Picture 8
}
private void button1_Click(object sender, EventArgs e) //Start Button
{
serialPort1.PortName = comboBox1.Text.ToString();
if (comboBox1.Text.ToString() == "Select Port... (Default: COM4)" || comboBox1.Text.ToString() == "")
serialPort1.PortName = "COM4";
serialPort1.Open();
button1.Enabled = false;
}
}
}
Any ideas why I get this error? I'm kinda new to C# and don't really know what's the problem..

'Emgu.CV.Invoke' threw an exception

I am relativity new EmguCV but I have done a lot of research and read a few tutorials and look through this site for the answer. All of the other people with similar problems are told to add the unmangaged dll to the output folder. I have done this and I am still getting this error 'Emgu.CV.Invoke' threw an exception.
using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;
using AForge;
using AForge.Video;
using AForge.Video.DirectShow;
using AForge.Video.VFW;
using System.Drawing.Imaging;
using System.IO;
namespace WindowsFormsApplication2
{
public partial class SandBox : Form
{
private bool DeviceExist = false;
public VideoCaptureDevice FinalVideoSource;
public FilterInfoCollection VideoCaptureDevices;
private Capture capture;
private VideoWriter captureOutput;
private void FinalVideoSource_NewFrame(object sender, AForge.Video.NewFrameEventArgseventArgs)
{
Bitmap image = (Bitmap)eventArgs.Frame.Clone();
image.RotateFlip(RotateFlipType.Rotate180FlipY);
pictureBox1.Image = image;
}
public SandBox()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
label1.Text = " ";
FPS.Text = " ";
try
{
VideoCaptureDevices = new FilterInfoCollection(AForge.Video.DirectShow.FilterCategory.VideoInputDevice);
DeviceExist = true;
foreach (AForge.Video.DirectShow.FilterInfo VideoCaptureDevice in VideoCaptureDevices)
{
comboBox1.Items.Add(VideoCaptureDevice.Name);
}
comboBox1.SelectedIndex = 0;
}
catch (ApplicationException)
{
DeviceExist = false;
comboBox1.Items.Add("No device on your system");
}
}
private void Start_Click(object sender, EventArgs e)
{
FinalVideoSource = new VideoCaptureDevice(VideoCaptureDevices[comboBox1.SelectedIndex].MonikerString);
FinalVideoSource.NewFrame += new NewFrameEventHandler(FinalVideoSource_NewFrame);
FinalVideoSource.Start();
label1.Text = "Device running...";
Start.Enabled = false;
Stop.Enabled = true;
timer1.Enabled = true;
capture = new Capture();
captureOutput = new VideoWriter("test.avi", 30, 1280, 720, true);
Image<Bgr, Byte> ImageFrame = capture.QueryFrame();
captureOutput.WriteFrame(ImageFrame);
}
}
The error is being thrown in line capture = new Capture();. I cant figure out what is wrong with the project. Just to clarify I am only using EmguCV to record video not to display it on screen. Any help would be greatly appreciated.
The type initializer for 'Emgu.CV.CvInvoke' threw an exception its means that EMGU.CV file is not dectecting by code. this is due to system dependency. you need to go in to configration manger window in visual stdio and choose your required platform and then copy respective dll files(64 dll files forx64 and 32bit dll for x86 can be downloaded from emgu website ) according to your platform. copile it now there is no error like emgu.cv.invoke
http://www.emgu.com/wiki/index.php/Setting_up_EMGU_C_Sharp

AxWindowsMediaPlayer Clip Will Sometimes Not Play

I have a simple one-threaded windows forms .NET 4.5 app where user listens to spoken words (wav files) and then selects the correct picture that represents the word.
The problem is that the clip will sometimes (very rarely - about 1% of the time and completelly at random) not play...
This is the method for playing clips:
public static void PlayWordAudio(Word word, AxWMPLib.AxWindowsMediaPlayer player)
{
string tempFile = Path.GetTempFileName() + ".wav";
MemoryStream stream = new MemoryStream(word.Audio);
using (Stream fileStream = File.OpenWrite(tempFile))
{
stream.WriteTo(fileStream);
}
player.URL = tempFile;
File.Delete(tempFile);
}
Can someone please suggest a solution to this problem? Maybe I shouldn't delete the file at the end of the method? But then temp files would pile up...
I am on Windows 7...
I guess the file is being deleted quicker than it can get played.
Can you try this in stead of File.Delete(tempFile); utilizing the PlayStateChange event
player.PlayStateChange += (snd, psce) => {
switch (psce.newState)
{
case 1: // Stopped (maybe use 12 => Last )
File.Delete(tempFile);
break;
default:
Debug.WriteLine(psce.newState);
break;
}
};
You might have to unsubscribe the event if you keep the player object around a long time.
It seems that I solved the problem... it was in fact the deletion of file that caused this...
solution:
public static void PlayWordAudio(Word word, AxWMPLib.AxWindowsMediaPlayer player)
{
string tempFile = Path.GetTempFileName() + ".wav";
MemoryStream stream = new MemoryStream(word.Audio);
using (Stream fileStream = File.OpenWrite(tempFile))
{
stream.WriteTo(fileStream);
}
player.URL = tempFile;
RunDelayed(5000, File.Delete, tempFile); //if we delete file immediately then clip sometimes would not be played
}
public delegate void DelayedFuncion(string param);
public static void RunDelayed(int delay, DelayedFuncion function, string param = null)
{
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
DelayedArgs args = new DelayedArgs() { delayedFunction = function, param = param };
timer.Tag = args;
timer.Tick += TimerElapsed;
timer.Interval = delay;
timer.Start();
}
private static void TimerElapsed(object sender, EventArgs e)
{
System.Windows.Forms.Timer timer = sender as System.Windows.Forms.Timer;
timer.Stop();
DelayedArgs args = timer.Tag as DelayedArgs;
args.delayedFunction(args.param);
}
class DelayedArgs
{
public Util.DelayedFuncion delayedFunction;
public string param;
}

Playing a .wav file using naudio, playback stops after 1 sec

I'm using the naudio lib in C# and want to play a simple file. The problem is, the playback stops after 1 second. I cant figure out the reason why it does that.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NAudio.Wave;
namespace NAudioTest
{
class Program
{
static IWavePlayer waveout;
static WaveStream outputStream;
static string filename = null;
static void Main(string[] args)
{
waveout = new WaveOut();
filename = "C:\\1.wav";
outputStream = CreateInputStream(filename);
try
{
waveout.Init(outputStream);
}
catch (Exception ex)
{
Console.WriteLine("Error while loading output");
Console.WriteLine("Details: " + ex.Message);
Console.ReadLine();
return;
}
Console.WriteLine("Press [Enter] to start playback");
Console.ReadLine();
waveout.Play(); //this stops after 1 sec. should it play until i hit enter cause of the next line?
Console.WriteLine("Press [Enter] to abort");
Console.ReadLine();
waveout.Dispose();
Console.ReadLine();
}
static WaveStream CreateInputStream(string name)
{
WaveChannel32 inputStream;
if (name.EndsWith(".wav"))
{
WaveStream readerStream = new WaveFileReader(name);
if (readerStream.WaveFormat.Encoding != WaveFormatEncoding.Pcm)
{
readerStream = WaveFormatConversionStream.CreatePcmStream(readerStream);
readerStream = new BlockAlignReductionStream(readerStream);
}
if (readerStream.WaveFormat.BitsPerSample != 16)
{
var format = new WaveFormat(readerStream.WaveFormat.SampleRate, 16, readerStream.WaveFormat.Channels);
readerStream = new WaveFormatConversionStream(format, readerStream);
}
inputStream = new WaveChannel32(readerStream);
}
else
{
throw new InvalidOperationException("Invalid extension");
}
return inputStream;
}
}
}
You need to make sure you are using function callbacks if you are trying to play audio from a console app, since the default for WaveOut is to use window callbacks.
new WaveOut(WaveCallbackInfo.FunctionCallback())
Update: With newer versions of NAudio I now recommend that you avoid function callbacks, as they can cause deadlocks with certain drivers. Instead, WaveOutEvent which uses event callbacks and a background thread is the preferred mechanism:
new WaveOutEvent()

Categories

Resources