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.
Industry Leaders: 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

New benefit for Premium Members - Upgrade now!

Ready to get started with anonymous questions today? It's easy! Learn more.

Question has a verified solution.

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

1.0 - Introduction Converting Visual Basic 6.0 (VB6) to Visual Basic 2008+ (VB.NET). If ever there was a subject full of murkiness and bad decisions, it is this one!   The first problem seems to be that people considering this task of converting…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
In this video, Percona Director of Solution Engineering Jon Tobin discusses the function and features of Percona Server for MongoDB. How Percona can help Percona can help you determine if Percona Server for MongoDB is the right solution for …
Suggested Courses
Course of the Month10 days, 16 hours left to enroll

770 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