Jump to content

Level Meter


taietel
 Share

Recommended Posts

Again, playing only with labels:

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

;a simple level indicator (of whatever)...
;change it to fit your needs
;by taietel

; I will use values in the range 0-100.
; For other ranges, you have to modify the script accordingly
Global $hLblValue ; label to show the values
$gui=GUICreate("GUI", 120, 150,-1,-1,BitOR($WS_POPUP,$WS_BORDER))
GUISetBkColor(0x000000)
;initialize the levelmeter
;fragmented
$a = _CreateLevelMeter(5,5)
$b = _CreateLevelMeter(40,5,False,20,5,30,0xFFFFFF,0x0000FF)
;continuous
$c = _CreateLevelMeter(80,5,True,20,5,10,0x00FF00,0xFFFF00)
WinSetTrans($gui,"",200)
GUISetState()

;and display some random values
For $i=1 To 50
    $s1=Random(0,100,1)
    $s2=Random(0,100,1)
    $s3=Random(0,100,1)
    ;GUICtrlSetData($hLblValue, $s)
    _ShowLevelMeter($s1,$a)
    _ShowLevelMeter($s2,$b)
    _ShowLevelMeter($s3,$c)
    Sleep(100)
Next
Sleep(2000)
Exit

While 1
    Sleep(10)
    Switch GUIGetMsg()
        Case -3
            Exit
    EndSwitch
WEnd

Func _CreateLevelMeter($iX=5, $iY=5, $bContinous=False, $iUnits=20, $iUnitHeight=5, $iUnitWidth=30, $lStartColour=0xFFFF00, $lEndColour=0xFF0000)
    Local $iUH, $arIndicator[$iUnits], $arColours[$iUnits]
    Local $arRet[$iUnits][3]
    If $bContinous = False Then
        $iUH = $iUnitHeight+1
    Else
        $iUnitHeight+=1
        $iUH = $iUnitHeight
    EndIf
    ;label to show some values (optional)
    $hLblValue = GUICtrlCreateLabel("", $iX, $iY+$iUH*$iUnits+$iUH+5, $iUnitWidth, 18,$SS_CENTER)
    GUICtrlSetColor(-1,0xEFEFEF)
    $Ri = Mod($lStartColour,256)
    $Gi = BitAND($lStartColour/256,255)
    $Bi = BitAND($lStartColour/65536,255)
    $Rf = Mod($lEndColour,256)
    $Gf = BitAND($lEndColour/256,255)
    $Bf = BitAND($lEndColour/65536,255)
    $Rs = Abs($Ri - $Rf)/$iUnits
    $Gs = Abs($Gi - $Gf)/$iUnits
    $Bs = Abs($Bi - $Bf)/$iUnits
    If $Rf < $Ri Then $Rs = -$Rs
    If $Gf < $Gi Then $Gs = -$Gs
    If $Bf < $Bi Then $Bs = -$Bs

    For $i=0 To $iUnits-1
        $Rf = $Ri + $Rs * $i
        $Gf = $Gi + $Gs * $i
        $Bf = $Bi + $Bs * $i
        $arColours[$i]="0x"&Hex($Bf,2) & Hex($Gf,2) & Hex($Rf,2)
    Next
    For $i=0 To $iUnits-1
        $arIndicator[$i] = GUICtrlCreateLabel("", $iX, ($iY+$iUH*$iUnits)-$iUH*$i, $iUnitWidth, $iUnitHeight)
        $arRet[$i][0]=$arIndicator[$i]
        $arRet[$i][1]=$arColours[$i]
        $arRet[$i][2]=$iUnits
    Next
    Return $arRet
EndFunc

Func _ShowLevelMeter($Signal,ByRef $avArray)
    Local $iUnitsColoured
    Local $m = Mod($Signal, $avArray[0][2])
    Switch $m
        Case 0
            $iUnitsColoured=($Signal-$m)*$avArray[0][2]/100
        Case Else
            $iUnitsColoured=($Signal-$m)*$avArray[0][2]/100 + 1
    EndSwitch
    For $i=0 To $iUnitsColoured-1
        GUICtrlSetBkColor($avArray[$i][0], $avArray[$i][1])
    Next
    For $j=UBound($avArray)-1 To $iUnitsColoured Step -1
        GUICtrlSetBkColor($avArray[$j][0], $GUI_BKCOLOR_TRANSPARENT)
    Next
EndFunc

Maybe someone find it useful.

