TrEaSoN
asked on
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!
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!
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!®©
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!®©
ASKER
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?
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?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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!
ASKER
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!
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!®©
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!®©
ASKER
I get the message "couldn't get wavin meter" and "couldn't get wavout meter".
Sorry, But I can't reproduce that error... Step through the program and let me know what line is giving the error.
ASKER
Adjusted points to 250
ASKER
well...
ok = GetControl(hmixer, MIXERLINE_COMPONENTTYPE_DS T_WAVEIN, MIXERCONTROL_CONTROLTYPE_P EAKMETER, inputVolCtrl)
If (ok <> True) Then
ok = GetControl(hmixer, MIXERLINE_COMPONENTTYPE_SR C_MICROPHO NE, MIXERCONTROL_CONTROLTYPE_P EAKMETER, inputVolCtrl)
End If
both of these instances return ok as false. That is where its going wrong. the
hmixer = -2102807656
MIXERLINE_COMPONENTTYPE_DS T_WAVEIN = 7
MIXERCONTROL_CONTROLTYPE_P EAKMETER = 268566529
MIXERLINE_COMPONENTTYPE_SR C_MICROPHO NE = 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.
ok = GetControl(hmixer, MIXERLINE_COMPONENTTYPE_DS
If (ok <> True) Then
ok = GetControl(hmixer, MIXERLINE_COMPONENTTYPE_SR
End If
both of these instances return ok as false. That is where its going wrong. the
hmixer = -2102807656
MIXERLINE_COMPONENTTYPE_DS
MIXERCONTROL_CONTROLTYPE_P
MIXERLINE_COMPONENTTYPE_SR
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.
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_COMPONE NTTYPE)
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(hmixe r, mxlc, MIXER_GETLINECONTROLSF_ONE BYTYPE)
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
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_COMPONE
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(hmixe
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
ASKER
That returned 'Unkown Error 1025'
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!®©
MIXERR_INVALCONTROL is defined like this:
Const MIXERR_INVALCONTROL = (MMSYSERR_BASE + 1)
Do you have a mixer control on your system??
Cheers!®©
ASKER
I have Creative Mixer...if that's what your getting at.
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!®©
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!®©
ASKER
okay....i'll check my configuration...if you can think of any suggestions just post it. Thanks for all the help!
Thanks for the points! Glad I could help!
Cheers!®©
Cheers!®©
can i control the amplitude thru the mci control? if so how ?
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
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
Result = mciSendString("save mywav " & cd1.FileName, ReturnString, 1024, 0) but it doesn't work.
how to solve this
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
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!