Is there a Pattern word that lets you skip a duration from the beginning

It seems like there is a word that lets you skip a duration from the end of a pattern,
that is Pfindur, but no one that lets you skip a duration from the beginning of a
pattern. Really what I want is get an excerpt from the pattern, but it seems like I
only need the word that will skip the beginning and to use that with Pfindur.

                Thanx

Unsure if there is a specific pattern, but you could just modify the array youā€™re feeding into the pattern:

(
var durs = [1,1,2,1,1,12,2];
var skip = {|array, i| array.removeAt(i); array;}; \\remove item and return ARRAY, not item
skip.(durs,5); //skip index 5 <- [ 1, 1, 2, 1, 1, 2 ]
)

There are a number of ways this can be dealt but then you have to be more specific about the behaviour you are after. Post a code example and explain what input-output you are looking for. Also, Pfindur is not exactly skipping a duration at the end of a pattern, Pfindur ensures a pattern lasts for a certain number of beats.

I think OP is hoping to have a pattern start after a certain. number of beats. Maybe thereā€™s a better way but Pseq([Rest( beats ), pattern]) or Ptpar( [beats, pattern]).play will play pattern after a delay of beats

I want to just play a part of an Event based Pattern, for example part of a Pbind. It seems as if I can control the end of my excerpt using Pfindur, but I am so far puzzled by setting the beginning, for example this is what I want:

p = Pbind(
\midinote, Pseq([60, 62, 64, 65]),
\dur, 1
);

a = p.asStream;

a.nextN(5, ());

ā†’ [ ( ā€˜midinoteā€™: 60, ā€˜durā€™: 1 ), ( ā€˜midinoteā€™: 62, ā€˜durā€™: 1 ), ( ā€˜midinoteā€™: 64, ā€˜durā€™: 1 ), ( ā€˜midinoteā€™: 65, ā€˜durā€™: 1 ), nil ]

Letā€™s suppose there was a word Pfoo that did what I want, then:

f = Pfoo(p, 1.5);

b = f.asStream;

b.nextN(4, ());

ā†’ [ ( ā€˜midinoteā€™: 62, ā€˜durā€™: 0.5 ), ( ā€˜midinoteā€™: 64, ā€˜durā€™: 1 ), ( ā€˜midinoteā€™: 65, ā€˜durā€™: 1 ), nil ]

       Thank You For Your Attention

There are many ways you can go about this. In general I like to use functions to define pbinds and use the Pdef class to play the output of the functions, like this:

(
~pbind = {|notes|
	Pbind(
		\midinote, Pseq(notes, inf),
		\dur, 1
	)
};
)

// play the orignal sequence

Pdef(\test, ~pbind.([60, 62, 64, 65])).play;

Pdef(\test).stop

// play from the third note, midinote 64.

Pdef(\test, ~pbind.([60, 62, 64, 65].rotate(-2))).play;

// play from the second note, midinote 62, without stopping first, the sequence will start from midinote 62 quantized to the nearest beat (the default quant setting)

Pdef(\test, ~pbind.([60, 62, 64, 65].rotate(-1)));

// it is more pratical to asign the notes to a variable

~notes = [60, 62, 64, 65];

Pdef(\test, ~pbind.(~notes.rotate(-3)));
Pdef(\test, ~pbind.(~notes.scramble));

Pdef(\test).stop

Another way using Pdefn:

// not using Pdef here just to show the simple way. I would still use Pdef in this case and actually pretty much always - just as simple and much more flexible.

(
p = Pbind(
	\midinote, Pdefn(\notes),
	\dur, 1
)
)
~notes = [60, 62, 64, 65];
Pdefn(\notes, Pseq(~notes, inf));

x = p.play;

Pdefn(\notes, Pseq(~notes.rotate(-2), inf));

x.stop;

Pdefn(\notes, Pseq(~notes.rotate(-1), inf));

x.play;
x.stop

Thank you for your reply. However one has to realize that my example Event pattern was very simplified, and in real practice I wish to use it for Event patterns that utilize Ppar and dur patterns that vary.

Iā€™d rather assume that Pfoo need not know anything about the internal construction of the Event pattern itā€™s operating on, save perhaps for the dur. Youā€™ll also note that even in my example I deliberately used a value that didnā€™t line up with the dur values so Pfoo has to adjust the primary dur value as indicated on my example.

             Thank You For Your Attention

