How record Audio from Kinect with NAudio - c#

I would like to record audio from Kinect. I'm using NAudio library.
I found this code:
private void button2_Click(object sender, EventArgs e) //Play Button
{
fileName = "lastReplay.wav";
FileStream FS_Write = File.OpenWrite("lastReplay.wav");
FS_Write.Close();
int deviceNumber = sourceList.SelectedItems[0].Index;
sourceStream = new NAudio.Wave.WaveIn();
sourceStream.DeviceNumber = deviceNumber;
sourceStream.WaveFormat = new NAudio.Wave.WaveFormat(44100,
NAudio.Wave.WaveIn.GetCapabilities(deviceNumber).Channels);
NAudio.Wave.WaveInProvider waveIn = new
NAudio.Wave.WaveInProvider(sourceStream);
sourceStream.DataAvailable += new EventHandler<NAudio.Wave.WaveInEventArgs>
(sourceStream_DataAvailable);
waveWriter = new NAudio.Wave.WaveFileWriter(fileName, sourceStream.WaveFormat);
sourceStream.StartRecording();
}
private void sourceStream_DataAvailable(object sender, NAudio.Wave.WaveInEventArgs e)
{
if (waveWriter == null) return;
waveWriter.Write(e.Buffer, 0, e.BytesRecorded);
waveWriter.Flush();
}
When i start the kinect the audio channel need to be started, so I use this:
Stream audioStream = this.sensor.AudioSource.Start();
How can I change the button2_click method for accepting audioStream?

I have solved my problem, the code is this:
static void WriteWavHeader(Stream stream, int dataLength)
{
//We need to use a memory stream because the BinaryWriter will close the underlying stream when it is closed
using (var memStream = new MemoryStream(64))
{
int cbFormat = 18; //sizeof(WAVEFORMATEX)
WAVEFORMATEX format = new WAVEFORMATEX()
{
wFormatTag = 1,
nChannels = 1,
nSamplesPerSec = 16000,
nAvgBytesPerSec = 32000,
nBlockAlign = 2,
wBitsPerSample = 16,
cbSize = 0
};
using (var bw = new BinaryWriter(memStream))
{
//RIFF header
WriteString(memStream, "RIFF");
bw.Write(dataLength + cbFormat + 4); //File size - 8
WriteString(memStream, "WAVE");
WriteString(memStream, "fmt ");
bw.Write(cbFormat);
//WAVEFORMATEX
bw.Write(format.wFormatTag);
bw.Write(format.nChannels);
bw.Write(format.nSamplesPerSec);
bw.Write(format.nAvgBytesPerSec);
bw.Write(format.nBlockAlign);
bw.Write(format.wBitsPerSample);
bw.Write(format.cbSize);
//data header
WriteString(memStream, "data");
//bw.Write(dataLength);
bw.Write(dataLength);
memStream.WriteTo(stream);
}
}
}
But with this method i should know before the time of file audio. I put dataLength parameter. If i use this code it found but now i would like to use this method never dataLength parameter because i don't know before the duration of file Audio, how can I modify it?

Related

wma compression audio files throwing error using Naudio

