Jump to content

Simple Music Visualization


Darth
 Share

Recommended Posts

For my first project using Bass.Dll I made a simple music player with visualization. The visualization I was going for was a scrolling set of colors rather than an oscilloscope.

The first version is the scrolling one

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Bass.au3>
#Include <BassConstants.au3>
Global $File
Global $Stream
Global $Length
Global $Controls[5]
Global $Labels[100][2]


_BASS_Startup("Bass.dll")
_BASS_Init($BASS_DEVICE_NOSPEAKER,1,44100,"NULL")


$Parent = GUICreate("Bass Test",200,100)
Opt("GUIOnEventMode", 1)

$Controls[0] = GUICtrlCreateButton("Open",10,40)
GUICtrlSetOnEvent($Controls[0],"_Open")
$Controls[1] = GUICtrlCreateButton(">",50,40)
GUICtrlSetOnEvent($Controls[1],"_Play")
$Controls[2] = GUICtrlCreateButton("| |",65,40)
GUICtrlSetOnEvent($Controls[2],"_Pause")
$Controls[3] = GUICtrlCreateButton("[]",80,40)
GUICtrlSetOnEvent($Controls[3],"_Stop")
$Controls[4] = GUICtrlCreateSlider(10,70,80)
GUICtrlSetData($Controls[4],50)
GUICtrlSetOnEvent($Controls[4],"_Vol")
For $i = 0 to 99
$Labels[$i][0] = GUICtrlCreateLabel("",100+$i,0,1,100)
GUICtrlSetBkColor($Labels[$i][0],0xFFFFFF)
Next
GUISetState(@SW_SHOW)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Close")


Func _Open()
    $File = FileOpenDialog('Music', '', 'MP3 (*.mp3;*.wav)')
    If $Stream <> "" Then
        _BASS_StreamFree($Stream)
        AdlibUnRegister()
    EndIf
    $Stream = _BASS_StreamCreateFile(False,$File,0,0,$BASS_SAMPLE_FLOAT)
    $Length = _BASS_ChannelBytes2Seconds($Stream, _BASS_ChannelGetLength($Stream,$BASS_POS_BYTE))
    _Vol()
EndFunc

Func _Play()
    _BASS_ChannelPlay($Stream,0)
    AdlibRegister("_Pos",1)
EndFunc

Func _Pause()
    _BASS_ChannelPause($Stream)
    AdlibUnRegister()
EndFunc

Func _Stop()
    _BASS_ChannelStop($Stream)
    AdlibUnRegister()
EndFunc

Func _Vol()
    _BASS_ChannelSetAttribute($Stream,$BASS_ATTRIB_VOL,GUICtrlRead($Controls[4])/100)
EndFunc


Func _Close()
    _BASS_Free()
    Exit
EndFunc

Func _Pos()
    $Level = _BASS_ChannelGetLevel($Stream)
    $Labels[99][1] = $Level
    For $j = 0 to 98
        GUICtrlSetBkColor ($Labels[$j+1][0],$Labels[$j][1])
        $Labels[$j][1] = $Labels[$j+1][1]
    Next

If _BASS_ChannelBytes2Seconds($Stream,_BASS_ChannelGetPosition($Stream,$BASS_POS_BYTE)) >= $Length Then AdlibUnRegister()
EndFunc


While(1)
    Sleep(100)
WEnd

The problems I have with it are

1. I realized that people can't actually read colors like they can read a waveform so to most if not all people it just looks like random colors. Suggestions to help with visualization would be nice

2. A white line keeps moving back and forth across the image, I know it's not because the Adlib delay is too low because I set it to once a second and it still did it.

The second is a full screen visualization that strobes with colors

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Bass.au3>
#Include <BassConstants.au3>
Global $File
Global $Stream
Global $Length
Global $Controls[5]


_BASS_Startup("Bass.dll")
_BASS_Init($BASS_DEVICE_NOSPEAKER,1,44100,"NULL")


Opt("GUIOnEventMode", 1)
$Parent = GUICreate("Visualizer",@DesktopWidth,@DesktopHeight)
$Labels = GUICtrlCreateLabel("",0,0,@DesktopWidth,@DesktopHeight)
GUICtrlSetBkColor($Labels,0xFFFFFF)
GUISetState(@SW_SHOW)

