Update - Audio Visualizing

  • Edit: Da mich UEZ gestern mit diesem Script: GDI+ Zoomer
    inspiriert hat, hab ich ein paar weiter Beispiele in "Vizualizing.zip" gepackt...


    Eine Spielerei von mir

    Ich weiß gar nicht, wie ich das Script beschreiben soll...
    Eine Wellenform und Spektrum Anzeige eines Liedes auf dem Bildschirm ^^

    Spoiler anzeigen
    [autoit]

    #AutoIt3Wrapper_UseX64=n
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <WINAPI.au3>
    #include "Bass.au3"
    #include "BassExt.au3"
    #include <GDIPlus.au3>
    #include "GDIP.au3"

    [/autoit] [autoit][/autoit] [autoit]

    HotKeySet("{ESC}", "_Exit")

    [/autoit] [autoit][/autoit] [autoit]

    Global $iWidth = @DesktopWidth * 0.7
    Global $iHeight = @DesktopHeight * 0.7
    Global $iPerspL = Round($iWidth * 0.3)
    Global $iPerspR = Round($iWidth * 0.1)
    Global $iWaveH = $iHeight / 10

    [/autoit] [autoit][/autoit] [autoit]

    Global $aP_Flip[5][2] = [[4, 0],[0, $iHeight],[$iWidth, $iHeight],[0, 0],[$iWidth, 0]]
    Local $aP_Warp[5][2] = [[4, 0],[$iPerspL, 0],[$iWidth - $iPerspR, 0],[0, $iHeight],[$iWidth, $iHeight]]

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $sFile = FileOpenDialog("Open...", "", "playable formats (*.MP3;*.MP2;*.MP1;*.OGG;*.WAV;*.AIFF;*.AIF)")

    [/autoit] [autoit][/autoit] [autoit]

    Global $hGui = GUICreate("FFT", $iWidth, $iHeight, -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TRANSPARENT, $WS_EX_TOPMOST))
    GUISetBkColor(0x000000)
    _WinAPI_SetLayeredWindowAttributes($hGui, 0x00000000, 0xFF, 0x01, True)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()
    Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
    Global $hBmpBuffer = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
    Global $hGfxBuffer = _GDIPlus_ImageGetGraphicsContext($hBmpBuffer)
    Global $hBrush_FFT = _GDIPlus_BrushCreateSolid(0xFF0000AA)
    Global $hPen_FFT = _GDIPlus_PenCreate(0xFF0000FF)

    [/autoit] [autoit][/autoit] [autoit]

    Global $hBrush_WL = _GDIPlus_BrushCreateSolid(0x8800FF00)
    Global $hPen_WL = _GDIPlus_PenCreate(0xEE00FF00)
    Global $hBrush_WR = _GDIPlus_BrushCreateSolid(0x88FF0000)
    Global $hPen_WR = _GDIPlus_PenCreate(0xEEFF0000)

    [/autoit] [autoit][/autoit] [autoit]

    Global $hBrush_Pos = _GDIPlus_BrushCreateSolid(0x44FFFFFF)
    Global $hPen_Pos = _GDIPlus_PenCreate(0x88FFFFFF)

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_Startup(@ScriptDir & "\bass.dll")
    _BASS_EXT_Startup(@ScriptDir & "\bassExt.dll")

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_Init(0, -1, 44100, 0, "")

    [/autoit] [autoit][/autoit] [autoit]

    Global $hStream = _BASS_StreamCreateFile(False, $sFile, 0, 0, $BASS_SAMPLE_FLOAT)

    [/autoit] [autoit][/autoit] [autoit]

    Global $aWave = _CreateWaveForm($sFile)
    Global $aFFT = _BASS_EXT_CreateFFT(50, 0, 0, $iWidth, $iHeight / 2, $iWidth / 100, True)
    _BASS_ChannelPlay($hStream, True)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    GUIRegisterMsg(0x000F, "WM_PAINT")
    GUIRegisterMsg(0x0014, "WM_ERASEBKGND")

    [/autoit] [autoit][/autoit] [autoit]

    Global $iTimer = TimerInit()
    While _BASS_ChannelIsActive($hStream)
    If TimerDiff($iTimer) > 25 Then
    ConsoleWrite(TimerDiff($iTimer) & @CRLF)
    $iTimer = TimerInit()
    _GDIPlus_GraphicsClear($hGfxBuffer, 0xFF000000)

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_EXT_ChannelGetFFT($hStream, $aFFT, 6)
    If Not @error Then _DrawFFT($hGfxBuffer, $aFFT, $hBrush_FFT, $hPen_FFT)

    [/autoit] [autoit][/autoit] [autoit]

    _DrawWave($hGfxBuffer, $aWave[0], $aWave[2], 0, $hBrush_WL, $hPen_WL)
    _DrawWave($hGfxBuffer, $aWave[1], $aWave[2], $iWaveH / 2, $hBrush_WR, $hPen_WR)
    _DrawPos($hGfxBuffer, $iWaveH, $hBrush_Pos, $hPen_Pos)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    EndIf
    WEnd
    _Exit()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _CreateWaveForm($sFile)
    Local $hStream = _BASS_StreamCreateFile(False, $sFile, 0, 0, $BASS_STREAM_DECODE)
    Local $iBytes = _BASS_ChannelGetLength($hStream, $BASS_POS_BYTE)
    Local $iLength = _BASS_ChannelBytes2Seconds($hStream, $iBytes)
    Local $iRes = 88
    Local $iWidth = $iLength * $iRes
    Local $aWave = _BASS_EXT_ChannelGetWaveformDecode($hStream, $iWidth, $iWaveH, 0, $iLength, $iRes, "_WaveformGetProc")
    ToolTip("")
    _BASS_StreamFree($hStream)
    Return $aWave
    EndFunc ;==>_CreateWaveForm

    [/autoit] [autoit][/autoit] [autoit]

    Func _WaveformGetProc($handle, $percent)
    ToolTip("Get Waveform: " & $percent & "%")
    EndFunc ;==>_WaveformGetProc

    [/autoit] [autoit][/autoit] [autoit]

    Func _DrawPos($hGraphics, $iH, $hBrush, $hPen)
    Local $hPath = _GDIPlus_PathCreate($FillModeAlternate)
    _GDIPlus_PathAddRectangle($hPath, $iWidth / 2 - 2, 0, 4, $iHeight)
    _GDIPlus_PathWarp($hPath, 0, $aP_Warp, 0, 0, $iWidth, $iHeight)
    _GDIPlus_GraphicsFillPath($hGraphics, $hPath, $hBrush)
    _GDIPlus_GraphicsDrawPath($hGraphics, $hPath, $hPen)
    _GDIPlus_PathDispose($hPath)
    EndFunc ;==>_DrawPos

    [/autoit] [autoit][/autoit] [autoit]

    Func _DrawWave($hGraphics, $pWave, $iCnt, $iYOffset, $hBrush, $hPen)
    Local $hPath_O = _GDIPlus_PathCreate($FillModeAlternate)
    Local $hPath_U = _GDIPlus_PathCreate($FillModeAlternate)
    Local $hPath = _GDIPlus_PathCreate($FillModeAlternate)
    Local $iPos = _BASS_ChannelGetPosition($hStream, $BASS_POS_BYTE)
    Local $iSec = _BASS_ChannelBytes2Seconds($hStream, $iPos)
    Local $iOffset = 88 * $iSec
    Local $iXOffset = 0
    Switch $iOffset
    Case 0 To $iWidth / 2
    $iXOffset = $iOffset
    $iOffset = 0
    Case Else
    $iOffset -= $iWidth / 2
    EndSwitch
    Local $iSegments = $iCnt / $aWave[5] * $iWidth
    If $iXOffset Then $iSegments -= $iWidth / 2 - $iXOffset
    If $iOffset + $iSegments > $iCnt Then $iSegments = $iCnt - $iOffset
    Local $fTension = 0.9
    DllCall($ghGDIPDll, "uint", "GdipAddPathCurve3", "hwnd", $hPath_O, "ptr", $pWave, "int", $iCnt, "int", $iOffset, "int", $iSegments, "float", $fTension)
    Local $aP_Flip[5][2] = [[4, 0],[0, $iWaveH / 4],[$iWidth, $iWaveH / 4],[0, 0],[$iWidth, 0]]
    _GDIPlus_PathWarp($hPath_O, 0, $aP_Flip, 0, 0, $iWidth, $iWaveH / 4) ; flip
    _GDIPlus_PathReverse($hPath_O)
    DllCall($ghGDIPDll, "uint", "GdipAddPathCurve3", "hwnd", $hPath_U, "ptr", $pWave, "int", $iCnt, "int", $iOffset, "int", $iSegments, "float", $fTension)
    Local $aP_Off[5][2] = [[4, 0],[0, 0],[$iWidth, 0],[0, $iWaveH / 4],[$iWidth, $iWaveH / 4]]
    _GDIPlus_PathWarp($hPath_U, 0, $aP_Off, 0, -$iWaveH / 4, $iWidth, $iWaveH / 4) ; Y-Offset
    _GDIPlus_PathAddPath($hPath, $hPath_U)
    _GDIPlus_PathAddPath($hPath, $hPath_O)
    _GDIPlus_PathCloseFigure($hPath)
    Local $aP_YOff[5][2] = [[4, 0],[0, 0],[$iWidth, 0],[0, $iWaveH / 2],[$iWidth, $iWaveH / 2]]
    _GDIPlus_PathWarp($hPath, 0, $aP_YOff, $iOffset, -$iYOffset, $iWidth, $iWaveH / 2) ; Y-Offset
    If $iXOffset Then _GDIPlus_PathWarp($hPath, 0, $aP_YOff, -$iWidth / 2 + $iXOffset, 0, $iWidth, $iWaveH / 2) ; Y-Offset
    _GDIPlus_PathWarp($hPath, 0, $aP_Warp, 0, 0, $iWidth, $iWaveH)
    _GDIPlus_GraphicsFillPath($hGraphics, $hPath, $hBrush)
    _GDIPlus_GraphicsDrawPath($hGraphics, $hPath, $hPen)
    _GDIPlus_PathDispose($hPath_O)
    _GDIPlus_PathDispose($hPath_U)
    _GDIPlus_PathDispose($hPath)
    EndFunc ;==>_DrawWave

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _DrawFFT($hGraphics, $aFFT, $hBrush, $hPen)
    Local $hPath = _GDIPlus_PathCreate($FillModeAlternate)
    DllCall($ghGDIPDll, "uint", "GdipAddPathPolygon", "hwnd", $hPath, "ptr", $aFFT[0], "int", $aFFT[1])
    _GDIPlus_PathWarp($hPath, 0, $aP_Flip, 0, 0, $iWidth, $iHeight) ; flip
    DllCall($ghGDIPDll, "uint", "GdipAddPathPolygon", "hwnd", $hPath, "ptr", $aFFT[0], "int", $aFFT[1])
    _GDIPlus_PathWarp($hPath, 0, $aP_Warp, 0, 0, $iWidth, $iHeight) ; warp
    _GDIPlus_GraphicsFillPath($hGraphics, $hPath, $hBrush)
    _GDIPlus_GraphicsDrawPath($hGraphics, $hPath, $hPen)
    _GDIPlus_PathDispose($hPath)
    EndFunc ;==>_DrawFFT

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    _BASS_StreamFree($hStream)
    _BASS_Free()
    _GDIPlus_BrushDispose($hBrush_FFT)
    _GDIPlus_BrushDispose($hBrush_WL)
    _GDIPlus_BrushDispose($hBrush_WR)
    _GDIPlus_BrushDispose($hBrush_Pos)
    _GDIPlus_PenDispose($hPen_FFT)
    _GDIPlus_PenDispose($hPen_WL)
    _GDIPlus_PenDispose($hPen_WR)
    _GDIPlus_PenDispose($hPen_Pos)
    _GDIPlus_GraphicsDispose($hGfxBuffer)
    _GDIPlus_BitmapDispose($hBmpBuffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>_Exit

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_PAINT($hWnd, $uMsgm, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    Return 'GUI_RUNDEFMSG'
    EndFunc ;==>WM_PAINT

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_ERASEBKGND($hWnd, $uMsgm, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    Return True
    EndFunc ;==>WM_ERASEBKGND

    [/autoit]

    Der Hintergrund sollte transparent sein - hab das Script bisher nur auf WinXP getestet...

    Alle benötigten Dateien sind im Anhang enthalten
    Viel Spaß...

    E

  • Gut gelungen.
    Sieht richtig nice aus, auch dass das Spektrum verschoben ist und es 3 verschiedene Spektren gibt find ich gut.

    Meine Projekte:
    ClipBoard Manager (beendet)
    Gutes ClipBoard Verwaltungs Programm mit nützlichen Funktionen.

    HTML Creator (beendet)
    Nützliches Tool um schnell ein eigenes HTML Dokument zu erstellen.

  • Sehr schön :thumbup:

    Aha, dafür hast du also das Spiegeln gebraucht... ;)


    Edit: Vista x86 ist der Hintergrund transparent!

    Gruß,
    UEZ

    PS: ich muss auch mal näher mit den Path Funktionen beschäftigen....

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    Einmal editiert, zuletzt von UEZ (31. August 2010 um 20:01)

  • Is leider nicht transparent :(
    Aber trotzdem mega gelungen :D, wünschte ich könnte das auch

    ist das normal das der ausschlag rechts ausssen nicht ausschlägt ???

    Gruß Mattthias

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal

  • erstmal Danke fürs Feedback!

    Die blauen Balken zeigen das Frequenzspektrum von 20Hz - 20000Hz

    Eine MP3 schneidet meistens alles über ca. 15000Hz ab - deshalb kein Ausschlag ganz rechts
    Mit einer Wav-Datei (Samplingfrequenz 44100Hz => Abspielfrequenz 22050Hz) bewegen sich dann auch diese Balken...

    Ach ja: Was Interessantes:
    Damit man mit _WinAPI_SetLayeredWindowAttributes eine Farbe als Transparent einstellt und diese auch mit GDI+ angenommen wird muss man folgendes machen:
    Farbe in GDI+ z.B.: 0xFFABCDEF
    _WinAPI_SetLayeredWindowAttributes($hWnd, 0x00EFCDAB,0,0x01, True)

    Es gab schon einige Threads, wo das jemand gebraucht hätte.

    E

  • @Matthias: probier mal diesen Code:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <WinApi.au3>
    #include <GDIPlus.au3>

    [/autoit] [autoit][/autoit] [autoit]

    HotKeySet("{ESC}", "_Exit")

    [/autoit] [autoit][/autoit] [autoit]

    $hGui = GUICreate("Test", 400, 400, Default, Default, $WS_POPUP, $WS_EX_LAYERED)
    GUISetBkColor(0xABCDEF)
    _WinAPI_SetLayeredWindowAttributes($hGui, 0x00EFCDAB, 0, 0x01, True)
    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()
    $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
    $hBmpBuffer = _GDIPlus_BitmapCreateFromGraphics(400, 400, $hGraphics)
    $hGfxBuffer = _GDIPlus_ImageGetGraphicsContext($hBmpBuffer)

    [/autoit] [autoit][/autoit] [autoit]

    $hBrush = _GDIPlus_BrushCreateSolid(0xFFABCDEF)
    $hPen = _GDIPlus_PenCreate(0xFFABCDEF, 5)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While 1
    _GDIPlus_GraphicsClear($hGfxBuffer, 0xFF000000)
    $iW = Random(50, 200, 1)
    $iH = Random(50, 200, 1)
    $iX = Random(0, 400, 1)
    $iY = Random(0, 400, 1)
    _GDIPlus_GraphicsFillEllipse($hGfxBuffer, $iX - $iW / 2, $iY - $iH / 2, $iW, $iH, $hBrush)

    [/autoit] [autoit][/autoit] [autoit]

    $iW = Random(50, 200, 1)
    $iH = Random(50, 200, 1)
    $iX = Random(0, 400, 1)
    $iY = Random(0, 400, 1)
    _GDIPlus_GraphicsFillRect($hGfxBuffer, $iX - ($iW * 0.7) / 2, $iY - ($iH * 0.7) / 2, $iW * 0.7, $iH * 0.7, $hBrush)
    _GDIPlus_GraphicsDrawRect($hGfxBuffer, $iX - $iW / 2, $iY - $iH / 2, $iW, $iH, $hPen)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    Sleep(1000)
    WEnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_GraphicsDispose($hGfxBuffer)
    _GDIPlus_BitmapDispose($hBmpBuffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>_Exit

    [/autoit]

    Sind die Ellipse und das Rechteck transparent?

  • Nee die sind beide grau, also ich erkenne sie, wären sie transparent würden sie ja schwarz sein :D

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal