Sound.cs

//**********************************************************

//* Direct X Sound Recorder                                *

//* Author: D. Zouchinski                                  *

//* http://zouchinski.co.uk                                *

//* Copyright @ 2009-2011                                  *

//**********************************************************

using System;

using System.Windows.Forms;

using System.Collections.Generic;

 

using Microsoft.DirectX.DirectSound;

 

namespace DZouch

{

    public class SoundCapture : IDisposable

    {

        private Capture capture;

        private CaptureBuffer buffer;

        private int bufferSize;

        private int position;

 

        public SoundCapture() : this(DSoundHelper.DefaultCaptureDevice)

        {

        }

 

        public SoundCapture(Guid deviceId)

        {

            capture = new Capture(deviceId);

            if (capture != null)

            {

                WaveFormat fmt = GetFormat();

 

                CaptureBufferDescription desc = new CaptureBufferDescription();

                desc.Format = fmt;

                desc.BufferBytes = fmt.AverageBytesPerSecond; // 1 second buffer

                desc.WaveMapped = true;

 

                buffer = new CaptureBuffer(desc, capture);

                bufferSize = desc.BufferBytes;

            }

        }

 

        public WaveFormat GetFormat()

        {

            WaveFormat fmt = new WaveFormat();

            fmt.FormatTag = WaveFormatTag.Pcm;

            fmt.SamplesPerSecond = Frequency();

            fmt.Channels = 2;

            fmt.BitsPerSample = 16;

            fmt.BlockAlign = 4;

            fmt.AverageBytesPerSecond = (fmt.BitsPerSample / 8) * fmt.Channels * fmt.SamplesPerSecond;

            return fmt;

        }

 

        public static int Frequency()

        {

            return 44100;

        }

 

        public bool Start()

        {

            if (buffer == null)

                return false;

 

            if(!buffer.Capturing)

                buffer.Start(true);

 

            return true;

        }

 

        public bool Stop()

        {

            if (buffer == null)

                return false;

 

            if (buffer.Capturing)

                buffer.Stop();

 

            return true;

        }

 

        public short[] Pull()

        {

            if (buffer == null)

                return null;

 

            int read, record;

            buffer.GetCurrentPosition(out record, out read);

            if (read < 0)

                return null;

            if (read > bufferSize)

                return null;

 

            int dataSize = read > position ? read - position : read + bufferSize - position;

            if (dataSize % 4 != 0)

                dataSize = (dataSize / 4) * 4;

            if (position >= bufferSize)

                position -= bufferSize;

            if (dataSize > 0)

            {

                short[] data = buffer.Read(position, typeof(short), LockFlag.None, new int[] { dataSize / 2 }) as short[];

                position += dataSize;

                return data;

            }

 

            return null;

        }

 

        #region IDisposable Members

 

        public void Dispose()

        {

            Stop();

            buffer.Dispose();

            capture.Dispose();

        }

 

        #endregion

    }

}