Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win


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

Posted on 2006-07-01
Medium Priority
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 google.com 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.
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Author Comment

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

Author Comment

ID: 17026721
WA, MyExperts ????
LVL 18

Accepted Solution

armoghan earned 2000 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

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

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

Article by: jpaulino
XML Literals are a great way to handle XML files and the community doesn’t use it as much as it should.  An XML Literal is like a String (http://msdn.microsoft.com/en-us/library/system.string.aspx) Literal, only instead of starting and ending with w…
A while ago, I was working on a Windows Forms application and I needed a special label control with reflection (glass) effect to show some titles in a stylish way. I've always enjoyed working with graphics, but it's never too clever to re-invent …
Want to learn how to record your desktop screen without having to use an outside camera. Click on this video and learn how to use the cool google extension called "Screencastify"! Step 1: Open a new google tab Step 2: Go to the left hand upper corn…
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…
Suggested Courses

610 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