An importan question, not only for me, but also for all this site.

Posted on 2006-07-01
Last Modified: 2008-03-17
I myself want to have a solution for recording from MICROPHONE, save file in Hardisk to process, In an VB.NET form. That's the question, many members have the same question, there's some solutions but It seems to be rather difficult for newbi like us( we're not expertssssss at all), or You advice us to buy component from some companies with an expensive price, ...etc . You experts should show a good solution for us.

I found this class really easy to use: but there's something wrong with capture device???? or ?????: here is the code:

Imports System
Imports Microsoft.DirectX.DirectSound
Imports System.Windows.Forms
Imports Buffer = Microsoft.DirectX.DirectSound.Buffer
Imports System.IO
Imports System.Collections

''' <summary>
''' Class used to handle the sound capture qualities of the program
''' </summary>
Public Class SoundRec

    Private devices As CaptureDevicesCollection = New CaptureDevicesCollection

    Private MyCapture As Capture = New Capture(devices(1).DriverGuid)

    Private MySndBuf As CaptureBuffer

    ''' <summary>
    ''' Sets a default format capture buffer with no effects; 22KHz 8bit/sample, mono
    ''' </summary>
    Public Sub New()
        Dim MySBufDesc As CaptureBufferDescription = New CaptureBufferDescription
        'setting the default wave capture format for use
        'by the buffer descriptor
        Dim DefaultFormat As WaveFormat = 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 = 1000000
        MySBufDesc.ControlEffects = False
        MySBufDesc.WaveMapped = True
        MySndBuf = New CaptureBuffer(MySBufDesc, MyCapture)
    End Sub

    ''' <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 Sub New(ByVal MyFormat As WaveFormat, ByVal bufsize As Integer)
        Dim MySBufDesc As CaptureBufferDescription = 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;
            'Create the CaptureBuffer
            MySndBuf = New CaptureBuffer(MySBufDesc, MyCapture)
        Catch se As SoundException
            MessageBox.Show(("There is a " _
                            + (se.ErrorString + " sound exception")), "DirectSound Error")
        End Try
    End Sub

    ''' <summary>
    ''' Starts the capture from the capture device
    ''' </summary>
    Public Sub StartRecord()
    End Sub

    ''' <summary>
    ''' Stops the recording of sound.
    ''' </summary>
    Public Sub StopRecord()
    End Sub

    ''' <summary>
    ''' Saves the data in the capture buffer into a wave file
    ''' </summary>
    Public Sub ReadData()
        Dim writeposition As Integer
        Dim readposition As Integer
        Dim byteArrayList As ArrayList = New ArrayList
        Dim ascii As System.Text.ASCIIEncoding = New System.Text.ASCIIEncoding
        'Create a new wav file to store the capture buffer data.
        'if already exists will overwrite filename is test.wav
        Dim path As String = ("c:\test.wav")
        Dim MemStream As Stream = New MemoryStream
        MySndBuf.GetCurrentPosition(writeposition, readposition)
        MySndBuf.Read(0, MemStream, writeposition, LockFlag.None)
        Dim MyStream As Stream = New FileStream(path, FileMode.Create)
        'begin to write the wave file header. for more details
        'Search for "wave formats"
        'RIFF header
            byteArrayList.AddRange(ToBytes((36 + CType(MemStream.Length, Integer)), 4))
            '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(ToBytes(CType(MemStream.Length, Integer), 4))
            Dim buffer() As Byte = New Byte((MemStream.Length) - 1) {}
            MemStream.Read(buffer, 0, CType(MemStream.Length, Integer))
            buffer = New Byte((byteArrayList.Count) - 1) {}
            MyStream.Write(buffer, 0, buffer.Length)
        Catch ae As ArgumentException
            MessageBox.Show(("Argument Exception with Message:" & vbLf.ToString & vbTab.ToString + ae.Message))
        End Try
    End Sub

    ''' <summary>
    ''' returns capture status (boolean)
    ''' </summary>
    ''' <returns></returns>
    Public Function Capturing() As Boolean
        Return MySndBuf.Capturing
    End Function

    ''' <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 Function ToBytes(ByVal targetnumber As Integer, ByVal numofbytes As Short) As ArrayList
        Dim result As Integer
        Dim remainder As Integer
        Dim returningarray As ArrayList
        Dim wrongnumofbytes As ArgumentException = New ArgumentException("Not enough bytes to represent number", "numofbytes")
        result = Math.DivRem(targetnumber, 256, remainder)
        'if not enough bytes specified to represent target number
        If (targetnumber >= Math.Pow(256, CType(numofbytes, Double))) Then
            Throw wrongnumofbytes
        End If
        'if there are higher significant hexadecima, run a recursion
        If (result >= 1) Then
            returningarray = ToBytes(result, CType((numofbytes - 1), Short))
            returningarray.Insert(0, Convert.ToByte(remainder))
            Return returningarray
            returningarray = New ArrayList(numofbytes)
            Dim i As Integer = 0
            Do While (i _
                        < (numofbytes - 1))
                'fill up most significant hexadecima with 0's
                i = (i + 1)
            Return returningarray
        End If
    End Function
End Class

With this class,from now on, every members can copy ~~> add class ~~> and use it easily.
Thank you very much.
Question by:cutoi
  • 6
  • 4

Expert Comment

by:Naveen Swamy
ID: 17024015

The CaptureSound sample in the DirectX SDK does exactly what you are trying to do.

Author Comment

ID: 17025507
CaptureSound in SDK writen in C#, I convert to VB.NET there's a lot of errors, and It's really difficult for me to Manage.
Your solutuion give me using Directx7(is it too old?)
Please help me with the other solution that easier to use.
Please help me.
Thank you.

Author Comment

ID: 17026301
Please help me.

Author Comment

ID: 17026534
NO Body helps me??????

Author Comment

ID: 17026721
WA, MyExperts ????
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

LVL 18

Accepted Solution

armoghan earned 500 total points
ID: 17029393
Hi cutoi,

I once wrote the following article to Capture from Screen and Record from MICROPHONE, using Windows Media Encoder

You can look into it to and extract the Voice part from it.

LVL 18

Expert Comment

ID: 17029400

Replace Code to something like
            Dim SrcAud As IWMEncAudioSource
            SrcAud = SrcGrp.AddSource(WMENC_SOURCE_TYPE.WMENC_AUDIO)
            SrcAud.SetInput("Default_Audio_Device", "Device", "")

and no need of Video resource

Author Comment

ID: 17031045
Excellent Solution. Thanks you very much.
Really great, easy to use.
could you show me how to improve the quality of sound ? , ex: 44100,16, stereo . The size of file is not important at all, I just want to capture a short time.

Thanks again.

Everybody, Armoghan is an ExcellentExpert.
LVL 18

Expert Comment

ID: 17032260
Look into the profiles and you will find one suitable for you.

i used this once for audio and it full filled my purpose
"Windows Media Audio 8 for Dial-up Modem (FM Radio Stereo, 28.8 Kbps)"

You can also make a profile yourself using The profile editor present with the encoder folder
LVL 18

Expert Comment

ID: 17032265
Thx for the comment :)

Author Comment

ID: 17033000
Thanks, I got it.

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I think the Typed DataTable and Typed DataSet are very good options when working with data, but I don't like auto-generated code. First, I create an Abstract Class for my DataTables Common Code.  This class Inherits from DataTable. Also, it can …
Introduction As chip makers focus on adding processor cores over increasing clock speed, developers need to utilize the features of modern CPUs.  One of the ways we can do this is by implementing parallel algorithms in our software.   One recent…
Internet Business Fax to Email Made Easy - With  eFax Corporate (, you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, f…
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…

896 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now