[EDIT] independent values for different styles/colours

Edited by taietel
Link to comment
Share on other sites

The following example is based on ripdad's MCI level meter ():

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

;example based on ripdad's MCI level meter (http://www.autoitscript.com/forum/topic/121624-sound-level-sampling/page__view__findpost__p__845098)
;by taietel

$gui=GUICreate("GUI", 40, 140,-1,-1,BitOR($WS_POPUP,$WS_BORDER)); I will use values in the range 0-100.
GUISetBkColor(0x000000)
;initialize the levelmeter
;fragmented
$a = _CreateLevelMeter(5,5)
;continuous
;~$a = _CreateLevelMeter(5,5,True,20,5,30,0x00FF00,0xFFFF00)
WinSetTrans($gui,"",200)
GUISetState()

Local $mciLevel, $lpszReturnString
$mciInit = DllCall('winmm.dll', 'long', 'mciSendStringA', 'str', 'open new type waveaudio alias mywave', 'str', $lpszReturnString, 'long', 64, 'long', 0)

Do
    $mciLevel = DllCall('winmm.dll', 'long', 'mciSendStringA', 'str', 'status mywave level', 'str', $lpszReturnString, 'long', 64, 'long', 0)
    If $mciLevel[0] <> 0 Then Exit
    _ShowLevelMeter($mciLevel[2],$a)
Until GUIGetMsg() = -3

Func _CreateLevelMeter($iX=5, $iY=5, $bContinous=False, $iUnits=20, $iUnitHeight=5, $iUnitWidth=30, $lStartColour=0xFFFF00, $lEndColour=0xFF0000)
    Local $iUH, $arIndicator[$iUnits], $arColours[$iUnits]
    Local $arRet[$iUnits][3]
    If $bContinous = False Then
        $iUH = $iUnitHeight+1
    Else
        $iUnitHeight+=1
        $iUH = $iUnitHeight
    EndIf
    $Ri = Mod($lStartColour,256)
    $Gi = BitAND($lStartColour/256,255)
    $Bi = BitAND($lStartColour/65536,255)
    $Rf = Mod($lEndColour,256)
    $Gf = BitAND($lEndColour/256,255)
    $Bf = BitAND($lEndColour/65536,255)
    $Rs = Abs($Ri - $Rf)/$iUnits
    $Gs = Abs($Gi - $Gf)/$iUnits
    $Bs = Abs($Bi - $Bf)/$iUnits
    If $Rf < $Ri Then $Rs = -$Rs
    If $Gf < $Gi Then $Gs = -$Gs
    If $Bf < $Bi Then $Bs = -$Bs

    For $i=0 To $iUnits-1
        $Rf = $Ri + $Rs * $i
        $Gf = $Gi + $Gs * $i
        $Bf = $Bi + $Bs * $i
        $arColours[$i]="0x"&Hex($Bf,2) & Hex($Gf,2) & Hex($Rf,2)
    Next
    For $i=0 To $iUnits-1
        $arIndicator[$i] = GUICtrlCreateLabel("", $iX, ($iY+$iUH*$iUnits)-$iUH*$i, $iUnitWidth, $iUnitHeight)
        $arRet[$i][0]=$arIndicator[$i]
        $arRet[$i][1]=$arColours[$i]
        $arRet[$i][2]=$iUnits
    Next
    Return $arRet
EndFunc

Func _ShowLevelMeter($Signal,ByRef $avArray)
    Local $iUnitsColoured
    If $Signal > 100 Then $Signal=100
    Local $m = Mod($Signal, $avArray[0][2])
    Switch $m
        Case 0
            $iUnitsColoured=($Signal-$m)*$avArray[0][2]/100
        Case Else
            $iUnitsColoured=($Signal-$m)*$avArray[0][2]/100 + 1
    EndSwitch
    For $i=0 To $iUnitsColoured-1
        GUICtrlSetBkColor($avArray[$i][0], $avArray[$i][1])
    Next
    For $j=UBound($avArray)-1 To $iUnitsColoured Step -1
        GUICtrlSetBkColor($avArray[$j][0], $GUI_BKCOLOR_TRANSPARENT)
    Next
EndFunc

Updated also the first post with 3 level meters on the same GUI.

Link to comment
Share on other sites

Glad you like it!

The script has general purpose, not only for sound level.

Why I use only autoit native functions? Because I don't understand GDI and dllcalls enough. Till I do, I use mainly simple functions.

