Page 1 of 1

Detect volume / audio level?

Posted: Fri Feb 17, 2012 11:52 pm
by jassing
Is there a way to detect the actual audio level?
Not the volume level, but the level out of hte speakers...

think tv commercials -- you don't change the volume, but it's louder during commercials.

I want to detect that "jump" in audio level and clip it.

Re: Detect volume / audio level?

Posted: Sat Feb 18, 2012 2:03 am
by idle
Best way would be to run an FFT over the wavout mix to get the power of the signal

Re: Detect volume / audio level?

Posted: Sat Feb 18, 2012 2:32 am
by jassing
idle wrote:Best way would be to run an FFT over the wavout mix to get the power of the signal
i'll seach the api's for fft... thanks.
-j

Re: Detect volume / audio level?

Posted: Sat Feb 18, 2012 4:40 am
by kenmo
Hmm... why would you need to perform an FFT?

You should be able to calculate various "power" or loudness statistics directly from the audio buffer/samples. No transform needed.

An RMS (root mean square) or moving-average type calculation would probably give you good values to monitor.

EDIT - However you do it, the hard part is getting realtime access to Window's audio out mix, and I have no idea how to do that :oops:

Re: Detect volume / audio level?

Posted: Sat Feb 18, 2012 4:40 pm
by idle
yes you're right, you could do it from the buffer directly.
I had mentioned that in a pm that I had sent along with the code to do the recording and FFT
though you would probably get better results looking at a specific frequency range 500hz to 3kz
The hard part is the mixer stuff since MS had a brainiac moment and broke the api.

Re: Detect volume / audio level?

Posted: Sat Feb 18, 2012 10:12 pm
by Tenaja
kenmo wrote:An RMS (root mean square) or moving-average type calculation would probably give you good values to monitor.
If you want any "useable" numbers, you have to get RMS (be it from an RMS calculation or derived with some other method), as that is the way to calculate dB.

Anything else will just be relative loudness (i.e. "louder" and "not as loud")...

Re: Detect volume / audio level?

Posted: Sat Feb 18, 2012 10:54 pm
by jassing
Tenaja wrote:
kenmo wrote:An RMS (root mean square) or moving-average type calculation would probably give you good values to monitor.
If you want any "useable" numbers, you have to get RMS (be it from an RMS calculation or derived with some other method), as that is the way to calculate dB.

Anything else will just be relative loudness (i.e. "louder" and "not as loud")...
I can deal with either..

"Clip anything that reaches x db"
or
"clip anything that jumps to 20% higher than now"

Re: Detect volume / audio level?

Posted: Sun Feb 19, 2012 3:52 pm
by Tenaja
jassing wrote:
Tenaja wrote:
kenmo wrote:An RMS (root mean square) or moving-average type calculation would probably give you good values to monitor.
If you want any "useable" numbers, you have to get RMS (be it from an RMS calculation or derived with some other method), as that is the way to calculate dB.

Anything else will just be relative loudness (i.e. "louder" and "not as loud")...
I can deal with either..

"Clip anything that reaches x db"
or
"clip anything that jumps to 20% higher than now"
If the sound is constant tones, then a straight comparison will work. However, a tinny sound can have a much higher peak amplitude but still be quieter (with lower RMS and lower dB) than a lower frequency sine wave that has a wide curve. It is not linear, but think of a tall skinny champagne glass vs. a short, wide beer mug. The beer mug is the loud bass sound, and the champagne glass is the tinny sound that has a tall peak, but very low dB.

Re: Detect volume / audio level?

Posted: Sun Feb 19, 2012 8:05 pm
by utopiomania

Code: Select all

'**************************************************************
'   Hank Doyle  October, 2010
'   VU meter for reading audio inputs from the sound card   ***
'   This reads the mciSendString 'level' status and         ***
'   display's it in a graphic box. The range of the level   ***
'   is from 0 to 128 and scaled to the width of the         ***
'   graphic box.                                            ***
'   Feel free to use this code or modify in any way for     ***
'   your application.                                       ***
'**************************************************************
    nomainwin
    WindowWidth = 450
    WindowHeight = 130
    UpperLeftX=int((DisplayWidth-WindowWidth)/2)
    UpperLeftY=int((DisplayHeight-WindowHeight)/2)
    graphicbox #1.cursor,  23,  50, 400,  20
    button #1.button1,"Start recording",[startRecording], UL,  25,  5, 120,  25
    button #1.button2,"Stop recording",[stopRecording], UL, 160, 5, 120, 25
    setTab$ = space$(23);" "
    statictext #1.levelLabel, "0%";setTab$;"25%";setTab$;"50%";setTab$;"75%";setTab$;"100%", 25,  30,  420,  15
    statictext #1.stLevel, "", 200,80,200,25
    open "Vu meter" for window_nf as #1
    #1.cursor, "down; fill white; flush"
    #1.cursor, "backcolor green"
    #1, "font ms_sans_serif 10"
    #1, "trapclose [quit]"
    'value when VU bar turns red to show overload.
    vuThreshold = 115
    timer 0

[waitLoop]
    calldll #user32, "GetAsyncKeyState", _VK_SPACE as long, ret as short  'Space bar to start recording
    if  ret = -32767 then [startRecording]
    scan
goto [waitLoop]

[startRecording]
    'open wav audio to get audio level
    r$=mciSendString$("open new type waveaudio alias wav")
    'open myRecord for recording your input sound
    r$=mciSendString$("open new type waveaudio alias myRecord")
    r$=mciSendString$("record myRecording") 'start the recording
    '**************************************************
    [readVolume]
    timer 0
    #1.cursor, "backcolor white"
    #1.cursor, "boxfilled 400 25; flush"
    r$=mciSendString$("status wav level")
    #1.stLevel, "level = ";val(r$)
    normLevel = (val(r$) * 400)/128
    #1.cursor, "backcolor green"
    if val(r$) > vuThreshold then  #1.cursor, "backcolor red"
    #1.cursor, "boxfilled ";normLevel;" 20; flush"
    timer 50, [readVolume]
    goto [waitLoop]
    wait

[stopRecording]
    timer 0
    #1.cursor, "down; fill white; flush"
    #1.stLevel, "level = 0"
    r$=mciSendString$("close wav")
    r$=mciSendString$("close myRecording")
    goto [waitLoop]
    wait

[quit] 'End the program
    r$=mciSendString$("close wav")
    r$=mciSendString$("close myRecording")
    close #1
    end

Function mciSendString$(s$)
    'Buffer will contain a return string from
    'the function, if there is one.
    buffer$=space$(1024)+chr$(0)
    calldll #winmm,"mciSendStringA",s$ as ptr,buffer$ as ptr,_
    1028 as long, 0 as long, r as long
'truncate returned string at null character
    buffer$=left$(buffer$, instr(buffer$, chr$(0)) - 1)
    if r>0 then
        mciSendString$="error"
    else
    mciSendString$=buffer$
    end if
End Function
Its a different language, but is easily translated. To use the level to detect jumps or
sudden changes should be easy.