Page 1 of 1

Posted: 29 Jun 2012, 12:48
by Fléau
Does anybody know an efficient and CPU friendly way to shuffle an array,
like 1/2/3/4/5/6/7/8 to 6/4/5/2/3/1/8/7 (inverse of the 'sort array' module)?

Posted: 29 Jun 2012, 16:15
by nay-seven
A job for a script guru...?

Posted: 29 Jun 2012, 16:34
by caco
Here is a quick one off the top of my head, not tested or optimized either so let me know if it doesn't work! If you need it to be more efficient I can come up with something much better using the C++ SDK as I am still unfamiliar with the script's Pascal syntax :)

Code: Select all

var ArrayIn, ButtonIn, ArrayOut : tparameter;
///////////////////////////////////////////////
procedure init;
begin  
 ArrayIn:= CreateParam('Array in',ptarray); SetisOutput(ArrayIn,false);
 ButtonIn:= CreateParam('Shuffle',ptbutton); SetisOutput(ButtonIn,false);
 Arrayout:= CreateParam('Arrayout',ptarray); Setisinput(ArrayOut,false); 
end;
//////////////////////////////////////
Procedure Callback(N:integer); 
Var i, j : Integer;
Var temp : real;
begin
    if (N=ButtonIn)  then begin
        for i:= 0 to GetLength(ArrayIn)-1 do begin
            SetDataArrayValue(ArrayOut, i, GetDataArrayValue(ArrayIn, i));
        end;    
        SetLength(ArrayOut,  GetLength(ArrayIn));
        for i:= GetLength(ArrayOut)-1 downto 0 do begin
            j := random(i);
            temp := GetDataArrayValue(ArrayOut, j);
            SetDataArrayValue(ArrayOut, j, GetDataArrayValue(ArrayOut, i));
            SetDataArrayValue(ArrayOut, i, temp);
        end;   
    end;
end;

Posted: 29 Jun 2012, 16:48
by nay-seven
works fine Caco, but only for array with min=0, max=100
if not you have to set those values manually

Posted: 29 Jun 2012, 16:54
by Fléau
Seem to works perfect (for me)!
Leaving for the weekend, so i will test it more on monday,
now able to share a 'midi stochastic seq' in my midi harmonizing tools patch.
Thank you caco.

Posted: 29 Jun 2012, 21:21
by caco
nay-seven wrote:works fine Caco, but only for array with min=0, max=100
if not you have to set those values manually
How strange, just to check you mean min and max value in array between 0-100? Will try and work out where I went wrong!

Posted: 29 Jun 2012, 21:32
by nay-seven
yes, but i just realize that modules like swap or shift array don't get (and set) those values automatically , so maybe it's normal ..?

Posted: 29 Jun 2012, 21:45
by caco
nay-seven wrote:yes, but i just realize that modules like swap or shift array don't get (and set) those values automatically , so maybe it's normal ..?
In that case I suspect array in and out ranges have default of 0-100 and just need modifying.

Posted: 01 Jul 2012, 13:19
by caco
Is this any better? Seems to work fine here now.

Code: Select all

var ArrayIn, ButtonIn, ArrayOut : tparameter;
///////////////////////////////////////////////
procedure init;
begin  
 ArrayIn:= CreateParam('Array in',ptarray); SetisOutput(ArrayIn,false);
 ButtonIn:= CreateParam('Shuffle',ptbutton); SetisOutput(ButtonIn,false);
 Arrayout:= CreateParam('Arrayout',ptarray); Setisinput(ArrayOut,false); 
 SetMin	   (ArrayIn, 1.4e-45);     // set min parameter value
 SetMax	   (ArrayIn, 3.4e38);     // set max parameter value
 SetMin	   (ArrayOut, 1.4e-45);     // set min parameter value
 SetMax	   (ArrayOut, 3.4e38);     // set max parameter value
end;
//////////////////////////////////////
Procedure Callback(N:integer); 
Var i, j : Integer;
Var temp : real;
begin
    if (N=ButtonIn)  then begin
        for i:= 0 to GetLength(ArrayIn)-1 do begin
            SetDataArrayValue(ArrayOut, i, GetDataArrayValue(ArrayIn, i));
        end;    
        SetLength(ArrayOut,  GetLength(ArrayIn));
        for i:= GetLength(ArrayOut)-1 downto 0 do begin
            j := random(i);
            temp := GetDataArrayValue(ArrayOut, j);
            SetDataArrayValue(ArrayOut, j, GetDataArrayValue(ArrayOut, i));
            SetDataArrayValue(ArrayOut, i, temp);
        end;   
    end;
end;

Posted: 01 Jul 2012, 16:24
by nay-seven
it works if you create the 2 array from the script , but i mean if you have a project with an array with min =20 and max =80 , and you want add your script behind this one, this don't work..?
i suppose we need here 2 variable , min and max and get their value from the first array..?

but it's not a big deal , so don't waste time for this if you don't have..

Posted: 02 Jul 2012, 09:28
by caco
Yes, but this is the same with all array modules that you need to make sure second array is compatible with first array for min, max etc I think?

Made minor change so that Array Out is now saved in patch as was not being restored before.

Code: Select all

//////////////////////////////////////////////
// Randomly reorders data in array 
// Version 1.01
// 2 July 2012
// By Caco
//////////////////////////////////////////////
var ArrayIn, ButtonIn, ArrayOut : tparameter;
///////////////////////////////////////////////
procedure init;
begin  
 ArrayIn:= CreateParam('Array in',ptarray); SetisOutput(ArrayIn,false);
 ButtonIn:= CreateParam('Shuffle',ptbutton); SetisOutput(ButtonIn,false);
 Arrayout:= CreateParam('Array out',ptarray); Setisinput(ArrayOut,false); 
 SetMin       (ArrayIn, 1.4e-45);     // set min parameter value
 SetMax       (ArrayIn, 3.4e38);     // set max parameter value
 SetMin       (ArrayOut, 1.4e-45);     // set min parameter value
 SetMax       (ArrayOut, 3.4e38);     // set max parameter value
 SetDontSave  (ArrayOut, FALSE);
end;
//////////////////////////////////////
Procedure Callback(N:integer); 
Var i, j : Integer;
Var temp : real;
begin
    if (N=ButtonIn)  then begin
        for i:= 0 to GetLength(ArrayIn)-1 do begin
            SetDataArrayValue(ArrayOut, i, GetDataArrayValue(ArrayIn, i));
        end;    
        SetLength(ArrayOut,  GetLength(ArrayIn));
        for i:= GetLength(ArrayOut)-1 downto 0 do begin
            j := random(i);
            temp := GetDataArrayValue(ArrayOut, j);
            SetDataArrayValue(ArrayOut, j, GetDataArrayValue(ArrayOut, i));
            SetDataArrayValue(ArrayOut, i, temp);
        end;   
    end;
end;

Posted: 02 Jul 2012, 10:58
by nay-seven
yes, you're certainly right, i sadly don't have time to study scripts right now, i first thing we can use something like GetDataArrayValue and a variable to get the min & max then set them back
or a GetMin equivalent to the GetLength we have yet

definitively need a parallel life...;)