$Child= GUICreate("Bass Test",200,100,-1,-1,-1,-1,$Parent)
$Controls[0] = GUICtrlCreateButton("Open",10,40)
GUICtrlSetOnEvent($Controls[0],"_Open")
$Controls[1] = GUICtrlCreateButton(">",50,40)
GUICtrlSetOnEvent($Controls[1],"_Play")
$Controls[2] = GUICtrlCreateButton("| |",65,40)
GUICtrlSetOnEvent($Controls[2],"_Pause")
$Controls[3] = GUICtrlCreateButton("[]",80,40)
GUICtrlSetOnEvent($Controls[3],"_Stop")
$Controls[4] = GUICtrlCreateSlider(10,70,80)
GUICtrlSetData($Controls[4],50)
GUICtrlSetOnEvent($Controls[4],"_Vol")
GUISetState(@SW_SHOW)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Close")


Func _Open()
    $File = FileOpenDialog('Music', '', 'MP3 (*.mp3;*.wav)')
    If $Stream <> "" Then
        _BASS_StreamFree($Stream)
        AdlibUnRegister()
    EndIf
    $Stream = _BASS_StreamCreateFile(False,$File,0,0,$BASS_SAMPLE_FLOAT)
    $Length = _BASS_ChannelBytes2Seconds($Stream, _BASS_ChannelGetLength($Stream,$BASS_POS_BYTE))
    _Vol()
EndFunc

Func _Play()
    _BASS_ChannelPlay($Stream,0)
    AdlibRegister("_Pos",100)
EndFunc

Func _Pause()
    _BASS_ChannelPause($Stream)
    AdlibUnRegister()
EndFunc

Func _Stop()
    _BASS_ChannelStop($Stream)
    AdlibUnRegister()
EndFunc

Func _Vol()
    _BASS_ChannelSetAttribute($Stream,$BASS_ATTRIB_VOL,GUICtrlRead($Controls[4])/100)
EndFunc


Func _Close()
    _BASS_Free()
    Exit
EndFunc

Func _Pos()
    $Level = _BASS_ChannelGetLevel($Stream)
    GUICtrlSetBkColor ($Labels,$Level)
If _BASS_ChannelBytes2Seconds($Stream,_BASS_ChannelGetPosition($Stream,$BASS_POS_BYTE)) >= $Length Then AdlibUnRegister()
EndFunc


While(1)
    Sleep(100)
WEnd

The problems I have

1. Same as above

2. The label prevents clicking on the buttons with the mouse so I have to use the keyboard to navigate

3. I'm working on a way to make the strobe speed coincide with the speed of the song. Suggestions on how to do that are very welcome

Edit:Changed to 2 gui windows as per suggestion

Thank you for the comments and advice, I hope you enjoy.

Edited by Darth
Link to comment
Share on other sites

The first one works nicely, volume bar is a bit touchy though, just my preference maybe...

the visualization is a bit random, changing it to incorporate less colors might be an idea, then it would be clear that a deep bass drop would be purple and a similar one would have the same color?

maybe a peak meter with the colors is also an option

