Sign in to follow this  
Followers 0
Champak

Array randomize and skip problem

11 posts in this topic

I'm having a problem with an array randomizer I found. It is essentially doing what it is suppose to as far as randomizing my array list. However I'm using it as a playlist randomizer, and after it is randomized, I can no longer get the index of the current song to skip to the next song if needed. What is wrong?

$oPlayer = ObjCreate("wmplayer.ocx")


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

I guess just make a quick array with paths to your songs here

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;





    While 1
        
        $msg = GuiGetMsg()
        
        Select  

            Case $msg = $WMP_Next
                $iKeyIndex = _ArrayBinarySearch ( $aSource, $oPlayer.currentmedia.sourceURL )
                ConsoleWrite($iKeyIndex & @CRLF & @CRLF)
                WMLoadFile($oPlayer, $aSource[$iKeyIndex+1])
                GUICtrlSetData($WMP_Duration,WMGetDuration($oPlayer))
                ;GUICtrlSetData($WMP_Duration,0)
                ;_TitleSplash()
                
            Case $msg = $WMP_Previous
                $iKeyIndex = _ArrayBinarySearch ( $aSource, $oPlayer.currentmedia.sourceURL )
                WMLoadFile($oPlayer, $aSource[$iKeyIndex-1])
                GUICtrlSetData($WMP_Duration,WMGetDuration($oPlayer))
                ;GUICtrlSetData($WMP_Duration,0)
                ;_TitleSplash()
                
            Case $msg = $WMP_Random
                ScrambleReturn()
                GUICtrlSetData($WMP_Duration,WMGetDuration($oPlayer))
                ;_TitleSplash()

endselect
wend

Func _MusicScramble($s_In,$s_Inde,$s_Outde)

    Dim $a_In = StringSplit($s_In, $s_Inde), $i_Count, $i_Index, $s_Temp, $s_Out=''
    For $i_Count = 1 to $a_In[0]
        $s_Temp = $a_In[$i_Count]
        $i_Index = Random($i_Count, $a_In[0], 1)
        $a_In[$i_Count] = $a_In[$i_Index]
        $a_In[$i_Index] = $s_Temp
        $s_Out &= $a_In[$i_Count]&$s_Outde
    Next
    Return stringtrimright($s_Out,1)

EndFunc


Func ScrambleReturn()
    
    WMStop($oPlayer)
    $MusicScrambleString = _ArrayToString($aSource, "|")
    $MusicScrambleString = _MusicScramble($MusicScrambleString,"|","|")
    $aSource = StringSplit($MusicScrambleString, '|', 1)
    _ArrayDelete($aSource,0)

    WMLoadFile($oPlayer, $aSource[0])
    Global $aSource
    ;_ArrayDisplay($aSource)

EndFunc

Share this post


Link to post
Share on other sites



If you are shuffling the playlist, what song do you expect to be next??

P.S. I posted 2000 times and all I got was this crappy t-shirt

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

After the shuffle the playlist starts at the first song, as you see "WMLoadFile($oPlayer, $aSource[0])". After that the arraybinarysearch should be recording the position of the song (when I press skip) and then skipping one up or back from the current array position, but that is breaking down after the randomizing; when I press skip the FIRST time after randomizing, it goes to the next song, after that it just repeats the same song anytime I skip forward, and throws errors and closes when I try to skip back.

Congrats on your 2000.

Edited by Champak

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

OK, so the help file clearly says that this wont work unless the array is sorted :) . So how else can I get the index point of the current song playing to do my skip function? Or is there another way? I prefer not to do the regular ArraySearch function, because I believe I will run into problems with that.

Edited by Champak

Share this post


Link to post
Share on other sites

Okay lets break this down.

Here is an array of files:

$array[0] = "C:\mp3\Jingle Bells.mp3"

$array[1] = "C:\mp3\Silent Night.mp3"

$array[2] = "C:\mp3\Grandma Got Run Over By A Reindeer.mp3" <-- Currently playing

$array[3] = "C:\mp3\Silver Bells.mp3"

$array[4] = "C:\mp3\Blink 182 - I Wont Be Home For Christmas.mp3"

Now you perform the shuffle:

$array[0] = "C:\mp3\Blink 182 - I Wont Be Home For Christmas.mp3"

$array[1] = "C:\mp3\Silver Bells.mp3"

$array[2] = "C:\mp3\Silent Night.mp3"

$array[3] = "C:\mp3\Grandma Got Run Over By A Reindeer.mp3" <-- Currently playing

$array[4] = "C:\mp3\Jingle Bells.mp3"

Now you click Next. Which song would you expect to be next?

Perhaps instead of shuffling the array you should use:

$nextSong = Random(0,Ubound($array) - 1, 1)

This way the song is random but the array stays the same. This is how it works in Winamp.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

In the first array, I would expect "C:\mp3\Silver Bells.mp3" next, in the second array I would expect "C:\mp3\Jingle Bells.mp3" next.

Your workaround sounds great in principle, and if all else fails I'll use it, however, two reasons why I wouldn't jump at it now is:

1/ Currently if I "randomize" the array, I can bring up a playlist and see what the next song is going to be in the randomized version----randomizing the next button, as you suggest, I won't see what the next song is...like throwing a dart blindfolded.

2/ Also, how do you prevent the same song from playing twice in your style.

Thanks.

Currently, I'm using the standard ArraySearch, but I'm afraid that if a array has two songs with the same name, and I'm on the second song, it is going to find the first song and skip to the song after that. So I'm still open to suggestions.

Edited by Champak

Share this post


Link to post
Share on other sites

You can't have two of the same filenames in the array if they are absolute / relative paths to the files. If there are two of the same song one has to be in a seperate folder and will have its folder name appended to the beginning of it.

Share this post


Link to post
Share on other sites

Another thing: _ArrayBinaryDearch needs a sorted Array. If its Randomized, xou have to use _ArraySearch.


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

Are you basically saying if there are two songs IN THE SAME FOLDER only, one just wont be in the array because they have the same path AND name? If that is the case it pretty much solves my apprehension for now, because the couple of my songs with the same name I have are in different folders, which I believe wont be a problem in this case because the array search is based off the entire path and name....correct me if I'm wrong.

However it does pose a problem if I ever get two songs which will be in the same folder. I believe the way you stated this, one song will just be left out...probably the second one that would have appeared in the array. Is there a way to resolve this? I know I could rename one with a suffix of "2", however that would affect a different search function I have. This isn't a major problem, but if there is a solution, please let me in.

Thanks

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

I have no clue what your array looks like. If I wrote a program like this I would have an array with absolute paths to every file, it is possible to have duplicate filenames but not the fully qualified path.

$array[0] = "C:\mp3\Jingle Bells.mp3"

$array[1] = "C:\mp3\Silent Night.mp3"

$array[2] = "C:\mp3\Grandma Got Run Over By A Reindeer.mp3" <-- Currently playing

$array[3] = "C:\mp3\Silver Bells.mp3"

$array[4] = "C:\mp3\Blink 182 - I Wont Be Home For Christmas.mp3"

$array[5] = "C:\mp3\Christmas\Silver Bells.mp3"

You may want to consider not using the builtin _Array functions and use your own:

#include <array.au3>

Dim $array[6][2]

$array[0][0] = "C:\mp3\Jingle Bells.mp3"
$array[1][0] = "C:\mp3\Silent Night.mp3"

$array[2][0] = "C:\mp3\Grandma Got Run Over By A Reindeer.mp3" ;<-- Currently playing
$array[2][1] = true ;<-- Currently playing boolean value

$array[3][0] = "C:\mp3\Silver Bells.mp3"
$array[4][0] = "C:\mp3\Blink 182 - I Wont Be Home For Christmas.mp3"
$array[5][0] = "C:\mp3\Christmas\Silver Bells.mp3"

_ArrayDisplay($array)
Shuffle($array)
_ArrayDisplay($array)

MsgBox(0,"Next Song",$array[RetrieveNextSong($array)][0])
MsgBox(0,"Previous Song",$array[RetrievePreviousSong($array)][0])

Func Shuffle(ByRef $myArray)
    Local $temp[1][2]
    Local $numElements = Ubound($myArray)
    
    ;Loop through all array elements
    For $X = 0 to $numElements - 1
        ;Store copy of current element
        $temp[0][0] = $myArray[$X][0]
        $temp[0][1] = $myArray[$X][1]
        
        $random = Random($X,$numElements-1,1)
        
        ;Overwrite current element with random element
        $myArray[$X][0] = $myArray[$random][0]
        $myArray[$X][1] = $myArray[$random][1]
        
        ;Overwrite random element with original copy of current element
        $myArray[$random][0] = $temp[0][0]
        $myArray[$random][1] = $temp[0][1]
    Next
EndFunc

;Retrieve index of next song, if at the end of the playlist return 0
Func RetrieveNextSong(ByRef $myArray)
    Local $numElements = Ubound($myArray)
        For $X = 0 to $numElements - 1
            ;If second element in second dimension is true then $X is the current song
            If $myArray[$X][1] Then
                If ($X +1) > ($numElements - 1) Then
                    Return 0
                Else
                    Return $X + 1
                EndIf
            EndIf
        Next
EndFunc


 ;Retrieve index of next song, if at the beginning of the playlist return Ubound()-1
Func RetrievePreviousSong(ByRef $myArray)
    Local $numElements = Ubound($myArray)
        For $X = 0 to $numElements - 1
            ;If second element in second dimension is true then $X is the current song
            If $myArray[$X][1] Then
                If ($X - 1) < 0 Then
                    Return $numElements - 1
                Else
                    Return $X - 1
                EndIf
            EndIf
        Next
EndFunc

The idea here is that when you play the next or previous song you clear the boolean value for the current song, then set it to true for the next/previous song. Let me know if this confuses you.

Edited by weaponx

Share this post


Link to post
Share on other sites

Well, I solved this problem. I actually don't remember how through all the coding, trial and error I've been doing the past few days. Your idea here did help me on another problem however. I was having a problem with the CD player functions, but placing a marker on the currently playing song helped with that.

http://www.autoitscript.com/forum/index.ph...st&p=480767

Thanks.

Share this post


Link to post
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
Sign in to follow this  
Followers 0