#include <Sound.au3>
#include <Timers.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include 'GuiLevelMeter.au3'

_mciSendString('close LevelMeter')
_mciSendString('open new Type waveaudio Alias LevelMeter')
_mciSendString('set LevelMeter bitspersample 8') ; <- 8 Bit pro Sample
_mciSendString('set LevelMeter samplespersec 44100') ; <- Samples pro Sek. = 44100
_mciSendString('set LevelMeter channels 2') ; <- Stereo
_mciSendString('set LevelMeter input 0') ; <- Soundkarten-Eingang (falls Anzeige nicht vorhanden, mal den Wert ändern 1 bis 5)
_mciSendString('cue LevelMeter input')

Global $iPeakL, $iPeakR
$iVolume = _SoundGetWaveVolume()
$sPath = FileOpenDialog('Bitte ein MP3 auswählen', '', 'MP3-Files (*.mp3)', 3)
If @error Then _End()
$hSound = _SoundOpen($sPath)
If @error Then _End()
_SoundPlay($hSound)
$hGui = GUICreate('LevelMeter Example', 600, 300)
$iXPos = 10
$iYPos = 30
$iWidth = 580
$hLevelMeter = _GUICtrlLevelMeter_Create($hGui, $iXPos, $iYPos, 580)
GUISetState()
GUIRegisterMsg($WM_TIMER, '_WM_TIMER')
$iTimerVUMeter = _Timer_SetTimer($hGui, 20)
While True
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			_SoundClose($hSound)
			_Timer_KillAllTimers($hGui)
			_End()
	EndSwitch
	$iVolume = _SoundGetWaveVolume()
WEnd

Func _End()
	_mciSendString('close LevelMeter')
	Exit
EndFunc

Func _WM_TIMER($hWnd, $iMsg, $iwParam, $ilParam)
	#forceref $hWnd, $iMsg, $ilParam
	Local $iRet, $iLeft, $iRight, $iTop
	$iTop = $iVolume
	If $iTop = 0 Then $iTop = 100
	Switch _Timer_GetTimerID($iwParam)
		Case $iTimerVUMeter
			$iRet = _mciSendString('Status LevelMeter Level', 12)
			$iLeft = BitAND($iRet, 0xFF) / $iTop * 100
			$iRight = BitShift($iRet, 16) / $iTop * 100
			If $iLeft > 100 Then $iLeft = 100
			If $iRight > 100 Then $iRight = 100
			If $iLeft > $iPeakL Then $iPeakL = $iLeft
			If $iRight > $iPeakR Then $iPeakR = $iRight
			_GUICtrlLevelMeter_SetData($hLevelMeter, $iPeakL, $iPeakR)
			$iPeakL -= 4
			$iPeakR -= 4
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_TIMER

Func _mciSendString($string, $iLen = 0)
	Local $iRet
	$iRet = DllCall('winmm.dll', 'int', 'mciSendStringA', 'str', $string, 'str', '', 'long', $iLen, 'long', 0)
	If Not @error Then Return $iRet[2]
EndFunc   ;==>__mciSendString

Func _SoundGetWaveVolume()
	Local $WaveVol = -1, $p, $ret
	Local Const $MMSYSERR_NOERROR = 0
	$p = DllStructCreate('dword')
	If @error Then Return SetError(2, 0, -2)
	$ret = DllCall('winmm.dll', 'long', 'waveOutGetVolume', 'long', -1, 'long', DllStructGetPtr($p))
	If ($ret[0] == $MMSYSERR_NOERROR) Then
		$WaveVol = Round(Dec(StringRight(Hex(DllStructGetData($p, 1), 8), 4)) / 0xFFFF * 100)
	Else
		SetError(1)
	EndIf
	$p = 0
	Return $WaveVol
EndFunc   ;==>_SoundGetWaveVolume