[really just throwing out idea's]

as for the white line i think there is a very small gap between colors, on my lcd its not so bad but the old crt its pretty noticeable.

all in all think your doing quite well, the buttons could also be a bit bigger, again just my personal preferance

EDIT:

just tested the second one and i cant get focus on the buttons. thinking there's a overlay or something, reading through your code now

Edited by C45Y
http://twentylinesofcode.blogspot.comLittle apps n crap. can be fun
Link to comment
Share on other sites

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Bass.au3>
#Include <BassConstants.au3>
Global $File
Global $Stream
Global $Length
Global $Controls[5]


_BASS_Startup("Bass.dll")
_BASS_Init($BASS_DEVICE_NOSPEAKER,1,44100,"NULL")


$Parent = GUICreate("Bass Test",@DesktopWidth,@DesktopHeight)
Opt("GUIOnEventMode", 1)


$Labels = GUICtrlCreateLabel("",100,0,@DesktopWidth - 100,@DesktopHeight)
GUICtrlSetBkColor($Labels,0xFFFFFF)

$Controls[0] = GUICtrlCreateButton("Open",10,40)
GUICtrlSetOnEvent($Controls[0],"_Open")
$Controls[1] = GUICtrlCreateButton(">",50,40)
GUICtrlSetOnEvent($Controls[1],"_Play")
$Controls[2] = GUICtrlCreateButton("| |",65,40)
GUICtrlSetOnEvent($Controls[2],"_Pause")
$Controls[3] = GUICtrlCreateButton("[]",80,40)
GUICtrlSetOnEvent($Controls[3],"_Stop")
$Controls[4] = GUICtrlCreateSlider(10,70,80)
GUICtrlSetData($Controls[4],50)
GUICtrlSetOnEvent($Controls[4],"_Vol")

GUISetState(@SW_SHOW)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Close")


Func _Open()
    $File = FileOpenDialog('Music', '', 'MP3 (*.mp3;*.wav)')
    If $Stream <> "" Then
        _BASS_StreamFree($Stream)
        AdlibUnRegister()
    EndIf
    $Stream = _BASS_StreamCreateFile(False,$File,0,0,$BASS_SAMPLE_FLOAT)
    $Length = _BASS_ChannelBytes2Seconds($Stream, _BASS_ChannelGetLength($Stream,$BASS_POS_BYTE))
    _Vol()
EndFunc

Func _Play()
    _BASS_ChannelPlay($Stream,0)
    AdlibRegister("_Pos",100)
EndFunc

Func _Pause()
    _BASS_ChannelPause($Stream)
    AdlibUnRegister()
EndFunc

Func _Stop()
    _BASS_ChannelStop($Stream)
    AdlibUnRegister()
EndFunc

Func _Vol()
    _BASS_ChannelSetAttribute($Stream,$BASS_ATTRIB_VOL,GUICtrlRead($Controls[4])/100)
EndFunc


Func _Close()
    _BASS_Free()
    Exit
EndFunc

Func _Pos()
    $Level = _BASS_ChannelGetLevel($Stream)
    GUICtrlSetBkColor ($Labels,$Level)
If _BASS_ChannelBytes2Seconds($Stream,_BASS_ChannelGetPosition($Stream,$BASS_POS_BYTE)) >= $Length Then AdlibUnRegister()
EndFunc


While(1)
    Sleep(1)
WEnd

Got it to work once i moved the label, the visual effect still kind of looks cool. i may start up dev work on this and mod it into the lights in my case :x

Im thinking the controls will need to go into a parent window and the visual effect in a child in order to be able to use them

the label is just taking order preference over the controls, so when you try to click them your actually clicking the label

Edited by C45Y
http://twentylinesofcode.blogspot.comLittle apps n crap. can be fun
Link to comment
Share on other sites

you can use GdiPlus to get smoother graphics and you can set the alpha value

#include <Bass.au3>
#include <BassConstants.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>

Opt("GUIOnEventMode", 1)

Global $hStream
Global $iLength
Global $iPos
Global $cSlider
Global $hGui
Global $hGraphics
Global $hBmpBuffer
Global $hGfxBuffer
Global $hBrush
Global $hBmpVis
Global $hGfxVis

_BASS_Startup("Bass.dll")
_BASS_Init($BASS_DEVICE_NOSPEAKER, 1, 44100, "NULL")

$hGui = GUICreate("Bass Test", 200, 100)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Close")

GUICtrlCreateButton("Open", 10, 40)
GUICtrlSetOnEvent(-1, "_Open")
GUICtrlCreateButton(">", 50, 40)
GUICtrlSetOnEvent(-1, "_Play")
GUICtrlCreateButton("| |", 65, 40)
GUICtrlSetOnEvent(-1, "_Pause")
GUICtrlCreateButton("[]", 80, 40)
GUICtrlSetOnEvent(-1, "_Stop")
$cSlider = GUICtrlCreateSlider(10, 70, 80)
GUICtrlSetData(-1, 50)
GUICtrlSetOnEvent(-1, "_Vol")

GUISetState(@SW_SHOW)

_GDIPlus_Startup()
$hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
$hBmpBuffer = _GDIPlus_BitmapCreateFromGraphics(100, 100, $hGraphics)
$hGfxBuffer = _GDIPlus_ImageGetGraphicsContext($hBmpBuffer)
$hBmpVis = _GDIPlus_BitmapCreateFromGraphics(100, 100, $hGraphics)
$hGfxVis = _GDIPlus_ImageGetGraphicsContext($hBmpVis)
;_GDIPlus_GraphicsSetSmoothingMode($hGfxVis,2)
$hBrush = _GDIPlus_BrushCreateSolid()


While 1
    If _BASS_ChannelIsActive($hStream) = $BASS_ACTIVE_PLAYING Then _Draw()
    Sleep(15)
WEnd

Func _Draw()
    _GDIPlus_GraphicsClear($hGfxVis, 0xFF000000)
    _GDIPlus_GraphicsDrawImage($hGfxVis, $hBmpBuffer, -1, 0)
    Local $iLevel = _BASS_ChannelGetLevel($hStream)
    Local $nLeft = _BASS_LoWord($iLevel) / 32768
    Local $nRight = _BASS_HiWord($iLevel) / 32768
    If $nRight > $nLeft Then $nLeft = $nRight
    Local Static $nHue = 0
    $nHue += 0.001
    If $nHue > 1 Then $nHue -= 1
    Local $nColor = _HSLAtoARGB($nHue, 1, $nLeft / 2, $nLeft)

    _GDIPlus_BrushSetSolidColor($hBrush, $nColor)
    _GDIPlus_GraphicsFillRect($hGfxVis, 99, 0, 1, 100, $hBrush)
    _GDIPlus_GraphicsDrawImage($hGfxBuffer, $hBmpVis, 0, 0)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 100, 0)
