Jump to content

I'm trying to create a sort of a mp3 sorter. Something's wrong with my script. Text out of "nowhere"


Recommended Posts

You may skip this paragraph. I have at least 15-25 hours in the following code. I have to admit I've been multitasking and reading the help file was the main time consumer. The info in the help file about the Dim/Local/Global issue, code formatting and especially arrays is simply not enough for me. I can work with them but when it comes to more complicated things, I run into problems. So I'm really afraid that though my code works (well, except for one thing) but it's inefficient and "dirty" because I experimented a lot. If someone could help me clean it out, I might learn a lot. I usually enjoy programming, but this time... I'll try to exchange the pleasure of finding my way through things on my own, with understanding and enjoying the look of a well and more quickly written code. In other words, sorry to bother you, but I feel like I don't have a choice. Hopefully someone will lend a hand

What I'm trying to do is a little application with a GUI, that would help me QUICKLY sort out my mp3s. The main idea is SPEED, otherwise any media player would do. So, I want to be able to move the currently played file with a double click or key-combination (Ctrl+1,2,3...0) to a certain folder which is on a list with other 9 (or rather more) favorite folders names. You can add-remove directories and the data is stored in an ini file. (This is what I've been working on lastly and I managed to create a bug, because when I add a new directory, x to the existing a,b,c, instead of getting a,b,c,x in the listview, I get a,b,c,a,b,c,x - but only apparently, cause the data in the ini is ok). My exception handling is as of now a disaster too. I created a "jump function" that would randomly seek the file, so that I don't have to waste 5 minutes on a file, 30 seconds of listening is more than enough to decide wether it's something I'd like to keep or not, and if I do where do I want to move it. And I want to develop this further, making an auto-jump function, and two modes of jumping, a standard and a more careful one. I have several comments in the script, mainly at the end. Suggestions are welcome. Here's the code:

; Script generated by AutoBuilder 0.5 Prototype
Opt("GUIOnEventMode", 0)
Opt("GUIDataSeparatorChar","|")

#include <GuiConstants.au3>
#include <File.au3>
#include <Sound.au3>
#include <Array.au3>
#include <GuiList.au3>
#include <GuiListView.au3>

Global $i = 1
Global $l = 1
global $Media = 0
global $Medial = 1
Global $pos = 0
Global $ssmin = 0
Global $jumpto = 0
Global $filelist[$i]
Global $f
$curdir = ""
$cursong = ""
Dim $dirlist[10] = [""]
Dim $x
Dim $li[100] = [""]
local $string
;~ $Medial = _SoundLength($Media, 2)    
;~ 

;gui starts here
;If Not IsDeclared('WS_CLIPSIBLINGS') Then Global $WS_CLIPSIBLINGS = 0x04000000

$mainwindow = GuiCreate("MP3Sorter", 419, 285,(@DesktopWidth-419)/2, (@DesktopHeight-285)/2 , $WS_OVERLAPPEDWINDOW + $WS_VISIBLE + $WS_CLIPSIBLINGS)

$loadbn = GuiCtrlCreateButton("Load", 10, 10, 60, 30)
$playpausebn = GuiCtrlCreateButton("Play", 80, 10, 60, 30)
$jumpbn = GuiCtrlCreateButton("Jump", 140, 10, 60, 30)

$filename2clipbn = GuiCtrlCreateButton("Filename", 210, 10, 60, 30)
$dirname2clipbn = GuiCtrlCreateButton("Dirname", 270, 10, 60, 30)


GUISetFont ( 7, 400)
$curdirlb = GuiCtrlCreateLabel( "", 20, 40, 400, 15)
GUISetFont ( 9, 800)
$cursonglb = GuiCtrlCreateLabel( "", 20, 52, 400, 38)
GUISetFont ( 7.5, 400)
$timelb = GuiCtrlCreateLabel( "", 20, 84, 400, 10)
GUISetFont ( 8.5, 400)
$songprogresspb = GuiCtrlCreateProgress(10, 100, 400, 12)
$soundvolpb = GuiCtrlCreateProgress(390, 10, 20, 30, $PBS_VERTICAL)
GUICtrlSetData ( $soundvolpb, 50 )

$delbn = GuiCtrlCreateButton("Delete", 10, 120, 60, 30)
$skipbn = GuiCtrlCreateButton("Skip", 10, 160, 60, 30)
$addirbn = GuiCtrlCreateButton("Add dir", 10, 200, 60, 30)
$remdirbn = GuiCtrlCreateButton("Rem dir", 10, 240, 60, 30)

