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
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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.
Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now


Author Comment

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

Author Comment

ID: 17026721
WA, MyExperts ????
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

[Webinar] How Hackers Steal Your Credentials

Do You Know How Hackers Steal Your Credentials? Join us and Skyport Systems to learn how hackers steal your credentials and why Active Directory must be secure to stop them. Thursday, July 13, 2017 10:00 A.M. PDT

Question has a verified solution.

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

Well, all of us have seen the multiple EXCEL.EXE's in task manager that won't die even if you call the .close, .dispose methods. Try this method to kill any excels in memory. You can copy the kill function to create a check function and replace the …
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 …
In this video, viewers are given an introduction to using the Windows 10 Snipping Tool, how to quickly locate it when it's needed and also how make it always available with a single click of a mouse button, by pinning it to the Desktop Task Bar. Int…
There's a multitude of different network monitoring solutions out there, and you're probably wondering what makes NetCrunch so special. It's completely agentless, but does let you create an agent, if you desire. It offers powerful scalability …

691 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