Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Audio...
#1
I'm looking for something...DLL, active X, or other way to be able to receive data from the sound card. Basically, just want to be able to use a computer as a silence alarm, a program will activate after so many seconds of silence.

I don't know if I have to do something with the audio driver or what.

Thanks for any help,
Jimmy Vig
#2
I think this is a start sorry I don't know more.

Timed Function

Macro
Code:
Copy      Help
bee "C:\WINDOWS\Media\tada.wav"
#3
Thats actually nothing like what I need...

I need to monitor the input of the "line in" on the sound card for if there is audio or not...when audio stops a timer will start, if that timer gets to a certain value, a program will run a command to play window media player. When audio starts again, the program will another command to stop windows media player.

I figure there is a DLL or something out there that will let me do this, it'd be nice if I could set values for what qualifies as silence as well...like under -40db for 6 sec will trigger the program.

Thanks for your help...
Jimmy Vig
#4
Ok...so I think I've got this a bit easier...maybe?

any idea on how to use:
MIXERLINE
http://msdn.microsoft.com/en-us/library/...S.85).aspx

I just need to poll for the value on the line input....from there I can figure out the rest!

How do I get the values of audio coming in on the line in?

I guess my next question would be getting the values on the "Stereo Mix" and "Microphone" etc...

Thanks,
Jimmy Vig
#5
Function Function2
Code:
Copy      Help
;;What does mixerGetLineInfo do and how do I use it?
mixerGetLineInfo ;;function retrieves information about a specific line of a mixer device.

;This is what pops up when I Ctrl+(L)Click-->
dll winmm [mixerGetLineInfoA]#mixerGetLineInfo hmxobj MIXERLINE*pmxl fdwInfo

;;I can't make heads or tales out of getting anything to work yet.
;;hmxobj and pmxl?? Not a clue.

;;then of course ther is:
;;which is nice to look at,
;;but still might as well be greek-->

;MMRESULT mixerGetLineInfo(
;;;HMIXEROBJ hmxobj,  
;;;LPMIXERLINE pmxl,  
;;;DWORD fdwInfo      
;);

;;http://msdn.microsoft.com/en-us/library/ms712120(VS.85).aspx
#6
here is a post I found searching mixerline peak:
http://delphi-id.org/dpr/Forum-viewtopic-t-717.pas

This looks more promising...I've actually got it spitting out some numbers, but I can't get 'em to change...but hey I feel like I'm getting somewhere!
http://support.microsoft.com/kb/181550
#7
Function Peak_Meter
Code:
Copy      Help
;;From (http://support.microsoft.com/kb/181550)
;;I think I have it adapted right for QM...not sure though :)
;;Right off the bat...MMRESULT and HMIXER types do not work...I think I need them?

;MMRESULT rc              ;; Return code.
int rc                    ;; (EDIT) Changed from MMRESULT rc
;HMIXER hMixer            ;; Mixer handle used in mixer API calls.
int hMixer                ;; (EDIT) Changed from HMIXER hMixer
MIXERCONTROL mxc;         ;; Holds the mixer control data.
MIXERLINE mxl;            ;; Holds the mixer line data.
MIXERLINECONTROLS mxlc;   ;; Obtains the mixer control.

;;;;;; Open the mixer. This opens the mixer with a deviceID of 0. If you
;;;;;; have a single sound card/mixer, then this will open it. If you have
;;;;;; multiple sound cards/mixers, the deviceIDs will be 0, 1, 2, and
;;;;;; so on.
rc = mixerOpen(&hMixer, 0,0,0,0);
if (MMSYSERR_NOERROR != rc)
,mes "Couldn't open the mixer."
;;;;;; Initialize MIXERLINE structure.
;ZeroMemory(&mxl,sizeof(mxl)); ;;(Disabled)DOES NOT WORK??
mxl.cbStruct = sizeof(mxl);

;;;;;; Specify the line you want to get. You are getting the input line
;;;;;; here. If you want to get the output line, you need to use
;;;;;; MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT.
mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;

rc = mixerGetLineInfo(hMixer, &mxl,MIXER_GETLINEINFOF_COMPONENTTYPE); ;;Changed from: rc = mixerGetLineInfo((HMIXEROBJ)hMixer, &mxl,MIXER_GETLINEINFOF_COMPONENTTYPE);
if (MMSYSERR_NOERROR == rc)
,mes "Couldn't get the mixer line."

