Advancing a Pattern, stage by stage

Hello,

I’m not sure there is a way to do this. It definitely doesn’t fit with my understanding of how a pattern works. Below is code for a simple stream where each event is triggered by an incoming amplitude exceeding a threshold.

I’m wondering how to keep the current event playing until it receives the impulse for a next event. Any advice on this would be greatly appreciated. Thank you.

~stream = Pbindef(\x,\freq, Pseq([900, 200, 500, 100], inf))
.asStream;

{ var amp = Lag.kr(Amplitude.kr(SoundIn.ar(0)), 0.1);
	//amp.poll;
SendReply.kr(amp > 0.2, '/act1', amp);
}.play;

OSCdef(\act1, { |packet|
         ~stream.next((fbkAmp: packet[3])).play},
'/act1');

The issue isn’t the pattern – it’s the event. The default event prototype is designed for the case when you can predict the onset of the next note (based on \dur). So it’s awkward when you don’t know the next event’s time.

One approach might be to use event type \on, and save the event in a variable. Then, when the next trigger happens, release the old event and play the new one. (Using event prototyping style to support multiple instances.)

(
~makeTriggerStreamer = { |pattern|
	var prevEvent;
	
	var stream = pattern.asStream;
	
	(nextEvent: { |self, prototype(Event.new)|
		var event = stream.next(prototype);
		self[\releaseNote].value;
		prevEvent = event.play;
	},
	releaseNote: { |self|
		if(prevEvent.notNil) {
			prevEvent.put(\type, \off).play;
			prevEvent = nil;
		};
	})
};
)

x = ~makeTriggerStreamer.(Pbind(
	\type, \on,
	\degree, Pwhite(-7, 7, inf)
));

x.nextEvent;  // for each trigger

x.releaseNote;

hjh

1 Like