I see that I misunderstood you a bit. This is the best I can come up with. You could Pchain your other patterns with this.

(
~pfoo = {|notes, durs, index = 0|
	var offset = if (index.isInteger.not) {(index.roundUp - 1).asInteger} {index};
	durs = durs.rotate(offset * -1);
	durs[0] = durs[0] - index.frac;
	Pbind(
		\midinote, Pseries(0, 1, inf).collect { |i| notes.wrapAt(i + offset) },
		\dur, Pseq(durs, inf),
	)
};
)
~notes = [60, 62, 64, 65];
~durs = [1, 1, 1, 1, nil];

Pdef(\test, ~pfoo.(~notes, ~durs, 0)).play
Pdef(\test, ~pfoo.(~notes, ~durs, 1)).play
Pdef(\test, ~pfoo.(~notes, ~durs, 1.5)).play
Pdef(\test, ~pfoo.(~notes, ~durs, 0.75)).play

Maybe something like this is what youā€™re after?

(
f = { |pattern, start = 0|
  var stream = pattern.asStream;
  fork {
    stream.fastForward(start).wait;
    EventStreamPlayer(stream).play;
  }
}
)

p = Pbind(\degree, Pseq([0, 1, 2, 3, 4]), \dur, 0.5);
f.(p, 0); // start from beginning
f.(p, 0.1); // start 0.1 beats from beginning
f.(p, 1.0); // etc.
2 Likes

This seems like it could be what Iā€™m looking for. One assumes that fastForward is the workhorse (not documented) and it skips until the beginning of my ā€˜excerptā€™. I guess Iā€™ll have to slog through the source code. Thanks

It seems like this manipulation of your code doesnā€™t do what I want, however:

(
f = { |pattern, start = 0|
  var stream = pattern.asStream;
  fork {
    stream.fastForward(start).wait;
    EventStreamPlayer(stream).play;
  }
}
)

p = Pbind(\degree, Pseq([0, 1, 2, 3, 4]), \dur, 0.5);

f.(p, 1.0);

Pseq([f.(p, 1), f.(p, 1)])

I wanā€™t the code to play ā€˜f.(p, 1)ā€™ twice. Instead it only plays it once.

Also, but of a lesser importance, a note that bestraddles the time mark is simply not played instead of played with shorter duration, which I would prefer. Pfindur will abbreviate notes, your function will not foreshorten them.

              Thanks For Your Attention

Iā€™ve used various approaches to this, but I donā€™t know if I ever used something that could ā€œchaseā€ notes, that is still play notes with the duration shortened. Maybe something like this could be useful? (Not thoroughly tested, making pattern classes is still a mystery to me)

Pdropdur has the same interface as Pdrop, but instead of dropping events, it drops a duration. It also comes with a mode argument, which can be \chase, \pad or \cut. The example will hopefully clarify what they do.

Thank you for your reply. However when I enter the following code it seems the \chase option doesnā€™t work like I expect:

(
a = Pbind(\note, Pseq([1,  2,  3,  4]));
b = Pbind(\note, Pseq([9, 11, 13, 15]));
c = Ppar([a, b]);
)

d = Pn(Pdropdur(1.5, c, \chase)).asStream;
d.next(Event.default); // press several times

responds with:

-> ( 'dur': 0.5, 'note': 11, 'delta': 1.0 )
-> ( 'note': 3, 'delta': 0.0 )
-> ( 'note': 13, 'delta': 1.0 )
-> ( 'note': 4, 'delta': 0.0 )
-> ( 'note': 15, 'delta': 1.0 )
-> ( 'dur': Rest(0.0), 'delta': 0.0 )
-> ( 'dur': 0.5, 'note': 11, 'delta': 1.0 )
-> ( 'note': 3, 'delta': 0.0 )
...

It seems as if it messed up the sequence of the output from Ppar. Any ideas on how to fix this?

                    Thank You For Your Attention

Yes, the previous version could only chase the last note. Iā€™ve updated the gist above which should make it work with your use case, and also (hopefully) shorten the sustain of the chased notes, so it matches a non-chased note.