Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 10251
  • Last Modified:

Sound Recording

Experts,
    I am currently developing a program that involves analyzing wav files and such.  A small part of this application, though, it in its ability to record to a wav file when a person talks.  I must admit, i don't know quite how to do this.  Could someone please help me with making the part where the program moniters the microphone for when a person talks (or a noise of a certain volume is heard) and then record for about 5 seconds and store that into a wav file?  Any help would be appreciated!  Thanks!
0
TrEaSoN
Asked:
TrEaSoN
1 Solution
 
RuchiCommented:
This is from http://www.experts-exchange.com/jsp/qShow.jsp?ta=vbcontrols&qid=10297165 &search=microphone

9 points available!


Hello,
I want to record at run time.
I use the MMControl, but I have some difficulties.
I want to be able to record my voice and then save it in wave file. I want that every time I record - it will be saved to a different file. ( I tried, but all the records were saved continuously to the same file ).
( I have the same problem for playing the files ).

Thanks...

From: mcrider
 Date: Thursday, February 17 2000 - 11:49PM CST    
You have to stop the recording, save the wav file, close the MCI control, and then set the new path to the next wav file and open the MCI device again.

Also dont forget to set the record mode:

    MMControl1.RecordMode = mciRecordOverwrite


Cheers!

From: chen_meir
 Date: Friday, February 18 2000 - 10:41AM CST    
dear mcrider ...
i did what you said.
i created a button for record ("rec"), a button to stop the record
("sto") and a button to play ("play").
i did some recording but it didnt work.
if it worked ,it was only some times and after that it did whatever it wanted. ( i noticed that some of the files after i closed the project i could not manage delete them (i got the message "access denaied").

here is my code:

'start the play
Private Sub play_Click()

MMControl1.Notify = True
MMControl1.Wait = True
MMControl1.Shareable = False
MMControl1.DeviceType = "WaveAudio"

str = "C:\My Documents\" & i & ".wav"
MMControl1.FileName = str
MMControl1.Command = "open"
MMControl1.Command = "play"
MMControl1.Command = "prev"
End Sub



'start the record
Private Sub rec_Click()

MMControl1.Command = "prev"
MMControl1.RecordMode = mciRecordOverwrite
str = "C:\My Documents\" & i & ".wav"
MMControl1.FileName = str
voiceRec(number).voicePath = str
MMControl1.Command = "open"
MMControl1.Command = "record"

End Sub



'stop the record
Private Sub sto_Click()
MMControl1.Command = "stop"
MMControl1.Command = "save"
MMControl1.Command = "close"
End Sub


In a new project, add a MMControl, a TextBox and 3 Command Buttons... Then paste the following code into the DECLARATIONS Section of FORM1:

Private Sub Command1_Click()
    MMControl1.Notify = False
    MMControl1.Wait = False
    MMControl1.Shareable = False
    MMControl1.DeviceType = "WaveAudio"
    MMControl1.filename = Text1.Text
    MMControl1.To = 10000
    MMControl1.Command = "Open"
    MMControl1.RecordMode = mciRecordOverwrite
    MMControl1.Command = "Record"
End Sub
Private Sub Command2_Click()
    MMControl1.Command = "Save"
    MMControl1.Command = "Close"
End Sub
Private Sub Command3_Click()
    MMControl1.Notify = False
    MMControl1.Wait = False
    MMControl1.Shareable = False
    MMControl1.DeviceType = "WaveAudio"
    MMControl1.filename = Text1.Text
    MMControl1.Command = "Open"
    MMControl1.Command = "Play"
    Do
        If MMControl1.Mode <> mciModePlay Then Exit Do
        DoEvents
    Loop
    MMControl1.Command = "Stop"
    MMControl1.Command = "Close"
End Sub
Private Sub Form_Load()
    Text1.Text = "" 
    Command1.Caption = "Record"
    Command2.Caption = "Stop Rec"
    Command3.Caption = "Play"
End Sub


Run the program and type the name of a WAV file (including the .WAV extension) and press the "Record" command button... Talk into your microphone and then hit the "Stop Rec" command button. Then Hit the "Play" command button... You should hear your voice.

Do it again with another file....


Cheers!  
0
 
mcriderCommented:
Ruchi,

Yep... Thats my code... ;-)


TrEaSoN,

Once you start recording using the above code, you may also want to look at the following microsoft KB article:

FILE: AUDIOLVL.EXE-Monitor Input and Output Audio Levels
http://support.microsoft.com/support/kb/articles/Q187/6/73.ASP?LNG=ENG&SA=MSDN&FR=0 
 

Cheers!®©
0
 
TrEaSoNAuthor Commented:
Hello,
    Is there any way to do the recording through API calls?  I'm trying to develop this where its not really dependant on any controlls.  If its not possible then that's okay, but i'm fairly certian that it is, i just don't know how to do it.  Any suggestions?
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
mcriderCommented:
Heres an example of recording through the mciSendString API call.  Create a new project and then add 2 command buttons to the project and paste this code.


Cheers!®©


