Sign in to follow this  
celean

How to capture sounds into a wave file ?

Recommended Posts

hi everyone I have used this code which is included @ http://www.tek-tips.com/faqs.cfm?fid=4782 and it worked out without any error, but the problem is that I can not hear the sound file after recording. Could u plz solve the problem? thax using System; using Microsoft.DirectX.DirectSound; using System.Windows.Forms; using Buffer = Microsoft.DirectX.DirectSound.Buffer; using System.IO; using System.Collections; namespace DirectSoundRecording { /// <summary> /// Class used to handle the sound capture qualities of the program /// </summary> public class SoundRec { private Capture MyCapture = new Capture(); private CaptureBuffer MySndBuf; /// <summary> /// Sets a default format capture buffer with no effects; 22KHz 8bit/sample, mono /// </summary> public SoundRec() { CaptureBufferDescription MySBufDesc = new CaptureBufferDescription(); //setting the default wave capture format for use //by the buffer descriptor WaveFormat DefaultFormat = new WaveFormat(); DefaultFormat.SamplesPerSecond = 22000; //default freq 22khz DefaultFormat.Channels = 1; DefaultFormat.BitsPerSample = 8; DefaultFormat.AverageBytesPerSecond = 22000; DefaultFormat.BlockAlign = 1; //setting the buffer descriptor to tell the capture buffer object how the //buffer should perform MySBufDesc.Format = DefaultFormat; MySBufDesc.BufferBytes = 100000; MySBufDesc.ControlEffects = false; MySBufDesc.WaveMapped = true; MySndBuf = new CaptureBuffer(MySBufDesc,MyCapture); } /// <summary> /// Constructor that sets format and buffersize, as well as enables /// echo cancellation and noise suppression effects /// </summary> /// <param name="MyFormat"></param> /// <param name="bufsize"></param> public SoundRec(WaveFormat MyFormat, int bufsize) { CaptureBufferDescription MySBufDesc = new CaptureBufferDescription(); //Format has been defined in MainForm MySBufDesc.Format = MyFormat; MySBufDesc.BufferBytes = bufsize; MySBufDesc.ControlEffects = true; MySBufDesc.WaveMapped = true; // CaptureAcousticEchoCancellationEffect AECEffect; // // MySBufDesc.CaptureEffectDescription = new CaptureEffectDescription[1]; // MySBufDesc.CaptureEffectDescription[0].LocateInSoftware = true; // MySBufDesc.CaptureEffectDescription[0].GuidEffectsClass = DSoundHelper.CaptureEffectsMsAcousticEchoCancellation; // MySBufDesc.CaptureEffectDescription[0].GuidEffectsInstance = DSoundHelper.InterfaceCaptureEffectsAcousticEchoCancellation; // MySBufDesc.CaptureEffectDescription[1].LocateInSoftware = true; // MySBufDesc.CaptureEffectDescription[1].GuidEffectsClass = DSoundHelper.CaptureEffectsMsNoiseSuppression; try { //Create the CaptureBuffer MySndBuf = new CaptureBuffer(MySBufDesc,MyCapture); } catch (SoundException se) { MessageBox.Show( "There is a " + se.ErrorString + " sound exception", "DirectSound Error"); } } /// <summary> /// Starts the capture from the capture device /// </summary> public void StartRecord() { MySndBuf.Start(true); } /// <summary> /// Stops the recording of sound. /// </summary> public void StopRecord() { MySndBuf.Stop(); } /// <summary> /// Saves the data in the capture buffer into a wave file /// </summary> public void ReadData() { int readposition, writeposition; ArrayList byteArrayList = new ArrayList(); System.Text.ASCIIEncoding ascii = new System.Text.ASCIIEncoding(); //Create a new wav file to store the capture buffer data. //if already exists will overwrite filename is test.wav string path =Application.StartupPath + "\\test.wav"; Stream MemStream = new MemoryStream(); MySndBuf.GetCurrentPosition(out writeposition, out readposition); MySndBuf.Read(0, MemStream, writeposition, LockFlag.None); Stream MyStream = new FileStream(path, FileMode.Create); //begin to write the wave file header. for more details //Search google.com for "wave formats" //RIFF header try { byteArrayList.AddRange(ascii.GetBytes("RIFF")); byteArrayList.AddRange( ToBytes(36 + (int)MemStream.Length, 4)); byteArrayList.AddRange(ascii.GetBytes("WAVE")); //fmt chunk byteArrayList.AddRange(ascii.GetBytes("fmt ")); //length of fmt chunk (never changes) byteArrayList.AddRange( ToBytes(16, 4)); //"1" for pcm encoding byteArrayList.AddRange( ToBytes(1, 2)); byteArrayList.AddRange( ToBytes(MySndBuf.Format.Channels, 2)); byteArrayList.AddRange( ToBytes(MySndBuf.Format.SamplesPerSecond, 4)); byteArrayList.AddRange( ToBytes(MySndBuf.Format.AverageBytesPerSecond, 4)); byteArrayList.AddRange( ToBytes(MySndBuf.Format.BlockAlign, 2)); byteArrayList.AddRange( ToBytes(MySndBuf.Format.BitsPerSample, 2)); //the data chunk byteArrayList.AddRange(ascii.GetBytes("data")); byteArrayList.AddRange( ToBytes((int)MemStream.Length, 4)); byte []buffer = new byte[MemStream.Length]; MemStream.Read(buffer, 0, (int)MemStream.Length); byteArrayList.AddRange(buffer); buffer = new byte[byteArrayList.Count]; byteArrayList.CopyTo(buffer); MyStream.Write(buffer, 0, buffer.Length); } catch(ArgumentException ae) { MessageBox.Show("Argument Exception with Message:\n\t" + ae.Message); } finally { MemStream.Close(); MyStream.Close(); } } /// <summary> /// returns capture status (boolean) /// </summary> /// <returns></returns> public bool Capturing() { return MySndBuf.Capturing; } /// <summary> /// Recursive method that returns a target number in the form /// of an ArrayList of bytes with designated number of bytes. If not enough /// bytes to hold the targetnumber, will throw argumentexception. /// Should be used in a try-catch clause /// </summary> /// <param name="targetnumber">the value intended to convert</param> /// <param name="numofbytes">number of bytes needed</param> /// <returns></returns> private ArrayList ToBytes(int targetnumber, short numofbytes) { int remainder, result; ArrayList returningarray; ArgumentException wrongnumofbytes = new ArgumentException("Not enough bytes to represent number", "numofbytes"); result = Math.DivRem(targetnumber, 256, out remainder); //if not enough bytes specified to represent target number if (targetnumber >= Math.Pow(256,(double)numofbytes)) { throw wrongnumofbytes; } //if there are higher significant hexadecima, run a recursion if (result >= 1) { returningarray = ToBytes(result, (short)(numofbytes-1)); returningarray.Insert(0, Convert.ToByte(remainder)); return returningarray; } else //if (result < 1) recursion terminating condition { returningarray = new ArrayList(numofbytes); returningarray.Add(Convert.ToByte(targetnumber)); for (int i=0; i < numofbytes-1; i++) { returningarray.Add(Convert.ToByte(0));//fill up most significant hexadecima with 0's } return returningarray; } } }//end class } thanx celean

Share this post


Link to post
Share on other sites
I wouldn't know off the top of my head, but as for troublshooting, since your not hearing anything I would check to make sure that any numbers of bytes are being generated to the stream. If you got the code some place you trust it to work, maybe its an issue of your computer setup. I've never setup the michrophone in DX, but I was make sure the library recognises its there. There must be a way to do that.

Share this post


Link to post
Share on other sites
Hi, I'm having same problem. I checked generated file in notepad and saw that there is only wave file header and data chunk contains only blank spaces. DX recognize mic, I've checked it listing CaptureDevicesCollection. I have also checked that there is signal captured by mic in system Record/Capture Devices panel.
Can anyone help?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this