Multiple Client Send and Receive voice using NAudio C# TCP Application - c#

I am trying to develope a Voice Chat window application using NAudio with multiple client, the problem is its not working or how can i send recorded voice to all the clients at same time and play on client side, then send the recorded voice of client and send it back to server.I am also using NetComm.dll to fetaure my application with Text Chat. Any help would be higly appreciated.enter image description here

using NAudio.Wave;
namespace NaudioVoiceChat
{
public partial class Server: Form
{
#region Codes for NAudio ------->>>> This is for NAudio
private BufferedWaveProvider bwp;
WaveIn wi;
WaveOut wo;
public Server()
{
InitializeComponent();
#region Code for Naudio
wo = new WaveOut();
wi = new WaveIn();
wi.DataAvailable += new EventHandler<WaveInEventArgs>(wi_DataAvailable);
bwp = new BufferedWaveProvider(wi.WaveFormat);
bwp.DiscardOnBufferOverflow = true;
wo.Init(bwp);
wi.StartRecording();
}
void wi_DataAvailable(object sender, WaveInEventArgs e)
{
bwp.AddSamples(e.Buffer, 0, e.BytesRecorded);
server.SendData("Client-1", e.Buffer);
}

Related

named pipes between winform (C#) and python

I am working on a window form app (C#) that should kick an external process and display some results and/or error messages from the exe in the form app.
I cannot seem to be able to form a named pipe connection between the form app and external process (exe) made in python. The exe fires up and works fine but it does not seem to hold the named pipe connection. So, I am not able to get any messages as such from the exe.
The exe is made with pyinstaller and named pipe connection seems to work pretty fine when paired with a window console app i.e. I could get messages back from the exe to a console app.
Consolse App
The script below can get return messages from the exe on to console.
namespace pipeConsoleApp
{
class Program
{
static void Main(string[] args)
{
NamedPipeClientStream pipeClient = new NamedPipeClientStream("teropipe");
Console.Write("Attempting to connect to the pipe...");
System.Diagnostics.Process.Start(#"my\path\to\external\app\tempp.exe");
pipeClient.Connect();
Console.WriteLine("Connected to the pipe");
Console.WriteLine("There are currently {0} pipe server instances open.", pipeClient.NumberOfServerInstances);
StreamWriter writer = new StreamWriter(pipeClient);
StreamReader reader = new StreamReader(pipeClient);
string temp;
while ((temp = reader.ReadLine()) != null)
{
Console.WriteLine("Received from server: {0}", temp);
}
Console.Write("Press Enter to continue..");
Console.ReadLine();
}
}
But when I tried a similar thing on window form app I am not able to get anything from the python server
Form App
Although I have used a similar approach for the form app somehow no messages are being returned. In fact, it looks like the named piped connection isn't being held open for the form to communicate.
namespace pipeDemoForm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void okayButton_Click(object sender, EventArgs e)
{
NamedPipeClientStream pipeClient = new NamedPipeClientStream("teropipe");
//MessageBox.Show("attempting to connect");
System.Diagnostics.Process.Start(#"my\path\to\external\app\tempp.exe");
pipeClient.Connect();
string numb = pipeClient.NumberOfServerInstances.ToString();
MessageBox.Show("There are currently {0} pipe server instances open", numb);
if (pipeClient.IsConnected)
{
MessageBox.Show("There are currently {0} pipe server instances open", pipeClient.NumberOfServerInstances.ToString());
}
}
}
}
Python Script - tempp.exe
The following is the python script, which I have packaged into a onefile exe with pyinstaller.
import win32pipe
import win32file
def process():
pipe_handle = win32pipe.CreateNamedPipe(r'\\.\pipe\teropipe',
win32pipe.PIPE_ACCESS_DUPLEX,
win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_WAIT,
1,65536,65536,300,None)
win32pipe.ConnectNamedPipe(pipe_handle, None)
# business logic
..................
#write some output to the form app
win32file.WriteFile(pipe_handle,"some string return from above")

usb to serial not working

This is my first time integrating Serial to USB in a C# application, so please pardon me if this sounds like a stupid question.
I have Class IV laser. I am integrating that in to my C# application.
My problem is I can connect to the laser, I can send data to the laser but i don't get any return from the laser.
private void Bt_Start_Click(object sender, EventArgs e)
{
SerialPort serialPort = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
serialPort.Handshake = Handshake.XOnXOff;
serialPort.DtrEnable = true;
serialPort.RtsEnable = true;
serialPort.ReadTimeout = 500;
serialPort.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
ConenctToLaser("COM3", serialPort);
}
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
byte[] buffer = new byte[sp.BytesToRead];
int bytesRead = sp.Read(buffer, 0, buffer.Length);
var message = Encoding.ASCII.GetString(buffer, 0, bytesRead);
MessageBox.Show(message);
}
public void ConenctToLaser(string port, SerialPort serialPort)
{
StreamReader openfile = new StreamReader(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\commands.txt");
if (serialPort.IsOpen == false)
{
serialPort.Open();
string command = "";
command = openfile.ReadLine();
while(command!=null)
{
byte[] buffer = Encoding.ASCII.GetBytes(command);
serialPort.Write(buffer, 0, buffer.Length);
command = openfile.ReadLine();
}
}
}
The commands.txt includes my commands. which are
\r
MTT\r
MCM\r
SPR300\r
on different lines
When i send these commands to the laser all i get back is the echo. So in reality when i send ("MTT\r") i should get back the temperature of the hardware. When i test my hardware in putty it works i get return for all the commands above. Here's the definition for one of the commands from the .pdf they have provided.
Laser Temperature Command: MTT\r
Description: The laser actual laser temperature expressed in XX.X degC
After hours of researching I found the answer to my question. From what i read online it seems like the SerialPort class by Microsoft doesn't work very well with all the serial Hardware. So I would need to use a wrapper class to work with Win32 API.
I found this article which explains how to use Win32 class to communicate with the serial device. It also has a wrapper to call the Win32 methods. You can read all about it and download all the code from the below link.
https://msdn.microsoft.com/en-us/magazine/cc301786.aspx
Hope this helps somebody who's having the same problem.

Connect an C# application thats running sockets using JAVASCRIPT

Hey i was wondering if you could help me
I'm creating an android application in html5 and java script.
There are a server that is created on c# that is listing connection.
I can connect the 2 apps together but get i can get the c# app to reply to my android application using javascript.
here is my server code
public void Listeners()
{
Socket socketForClient = tcpListener.AcceptSocket();
if (socketForClient.Connected)
{
nr_connections = nr_connections + 1;
nr_qry = nr_qry + 1;
SetText("");
SetText("New Connection.");
NetworkStream networkStream = new NetworkStream(socketForClient);
StreamWriter streamWriter = new StreamWriter(networkStream);
StreamReader streamReader = new StreamReader(networkStream);
streamWriter.Flush();
string GettheString = streamReader.ReadLine();
if (GettheString == "server_status")
{
SetText("Checking Server Status.");
streamWriter.WriteLine("Online");
streamWriter.Close();
streamReader.Close();
networkStream.Close();
}
}
socketForClient.Close();
SetText("Connection Closed...");
Thread newThread = new Thread(new ThreadStart(Listeners));
newThread.Start();
nr_connections = nr_connections - 1;
}
and my javascript code
function connect ()
{
try
{
var connection = new WebSocket('ws://105.237.125.247:8');
connection.onopen = function ()
{
connection.send('server_status');
};
connection.onmessage = function (event) {
alert(event.data);
}
}
catch(Exeption)
{
alert("Check Connection");
}
}
Im getting data from the android app but can send back to the javascript file
Web-sockets is a protocol that sits on top of a regular transport (such as a socket); basically, you need a web-socket library. If you are using recent versions of Windows, then much of this is baked into HTTP.SYS, and available via HttpListnener (in particular, AcceptWebSocketAsync on a context). However, alternative web-socket libraries are available, or can be written from scratch if you so choose.

Playing NAudio .mp3 through an Audio Source in Unity

I'm using a package called Visualizer Studio (http://www.alteredr.com/visualizer-studio/) to make a game where objects react to music. My goal is to have the user be able to load a song at any time during the game. It's going to be standalone/PC, not WebPlayer.
My problem is that Visualizer Studio takes the audio data from an Audio Source in the scene. So when I use NAudio to load and stream MP3s, visualizer studio doesn't hear them, and my objects don't react to the music.
I'm using IWavePlayer right now in my code. I've tried adding audio.clip = www.GetAudioClip and similar functions to have the audio clip load the music that is being played, but to no avail.
I got the code I'm using to select and stream .mp3s from this blog post (the source code is at the bottom): (http://denis-potapenko.blogspot.com/2013/04/task-6-loading-mp3-audio-via-www-class.html). It's unchanged at the moment, because nothing I was trying was working.
To be clear, the .mp3s DO play when I select them from a file browser. I just need them to play via an audio source in my scene. Please, there has to be a way to do this. I've contacted visualizer studio support and asked on the unity forums, but nobody can help so far.
Please keep in mind that I'm not exactly a great programmer, so you might have to dumb answers down for me. Thanks for you patience in advance. Anyway,
Here's my code I'm using to open a file browser and stream audio:
using UnityEngine;
using System.Collections;
using System.IO;
using System.Runtime;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using NAudio;
using NAudio.Wave;
public class AppRoot : MonoBehaviour
{
///////////////////////////////////////////////////////////////////////////
#region Variables
private static AppRoot mInstance = null;
private const string cLocalPath = "file://localhost/";
private IWavePlayer mWaveOutDevice;
private WaveStream mMainOutputStream;
private WaveChannel32 mVolumeStream;
#endregion
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
#region Interface
public AppRoot()
{
mInstance = this;
}
public void Start()
{
}
public void Update()
{
if(Input.GetKeyDown(KeyCode.F))
{
UnloadAudio();
LoadAudio();
}
}
public void OnGUI()
{
if (GUI.Button(new Rect(100, Screen.height - 200 + 100, Screen.width - 200, 35), "Load audio"))
{
UnloadAudio();
LoadAudio();
}
}
public void OnApplicationQuit()
{
UnloadAudio();
}
#endregion
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
#region Implementation
private void LoadAudio()
{
System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
ofd.Title = "Open audio file";
ofd.Filter = "MP3 audio (*.mp3) | *.mp3";
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
WWW www = new WWW(cLocalPath + ofd.FileName);
Debug.Log("path = " + cLocalPath + ofd.FileName);
while (!www.isDone) { };
if (!string.IsNullOrEmpty(www.error))
{
System.Windows.Forms.MessageBox.Show("Error! Cannot open file: " + ofd.FileName + "; " + www.error);
return;
}
byte[] imageData = www.bytes;
if (!LoadAudioFromData(imageData))
{
System.Windows.Forms.MessageBox.Show("Cannot open mp3 file!");
return;
}
mWaveOutDevice.Play();
Resources.UnloadUnusedAssets();
}
}
private bool LoadAudioFromData(byte[] data)
{
try
{
MemoryStream tmpStr = new MemoryStream(data);
mMainOutputStream = new Mp3FileReader(tmpStr);
mVolumeStream = new WaveChannel32(mMainOutputStream);
mWaveOutDevice = new WaveOut();
mWaveOutDevice.Init(mVolumeStream);
return true;
}
catch (System.Exception ex)
{
Debug.LogWarning("Error! " + ex.Message);
}
return false;
}
private void UnloadAudio()
{
if (mWaveOutDevice != null)
{
mWaveOutDevice.Stop();
}
if (mMainOutputStream != null)
{
// this one really closes the file and ACM conversion
mVolumeStream.Close();
mVolumeStream = null;
// this one does the metering stream
mMainOutputStream.Close();
mMainOutputStream = null;
}
if (mWaveOutDevice != null)
{
mWaveOutDevice.Dispose();
mWaveOutDevice = null;
}
}
#endregion
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
#region Properties
private static AppRoot Instance
{
get
{
return mInstance;
}
}
#endregion
///////////////////////////////////////////////////////////////////////////
}
Sincerely,
Jonathan
http://answers.unity3d.com/answers/1128204/view.html
With the "latest" version of NAudio.dll and NAudio.WindowsMediaFormat.dll inserted into your Resources folder utilize this code to do what you described:
var musicInput : GameObject;
private var aud : AudioFileReader;
private var craftClip : AudioClip;
private var AudioData : float[];
private var readBuffer : float[];
private var soundSystem : AudioSource;
private var musicPath : String[];
//Check if there's a pref set for the music path. Use it AND add all the files from it
function CheckMusic()
{
var pathname = musicInput.GetComponent.<InputField>();
if(PlayerPrefs.HasKey("musicpath") == false)
{
PlayerPrefs.SetString("musicpath", "Enter Music Directory");
}
else
{
pathname.text = PlayerPrefs.GetString("musicpath");
musicPath = Directory.GetFiles(PlayerPrefs.GetString("musicpath"),"*.mp3");
}
}
function LoadSong(songToPlay : int)
{
//Download the song via WWW
var currentSong : WWW = new WWW(musicPath[songToPlay]);
//Wait for the song to download
if(currentSong.error == null)
{
//Set the title of the song
playingSong.text = Path.GetFileNameWithoutExtension(musicPath[songToPlay]);
//Parse the file with NAudio
aud = new AudioFileReader(musicPath[songToPlay]);
//Create an empty float to fill with song data
AudioData = new float[aud.Length];
//Read the file and fill the float
aud.Read(AudioData, 0, aud.Length);
//Create a clip file the size needed to collect the sound data
craftClip = AudioClip.Create(Path.GetFileNameWithoutExtension(musicPath[songToPlay]),aud.Length,aud.WaveFormat.Channels,aud.WaveFormat.SampleRate, false);
//Fill the file with the sound data
craftClip.SetData(AudioData,0);
//Set the file as the current active sound clip
soundSystem.clip = craftClip;
}
}
And I quote
The "songToPlay" variable that is passed to the function is a simple int that is acquired from the array created under the CheckMusic function. I search a chosen directory entered from a GUI Inputfield for a specific file type (MP3) which can be changed to WAV or OGG and then input those files to an array. Other code chooses the number of the song on the array to play and you can change that to anything you like. The important part is that the NAudio,dll does all the heavy lifting. All you need to do is use the aud.Read(float[] to send data to, song starting point(usually 0),length of song data (aud.length). The Float[] here is the same length as aud.length so create the float of the same length, read the file, fill the float, create the clip, then dump the float data in with AudioClip.SetData()
Right now this code works and it does the job. Downside is it takes
2-3 seconds to fill the float in this way and is a noticeable drag. It
also tends to chew up memory pretty fast, but it gets the job done.
Hope it helps as a starting point for those who are looking to do
this. I know I needed it.
When you use a WaveOut instance you are playing (relatively) directly on the soundcard, outside of the Unity environment. You need a way to introduce that data into Unity.
I haven't worked with Unity so this might not be the best answer,but...
You can introduce wave data into the scene using OnAudioFilterRead. You can use this to create procedural sound, and with a little coding it can presumably be hooked up to a NAudio wave source. This will introduce the audio data directly into the game for your in-game code to deal with.
Here's an article I found that might help: Procedural Audio with Unity
mWaveOutDevice = new WaveOut();
Maybe causing the issue, it is better practice to use WaveOutEvent() which supports running in all non GUI threads.
mWaveOutDevice = new WaveOutEvent();
Related StackOverFlow Question

Windows 8 app how to connect to Socket server

i have done a server using this example socketAsyncEventArgs
in visual studio 2010 and .net 4.0.
Now i'm trying to connect to it from a windows 8 app using StreamSocket but i'm getting a "Acces denied" message.
here is the Client code:
private StreamSocket streamSocket;
public string Server = "192.168.0.101";
public int Port = 9900;
public async void Connect()
{
streamSocket = new StreamSocket();
Connect();
try
{
await streamSocket.ConnectAsync(
new Windows.Networking.HostName(Server),
Port.ToString()); // getting Acces Denied here
DataReader reader = new DataReader(streamSocket.InputStream);
reader.InputStreamOptions = InputStreamOptions.Partial;
while (true)
{
var bytesAvailable = await reader.LoadAsync(1000);
var byteArray = new byte[bytesAvailable];
reader.ReadBytes(byteArray);
}
}
catch (Exception e)
{
MessageBox(e.StackTrace);
}
}
How to fix the problem? Is there another way to send and receive messages using this server?
You are probably also seeing the following as part of your error message:
WinRT information: A network capability is required to access this network resource
This is because you need to add a capability to your application that allows you to access local networks. Double click on the Package.appxmanifest file in your project. Click on the Capabilities tab. Add the Private Networks (Client & Server) capability to your project.

Categories