;;;;;; Get the control.
;ZeroMemory(&mxlc, sizeof(mxlc)); ;;(Disabled)DOES NOT WORK??
mxlc.cbStruct = sizeof(mxlc);
mxlc.dwLineID = mxl.dwLineID;
mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_PEAKMETER;
mxlc.cControls = 1;
mxlc.cbmxctrl = sizeof(mxc);
mxlc.pamxctrl = &mxc;

;ZeroMemory(&mxc, sizeof(mxc)); ;;(Disabled)DOES NOT WORK??

mxc.cbStruct = sizeof(mxc);
rc = mixerGetLineControls(hMixer,&mxlc,MIXER_GETLINECONTROLSF_ONEBYTYPE); ;;Changed from: rc = mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc,MIXER_GETLINECONTROLSF_ONEBYTYPE);
if (MMSYSERR_NOERROR != rc)
,mes "Couldn't get the control."

;;;;;; After successfully getting the peakmeter control, the volume range
;;;;;; will be specified by mxc.Bounds.lMinimum to mxc.Bounds.lMaximum.

MIXERCONTROLDETAILS mxcd;             ;; Gets the control values.
MIXERCONTROLDETAILS_SIGNED volStruct; ;; Gets the control values.
long volume;                          ;; Holds the final volume value.

;;;;;; Initialize the MIXERCONTROLDETAILS structure
;ZeroMemory(&mxcd, sizeof(mxcd));
mxcd.cbStruct = sizeof(mxcd);
mxcd.cbDetails = sizeof(volStruct);
mxcd.dwControlID = mxc.dwControlID;
mxcd.paDetails = &volStruct;
mxcd.cChannels = 1;

;;;;;; Get the current value of the peakmeter control. Typically, you
;;;;;; would set a timer in your program to query the volume every 10th
;;;;;; of a second or so.
rc = mixerGetControlDetails(hMixer, &mxcd,MIXER_GETCONTROLDETAILSF_VALUE); ;;Changed from: rc = mixerGetControlDetails((HMIXEROBJ)hMixer, &mxcd,MIXER_GETCONTROLDETAILSF_VALUE);
if (MMSYSERR_NOERROR == rc)
,mes "Couldn't get the current volume."
volume = volStruct.lValue;

;;;;;; Get the absolute value of the volume.
if (volume < 0)
,volume = -volume;
,
out volume
;;output is 0 which tells me it is not working.  Maybe someone will have good luck with this!  Thanks...Jimmy Vig
#8
The code is correctly converted. Just one mistake, in two places: if (MMSYSERR_NOERROR == rc)
But says 'Couln't get the control'.
rc is MIXERR_INVALCONTROL, The control reference is invalid.
Maybe my soundcard does not have a peakmeter.
#9
Did the code work for you? I'm a testing on another computer...it doesn't work there either. Do you have any ideas?
#10
Doesn't work.
mixerGetLineControls returns MIXERR_INVALCONTROL, The control reference is invalid.
#11
http://msdn.microsoft.com/en-us/library/...S.85).aspx
#12
Phoo-ie I am wearing thin on this...I thought I had it...Here the msdn MIXERCONTROL:
http://msdn.microsoft.com/en-us/library/...S.85).aspx

Well...if you come up with any ideas, I sure would appreciate some help on this!

Thanks,
Jimmy Vig
#13
mixerGetLineControls does not fail if i use MIXERCONTROL_CONTROLTYPE_VOLUME instead of MIXERCONTROL_CONTROLTYPE_PEAKMETER. It means that my soundcard does not have a peakmeter.

Another way - record from wave in and get peak from the recorded data. But i think you can record only wave in, but not wave out, unless you connect them.

waveInOpen ...
#14
could you give an example of waveInOpen?
#15
Much work, learning, experimenting...
Search on the Internet.
#16
I emailed the guy that wrote http://www.darkwood.demon.co.uk/PC/meter.html to see if he could modify with a textbox output of the dB that I can grab with a getwintext with QM or if he would be willing to send the code that he used to build the exe...which is in Borland Delphi. If he actually replies that would be great, and if I get the codes, I'll probably need some help converting the Borland Delphi code to something that QM can use.

Thanks for all your help.
Jimmy Vig
#17
So that program has an "OVER" editbox...it turns red when the audio is above a configured point...I grabbed the style of the wintext...And believe it or not I have it working. Its pretty clunky, but the computer that will run this will be a dedicated to do just this.