EndFunc   ;==>_Draw


Func _HSLAtoARGB($nH, $nS, $nL, $nA)
    Local $nR, $nG, $nB
    Local $nValB = $nL * ($nS + 1)
    Local $nValA = 2 * $nL - $nValB

    $nR = _HueToRGB($nValA, $nValB, $nH + 1 / 3)
    $nG = _HueToRGB($nValA, $nValB, $nH)
    $nB = _HueToRGB($nValA, $nValB, $nH - 1 / 3)

    Return BitOR(BitShift($nA * 0xFF, -24), BitShift($nR * 0xFF, -16), BitShift($nG * 0xFF, -8), $nB * 0xFF)
EndFunc   ;==>_HSLAtoARGB


Func _HueToRGB($nA, $nB, $nH)
    If $nH < 0 Then $nH += 1
    If $nH > 1 Then $nH -= 1

    If (6 * $nH) < 1 Then Return $nA + ($nB - $nA) * 6 * $nH
    If (2 * $nH) < 1 Then Return $nB
    If (3 * $nH) < 2 Then Return $nA + ($nB - $nA) * 6 * (2 / 3 - $nH)
    Return $nA
EndFunc   ;==>_HueToRGB


Func _Open()
    Local $sFile = FileOpenDialog('Music', '', 'MP3 (*.mp3;*.wav)')
    If $hStream Then _BASS_StreamFree($hStream)
    $hStream = _BASS_StreamCreateFile(False, $sFile, 0, 0, $BASS_SAMPLE_FLOAT)
    _Vol()
EndFunc   ;==>_Open

Func _Play()
    _BASS_ChannelPlay($hStream, 0)
EndFunc   ;==>_Play

Func _Pause()
    _BASS_ChannelPause($hStream)
EndFunc   ;==>_Pause

Func _Stop()
    _BASS_ChannelStop($hStream)
    _BASS_ChannelSetPosition($hStream, 0, $BASS_POS_BYTE)
EndFunc   ;==>_Stop

Func _Vol()
    _BASS_ChannelSetAttribute($hStream, $BASS_ATTRIB_VOL, GUICtrlRead($cSlider) / 100)
EndFunc   ;==>_Vol

Func _Close()
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGfxVis)
    _GDIPlus_BitmapDispose($hBmpVis)
    _GDIPlus_GraphicsDispose($hGfxBuffer)
    _GDIPlus_BitmapDispose($hBmpBuffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    _BASS_Free()
    Exit
EndFunc   ;==>_Close

E

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...