Here I have some codes for encoding wma audio files..Its works perfectly.but uploading out put file to server ,some error happend.Its shows output file should be meet the
requirements like rate should be in 16000
public void ConvertToWMA(string tempFilePath, string tempFileName, string audioType)
{
WaveFormat form = new WaveFormat(16000, 16, 1);
using (WmaStream str = new WmaStream(tempFilePath + tempFileName, form))
{
string profileData;
using (StreamReader reader = new StreamReader(File.OpenRead("audio.prx")))
{
profileData = reader.ReadToEnd();
}
IWMProfileManager profileManager;
IWMProfile wmProfile = null;
profileManager = WM.CreateProfileManager();
profileManager.LoadProfileByData(profileData, out wmProfile);
WMProfile wmp = new WMProfile(str.Profile);
NAudio.WindowsMediaFormat.WmaWriter ww = new NAudio.WindowsMediaFormat.WmaWriter(new FileStream(#"D:\wma\conv\test.wma", FileMode.Create), form, wmProfile);
byte[] buff = null;
int read = 0;
buff = new byte[form.AverageBytesPerSecond];
read = str.Read(buff, 0, buff.Length);
while ((read > 0))
{
ww.Write(buff, 0, read);
read = str.Read(buff, 0, buff.Length);
}
}
}
how can get rid of this issue.someone please help me..
{
var temp = tempFilePath + tempFileName;
using (var reader = new MediaFoundationReader(temp))
{
// Create a wave format for 16-bit pcm at 8000 samples per second.
int channels = reader.WaveFormat.Channels;
int rate = 8000;
int rawsize = 2;
int blockalign = rawsize * channels; // this is the size of one sample.
int bytespersecond = rate * blockalign;
//MediaFoundationEncoder.enc(reader, "test.mp3");
var midformat =
WaveFormat.CreateCustomFormat(WaveFormatEncoding.Pcm,
rate,
channels,
bytespersecond,
blockalign,
rawsize * 8);
// And a conversion stream to turn input into 16-bit PCM.
//var midstream = new MediaFoundationResampler(reader, midformat);
// var outstream = new PcmToALawConversionStream(midstream);
// var outstream = new PcmToALawConversionStream(midstream);
//var converted16Bit = new SampleToWaveProvider16(mixer);
//
// now for MP3, we need to upsample to 44.1kHz. Use MediaFoundationResampler
using (var resampled = new MediaFoundationResampler(
reader, midformat))
{
var outstream = new PcmToALawConversionStream(resampled);
// var desiredBitRate = 16000; // ask for lowest available bitrate
//MediaFoundationEncoder.EncodeToWma(outstream,
// "mixedtets10.wma", desiredBitRate);
WaveFileWriter.CreateWaveFile("mixedtets10.wma", outstream);
//NAudio.WindowsMediaFormat.WmaWriter ww = new NAudio.WindowsMediaFormat.WmaWriter(new FileStream(#"D:\wma\conv\test1.wma", FileMode.Create), midformat, outstream);
}
// NAudio.WindowsMediaFormat.WmaWriter ww = new NAudio.WindowsMediaFormat.WmaWriter(new FileStream(#"D:\wma\conv\test1.wma", FileMode.Create), midformat, outstream);
//NAudio.WindowsMediaFormat.WmaWriter Ww=
// The output stream is our custom stream.
//var outstream = new PcmToALawConversionStream(midstream);
}
}

'Memory stream is not expandable' but size of array is the same?

I am trying to multithread AES in C# but I can't seem to fix this weird exception. My buffer sizes are exactly the same but it still says it can't expand maybe you can see the error this is for a file of size 101 bytes.
In the while loop it will skip if and go inside the else creating (one thread?) that writes a not encrypted buffer to an encrypted buffer. After that is done to synchronize I want to write the encrypted buffer to a file in the runworkerComplete function. The issue presents itself when I try to write the not encrypted buffer into a encrypted buffer. The error message puzzles me since the size of the second buffer is created with the length of the first buffer but yet is says it can't expand the memory!?
static List<BackgroundWorker> threadCompany = new List<BackgroundWorker>();
static List<BackgroundWorker> listWorkers = new List<BackgroundWorker>();
static List<BackgroundWorker> listFreeWorkers = new List<BackgroundWorker>();
static FileStream fsIn;
static string file;
static byte[] key;
const int BLOCK_SIZE = 1000;
static FileStream outFile;
public static void EncryptFile(string inputFile, string outputFile, string sKey, ProgressBar progress)
{
String fileName = inputFile;
fileName = "\\" + fileName.Split('\\').Last();
var progres = new Progress<int>(value => progress.Value = value);
file = outputFile + fileName;
fsIn = new FileStream(inputFile, FileMode.Open);
outFile = new FileStream(file, FileMode.Create);
key = new UnicodeEncoding().GetBytes(sKey);
for (int t = 0; t < 4; t++)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
listWorkers.Add(worker);
listFreeWorkers.Add(worker);
}
byte[] buffer = new byte[BLOCK_SIZE];
FileInfo fileInfo = new FileInfo(inputFile);
double numBlocks = Math.Ceiling(((double)fileInfo.Length) / BLOCK_SIZE);
int ixCurrentBlock = 0;
while (ixCurrentBlock < numBlocks)
{
//check if any free workers
if (listFreeWorkers.Count > 0)
{
//Get the worker, remove it from the list
BackgroundWorker freeWorker = listFreeWorkers[0];
listFreeWorkers.RemoveAt(0);
//read the next block of the file
int bytes;
if (ixCurrentBlock < numBlocks - 1)
{
bytes = fsIn.Read(buffer, ixCurrentBlock * BLOCK_SIZE, BLOCK_SIZE);
freeWorker.RunWorkerAsync(Tuple.Create(ixCurrentBlock, buffer));
threadCompany.Remove(freeWorker);
}
else //special handling for last block
{
MessageBox.Show((ixCurrentBlock * BLOCK_SIZE) + " " + (int)(fileInfo.Length - ixCurrentBlock * BLOCK_SIZE)); // 0 101
bytes = fsIn.Read(buffer, ixCurrentBlock * BLOCK_SIZE, (int)(fileInfo.Length - ixCurrentBlock * BLOCK_SIZE));
freeWorker.RunWorkerAsync(Tuple.Create(ixCurrentBlock, new byte[(int)(fileInfo.Length - ixCurrentBlock * BLOCK_SIZE)]));
threadCompany.Remove(freeWorker);
}
//now pass it to a worker
//advance to the next block
ixCurrentBlock++;
//update the UI status here
// ...
}
else //no workers free
{
Thread.Sleep(50);
}
}
//if we make it to here we have sent off all the blocks
//now we wait for the threads to complete
bool threadsRunning = false;
while (threadsRunning)
{
threadsRunning = false;
foreach (BackgroundWorker worker in listWorkers)
{
threadsRunning |= worker.IsBusy;
}
//if still running, wait and try again in 50ms
if (threadsRunning)
{
Thread.Sleep(50);
}
}
}
private static void worker_DoWork(object sender, DoWorkEventArgs e)
{
Tuple<int, byte[]> t = e.Argument as Tuple<int, byte[]>;
int blockIndex = (int)t.Item1;
byte[] inBuffer = (byte[])t.Item2;
byte[] outBuffer = new byte[inBuffer.Length];
//using keyword will automatically close the stream
using (MemoryStream outStream = new MemoryStream(outBuffer)) // issue may be here?
{
RijndaelManaged RMCrypto = new RijndaelManaged();
using (CryptoStream cs = new CryptoStream(outStream,
RMCrypto.CreateEncryptor(key, key),
CryptoStreamMode.Write))
{
// I want to write inbuffer non encrypted to outbuffer encrypted.
cs.Write(inBuffer, blockIndex, inBuffer.Length);
}
}
e.Result = Tuple.Create(blockIndex, outBuffer);
}
private static void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show(e.Error.Message + " "); // memory is not expendable
Tuple<int, byte[]> t = e.Result as Tuple<int, byte[]>;
int blockIndex = (int)t.Item1;
byte[] buffer = (byte[])t.Item2;
//assumes you have a class variable, _outFile, that is an open filestream
outFile.Write(buffer, blockIndex, buffer.Length);
outFile.Close();
//add the worker back to the free workers list
listFreeWorkers.Add((BackgroundWorker)sender);
}
Encryption and decryption arn't the same size to solve this issue flush the stream (already implied with the using statement) toarray the stream to your outbuffer.
SOLUTION
private static void worker_DoWork(object sender, DoWorkEventArgs e)
{
Tuple<int, byte[]> t = e.Argument as Tuple<int, byte[]>;
int blockIndex = (int)t.Item1;
byte[] inBuffer = (byte[])t.Item2;
byte[] outBuffer;
//using keyword will automatically close the stream
using (MemoryStream outStream = new MemoryStream()) // issue may be here?
{
AesCryptoServiceProvider RMCrypto = new AesCryptoServiceProvider();
using (CryptoStream cs = new CryptoStream(outStream,
RMCrypto.CreateEncryptor(key, key),
CryptoStreamMode.Write))
{
// I want to write inbuffer non encrypted to outbuffer encrypted.
cs.Write(inBuffer, blockIndex, inBuffer.Length);
}
outBuffer = outStream.ToArray();
}
e.Result = Tuple.Create(blockIndex, outBuffer);
}

Error at sending a picture from server to client

I have 2 Apps (server - client ) .
The server is modified version of TVsharp (Application that stream local analog tv signal using RTLSDR)
Each frame of the streamed video is a grayscale array of bytes .
I have modified it so it re sizes and sends each frame for a client over TCP socket
The client is supposed to receive the frames through the socket as Image objects and displays them in a picture box
Im getting invalid parameters error .
After i added a delay (Thread.Sleep()) it started to display one frame and then it gives invalid parameter exception (after the sleeping time)
This is the part of TVsharp that dose the sending :
Grayscale is an array that contains the brightness for each pixel
private string drive = "E:\\";
private string file = "0";
private string extension = ".bmp";
private string path2 = "E:\\test\\";
private string fullpath;
private int file_counter = 0;
Bitmap bitmap2 = new Bitmap(_pictureWidth, _pictureHeight);
var data2 = bitmap2.LockBits(new Rectangle(Point.Empty, bitmap2.Size),
ImageLockMode.WriteOnly,PixelFormat.Format24bppRgb);
Marshal.Copy(GrayScaleValues, 0, data2.Scan0, GrayScaleValues.Length);
bitmap2.UnlockBits(data2);
bitmap2.Save(fullpath, System.Drawing.Imaging.ImageFormat.Bmp);
string Npath = path2 + file + extension;
Image img = Image.FromFile(fullpath);
// Size size = new Size(982, 543);
// ResizeImage(img, size);
Rectangle cropRect = new Rectangle(80, 0, 240, 175);
Bitmap target = new Bitmap(cropRect.Width, cropRect.Height);
using (Graphics g = Graphics.FromImage(target))
{
g.DrawImage(img, new Rectangle(0, 0, target.Width, target.Height), cropRect, GraphicsUnit.Pixel);
}
//double scale = 203 / 96;
int width = (int)(target.Width);
int height = (int)(target.Height);
BinaryWriter brn = new BinaryWriter(s);
System.Drawing.Bitmap bmpScaled = new System.Drawing.Bitmap(target, width, height);
bmpScaled.Save(Npath);
byte[] imageArray = File.ReadAllBytes(Npath);
sw.WriteLine(imageArray.Length.ToString());
sw.Flush();
// Thread.Sleep(500);
brn.Write(imageArray);
//Thread.Sleep(500);
_detectLevel = Convert.ToInt32(_maxSignalLevel * _detectorLevelCoef);
_agcSignalLevel = agcMaxLevel;
}
This client the client segment that suppose to get the frames and display them
flag = true;
TcpClient client = new TcpClient(textBox1.Text, Convert.ToInt32(textBox2.Text));
Stream s = client.GetStream();
StreamReader sr = new StreamReader(s);
StreamWriter sw = new StreamWriter(s);
sw.Flush();
BinaryFormatter formatter = new BinaryFormatter();
string msg = sr.ReadLine();
MessageBox.Show("It's working !! the message is " + msg);
BinaryReader Brn = new BinaryReader(s);
Thread.Sleep(5000);
while (flag)
{
// Thread.Sleep(5000);
int size = Convert.ToInt32(sr.ReadLine());
label3.Text = "Size is " + size;
byte[] imagerray = Brn.ReadBytes(size);
MemoryStream ms = new MemoryStream(imagerray);
Thread.Sleep(10000);
Image image = Image.FromStream(ms);
ResizeImage(image, this.Size);
pictureBox1.Image = image;
Thread.Sleep(10);
}
}

