mit GDI+ Stream Amplitude (Bass.dll) anzeigen

  • Hey @ all,
    ich beschäftige mich mal wieder mit der Bass.dll und möchte diesmal gerne den gesamten Amplituden-Verlauf eines Streams komplett anzeigen, ohne dass dieser dabei abgespielt werden muss. Habe mal recherchiert und bin dabei auf _BASS_ChannelGetData gestoßen. Ich hab da was von Floats und Buffer gelesen, jedoch verstehe ich das nicht so ganz. Ich kann es nachvollziehen, wenn es zu umständlich ist hierzu ein Beispiel zu liefern, aber für eine kurze Erläuterung, wie man das umsetzen kann, wäre ich dankbar.

    mfG
    Developer30

    "Je mehr Käse, desto mehr Löcher; je mehr Löcher, desto weniger Käse. Ergo: Je mehr Käse, desto weniger Käse. 8| "
    "Programmers never die: they just GOSUB without RETURN"
    "I tried to change the world but I couldn't find the source code."

    Einmal editiert, zuletzt von Developer30 (7. November 2010 um 10:46)

  • ich hab einen Visualizer gefunden, in dem das teilweise steht. Jedoch kann ich nicht alles nachvollziehen, was da drin steht. Zudem wird das mit dem Visualizer so gemacht, dass ein Channel abgespielt wird und mit jedem Ton dann der Amplitudenverlauf erweitert wird. Was ich brauche ist einfach nur den gesamten Amplitudenverlauf auf einen Blick.. und ich hab keine große Ahnung wie das geht.

    "Je mehr Käse, desto mehr Löcher; je mehr Löcher, desto weniger Käse. Ergo: Je mehr Käse, desto weniger Käse. 8| "
    "Programmers never die: they just GOSUB without RETURN"
    "I tried to change the world but I couldn't find the source code."

  • Hier ein kleines Beispielscrip, welches zeigt wie es in etwa funktioniert (ist jedoch extrem langsam)

    Spoiler anzeigen
    [autoit]

    #AutoIt3Wrapper_UseX64=n
    #include "Bass.au3"
    #include <GDIPlus.au3>

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

    Global $iBufferSize = 20000 ; bytes

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

    Global $tBuffer = DllStructCreate("float[" & $iBufferSize / 4 & "]")
    Global $pBuffer = DllStructGetPtr($tBuffer)

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

    _GDIPlus_Startup()
    Global $hGui = GUICreate("Test", 1000, 230)
    GUISetBkColor(0x000000)
    GUISetState()
    Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
    Global $hPenL = _GDIPlus_PenCreate(0xFF00FF00)
    Global $hPenR = _GDIPlus_PenCreate(0xFFFF0000)

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

    _BASS_Startup()

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

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

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

    Global $sFile = FileOpenDialog("Open...", "", "Wav Files (*.wav)")
    Global $hStream = _BASS_StreamCreateFile(False, $sFile, 0, 0, $BASS_STREAM_DECODE)

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

    Global $iBytes = _BASS_ChannelGetLength($hStream, $BASS_POS_BYTE)

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

    Global $fXStep = 990 / ($iBytes / 8)

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

    For $i = 1 To $iBytes Step $iBufferSize
    ToolTip(Round($i * 100 / $iBytes, 1) & "%")
    If $i + $iBufferSize <= $iBytes Then
    _BASS_ChannelGetData($hStream, $pBuffer, BitOR($iBufferSize, $BASS_DATA_FLOAT))
    _Analyze($iBufferSize, $fXStep)
    Else
    _BASS_ChannelGetData($hStream, $pBuffer, BitOR($iBytes - $i, $BASS_DATA_FLOAT))
    _Analyze($iBytes - $i, $fXStep)
    EndIf
    Next
    _BASS_FREE()

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

    While GUIGetMsg() <> -3
    Sleep(10)
    WEnd

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

    _GDIPlus_PenDispose($hPenL)
    _GDIPlus_PenDispose($hPenR)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()

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

    Func _Analyze($iBytes, $fXStep)
    Local Static $fX = 0
    Local $fL = 0
    Local $fR = 0
    For $i = 1 To $iBytes / 4 Step 2
    $fL = DllStructGetData($tBuffer, 1, $i)
    $fR = DllStructGetData($tBuffer, 1, $i + 1)
    _GDIPlus_GraphicsDrawLine($hGraphics, $fX, 60, $fX, 60 + $fL * 50, $hPenL)
    _GDIPlus_GraphicsDrawLine($hGraphics, $fX, 170, $fX, 170 + $fR * 50, $hPenR)
    $fX += $fXStep
    Next
    EndFunc ;==>_Analyze

    [/autoit]


    Und hier ein Beispiel zu BassExt.dll:

    Spoiler anzeigen
    [autoit]

    #AutoIt3Wrapper_UseX64=n
    #include "Bass.au3"
    #include "BassExt.au3"
    #include <GDIPlus.au3>

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

    Opt("GUIOnEventMode", 1)

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

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

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

    $hGui = GUICreate("WaveformDecode", 800, 250)
    GUISetOnEvent(-3, "_EXIT")
    GUISetState()

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

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

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

    $hBmpBk = _GDIPlus_BitmapCreateFromGraphics(800, 250, $hGraphics)
    $hGfxBk = _GDIPlus_ImageGetGraphicsContext($hBmpBk)
    _GDIPlus_GraphicsSetSmoothingMode($hGfxBk, 2)

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

    $hPenL = _GDIPlus_PenCreate(0xFF00FF00, 1)
    $hPenR = _GDIPlus_PenCreate(0xFFFF0000, 1)
    $hBrushL = _GDIPlus_BrushCreateSolid(0xBB00BB00)
    $hBrushR = _GDIPlus_BrushCreateSolid(0xBBBB0000)
    $hPenPos = _GDIPlus_PenCreate(0xFF000099, 3)
    $hPenPos2 = _GDIPlus_PenCreate(0x99FFFF00, 1)

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

    _BASS_Startup(@ScriptDir & "\bass.dll")
    ___Debug(@error, "load bass.dll")

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

    _BASS_EXT_Startup(@ScriptDir & "\bassExt.dll")
    ___Debug(@error, "load bassext.dll")

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

    _BASS_Init(0, -1, 44100, 0, "")
    ___Debug(@error, "initialize bass")

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

    $hStreamDecode = _BASS_StreamCreateFile(False, $sFile, 0, 0, $BASS_STREAM_DECODE)
    ___Debug(@error, "create stream from file")

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

    $hStreamPlay = _BASS_StreamCreateFile(False, $sFile, 0, 0, 0)
    ___Debug(@error, "create stream from file")

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

    $iBytes = _BASS_ChannelGetLength($hStreamDecode, $BASS_POS_BYTE)
    $iLength = _BASS_ChannelBytes2Seconds($hStreamDecode, $iBytes)

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

    $iRes = 88; polygon segments per second

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

    $iWidth = $iLength * $iRes
    $aWave = _BASS_EXT_ChannelGetWaveformDecode($hStreamDecode, $iWidth, 200, 0, $iLength, $iRes, "_WaveformGetProc")

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

    _BASS_StreamFree($hStreamDecode)

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

    $hBmpWave = _BASS_EXT_GDIpBitmapCreateWaveform($hGraphics, $aWave, $hBrushL, $hPenL, $hBrushR, $hPenR, 0, 1)
    ToolTip("")

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

    _GDIPlus_GraphicsClear($hGfxBk, 0xFF000000)
    Switch $iWidth
    Case 0 To 30000
    _GDIPlus_GraphicsDrawImageRect($hGfxBk, $hBmpWave, 0, 200, 800, 50)
    Case Else
    For $i = 0 To $iWidth Step 30000
    _GDIPlus_GraphicsDrawImageRectRect($hGfxBk, $hBmpWave, $i, 0, 30000, 200, Round($i * 800 / $iWidth), 200, Ceiling(30000 * 800 / $iWidth), 50)
    Next
    EndSwitch

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

    _BASS_ChannelPlay($hStreamPlay, True)
    ___Debug(@error, "start stream")

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

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

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

    $iTimer = TimerInit()
    While _BASS_ChannelIsActive($hStreamPlay)
    If TimerDiff($iTimer) > 20 Then
    $iTimer = TimerInit()
    $iPosByte = _BASS_ChannelGetPosition($hStreamPlay, $BASS_POS_BYTE)
    $iPosSec = _BASS_ChannelBytes2Seconds($hStreamPlay, $iPosByte)
    $iOffset = Round($iPosSec * $iRes)
    _GDIPlus_GraphicsDrawImage($hGfxBuffer, $hBmpBk, 0, 0)
    _GDIPlus_GraphicsDrawLine($hGfxBuffer, 400, 2, 400, 198, $hPenPos)
    _GDIPlus_GraphicsDrawLine($hGfxBuffer, 800 * $iOffset / $iWidth, 202, 800 * $iOffset / $iWidth, 248, $hPenPos2)
    Select
    Case $iOffset < 400
    _GDIPlus_GraphicsDrawImageRectRect($hGfxBuffer, $hBmpWave, 0, 0, 800, $aWave[6] * 4, 400 - $iOffset, 0, 800, $aWave[6] * 4)
    Case $iOffset >= $iWidth - 800
    _GDIPlus_GraphicsDrawImageRectRect($hGfxBuffer, $hBmpWave, $iWidth - ($iWidth - $iOffset) - 400, 0, $iWidth - $iOffset + 400, $aWave[6] * 4, 0, 0, $iWidth - $iOffset + 400, $aWave[6] * 4)
    Case Else
    _GDIPlus_GraphicsDrawImageRectRect($hGfxBuffer, $hBmpWave, $iOffset - 400, 0, 800, $aWave[6] * 4, 0, 0, 800, $aWave[6] * 4)
    EndSelect
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    EndIf
    Sleep(10)
    WEnd

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

    _Exit()

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

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

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

    Func _Exit()
    _BASS_ChannelStop($hStreamPlay)
    ___Debug(@error, "stop stream")

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

    _BASS_StreamFree($hStreamPlay)
    ___Debug(@error, "free stream")

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

    _BASS_Free()
    ___Debug(@error, "free bass")

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

    GUIRegisterMsg(0x000F, "")
    GUIRegisterMsg(0x0014, "")
    _GDIPlus_PenDispose($hPenL)
    _GDIPlus_PenDispose($hPenR)
    _GDIPlus_BrushDispose($hBrushL)
    _GDIPlus_BrushDispose($hBrushR)
    _GDIPlus_PenDispose($hPenPos)
    _GDIPlus_PenDispose($hPenPos2)
    _GDIPlus_BitmapDispose($hBmpBk)
    _GDIPlus_GraphicsDispose($hGfxBk)
    _GDIPlus_BitmapDispose($hBmpWave)
    _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] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func ___DeBug($iError, $sAction)
    Switch $iError
    Case -1
    ConsoleWrite(@CRLF & "-" & $sAction & @CRLF)
    Case 0
    ConsoleWrite(@CRLF & "+" & $sAction & " - OK" & @CRLF)
    Case Else
    ConsoleWrite(@CRLF & "!" & $sAction & " - FAILED" & @CRLF)
    Exit
    EndSwitch
    EndFunc ;==>___DeBug

    [/autoit]

    benötigte Dateien findest du hier:
    Audio Visualization Collection

    E

  • danke :thumbup:

    "Je mehr Käse, desto mehr Löcher; je mehr Löcher, desto weniger Käse. Ergo: Je mehr Käse, desto weniger Käse. 8| "
    "Programmers never die: they just GOSUB without RETURN"
    "I tried to change the world but I couldn't find the source code."