;~ ``````````````````````````````````````````````
$list = GUICtrlCreateListView("", 80, 120, 190, 150 )
GUICtrlSetStyle ($list, BItOR( $LVS_SHOWSELALWAYS, $LVS_NOSORTHEADER))
;~ $listviewitem = GUICtrlCreateListViewItem ("", $listview)$LVS_EX_HEADERDRAGDROp $LVS_ICON, $LVS_LIST

$subdirck = GuiCtrlCreateCheckbox("Load subdirectories", 280, 120, 120, 20)
$recycleck = GuiCtrlCreateCheckbox("Delete to recyclebin", 280, 140, 120, 20)
$topck = GuiCtrlCreateCheckbox("Always on top", 280, 160, 110, 20)

GuiSetState()
UpdateLV()
While 1
    $msg = GuiGetMsg()
    Select
    Case $msg = $GUI_EVENT_CLOSE            ; EXIT
        _SoundClose ($Media)
        ;write currentdir and file to ini
        ExitLoop
    Case $msg = $playpausebn                ; PLAY PAUSE 
        Select
            Case _SoundStatus($Media) = "playing"
                _SoundPause($Media)
                GUICtrlSetData ( $playpausebn, "Play" )
            Case _SoundStatus($Media) <> "playing" 
                _SoundPlay($Media)
                GUICtrlSetData ( $playpausebn, "Pause" )
        EndSelect
    Case $msg = $loadbn                     ; LOAD 
        _SoundStop($Media) ;if you don't want to files playing at once...
        $i = 1 ; start from new index
        $folder=FileSelectFolder ( "Choose a folder", "" , 2 ) ;default folder as last param
        ;return array of contained files, based on subdirck and open them one by one
        $sPath = $folder
        $sFilter = "*.mp3"
        $iFlag = "1" ;files only for now
        LoadSong ()
    Case $msg = $jumpbn                     ; JUMP
        $Medial = _SoundLength($Media, 2)
        $pos = _SoundPos ( $Media, 2 )
        $jumpto = 0
        $ssmin = 0
        $jumpto = $Medial - $pos
        $r = random (3, 5)
        $jumpto = $jumpto/$r
        $jumpto = $jumpto + $pos
        $jumpto = $jumpto/1000
        While $jumpto > 60
            $jumpto = $jumpto - 60
            $ssmin = $ssmin + 1
        WEnd
        $iHour = 0                  ; this must be changed to allow handling of longer songs.                        
        $iMin = int ($ssmin)
        $iSec = int ($jumpto)
        _SoundPause ($Media)
        _SoundSeek ( $Media, 0, $iMin, $iSec)
        Sleep (200)
        _SoundPlay ( $Media )
        ;MsgBox (0, $jumpto, $ssmin)
    Case $msg = $delbn                      ; DELETE 
        CloseSong()
        msgbox (0, "File deleted", $curdir & "\" & $cursong ) ; will be replaced with delete !
        NextSong()
        LoadSong()
    Case $msg = $skipbn                     ; SKIP
        CloseSong()
        NextSong()
        LoadSong()
    Case $msg = $addirbn ; on adddir popup window      ; BROWSE FOR FAV
        $browsefav = GuiCreate("Browse for a favorite folder", 276, 63,(@DesktopWidth-276)/2, (@DesktopHeight-63)/2 , 

$WS_OVERLAPPEDWINDOW + $WS_VISIBLE + $WS_CLIPSIBLINGS, -1, $mainwindow)
        ;If Not IsDeclared('WS_CLIPSIBLINGS') Then Global $WS_CLIPSIBLINGS = 0x04000000
        $Input = GuiCtrlCreateInput("Path...", 9, 10, 240, 20)
        $bbn = GuiCtrlCreateButton("...", 250, 10, 20, 20)
        $ldbn = GuiCtrlCreateButton("Load directory", 220, 30, 50, 20)
        GuiSetState()
        While 1
            $msgs = GuiGetMsg()
            Select
            Case $msgs = $GUI_EVENT_CLOSE
                GuiSetState (@SW_HIDE, $browsefav)
                GuiSetState (@SW_SHOW, $mainwindow)
            Case $msgs = $bbn
                $f=FileSelectFolder ( "Choose a folder", "" , 1 )
                Guictrlsetdata ( $Input, $f )
            Case $msgs = $ldbn
                $favdir = GUICtrlRead($input)
                AddDirlist() 
                Sleep (50)
                GuiSetState (@SW_HIDE, $browsefav)
                GuiSetState (@SW_SHOW, $mainwindow)
                UpdateLV()
                ExitLoop
            EndSelect
        WEnd
    Case $msg = $remdirbn
        RemDirlist()
    Case Else
        ;;;
    EndSelect
    if _SoundStatus($Media) = "playing" Then ;progressbar and timer mechs here 
    $pos = _SoundPos ( $Media, 2 )
    $Medial = _SoundLength($Media, 2)
    $pr = $pos/$Medial*100
    GUICtrlSetData ( $songprogresspb, $pr )
    Sleep (50) ;does this save cpu ?
    $posc = _SoundPos ( $Media, 1 )
    $Medialc = _SoundLength($Media, 1)
    GUICtrlSetData($timelb, $posc & "/" & $Medialc)
    Endif
WEnd
;TraySetState(2)
Exit

Func CloseSong()
    _SoundClose ($Media)
    GUICtrlSetData($cursonglb, "") ;remove songname in title probably update label function
    GUICtrlSetData($curdirlb, "")
EndFunc
Func LoadSong()
    $filelist =_FileListToArray ( $sPath , $sFilter , $iFlag ) ;update directory index on every new start (useful after delete)
    $filepath = $folder & "\" & $filelist[$i]
    $cursong = $filelist[$i]
    $curdir = $folder
    ;MsgBox (0, "", $curdir)
    ;MsgBox (0, "", $filepath)
    $Media=_SoundOpen($filepath)
        If @error = 2 Then
            MsgBox(0, "Error", "The file does not exist") 
        EndIf
    GUICtrlSetData($curdirlb, $curdir  & "       " &"("& $i & "/" & $filelist[0] & ")")
    GUICtrlSetData($cursonglb, $cursong) ;display songname in title also for use with file2clip and nr/total
    $Medialc = _SoundLength($Media, 1)  
    GUICtrlSetData($timelb, $Medialc)
    _SoundPlay($Media)
    SelPP()                                  ;needs a better place or what...
EndFunc
Func NextSong()
    if $i < $filelist[0] Then
        $i = $i + 1 ;next name in array
    else 
        $i = 1
    EndIf
EndFunc
Func SelPP() ; function for setting the right song state after file change --------- needs improvement
    Select
        Case _SoundStatus($Media) = "playing"
            GUICtrlSetData ( $playpausebn, "Pause" )
        Case _SoundStatus($Media) <> "playing" 
            GUICtrlSetData ( $playpausebn, "Play" )
    EndSelect
EndFunc
; dir
Func GetDirlist()
    $string = IniRead ( @WorkingDir & "\mp3sorter.ini", "settings", "dirlist", "NotFound") ;if not found........
    $dirlist = StringSplit ($string, "|")
EndFunc
Func AddDirlist()
    GetDirlist()
    _ArrayAdd ($dirlist, $favdir)
    $string = _ArrayToString ($dirlist, "|", 1)
    IniWrite( @WorkingDir & "\mp3sorter.ini", "settings", "dirlist", $string )
EndFunc
Func RemDirlist()
    Local $a_indices = _GUICtrlListViewGetSelectedIndices($list, 1)
    GetDirlist ()
;~      GUICtrlSetData($Status, "Not Items Selected")
;~      MsgBox (0, "", "none selected")
    If(IsArray($a_indices))Then
        Local $i
        For $i = 1 To $a_indices[0]
            $x = $a_indices[$i] + 1
            MsgBox(0,"Selected", $dirlist[$x])
        _ArrayDelete ($dirlist, $x )
;~      _GUICtrlListDeleteItem ( $list, $i )*
        Local $string = ""
        $string = _ArrayToString ($dirlist, "|", 1)
        IniWrite( @WorkingDir & "\mp3sorter.ini", "settings", "dirlist", $string )
        UpdateLV()
        Next
    Else
        MsgBox(0,"Selected", "none")
;~      GUICtrlSetData($Status, "Not Items Selected")
    EndIf
;~  GUICtrlDelete ($li[$x])
EndFunc
Func UpdateLV()
    GetDirlist()
;~  msgbox (0, "", $dirlist[0] & " " & $dirlist[1])
    Local $x = 1
    For $x = 1 to $dirlist[0] ; nr of dirs is equal to listviewitems.
        _GUICtrlListDeleteItem ($list, $x) ; deleting listviewitems......
    Next
    Local $x = 1
    For $x = 1 to $dirlist[0] ;display items one by one
        $li[$x] = GUICtrlCreateListViewItem ($dirlist[$x], $list)
;~      msgbox (0, "", $dirlist[$x])
    Next
EndFunc


;gui ends here

#cs
;protection against accidental delete, by disabling the button until the first 5 seconds of the song are played.
;grayout "play" before loading any folder
;canceling the folder dialog exists - exception handling
;support to load more than one files and folders
;option load subfolders or not
;delete or move to recylcebin
;autoload last dir
;warn on dir empty or end with sound
;path, dirname and filename to clip with one click on the labels
;functions from checkboxes -> menu
;current dir, dirstats and time -> status menu
;better display of favorite dirs ( C:\Documents...Desktop\fav) - path and displayed name needs to be differentiated
;A volume control that wouldn't set the sistems wave would be ideal
;skip button works as a "next". I need to add a <<
;seek with mouse on progress bar. seek with left arrow if in focus (step back 5 seconds)
;undo last move
#ce

I'll start writing a program that would listen from a command from a remote computer on the internet. It's supposed to be easy, right ? :whistle:

Edited by birdofprey
Link to comment
Share on other sites

To make it easier to debug your code, please try to teach yourself the good habit of avoiding mixing global and local variables. Use more function parameters and return values, and pass the data between the functions. In this way you avoid situations like these (where one part of the program changes a variable and another part too, and you don't follow what changes where and that often leads to unexpected data...)

I'll start writing a program that would listen from a command from a remote computer on the internet. It's supposed to be easy, right ? :whistle:

Maybe this thread helps a little bit:

http://www.autoitscript.com/forum/index.php?showtopic=42963

Roses are FF0000, violets are 0000FF... All my base are belong to you.

Link to comment
Share on other sites

Yes it does. Thank you very much.

But regarding my script, can you give me an example or something. I learn fast, if I have enough documentation...

Well at least I managed to fix your listview creation problem of multiple folders. Seems fixed with my changes.

Also I showed what I meant with returning values, by making GetDirList return a 'dirlist' instead of changing the globel dirlist. In this way you can easily manage multiple dirlists, in future implememtations. Multiple dirlists will be way messier to code with multiple global dirlists than with a nice manageable dirlist array. (Then you just, for instance, redim your array and read in another dirlist, I mean, instead of having to change anything in the source code such as adding it manually. Maybe you don't need it now but if you start off in this organized manner and make all your functions return things that you can store, it will be way more inviting to later build out your code if you have new ideas.)

This is just my 2cts of experience speaking, ofcourse you can figure out your own path to heaven! :whistle:

Replace:

Func GetDirlist()
    $string = IniRead ( @WorkingDir & "\mp3sorter.ini", "settings", "dirlist", "NotFound") ;if not found........
    $dirlist = StringSplit ($string, "|")
EndFunc

(...)

Func UpdateLV()
    GetDirlist()
;~  msgbox (0, "", $dirlist[0] & " " & $dirlist[1])
    Local $x = 1
    For $x = 1 to $dirlist[0] ; nr of dirs is equal to listviewitems.
        _GUICtrlListDeleteItem ($list, $x) ; deleting listviewitems......
    Next
    Local $x = 1
    For $x = 1 to $dirlist[0] ;display items one by one
        $li[$x] = GUICtrlCreateListViewItem ($dirlist[$x], $list)
;~   msgbox (0, "", $dirlist[$x])
    Next
EndFuncoÝ÷ Ù¼ºÚ"µÍ[ÈÙ]Ý

BIÌÍÜÝ[ÈH[TXY
ÛÜÚ[Ñ   [È ][ÝÉÌLÛÜÛÜ[I][ÝË   ][ÝÜÙ][ÜÉ][ÝË    ][ÝÙÝ    ][ÝË  ][ÝÓÝÝ[ ][ÝÊHÚYÝÝ[IÌÍÙÝHÝ[ÔÜ]
    ÌÍÜÝ[Ë ][Ýß  ][ÝÊBT]   ÌÍÙÝ[[ÂB[È]S
BSØØ[ ÌÍÙÝHÙ]Ý

BWÑÕRPÝÝY]Ñ[]P[][È
    ÌÍÛÝ
HÈ[][ÈÝY]Ú][ËQÜ   ÌÍÞHHÈ  ÌÍÙÝÌHÙÜ^H][ÈÛHHÛBBIÌÍÛVÉÌÍÞHHÕRPÝÜX]SÝY]Ò][H
    ÌÍÙÝÉÌÍÞK   ÌÍÛÝ
BS^[[

Roses are FF0000, violets are 0000FF... All my base are belong to you.

Link to comment
Share on other sites

One more thing: you don't need to declare $x = 1 before you do for $x = 1 to (some_number). $x will be assigned the values automatically during the for loop and AutoIt will consider the variable declared too, even if first used in a for loop. This might save you quite some lines of code of you add more loops to your code :whistle:

Roses are FF0000, violets are 0000FF... All my base are belong to you.

Link to comment
Share on other sites

  • 5 weeks later...

One more thing: you don't need to declare $x = 1 before you do for $x = 1 to (some_number). $x will be assigned the values automatically during the for loop and AutoIt will consider the variable declared too, even if first used in a for loop. This might save you quite some lines of code of you add more loops to your code :shocked:

Thank you ! I postponed replying because I planned to add something more here, but your help set me back on the right track again.

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