Adding multiple attachments to a mail, in c# windows forms

I'm making an c# and Windows Forms (Classic Windows app like notepad, paint etc.) app that has a feature to get screenshot and send it via mail.
However, It can only take 6 pictures now (I can add more, but I don't want to add more code, I want to make it programmatically), how can I make it send more or less, as set by user, outside of app?
Timer1 sends mail.
Timer2 takes screenshot.
resimoran is an int which is image ratio of resizing, it's 1 by default.
counter is an int,
It's working right now...
here is my code:
private Bitmap Screenshot()
{
Bitmap Screenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics GFX = Graphics.FromImage(Screenshot);
GFX.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size);
return Screenshot;
}
void SendReport()
{
MailMessage mail;
var fromAddress = new MailAddress(frommail, fromname);
var toAddress = new MailAddress(alici, aliciname);
string fromPassword = mailpass;
var smtp = new SmtpClient
{
Host = mailhostaddress,
Port = mailport,
EnableSsl = sslenabled,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = usedefaultcre,
Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
};
using (mail = new MailMessage(fromAddress, toAddress)
{
Subject = konu + DateTime.Now,
Body = "None of your businness!"
})
{
mail.Attachments.Add(attach1);
mail.Attachments.Add(attach2);
mail.Attachments.Add(attach3);
mail.Attachments.Add(attach4);
mail.Attachments.Add(attach5);
mail.Attachments.Add(attach6);
smtp.Send(mail);
}
}
private void timer1_Tick(object sender, EventArgs e)
{
SendReport();
}
private void timer2_Tick(object sender, EventArgs e)
{
counter++;
if (counter == 1)
{
Bitmap ekrangor = Screenshot();
Bitmap imagee = resizeImage(ekrangor, new Size(ekrangor.Width / resimoran, ekrangor.Height / resimoran));
imagee.Save(#"screen1.jpg");
System.IO.Stream streamer = new System.IO.MemoryStream();
imagee.Save(streamer, System.Drawing.Imaging.ImageFormat.Jpeg);
streamer.Position = 0;
attach1 = new Attachment(streamer, "screen1.jpg");
}
else if (counter == 2)
{
Bitmap ekrangor = Screenshot();
Bitmap imagee = resizeImage(ekrangor, new Size(ekrangor.Width / resimoran, ekrangor.Height / resimoran));
imagee.Save(#"screen2.jpg");
System.IO.Stream streamer = new System.IO.MemoryStream();
imagee.Save(streamer, System.Drawing.Imaging.ImageFormat.Jpeg);
streamer.Position = 0;
attach2 = new Attachment(streamer, "screen2.jpg");
}
else if (counter == 3)
{
Bitmap ekrangor = Screenshot();
Bitmap imagee = resizeImage(ekrangor, new Size(ekrangor.Width / resimoran, ekrangor.Height / resimoran));
imagee.Save(#"screen3.jpg");
System.IO.Stream streamer = new System.IO.MemoryStream();
imagee.Save(streamer, System.Drawing.Imaging.ImageFormat.Jpeg);
streamer.Position = 0;
attach3 = new Attachment(streamer, "screen3.jpg");
}
else if (counter == 4)
{
Bitmap ekrangor = Screenshot();
Bitmap imagee = resizeImage(ekrangor, new Size(ekrangor.Width / resimoran, ekrangor.Height / resimoran));
imagee.Save(#"screen4.jpg");
System.IO.Stream streamer = new System.IO.MemoryStream();
imagee.Save(streamer, System.Drawing.Imaging.ImageFormat.Jpeg);
streamer.Position = 0;
attach4 = new Attachment(streamer, "screen4.jpg");
}
else if (counter == 5)
{
Bitmap ekrangor = Screenshot();
Bitmap imagee = resizeImage(ekrangor, new Size(ekrangor.Width / resimoran, ekrangor.Height / resimoran));
imagee.Save(#"screen5.jpg");
System.IO.Stream streamer = new System.IO.MemoryStream();
imagee.Save(streamer, System.Drawing.Imaging.ImageFormat.Jpeg);
streamer.Position = 0;
attach5 = new Attachment(streamer, "screen5.jpg");
}
else if (counter == 6)
{
Bitmap ekrangor = Screenshot();
Bitmap imagee = resizeImage(ekrangor, new Size(ekrangor.Width / resimoran, ekrangor.Height / resimoran));
imagee.Save(#"screen6.jpg");
System.IO.Stream streamer = new System.IO.MemoryStream();
imagee.Save(streamer, System.Drawing.Imaging.ImageFormat.Jpeg);
streamer.Position = 0;
attach6 = new Attachment(streamer, "screen6.jpg");
counter = 0;
}
}
public static Bitmap resizeImage(Bitmap imgToResize, Size size)
{
return (new Bitmap(imgToResize, size));
}
And, please, give me answers in C#, not in English! (not "do this: MSDN bla bla", but "try this void lolnocodezhere() {}")
List<T> is your friend.
you declare it at a proper place as
List<Attachment> attachments = new List<Attachment>();
Then you replace your 6 blocks with a single one where you do a
attachments.Add(new Attachment(streamer, "screen.jpg");)
and when the right time has come you do a
foreach(Attachment a in attachments ) mail.Attachments.Add(a);
After successfully sending the mail you delete the collection like this:
attachments.Clear();
It is up to you to control things like counters, the screen images etc.
Btw: mail.Attachmentsis just such a collection and maybe you want to use it directly..?

Retrieving favicon as icon instead of image

I used the favicon-code I found here to retrieve the favicon of the site loaded in the browser element.
I want to use this favicon as the icon of my Windows Form.
Thanks to JP Hellemons this code works:
private void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) {
this.Icon = favicon(GetActiveBrowser().Url);
}
private WebBrowser GetActiveBrowser() {
return (WebBrowser)tabs.SelectedTab.Controls[0];
}
private Icon favicon(Uri url) {
WebRequest request = (HttpWebRequest)WebRequest.Create("http://" + url.Host + "/favicon.ico");
Bitmap bm = new Bitmap(32, 32);
MemoryStream memStream;
using (Stream response = request.GetResponse().GetResponseStream()) {
memStream = new MemoryStream();
byte[] buffer = new byte[1024];
int byteCount;
do {
byteCount = response.Read(buffer, 0, buffer.Length);
memStream.Write(buffer, 0, byteCount);
} while (byteCount > 0);
}
bm = new Bitmap(Image.FromStream(memStream));
if (bm != null) {
Icon ic = Icon.FromHandle(bm.GetHicon());
return ic;
} else
return Properties.Resources.GZbrowser;
}
According to this documentation, it should work from stream.
http://msdn.microsoft.com/en-us/library/system.drawing.icon.aspx
I used this article: http://odetocode.com/Blogs/scott/archive/2004/10/05/webrequest-and-binary-data.aspx
WebRequest request = (HttpWebRequest)WebRequest.Create("http://" + url.Host + "/favicon.ico");
Icon ic = new Icon(); // put default here
Bitmap bm = new Bitmap();
try
{
using(WebResponse response = request.GetResponse())
{
using(Stream responseStream = response.GetResponseStream())
{
using(MemoryStream ms = new MemoryStream())
{
var tmp = Image.FromStream(ms); // changed bitmap to image
bm = new Bitmap(tmp);
}
}
}
}catch{}
if(bm != null)
{
ic = Icon.FromHandle(bm.GetHicon);
}
return ic;
Edit: something like this should do it
Edit2: changed some things in the answer. Can you try this?
Final edit: (lol)
Just tested this in a windows form app and this works! :)
Uri url = new Uri("http://www.google.nl");
WebRequest request = (HttpWebRequest)WebRequest.Create("http://" + url.Host + "/favicon.ico");
Bitmap bm = new Bitmap(32,32);
MemoryStream memStream;
using (Stream response = request.GetResponse().GetResponseStream())
{
memStream = new MemoryStream();
byte[] buffer = new byte[1024];
int byteCount;
do
{
byteCount = response.Read(buffer, 0, buffer.Length);
memStream.Write(buffer, 0, byteCount);
} while (byteCount > 0);
}
bm = new Bitmap(Image.FromStream(memStream));
if (bm != null)
{
Icon ic = Icon.FromHandle(bm.GetHicon());
this.Icon = ic;
}
Read response byte array first, than create MemoryStream of it and create icon from that MemoryStream.
Network stream do not support seek operations that seem to be necessary for creating an icon.

Categories