Play a random media file

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Play a random media file

#1 Post by foxidrive » 19 Apr 2012 13:51

This batch file I call R.bat for playing a random media file.
I pick a folder in my file manager and type R and it plays a random file.

It filters some filetypes out which I don't want to launch but keeps the rest, and relies on the file association to pick the media player.


Code: Select all

@echo off
:: launch random file
set tempfile2="%temp%.\randfile.txt"
set "lines="
dir /b /a:-d |findstr /v /i /c:.txt /c:.htm /c:.html /c:.doc /c:.exe /c:.com /c:.bat /c:.cmd /c:.msi /c:.scr /c:.dll /c:.reg /c:.zip /c:.rar /c:.bas >%tempfile2% 2>nul
if errorlevel 1 (
echo No files to play in this folder
echo.
pause
goto :eof
)

for /f "delims=" %%a in ('find /c /v "" ^<%tempfile2%') do set lines=%%a

:start
set c=
:loop
   set /a c+=1
   set /a "rand=(%random%*%lines%)/32768+1"
if not %c% EQU 10 goto :loop   

for /f "tokens=1* delims=]" %%a in (
'find /n /v "" ^<"%tempfile2%" ^|findstr /r ^^[%rand%]'
) do set "file=%%b"

start "" "%file%"



I was using Gawk to get the random number and then I noticed a post here viewtopic.php?p=15174#p15174 re copying random files
Aacini uses this to get a random number from 1 to n (lines/n is the number of lines in the list of files).

set /a "rand=(%random%*%lines%)/32768+1"

It seemed to always start with the same integer (6) when I tested it but letting it have several passes made it more random, so I settled on 10 passes.

Maybe someone else will find the batch file useful.

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Play a random media file

#2 Post by abc0502 » 19 Apr 2012 14:59

nice batch, &
i have a question when u type:

Code: Select all

:start
set c=
:loop
   set /a c+=1
   set /a "rand=(%random%*%lines%)/32768+1"
if not %c% EQU 10 goto :loop   

for /f "tokens=1* delims=]" %%a in (
'find /n /v "" ^<"%tempfile2%" ^|findstr /r ^^[%rand%]'
) do set "file=%%b"

isn't

Code: Select all

if not %c% EQU 10 goto :loop
will be set to %c% then how it check if %c% = 10 or not

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Play a random media file

#3 Post by foxidrive » 19 Apr 2012 15:14

abc0502 wrote:nice batch, &
i have a question when u type:

Code: Select all

:start
set c=
:loop
   set /a c+=1
   set /a "rand=(%random%*%lines%)/32768+1"
if not %c% EQU 10 goto :loop   

isn't

Code: Select all

if not %c% EQU 10 goto :loop
will be set to %c% then how it check if %c% = 10 or not


This reads: if the variable %c% is not equal to 10 then branch to the :loop label.
if not %c% EQU 10 goto :loop

And c is initialised as nul, and is incremented everytime it goes through the loop. When a variable is nul then batch math considers that to be zero, so it starts out as zero.

set /a c+=1 is the same as set /a c=c+1

When it gets to 10 then it drops out of the loop to the next statement.

I hope that is what you meant.

MrKnowItAllxx
Posts: 43
Joined: 20 Mar 2012 20:53

Re: Play a random media file

#4 Post by MrKnowItAllxx » 19 Apr 2012 17:51

Could you explain the line:

Code: Select all

set /a "rand=(%random%*%lines%)/32768+1"


I typically use:

Code: Select all

set /a "rand=(%random% %%(%max%-%min%))+%min%"


which in this case I think would be:

Code: Select all

set /a "rand=%random% %% (%lines%)"


Just wondering the difference between the two :)

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Play a random media file

#5 Post by foxidrive » 19 Apr 2012 18:44

Math isn't my strong suit. I copy from other people. :)

I think it would have to add 1 to get a range from 1 to 10 if lines=10

Code: Select all

set /a "rand=(%random% %% %lines%)+1"

Liviu
Expert
Posts: 470
Joined: 13 Jan 2012 21:24

Re: Play a random media file

#6 Post by Liviu » 19 Apr 2012 19:35

MrKnowItAllxx wrote:Just wondering the difference between the two :)

They err in different ways ;-)

For one thing, your formula returns numbers starting at 0, not 1. Otherwise, it should work well enough for "small" ranges (relative to 2^15 = 32,768) - but completely fail for wider (%max%-%min%) ranges > 32,768.