THE CODE:

    Private Declare Function mciSendString Lib "winmm.dll" _
        Alias "mciSendStringA" _
        (ByVal lpstrCommand As String, _
        ByVal lpstrReturnString As String, _
        ByVal uReturnLength As Long, _
        ByVal hwndCallback As Long) As Long
    Private Declare Function mciGetErrorString Lib "winmm.dll" _
        Alias "mciGetErrorStringA" _
        (ByVal dwError As Long, _
        ByVal lpstrBuffer As String, _
        ByVal uLength As Long) As Long
    Private Sub Command1_Click()
        Dim Result As Long
        Dim ErrorMsg As Long
        Dim ReturnString As String * 1024
        Dim ErrorString As String * 1024
       
        Result = mciSendString("open new type waveaudio alias mywav", ReturnString, 1024, 0)
        If Not Result = 0 Then
            ErrorMsg = mciGetErrorString(Result, ErrorString, 1024)
            MsgBox ErrorString, 0, "Error"
            Exit Sub
        End If
   
        Result = mciSendString("set mywav time format ms bitspersample 8 samplespersec 11025", ReturnString, 1024, 0)
        If Not Result = 0 Then
            ErrorMsg = mciGetErrorString(Result, ErrorString, 1024)
            MsgBox ErrorString, 0, "Error"
            Exit Sub
        End If
   
        'Record for 60000 milliseconds
        Result = mciSendString("record mywav to 60000", ReturnString, 1024, 0)
        If Not Result = 0 Then
            ErrorMsg = mciGetErrorString(Result, ErrorString, 1024)
            MsgBox ErrorString, 0, "Error"
            Exit Sub
        End If
    End Sub
    Private Sub Command2_Click()
        Dim Result As Long
        Dim ErrorMsg As Long
        Dim ReturnString As String * 1024
        Dim ErrorString As String * 1024
       
        Result = mciSendString("stop mywav", ReturnString, 1024, 0)
        If Not Result = 0 Then
            ErrorMsg = mciGetErrorString(Result, ErrorString, 1024)
            MsgBox "stop " + ErrorString, 0, "Error"
        End If
        Result = mciSendString("save mywav c:\windows\desktop\testme.wav", ReturnString, 1024, 0)
        If Not Result = 0 Then
            ErrorMsg = mciGetErrorString(Result, ErrorString, 1024)
            MsgBox "save " + ErrorString, 0, "Error"
        End If
        Result = mciSendString("close mywav", ReturnString, 1024, 0)
        If Not Result = 0 Then
            ErrorMsg = mciGetErrorString(Result, ErrorString, 1024)
            MsgBox "close " + ErrorString, 0, "Error"
        End If
    End Sub
    Private Sub Form_Load()
        Command1.Caption = "record"
        Command2.Caption = "stop/save"
    End Sub
0
 
TrEaSoNAuthor Commented:
I have two questions now, and then i think i'll have my answer.  Thanks so much so far!  A) i downloaded that sample from the microsoft page - the one that moniters input volume.  Problem is it won't work.  It keeps giving me an error message.  I have a very new computer/sound card so i'm sure that that is not the problem.  Think you could provide any help with that?  B) for the recording sample you just gave me...how do i go about setting up the recording quality (e.g. 8.000kHz, 8bit Mono, 7k/sec, etc.)?  I know it can be done, i just don't know how.  Thanks!
0
 
TrEaSoNAuthor Commented:
Never mind on setting quality...i figured that much out.  I still need the volume measuring though...Can you supply me with some help?  Thanks!
0
 
mcriderCommented:
I dont have any problems running the AUDIOLVL example... What error are you getting??

As for changing the quality, you will need to play with the line:

   Result = mciSendString("set mywav time format ms bitspersample 8 samplespersec 11025", ReturnString, 1024, 0)

in the code I gave you.  The mciSendString "set" command is defined here:  http://msdn.microsoft.com/library/psdk/multimed/mmcmdstr_8eyc.htm


Hope this helps!


Cheers!®©
0
 
TrEaSoNAuthor Commented:
I get the message "couldn't get wavin meter" and "couldn't get wavout meter".
0
 
mcriderCommented:
Sorry, But I can't reproduce that error... Step through the program and let me know what line is giving the error.
0
 
TrEaSoNAuthor Commented:
Adjusted points to 250
0
 
TrEaSoNAuthor Commented:
well...

   ok = GetControl(hmixer, MIXERLINE_COMPONENTTYPE_DST_WAVEIN, MIXERCONTROL_CONTROLTYPE_PEAKMETER, inputVolCtrl)
   
   If (ok <> True) Then
       ok = GetControl(hmixer, MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE, MIXERCONTROL_CONTROLTYPE_PEAKMETER, inputVolCtrl)
   End If

both of these instances return ok as false.  That is where its going wrong.  the
hmixer = -2102807656
MIXERLINE_COMPONENTTYPE_DST_WAVEIN = 7
MIXERCONTROL_CONTROLTYPE_PEAKMETER = 268566529
MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE = 4099

