How transfer system mic audio stream to attached device mic audio stream - c#

I am trying to attach USB device used for tele calling which have pnp sound controller for mic and speaker. Now i have two speaker and two mic for input output as shown in image below.. Now my motive is to transfer audio stream from system mic to usb mic and from usb speaker to system speaker.
I tried to solve this issue with virtual cable software but with this i need to depend on third party. What can be the possible solution that can attained using c#.
I don't have knowledge about this, so don't know how to start. After googling i found
CS Core
N Audio
Can help me i don't know how.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
List<NAudio.Wave.WaveInCapabilities> sources = new List<NAudio.Wave.WaveInCapabilities>();
for (int i = 0; i < NAudio.Wave.WaveIn.DeviceCount; i++)
{
sources.Add(NAudio.Wave.WaveIn.GetCapabilities(i));
}
sourceList.Items.Clear();
foreach (var source in sources)
{
ListViewItem item = new ListViewItem(source.ProductName);
item.SubItems.Add(new ListViewItem.ListViewSubItem(item, source.Channels.ToString()));
sourceList.Items.Add(item);
}
}
NAudio.Wave.WaveIn sourceStream,sourceStream1 = null;
NAudio.Wave.DirectSoundOut waveOut = null;
private void button2_Click(object sender, EventArgs e)
{
if (sourceList.SelectedItems.Count == 0) return;
int deviceNumber = sourceList.SelectedItems[0].Index;
sourceStream = new NAudio.Wave.WaveIn();
sourceStream.DeviceNumber = 0;
sourceStream.WaveFormat = new NAudio.Wave.WaveFormat(44100, NAudio.Wave.WaveIn.GetCapabilities(deviceNumber).Channels);
NAudio.Wave.WaveInProvider waveIn = new NAudio.Wave.WaveInProvider(sourceStream1);
sourceStream.
waveOut = new NAudio.Wave.DirectSoundOut();
waveOut.Init(waveIn);
sourceStream1.StartRecording();
waveOut.Play();
}
private void button3_Click(object sender, EventArgs e)
{
if (waveOut != null)
{
waveOut.Stop();
waveOut.Dispose();
waveOut = null;
}
if (sourceStream != null)
{
sourceStream.StopRecording();
sourceStream.Dispose();
sourceStream = null;
}
}
private void button4_Click(object sender, EventArgs e)
{
button3_Click(sender, e);
this.Close();
}
}
Using this code i can send mic audio to speaker but how can i implement my task using this.

Actually there is no way to do this without writing any custom driver. You can not render audio data to a input device. Input devices are meant to read data from. Output devices (speakers) are meant to write data to.
There are programs like virtual audio cable, which are using custom drivers to bypass these limitations.

Related

Speech Recognition Engine Audio Device

I am attempting to use a different input device with Speech Recognition Engine. I have attempted to use NAudio to achieve this, using WaveIn and the DataAvailable event, however I can't quite work out how to convert the buffer from the event into a stream usable with speech recognition engine's SetInputToAudioStream(). My current code looks like:
using System.Speech.Recognition;
using NAudio.Wave;
private SpeechRecognition sre;
private WaveInEvent wi;
private Stream st;
static void main(string[] args) {
Choices words = new Choices(new string[] { "word", "test" });
Grammar g = new Grammar(words);
wi = new WaveInEvent();
wi.DeviceNumber = 0; // Default device
wi.DataAvailable += Wi_DataAvailable;
wi.StartRecording();
st = new MemoryStream();
sre = new SpeechRecognitionEngine();
sre.LoadGrammar(g);
//sre.SetInputToDefaultAudioDevice();
sre.SetInputToAudioStream(st, /* SpeechAudioFormatInfo */);
sre.SpeechRecognized += Sre_SpeechRecognized;
sre.RecognizeAsync(RecognizeMode.Multiple);
}
private void Wi_DataAvailable(object sender, WaveInEventArgs e) {
// Convert e.Buffer to Stream st
}
private void Sre_SpeechRecognized(object sender, SpeechRecognizedEventArgs e) {
Console.WriteLine(e.Result.Text);
}
Could anybody help me with this? Thanks.

