Solved

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

Posted on 2006-07-01
11
598 Views
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()
        MyBase.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)
        MyBase.New()
        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;
        Try
            '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()
        MySndBuf.Start(True)
    End Sub

    ''' <summary>
    ''' Stops the recording of sound.
    ''' </summary>
    Public Sub StopRecord()
        MySndBuf.Stop()
    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
        Try
            byteArrayList.AddRange(ascii.GetBytes("RIFF"))
            byteArrayList.AddRange(ToBytes((36 + CType(MemStream.Length, Integer)), 4))
            byteArrayList.AddRange(ascii.GetBytes("WAVE"))
            '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(ascii.GetBytes("data"))
            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))
            byteArrayList.AddRange(buffer)
            buffer = New Byte((byteArrayList.Count) - 1) {}
            byteArrayList.CopyTo(buffer)
            MyStream.Write(buffer, 0, buffer.Length)
        Catch ae As ArgumentException
            MessageBox.Show(("Argument Exception with Message:" & vbLf.ToString & vbTab.ToString + ae.Message))
        Finally
            MemStream.Close()
            MyStream.Close()
        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
        Else
            returningarray = New ArrayList(numofbytes)
            returningarray.Add(Convert.ToByte(targetnumber))
            Dim i As Integer = 0
            Do While (i _
                        < (numofbytes - 1))
                returningarray.Add(Convert.ToByte(0))
                'fill up most significant hexadecima with 0's
                i = (i + 1)
            Loop
            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.
0
Comment
Question by:cutoi
  • 6
  • 4
11 Comments
 
LVL 9

Expert Comment

by:Naveen Swamy
ID: 17024015
http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/VB_DOT_NET/Q_21474281.html

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

Author Comment

by:cutoi
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.
0
 

Author Comment

by:cutoi
ID: 17026301
Please help me.
0
 

Author Comment

by:cutoi
ID: 17026534
NO Body helps me??????
0
 

Author Comment

by:cutoi
ID: 17026721
WA, MyExperts ????
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 18

Accepted Solution

by:
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
http://www.codeproject.com/vb/net/CaptureScreenAsVideo.asp

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


Cheers!
0
 
LVL 18

Expert Comment

by:armoghan
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
0
 

Author Comment

by:cutoi
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.
0
 
LVL 18

Expert Comment

by:armoghan
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
0
 
LVL 18

Expert Comment

by:armoghan
ID: 17032265
Thx for the comment :)
0
 

Author Comment

by:cutoi
ID: 17033000
Thanks, I got it.
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

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 …
Introduction When many people think of the WebBrowser (http://msdn.microsoft.com/en-us/library/2te2y1x6%28v=VS.85%29.aspx) control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

747 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

12 Experts available now in Live!

Get 1:1 Help Now