Club.NET Almería

Plataforma .NET de Ingenieros/Ingenieros Técnicos en Informática de Almería
¡Bienvenid@ a Club.NET Almería! Iniciar sesión | ÚNETE a la web | Ayuda
en Buscar
Principal Blogs Foros Imágenes Descargas

Grabar sonido con C#

Último artículo 03-27-2007, 2:57 escrito por amarquez. 4 respuestas.
Ordenar mensajes: Anterior Siguiente
  •  03-19-2007, 12:48 882

    Grabar sonido con C#

    Hola a todos, he estado mirando como se hace para reproducir sonido en c#, es facil, pero lo que no he conseguido es grabar sonido desde microfono, he estado mirando y en el .net framework no viene nada, pero parece ser que con DirectSound si se puede hacer. ¿Alguien lo ha probado o sabe como hacerlo? o si habeis visto algun ejemplo por ahi, por favor avisarme.

     

    Un saludo, y gracias de antemano. 


    cArLoS
  •  03-20-2007, 15:50 885 en respuesta a 882

    Re: Grabar sonido con C#

    Si tienes un dispositivo de grabación compatible, instalate DirectX 9 SDK y usa DirectSound. Prueba este ejemplo  :

     

     

     /*****************************************************************************
     * Class Name: SoundRec
     * Purpose: Primitive Sound Capture Class for Managed DirectX 9.0 C#.Net
     * Description: This Class uses the CaptureBuffer Class
     *                to capture sounds from the default system device
     *                and saves it in the file name test.wav. You will need
     *                to modifify it for your purposes. Hope anyone who uses
     *                This class can have an easier time learning how to use
     *                M.DirectX.DirectSound than I did! Have Fun!!
     *
     * You may not: Alter any part of this comment, however you may add
     *                on new comments if you have improved on it.
     * Original Author:    Nicholas Wong (Jan 2004)
     * email:            fiaery2@hotmail.com
     *
     *****************************************************************************/
    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

    }


    José Antonio Álvarez Bermejo.
    - - - disclaimer - - -
    Las opiniones son como el olor corporal, a cada uno le gusta el suyo. No te esfuerces en oponerte a mi opinión por que esa es tú opinión y a mi me trae sin cuidado.
  •  03-20-2007, 15:51 886 en respuesta a 882

    Re: Grabar sonido con C#

    Oye, en codeguru hay un codigo y una explicacion mu wena:

     

    http://www.codeguru.com/csharp/csharp/cs_graphics/sound/article.php/c10931/ 


    José Antonio Álvarez Bermejo.
    - - - disclaimer - - -
    Las opiniones son como el olor corporal, a cada uno le gusta el suyo. No te esfuerces en oponerte a mi opinión por que esa es tú opinión y a mi me trae sin cuidado.
  •  03-21-2007, 6:22 890 en respuesta a 886

    Re: Grabar sonido con C#

    Muchas gracias por contestar, voy a mirarmelo ahora mismo a ver como va. Un saludo
    cArLoS
  •  03-27-2007, 2:57 933 en respuesta a 890

    Re: Grabar sonido con C#

    Lo muevo al apartado de "Dudas"

    Fullbyte Alchemist
Ver como una fuente de noticias RSS en XML
Ofrecido por Community Server (Personal Edition)