Thanks for the link wakillon. I'll take a look, for learning purposes. I bet eucalyptus use GDI!

Link to comment
Share on other sites

Glad you like it!

The script has general purpose, not only for sound level.

Why I use only autoit native functions? Because I don't understand GDI and dllcalls enough. Till I do, I use mainly simple functions.

Thanks for the link wakillon. I'll take a look, for learning purposes. I bet eucalyptus use GDI!

you're right ! Posted Image

I am actually making a music player and I must admit that the GDI functions are impressives

but a bit complicated, so i try to adapt them to my script and it's not easy !

Try the link, it's beautifull ! Posted Image

AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Link to comment
Share on other sites

taietel: nice work!

I couldn't resist ...

Here is one thats "virtually flicker free" and in stereo.

;a simple level indicator (of whatever)...
;change it to fit your needs
;by taietel

; I will use values in the range 0-100.
; For other ranges, you have to modify the script accordingly
Global $gui = GUICreate("GUI", 140, 160, -1, -1, Default, 0x00000008)
GUISetBkColor(0x000000)
;initialize the levelmeter
Global $a = _CreateLevelMeter(44, 8)
Global $b = _CreateLevelMeter(70, 8)
;WinSetTrans($gui, "", 200)
Local $ct = GUICtrlCreateInput("", 150, 10, 2, 4)
GUISetState()
;
Global $mciLevel, $LeftChannel, $RightChannel, $temp, $tmpL = 0, $tmpR = 0, $delay = 4
Global $mciDll = DllOpen(@SystemDir & '\winmm.dll')
If @error Then Exit
mciInit()
AdlibRegister('mci_Status_Level', 10)
;
While 1
    Switch GUIGetMsg()
        Case -3
            ExitLoop
    EndSwitch
WEnd
;
; Cleanup before exit
AdlibUnRegister('mci_Status_Level')
GUIDelete($gui)
mciSendString('stop myStatus')
mciSendString('close myStatus')
DllClose($mciDll)
Exit
;
Func _HiWord($value); From WinAPI.au3
    Return BitShift($value, 16)
EndFunc
;
Func _LoWord($value); From WinAPI.au3
    Return BitAND($value, 0xFFFF)
EndFunc
;
Func mciInit(); Open a live stream and set 2 channel parameters
    mciSendString('open new type waveaudio alias myStatus buffer 2')
    If @error Then Exit
    mciSendString('set myStatus bitspersample 8 channels 2 samplespersec 11025')
    If @error Then Exit
EndFunc
;
Func mci_Status_Level()
    $mciLevel = mciSendString('status myStatus level')
    If @error Then Exit
    $temp = Round((_LoWord($mciLevel) / 128) * 200) - 1
    If $temp > $LeftChannel Then $LeftChannel = $temp; <-- snitched from bassenc udf - thanks BrettF
    $temp = Round((_HiWord($mciLevel) / 128) * 200) - 1
    If $temp > $RightChannel Then $RightChannel = $temp; <--

    _ShowLevelMeter($LeftChannel, $a, $tmpL, 1)
    _ShowLevelMeter($RightChannel, $b, $tmpR, 2)

    $LeftChannel -= $delay; <--
    $RightChannel -= $delay; <--
EndFunc
;
Func mciSendString($string = '', $mciMsg = ''); Custom MCI Command and Error Function (Nov-19-2010)
    $mciMsg = DllCall($mciDll, 'long', 'mciSendStringA', 'str', $string, 'str', '', 'int', 180, 'ptr', 0)
    If @error Then Return SetError(@error)
    If $mciMsg[0] <> 0 Then
        Local $eMsg = DllCall($mciDll, 'long', 'mciGetErrorStringA', 'int', $mciMsg[0], 'str', '', 'int', 180)
        If @error Then Return SetError(@error)
        MsgBox(8208, 'MCI Stereo Level Meter', 'MCI Error: ' & $mciMsg[0] & @CRLF & $eMsg[2])
        Return SetError(-1)
    EndIf
    SetError(0)
    Return $mciMsg[2]