The formula foxidrive quoted is technically right, but may not fully cover the range due to integer arithmetics (loss of) precision. For an extreme example, if %lines% is 2*32,768 then it would only return odd integers.

Liviu

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Play a random media file

#7 Post by foxidrive » 19 Apr 2012 20:15

Liviu wrote:They err in different ways ;-)

The formula foxidrive quoted is technically right, but may not fully cover the range due to integer arithmetics (loss of) precision. For an extreme example, if %lines% is 2*32,768 then it would only return odd integers.

Liviu


Like wet paint, I had to try it. Crazy. Only odd numbers.

Thanks for the info.

MrKnowItAllxx
Posts: 43
Joined: 20 Mar 2012 20:53

Re: Play a random media file

#8 Post by MrKnowItAllxx » 19 Apr 2012 20:22

For one thing, your formula returns numbers starting at 0, not 1. Otherwise, it should work well enough for "small" ranges (relative to 2^15 = 32,768) - but completely fail for wider (%max%-%min%) ranges > 32,768.

My formula should return integers from 1-%lines% not including 0

Good to know theres another way though, I assumed any calculations beyond 32,768 failed in batch no matter what, but the "only-odd" thing is quite ... "odd" lol, hopefully I never have to tackle that problem :)

Aacini
Expert
Posts: 1932
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Play a random media file

#9 Post by Aacini » 19 Apr 2012 22:15

@Liviu:

"%RANDOM% - expands to a random decimal number between 0 and 32767." Because of this, there is no way to accurately generate random numbers larger than 32767 using this value. If %lines% is 3*32,768 then will be "holes" of two numbers in the sequence generated. With lines=4*32,768 the "holes" will be 3 numbers wide and so on.


@MrKnowItAllxx:

When you divide %random%*%max% by 32768 you get a number between 0 and %max% with the same distribution of %random% value. If you get the remainder (MOD) of the division of %random% by %max% then the distribution of the generated number is completely unknow, but worst than the original distribution of %random% for sure. The most difficult part to generate a sequence of random numbers in a computer is that they have an evenly distribution in the range of values. You should use:

Code: Select all

set /a "rand=(%random%*(%max%-%min%+1)) / 32768 +%min%"
Last edited by Aacini on 20 Apr 2012 15:15, edited 1 time in total.

Liviu
Expert
Posts: 470
Joined: 13 Jan 2012 21:24

Re: Play a random media file

#10 Post by Liviu » 19 Apr 2012 23:34

Aacini wrote:@Liviu: "%RANDOM% - expands to a random decimal number between 0 and 32767." Because of this, there is no way to accurately generate random numbers larger than 32767 using this value.

That's correct. One could generate larger numbers for example with "%random% * %random%" but those would no longer be uniformly distributed.

Aacini wrote:When you divide %random%*%max% by 32768 you get a number between 0 and %max% with the same distribution of %random% value.

Almost, but not quite the same. Assume for example %max% is 16383. In a run of 32768 tries, %random%*%max%/32768 would return "0" in 3 cases (when %random% == 0, 1, 2) and "16383" in just 1 case (%random% == 32767). Even allowing for integer roundoffs, a truly flat distribution would not be expected to have 2-wide variations.

Aacini wrote:The most difficult part to generate a sequence of random numbers in a computer is that they have an evenly distribution in the range of values.

Agreed. And I don't know of an easy and completely satisfying resolution (in batch language).

Liviu

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Play a random media file

#11 Post by abc0502 » 20 Apr 2012 05:44

foxidrive wrote:
abc0502 wrote:nice batch, &
i have a question when u type:

Code: Select all

:start
set c=
:loop
   set /a c+=1
   set /a "rand=(%random%*%lines%)/32768+1"
if not %c% EQU 10 goto :loop   

isn't

Code: Select all

if not %c% EQU 10 goto :loop
will be set to %c% then how it check if %c% = 10 or not


This reads: if the variable %c% is not equal to 10 then branch to the :loop label.
if not %c% EQU 10 goto :loop

And c is initialised as nul, and is incremented everytime it goes through the loop. When a variable is nul then batch math considers that to be zero, so it starts out as zero.

set /a c+=1 is the same as set /a c=c+1

When it gets to 10 then it drops out of the loop to the next statement.

I hope that is what you meant.

oh i thought the loop section is assigned to the c variabl, now i understand thanks

Post Reply