Array extract couples, filter and scale values || Newbie Question

Hello everyone,

I know that is simple but…

[ 100, 0.25, 100, 0.5, rest, 0.25 ]

I have this Array made of midi data velocity, duration.
I need to put them in couple and filter the ‘rest’ with something like: if(a == rest){a = 0.0 };
and scale the velocity in the range 0.0 - 1.0 eg:( \amp,velocity/127.0 )
to obtain something like that:
[ [0.7874, 0.25], [0.7874, 0.5], [0, 0.25] ]
that I need to use with patterns.

Really thanks in advance

How about this:

[ 100, 0.25, 100, 0.5, “rest”, 0.25 ].clump(2).collect{|item| if(item[0]==“rest”){item.put(0, 0)}; item.put(0, item[0]/127)}

1 Like

.clump(2) is right.

I’d suggest to encode the rest as Rest(0) instead of a string. Then you don’t have to do any preprocessing at all. The events produced by your pattern will automatically not perform their action (i.e. no synth) if they contain a Rest object.

If you’d prefer a string, then use a \rest symbol (not a "rest" string). \rest is a special value that will also cause an event to be recognized as a rest.


p = Pbind(
    [\amp, \dur], Pseq(
        [100, 0.25, 100, 0.5, Rest(0), 0.25].clump(2),
    \amp, Pkey(\amp) / 127



Thanks @Sam_Pluta @jamshark70

now there is the problem of remove rest with Rest(0)…

just to clarify the problem.

m = “~/Desktop/abletonMidi.mid” );

// to have the [\midinote, \dur]
x = m.generatePatternSeqs.flatten(1).postln;

here it’s not amp - dur it’s [\midinote, \dur] something like this:
[ [ 72, 0.25 ], [ rest, 0.25 ], [ 72, 0.25 ], [ rest, 0.25 ], [ 72, 0.25 ], [ 72, 0.25 ] ]


var a;
arg item,item1, i; [
a = if(item == ‘rest’,{ item = “Rest(0),” + item1 },{ item +","+ item1 });



// here I’m able to substitute the rest with Rest(0) in the post windows:
[ 72 , 0.25 ][ Rest(0), 0.25 ][ 72 , 0.25 ][ Rest(0), 0.25 ][ 72 , 0.25 ][ 72 , 0.25 ]
but I can’t find a way to have everything in order in a new array.

I mean not in the post window, but in an array, with the correct structure/syntax

[[ 72 , 0.25 ],[ Rest(0), 0.25 ],[ 72 , 0.25 ],[ Rest(0), 0.25 ],[ 72 , 0.25 ],[ 72 , 0.25 ]]

if you have any hint it would be great :slight_smile:

thanks like always

You don’t have to. (Or, shouldn’t have to.)

I just checked wslib’s code: rest here is already a symbol \rest, not a string.

As I said in my last message: "\rest is a special value that will also cause an event to be recognized as a rest."

So, if SimpleMIDIFile is already putting a symbol \rest into the output arrays, then you already have rests. And if you already have rests, then it’s a non-issue.


1 Like

I didn’t understand… That in this case rest wasn’t a string but a symbol… That look like a string.
I used to use Rest() with a duration inside the brackets… So was more then confusing.
Thanks again @jamshark70 for the check and clarification.

Right, in normal posting, a string "abc" and a symbol \abc look the same. Try .postcs instead to be sure of the difference (with .postcs, symbols are in ‘single quotes’ rather than “double quotes for strings”).

The oldest way of writing a rest into a pattern was to put any symbol into a pitch key such as \midinote here. That had to change when it became possible to map buses in patterns using symbols like \c0 or \c67. So now a rest symbol must be \rest or \r, but it can be anywhere in the event now. Currently the preferred way is to use Rest(value) but we kept the two symbols to avoid breaking older code like SimpleMIDIFile.



Somewhat obscurely, the entire Event can be a rest object because

Rest(3).dur // -> 3
// and
Rest(3).playAndDelta // -> 3


Rest(3).play // error (lacks a play method itself)
// but
Pseq([Rest(1), (degree: {9.rand})], 5).play // ok

Due to that I was thinking of deriving a Hang object from Rest.

Another aside: Rest not only responds to asControlInput too but even eval’s its dur as a function on playAndDelta, so you can even do random (or any function-eval’d) rests directly…

Pseq([Rest({ 0.05*rrand(1,5) }), (dur: 0.1)], 19).play

9 do: { Rest({ 0.05*rrand(1,5) }).playAndDelta.postln }