EndFunc
;
Func _CreateLevelMeter($iX = 5, $iY = 5, $bContinous = False, $iUnits = 20, $iUnitHeight = 5, $iUnitWidth = 20, $lStartColour = 0x00FF00, $lEndColour = 0xFF0000)
    Local $iUH, $arIndicator[$iUnits], $arColours[$iUnits]
    Local $arRet[$iUnits][4]; increased columns to 4 to hold color state (ripdad)
    If $bContinous = False Then
        $iUH = $iUnitHeight + 2
    Else
        $iUnitHeight += 2
        $iUH = $iUnitHeight
    EndIf
    $Ri = Mod($lStartColour, 256)
    $Gi = BitAND($lStartColour / 256, 255)
    $Bi = BitAND($lStartColour / 65536, 255)
    $Rf = Mod($lEndColour, 256)
    $Gf = BitAND($lEndColour / 256, 255)
    $Bf = BitAND($lEndColour / 65536, 255)
    $Rs = Abs($Ri - $Rf) / $iUnits
    $Gs = Abs($Gi - $Gf) / $iUnits
    $Bs = Abs($Bi - $Bf) / $iUnits
    If $Rf < $Ri Then $Rs = -$Rs
    If $Gf < $Gi Then $Gs = -$Gs
    If $Bf < $Bi Then $Bs = -$Bs

    For $i = 0 To $iUnits - 1
        $Rf = $Ri + $Rs * $i
        $Gf = $Gi + $Gs * $i
        $Bf = $Bi + $Bs * $i
        $arColours[$i] = "0x" & Hex($Bf, 2) & Hex($Gf, 2) & Hex($Rf, 2)
    Next

    For $i = 0 To $iUnits - 1
        $arIndicator[$i] = GUICtrlCreateLabel("", $iX, ($iY + $iUH * $iUnits) - $iUH * $i, $iUnitWidth, $iUnitHeight, Default, 0x00000020)
        GUICtrlSetBkColor(-1, 0x000000)
        $arRet[$i][0] = $arIndicator[$i]
        $arRet[$i][1] = $arColours[$i]
        $arRet[$i][2] = $iUnits
        $arRet[$i][3] = 0x000000; set column black (ripdad)
    Next
    Return $arRet
EndFunc

Func _ShowLevelMeter($Signal, ByRef $avArray, $tmp, $nChannel); heavily modified (ripdad)
    $Signal /= 10
    For $i = 1 To $Signal
        If (Not $avArray[$i][3] = $avArray[$i][1]) Then
            GUICtrlSetBkColor($avArray[$i][0], $avArray[$i][1])
            $avArray[$i][3] = $avArray[$i][1]
        Else
            GUICtrlSetBkColor($avArray[$tmp][0], 0x000000)
            $avArray[$tmp][3] = 0x000000
        EndIf
    Next
    If $nChannel = 1 Then $tmpL = $Signal; copy last level number into global vars
    If $nChannel = 2 Then $tmpR = $Signal
EndFunc

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Link to comment
Share on other sites

ripdad, nice work! At first I had an mci error (282), but when I changed the channel to 1 was ok.

Looks like nice stuff can came up from simple things.  :graduated:

Link to comment
Share on other sites

taietel,

$ct was a leftover when I was testing inputs instead of labels -- it stands for CursorTrap.

I haven't found a way to disable a cursor yet. So I rest it just to the edge of the GUI.

Anyway ... from one PC to another .. things will change. I'm on XP Pro SP2.

Try this:

bitspersample 16 channels 2 samplespersec 44100

-Edit-

If no MCI errors - then I'll have to modify the script a bit.

Edited by ripdad

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Link to comment
Share on other sites

Manadar, when I gave that name, I thought at some sort of measuring the level of something. If you know what this is called, I'll be grateful if you tell me!

ripdad, I think the problem is with my microphone.

Link to comment
Share on other sites

taietel,

Thats strange. I wonder why the microphone is causing problems.

Well, if anyone else is having problems .. I'll make an alternate script.

Keep up the good work!

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Link to comment
Share on other sites

Found it!  Level meter it is. English is not my primary language and I try to learn as much as I can.

ripdad, I've tested with another mic and your script is ok. I have replaced the mic from the laptop with another from a telephone, a while ago. Maybe that is the issue.

Edited by taietel
Link to comment
Share on other sites

JohnOne, neither do I, till I saw some blank papers (before I wrote 3D Bar Chart). Darn.. I don't know how it's called lots of paper sheets one on top of the other... like a block.

[edit] Slight modification of the first post:

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <WinApi.au3>
;a simple level indicator (of whatever)...
;change it to fit your needs
;by taietel