automatic speech detection and recording

I am new to coding in c#. I am building an application to detect the speech and automatically record it. All the information available is based on windows speech recognition engine but my requirement is, the program should detect the speech and record it.
after recording that file is used for processing using hidden markov model(HMM).
namespace Application
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button_1_Click(object sender, EventArgs e)
{
List<NAudio.Wave.WaveInCapabilities> sources = new List<NAudio.Wave.WaveInCapabilities>();
for (int i = 0; i < NAudio.Wave.WaveIn.DeviceCount; i++)
{
sources.Add(NAudio.Wave.WaveIn.GetCapabilities(i));
}
sourceList.Items.Clear();
foreach (var source in sources)
{
ListViewItem item = new ListViewItem(source.ProductName);
item.SubItems.Add(new ListViewItem.ListViewSubItem(item, source.Channels.ToString()));
sourceList.Items.Add(item);
}
}
NAudio.Wave.WaveIn sourceStream = null;
NAudio.Wave.DirectSoundOut waveOut = null;
NAudio.Wave.WaveFileWriter waveWriter = null;
private void button_2_click(object sender, MouseEventArgs e)
{
if (sourceList.SelectedItems.Count == 0) return;
int deviceNumber = sourceList.SelectedItems[0].Index;
sourceStream = new NAudio.Wave.WaveIn();
sourceStream.DeviceNumber = deviceNumber;
sourceStream.WaveFormat = new NAudio.Wave.WaveFormat(16000, NAudio.Wave.WaveIn.GetCapabilities(deviceNumber).Channels);
sourceStream.DataAvailable += new EventHandler<NAudio.Wave.WaveInEventArgs>(sourceStream_DataAvailable);
waveWriter = new NAudio.Wave.WaveFileWriter("test.wav", sourceStream.WaveFormat);
sourceStream.StartRecording();
}
private void sourceStream_DataAvailable(object sender, NAudio.Wave.WaveInEventArgs e)
{
if (waveWriter == null) return;
waveWriter.WriteData(e.Buffer, 0, e.BytesRecorded);
waveWriter.Flush();
}
private void button_3_click(object sender, EventArgs e)
{
if (waveOut != null)
{
waveOut.Stop();
waveOut.Dispose();
waveOut = null;
}
if (sourceStream != null)
{
sourceStream.StopRecording();
sourceStream.Dispose();
sourceStream = null;
}
if (waveWriter != null)
{
waveWriter.Dispose();
waveWriter = null;
}
speechprocessing.Model_test.speech();
}
private void button4_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
this suits my requirement but it has two button to initiate and terminate the recording process which is not under my requirement..
the program should be running and when the speech is detected it must be recorded and further processed. the words which it should detect is also not too much only a few set of words for which we have made the models using hidden markov model..
so please help me out from this problem.

Access raw video stream from Webcam - DirectShow, C#