I still want to work out the other stuff, but I can get moving on the rest of this code.
#18
Audio recording and level meter example. Measures sound power (sorry, don't know how it is in English) instead of max amplitude. Liner, not dB.

Function dlg_wave_meter
Code:
Copy      Help
\Dialog_Editor
function# hDlg message wParam lParam
if(hDlg) goto messages

str controls = "3"
str e3
if(!ShowDialog("dlg_wave_meter" &dlg_wave_meter &controls)) ret

;BEGIN DIALOG
;0 "" 0x90C80A44 0x100 0 0 223 135 "Wave In Level"
;1 Button 0x54030001 0x4 120 116 48 14 "OK"
;2 Button 0x54030000 0x4 170 116 48 14 "Cancel"
;3 Edit 0x54030080 0x200 2 16 42 14 ""
;4 msctls_progress32 0x54030000 0x0 2 2 220 12 ""
;END DIALOG
;DIALOG EDITOR: "" 0x2030002 "*" "" ""

ret
;messages
int- hwi
WAVEHDR- hd
sel message
,case WM_INITDIALOG
,;SendMessage id(4 hDlg) PBM_SETRANGE 0 0x8000<<16
,
,WAVEFORMATEX wf.cbSize=sizeof(wf)
,wf.wFormatTag=WAVE_FORMAT_PCM
,wf.nChannels=1 ;;mono
,wf.nSamplesPerSec=44.1*1000 ;;44.1 kHz
,wf.wBitsPerSample=16
,wf.nBlockAlign=wf.nChannels*wf.wBitsPerSample/8
,wf.nAvgBytesPerSec=wf.nSamplesPerSec*wf.nBlockAlign
,
,int rc=waveInOpen(&hwi WAVE_MAPPER &wf hDlg 0 CALLBACK_WINDOW)
,if(rc) out "waveInOpen: %i" rc; ret
,
,hd.dwBufferLength=wf.nAvgBytesPerSec/10 ;;10 buffers/s
,hd.lpData=q_malloc(hd.dwBufferLength)
,rc=waveInPrepareHeader(hwi &hd sizeof(hd))
,if(rc) out "waveInPrepareHeader: %i" rc; ret
,
,rc=waveInStart(hwi)
,if(rc) out "waveInStart: %i" rc; ret
,
,case WM_DESTROY
,waveInStop(hwi)
,waveInClose(hwi)
,0
,
,case MM_WIM_OPEN
,out "open"
,rc=waveInAddBuffer(hwi &hd sizeof(hd))
,if(rc) out "waveInAddBuffer: %i" rc; ret
,
,case MM_WIM_CLOSE
,out "close"
,rc=waveInUnprepareHeader(hwi &hd sizeof(hd))
,q_free hd.lpData
,
,case MM_WIM_DATA
,;out "%i %i 0x%X" hd.dwBytesRecorded hd.lpData hd.dwFlags
,int i dc p k
,word* w=hd.lpData; int nsamples=hd.dwBytesRecorded/2
,if(!nsamples) ret
,;calc direct current level
,for(i 0 nsamples) dc+w[i]
,dc/nsamples
,;calc power
,for(i 0 nsamples) p+abs(w[i]-dc)
,p/nsamples
,;out "%i %i" dc p
,p=p*100/0x8000 ;;normalize to max 100. Near 100 can be only for square waveform or when peaks are cut. For nondistorted sinus waveform would be max about 60 or 70.
,if(p>100) p=100
,SendMessage id(4 hDlg) PBM_SETPOS p 0
,SetDlgItemInt hDlg 3 p 0
,rc=waveInAddBuffer(hwi &hd sizeof(hd))
,
,case WM_COMMAND goto messages2
ret
;messages2
sel wParam
,case IDOK
,case IDCANCEL
ret 1
#19
Wicked sweet! Must say good work.

Thanks so much!...now for working out a timer...and whammo silence alarm! So rad.
#20
Here's what I have worked out so far...if anyone has ways of doing things better I would love to look at them. I feel like some of my methods are fairly clunky.

Thanks,
Jimmy Vig


.qml   Line-In_Meter.qml (Size: 4.2 KB / Downloads: 470)


Forum Jump:


Users browsing this thread: 3 Guest(s)