Solved

Sound Recording

Posted on 2000-03-06
21
10,189 Views
Last Modified: 2012-06-27
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
Comment
Question by:TrEaSoN
21 Comments
 
LVL 9

Expert Comment

by:Ruchi
ID: 2590242
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
 
LVL 14

Expert Comment

by:mcrider
ID: 2590363
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
 

Author Comment

by:TrEaSoN
ID: 2593471
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
 
LVL 14

Accepted Solution

by:
mcrider earned 250 total points
ID: 2594189
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
 

Author Comment

by:TrEaSoN
ID: 2594253
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
 

Author Comment

by:TrEaSoN
ID: 2594287
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
 
LVL 14

Expert Comment

by:mcrider
ID: 2594322
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
 

Author Comment

by:TrEaSoN
ID: 2594325
I get the message "couldn't get wavin meter" and "couldn't get wavout meter".
0
 
LVL 14

Expert Comment

by:mcrider
ID: 2594372
Sorry, But I can't reproduce that error... Step through the program and let me know what line is giving the error.
0
 

Author Comment

by:TrEaSoN
ID: 2594401
Adjusted points to 250
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 

Author Comment

by:TrEaSoN
ID: 2594402
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
 
LVL 14

Expert Comment

by:mcrider
ID: 2594573
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
 

Author Comment

by:TrEaSoN
ID: 2598041
That returned 'Unkown Error 1025'
0
 
LVL 14

Expert Comment

by:mcrider
ID: 2598545
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
 

Author Comment

by:TrEaSoN
ID: 2598561
I have Creative Mixer...if that's what your getting at.
0
 
LVL 14

Expert Comment

by:mcrider
ID: 2599109
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
 

Author Comment

by:TrEaSoN
ID: 2602424
okay....i'll check my configuration...if you can think of any suggestions just post it.  Thanks for all the help!
0
 
LVL 14

Expert Comment

by:mcrider
ID: 2603092
Thanks for the points! Glad I could help!


Cheers!®©
0
 

Expert Comment

by:tgkprog
ID: 9835625
can i control the amplitude thru the mci control? if so how ?
0
 

Expert Comment

by:finster
ID: 13010599
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
 
LVL 2

Expert Comment

by:rkpune
ID: 13858363
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

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

743 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

9 Experts available now in Live!

Get 1:1 Help Now