I'm trying to build a video conference desktop software using DirectShow.Net libraries
I have been able to preview the live footage on a panel locally.
Now I need this raw data feed to go over the network.
Sorry for the noob question but I cannot figure how to get access to this feed.
Code so far:
public partial class Form1 : Form
{
private LiveJob job;
private LiveDeviceSource livedevicesource;
private bool startedrecording;
List<object> lstVideoDevices = new List<object>(10);
List<object> lstAudioDevices = new List<object>(10);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
foreach (EncoderDevice edv in EncoderDevices.FindDevices(EncoderDeviceType.Video)) {
lstVideoDevices.Add(edv.Name);
label1.Text=label1.Text+" "+ edv.Name;
}
foreach (EncoderDevice eda in EncoderDevices.FindDevices(EncoderDeviceType.Audio))
{
lstVideoDevices.Add(eda.Name);
label2.Text = label2.Text + " " + eda.Name;
}
}
private void btnStartPreview_Click(object sender, EventArgs e)
{
EncoderDevice video = EncoderDevices.FindDevices(EncoderDeviceType.Video).ElementAt(1);
EncoderDevice audio = EncoderDevices.FindDevices(EncoderDeviceType.Audio).ElementAt(0);
if (video == null)
{
return;
}
job = new LiveJob();
if (video != null && audio != null) {
livedevicesource = job.AddDeviceSource(video, audio);
livedevicesource.PickBestVideoFormat(new Size(640,480), 15);
SourceProperties sourceprop = livedevicesource.SourcePropertiesSnapshot();
pnlVideoUs.Size = new Size(sourceprop.Size.Width, sourceprop.Size.Height);
//This line here sets panel as the preview window
livedevicesource.PreviewWindow = new PreviewWindow(new HandleRef(pnlVideoUs, pnlVideoUs.Handle));
job.ActivateSource(livedevicesource);
}
}
I need this raw data feed
Have a look at \Samples\Capture\DxLogo sample coming with DirectShow.NET:
A sample application showing how to superimpose a logo on a data stream. It uses
a capture device for the video source, and outputs the result to a file.
Nevertheless the sample's main goal is a bit different, it features access to raw video data:
int ISampleGrabberCB.BufferCB( double SampleTime, IntPtr pBuffer, int BufferLen )
{
// ...
CopyMemory(ipDest, ipSource, (uint)m_bmdLogo.Stride);

Hearing the Incoming audio from mic

i just want to hear what i say to microphone using NAudio and this is my code so far but the problem is i can't hear anything. any help would be appreciated.
public partial class frmMain : Form
{
private WaveIn waveIn; // Gets an audio from microphone
private WaveOut waveOut; // Sends audio to speaker
private BufferedWaveProvider waveProvider; // Gets an audio from stream
public frmMain()
{
InitializeComponent();
}
private void frmMain_Load(object sender, EventArgs e)
{
waveOut = new WaveOut();
waveIn = new WaveIn();
waveProvider = new BufferedWaveProvider(waveIn.WaveFormat);
waveOut.Init(waveProvider);
waveIn.DataAvailable += waveIn_DataAvailable;
waveOut.Play();
}
private void waveIn_DataAvailable(object sender, WaveInEventArgs e)
{
waveProvider.Read(e.Buffer, 0, e.BytesRecorded);
}
private void btnStop_Click(object sender, EventArgs e)
{
waveIn.StopRecording();
waveIn.Dispose();
}
private void btnStart_Click(object sender, EventArgs e)
{
waveIn.StartRecording();
}
}
i will use this scenario in network programming on which i send the data from microphone to the socket then on the client side the BufferedWaveProvider will read the data then send it to the speaker. Please put also some comment if what is the better way to do it.
TIA
Sample code as promised. Code is for a form with two buttons (named StartBtn and StopBtn).
public partial class Form1 : Form
{
private WaveIn waveIn = null;
private BufferedWaveProvider waveProvider = null;
private WaveOut waveOut = null;
public Form1()
{
InitializeComponent();
}
private void StartBtn_Click(object sender, EventArgs e)
{
if (waveIn != null)
return;
// create wave input from mic
waveIn = new WaveIn(this.Handle);
waveIn.BufferMilliseconds = 25;
waveIn.RecordingStopped += waveIn_RecordingStopped;
waveIn.DataAvailable += waveIn_DataAvailable;
// create wave provider
waveProvider = new BufferedWaveProvider(waveIn.WaveFormat);
// create wave output to speakers
waveOut = new WaveOut();
waveOut.DesiredLatency = 100;
waveOut.Init(waveProvider);
waveOut.PlaybackStopped += wavePlayer_PlaybackStopped;
// start recording and playback
waveIn.StartRecording();
waveOut.Play();
}
void waveIn_DataAvailable(object sender, WaveInEventArgs e)
{
// add received data to waveProvider buffer
if (waveProvider != null)
waveProvider.AddSamples(e.Buffer, 0, e.BytesRecorded);
}
private void StopBtn_Click(object sender, EventArgs e)
{
if (waveIn != null)
waveIn.StopRecording();
}
void waveIn_RecordingStopped(object sender, StoppedEventArgs e)
{
// stop playback
if (waveOut != null)
waveOut.Stop();
// dispose of wave input
if (waveIn != null)
{
waveIn.Dispose();
waveIn = null;
}
// drop wave provider
waveProvider = null;
}
void wavePlayer_PlaybackStopped(object sender, StoppedEventArgs e)
{
// stop recording
if (waveIn != null)
waveIn.StopRecording();
// dispose of wave output
if (waveOut != null)
{
waveOut.Dispose();
waveOut = null;
}
}
}
Note especially the waveIn.BufferMilliseconds and waveOut.DesiredLatency settings to reduce the lag times.
For compressing the data for network transmission I suggest using a different library to process the data blocks. You might need to tune the BufferMilliseconds value to reduce the overheads and get better compression ratios.
The Opus Codec looks like a reasonable option, with Opus.NET for C#.

Sending ASCII from C# to Arduino using Bluetooth

I am trying to interface my C# Windows Forms application from my laptop to the Arduino Duemilanove. A Bluetooth module is connected to the Tx and Rx pins on the Arduino. My goal is to light up the on-board LED when I type in the letter 'a' and so far it has been unsuccessful. I am sure the Bluetooth is connected with my laptop, but it is not responding to the letter I am pressing.
C# code
public partial class Form1 : Form
{
private Guid service = BluetoothService.SerialPort;
private BluetoothClient bluetoothClient;
public Form1()
{
InitializeComponent();
this.KeyPreview = true;
this.KeyPress += new KeyPressEventHandler(Form1_KeyPress);
}
void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 'a')
{
Stream peerStream = bluetoothClient.GetStream();
Byte[] buffer = Encoding.ASCII.GetBytes("a");
peerStream.Write(buffer, 0, buffer.Length);
}
}
private void search_Click(object sender, EventArgs e)
{
BluetoothRadio.PrimaryRadio.Mode = RadioMode.Discoverable;
BluetoothRadio myRadio = BluetoothRadio.PrimaryRadio;
bluetoothClient = new BluetoothClient();
Cursor.Current = Cursors.WaitCursor;
BluetoothDeviceInfo[] bluetoothDeviceInfo = { };
bluetoothDeviceInfo = bluetoothClient.DiscoverDevices(10);
comboBox1.DataSource = bluetoothDeviceInfo;
comboBox1.DisplayMember = "DeviceName";
comboBox1.ValueMember = "DeviceAddress";
comboBox1.Focus();
Cursor.Current = Cursors.Default;
}
private void Connect_Click(object sender, EventArgs e)
{
if (comboBox1.SelectedValue != null)
{
try
{
bluetoothClient.Connect(new BluetoothEndPoint((BluetoothAddress)comboBox1.SelectedValue, service));
MessageBox.Show("Connected");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
Arduino Code
int incomingByte = 0; // For incoming serial data
void setup()
{
pinMode(13, OUTPUT); // On-board LED as output
Serial.begin(9600); // Opens serial port, sets data rate to 9600 bit/s.
}
void loop()
{
if (Serial.available() > 0)
{
// Read the incoming byte:
incomingByte = Serial.read();
if (incomingByte == 'a')
digitalWrite(13, HIGH);
}
}
Am I sending the ASCII code wrongly or what am I missing?
May be the same issue as I answered here.
I recently dabbled into this. The Arduino automatically resets when it
receives serial communication from most things other than the Arduino
IDE. This is why you can send from the IDE but not node.js.
I have an Uno and put a capacitor between Reset and Ground.Here's a
page with some good info on the subject. Good luck.
http://arduino.cc/playground/Main/DisablingAutoResetOnSerialConnection

Categories