; I will use values in the range 0-100.
; For other ranges, you have to modify the script accordingly
Global $hLblValue ; label to show the values
$gui=GUICreate("GUI", 120, 150,-1,-1,$WS_POPUP,$WS_EX_LAYERED)
GUISetBkColor(0xabcdef)
;initialize the levelmeter
;example fragmented
$a = _CreateLevelMeter(5,5)
$b = _CreateLevelMeter(40,5,False,20,5,30,0xFFFFFF,0x0000FF)
;example continuous
$c = _CreateLevelMeter(75,5,True,20,5,30,0x00FF00,0xFFFF00)
_WinAPI_SetLayeredWindowAttributes($gui,0xabcdef)
GUISetState()

;and display some random values
For $i=1 To 100
    $s1=Random(0,100,1)
    $s2=Random(0,100,1)
    $s3=Random(0,100,1)
    _ShowLevelMeter($a, $s1)
    _ShowLevelMeter($b, $s2)
    _ShowLevelMeter($c, $s3)
    Sleep(100)
Next
Sleep(2000)
Exit

While 1
    Sleep(10)
    Switch GUIGetMsg()
        Case -3
            Exit
    EndSwitch
WEnd

Func _CreateLevelMeter($iX=5, $iY=5, $bContinous=False, $iUnits=20, $iUnitHeight=5, $iUnitWidth=30, $lStartColour=0xFFFF00, $lEndColour=0xFF0000,$hLblValue="")
    Local $iUH, $arIndicator[$iUnits], $arColours[$iUnits]
    Local $arRet[$iUnits][4]
    If $bContinous = False Then
        $iUH = $iUnitHeight+1
    Else
        $iUnitHeight+=1
        $iUH = $iUnitHeight
    EndIf
    ;label to show some values (optional)
    $hLblValue = GUICtrlCreateLabel("", $iX, $iY+$iUH*$iUnits+$iUH+5, $iUnitWidth, 18,$SS_CENTER)
    GUICtrlSetColor(-1,0xFF0000)
    $Ri = Mod($lStartColour,256)
    $Gi = BitAND($lStartColour/256,255)
    $Bi = BitAND($lStartColour/65536,255)
    $Rf = Mod($lEndColour,256)
    $Gf = BitAND($lEndColour/256,255)
    $Bf = BitAND($lEndColour/65536,255)
    $Rs = Abs($Ri - $Rf)/$iUnits
    $Gs = Abs($Gi - $Gf)/$iUnits
    $Bs = Abs($Bi - $Bf)/$iUnits
    If $Rf < $Ri Then $Rs = -$Rs
    If $Gf < $Gi Then $Gs = -$Gs
    If $Bf < $Bi Then $Bs = -$Bs

    For $i=0 To $iUnits-1
        $Rf = $Ri + $Rs * $i
        $Gf = $Gi + $Gs * $i
        $Bf = $Bi + $Bs * $i
        $arColours[$i]="0x"&Hex($Bf,2) & Hex($Gf,2) & Hex($Rf,2)
    Next
    For $i=0 To $iUnits-1
        $arIndicator[$i] = GUICtrlCreateLabel("", $iX, ($iY+$iUH*$iUnits)-$iUH*$i, $iUnitWidth, $iUnitHeight)
        $arRet[$i][0]=$arIndicator[$i]
        $arRet[$i][1]=$arColours[$i]
        $arRet[$i][2]=$iUnits
        $arRet[$i][3]=$hLblValue
    Next
    Return $arRet
EndFunc

Func _ShowLevelMeter(ByRef $avArray, $Signal,$iMinValue=0,$iMaxValue=100)
    GUICtrlSetData($avArray[0][3], $Signal)
    Local $iUnitsColoured
    Local $m = Mod($Signal, $avArray[0][2])
    Switch $m
        Case 0
            $iUnitsColoured=($Signal-$m)*$avArray[0][2]/100
        Case Else
            $iUnitsColoured=($Signal-$m)*$avArray[0][2]/100 + 1
    EndSwitch
    For $i=0 To $iUnitsColoured-1
        GUICtrlSetBkColor($avArray[$i][0], $avArray[$i][1])
    Next
    For $j=UBound($avArray)-1 To $iUnitsColoured Step -1
        GUICtrlSetBkColor($avArray[$j][0], $GUI_BKCOLOR_TRANSPARENT)
    Next
EndFunc
Edited by taietel
Link to comment
Share on other sites

Looks really cool without GDI+ Posted Image

...But first I have to finish UEZ's thread. :graduated:

I hope it is not chaotic pure and easy to learn...

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...