Those are the values that appear all the time.  I'm not really sure what i'm supposed to be looking for.  Do you need any more information?  If so just let me know.
0
 
mcriderCommented:
This is not a fix, but it is a diagnostic... Replace the GetControl function in the AUDIOLVL example with this.  When the mixerGetLineControls API fails, a messagebox will popup with the return error.


Cheers!®©

THE CODE:

Function GetControl(ByVal hmixer As Long, ByVal componentType As Long, ByVal ctrlType As Long, ByRef mxc As MIXERCONTROL) As Boolean
' This function attempts to obtain a mixer control. Returns True if successful.
    Const MIXERR_BASE = 1024
    Const MIXERR_INVALLINE = (MIXERR_BASE + 0)
   
    Const MMSYSERR_BASE = 0
    Const MMSYSERR_BADDEVICEID = (MMSYSERR_BASE + 2)
    Const MMSYSERR_INVALFLAG = (MMSYSERR_BASE + 10)
    Const MMSYSERR_INVALHANDLE = (MMSYSERR_BASE + 5)
    Const MMSYSERR_INVALPARAM = (MMSYSERR_BASE + 11)
    Const MMSYSERR_NODRIVER = (MMSYSERR_BASE + 6)

   Dim mxlc As MIXERLINECONTROLS
   Dim mxl As MIXERLINE
   Dim hmem As Long
   Dim rc As Long
       
   mxl.cbStruct = Len(mxl)
   mxl.dwComponentType = componentType
   
   ' Obtain a line corresponding to the component type
   rc = mixerGetLineInfo(hmixer, mxl, MIXER_GETLINEINFOF_COMPONENTTYPE)
   
   If (MMSYSERR_NOERROR = rc) Then
      mxlc.cbStruct = Len(mxlc)
      mxlc.dwLineID = mxl.dwLineID
      mxlc.dwControl = ctrlType
      mxlc.cControls = 1
      mxlc.cbmxctrl = Len(mxc)
     
      ' Allocate a buffer for the control
      'hmem = GlobalAlloc(&H40, Len(mxc))
      hmem = GlobalAlloc(GMEM_FIXED, Len(mxc))
      mxlc.pamxctrl = GlobalLock(hmem)
      mxc.cbStruct = Len(mxc)
     
      ' Get the control
      rc = mixerGetLineControls(hmixer, mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE)
           
      If (MMSYSERR_NOERROR = rc) Then
         GetControl = True
         
         ' Copy the control into the destination structure
         CopyStructFromPtr mxc, mxlc.pamxctrl, Len(mxc)
      Else
         GetControl = False
         Select Case rc
            Case MIXERR_INVALLINE: MsgBox "MIXERR_INVALLINE"
            Case MMSYSERR_BADDEVICEID: MsgBox "MMSYSERR_BADDEVICEID"
            Case MMSYSERR_INVALFLAG: MsgBox "MMSYSERR_INVALFLAG"
            Case MMSYSERR_INVALHANDLE: MsgBox "MMSYSERR_INVALHANDLE"
            Case MMSYSERR_INVALPARAM: MsgBox "MMSYSERR_INVALPARAM"
            Case MMSYSERR_NODRIVER: MsgBox "MMSYSERR_NODRIVER"
            Case Else: MsgBox "UNKNOWN ERROR " + CStr(rc)
        End Select
      End If
      GlobalFree (hmem)
      Exit Function
   End If
   
   GetControl = False
End Function
0
 
TrEaSoNAuthor Commented:
That returned 'Unkown Error 1025'
0
 
mcriderCommented:
Well, the error coming back is MIXERR_INVALCONTROL, The control reference is invalid.

MIXERR_INVALCONTROL is defined like this:

   Const MIXERR_INVALCONTROL = (MMSYSERR_BASE + 1)
   
Do you have a mixer control on your system??


Cheers!®©
0
 
TrEaSoNAuthor Commented:
I have Creative Mixer...if that's what your getting at.
0
 
mcriderCommented:
Well, I've run the AUDIOLVL sample on 3 different systems and it works on all of them. I don't know what to tell you...  Maybe There's a configuration problem with your system...

Anyhow, the answer I posted shows you how to record to a WAV file use the API interface and should answer your original question.



Cheers!®©
0
 
TrEaSoNAuthor Commented:
okay....i'll check my configuration...if you can think of any suggestions just post it.  Thanks for all the help!
0
 
mcriderCommented:
Thanks for the points! Glad I could help!


Cheers!®©
0
 
tgkprogCommented:
can i control the amplitude thru the mci control? if so how ?
0
 
finsterCommented:
Found this article here  (http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.mmedia/2004-02/0103.html)  which might explain why the audiolvl sample project won't work
0
 
rkpuneCommented:
The sample you have given works fine. But it saves at c:\windows\desktop\testme.wav if I want the wave file to be stored upto user's choice ? I tried to put a Common dialog on click event of Stop/save button. and set
Result = mciSendString("save mywav " & cd1.FileName, ReturnString, 1024, 0) but it doesn't work.
how to solve this
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now