Tie notes together if they have same pitch

Hi,
I am trying to tie notes in a pattern together, if they happen to have the same pitch.
For example in the following scenario:

Pbind(\degree, Pwhite(0,3), \dur, 1/8).play;

If \degree happens to be 0 twice in a row, how could it be possible to make it a single note with \degree 0 and \dur 1/4, instead of two notes with \dur 1/8.
Does anyone have a suggestion? Thanks!

Not really what you’re asking but for your example you could simply write \degree,Pxrand(0,3),\dur,Pwrand([1/8,1/4],[3/4,1/4]) and the effect would be similar -

Thanks for your suggestion.

I tried to figure it out once more and now i am at this point:

(
(Penvir((),
	Pbind(
		\sendGate, false,
		\id, Pfunc { s.nextNodeID },
		\tie, Pfunc { |ev|
			// ~lastDegree.postln;
			if(~lastDegree == ev.degree){
				ev.dur = Rest(ev.dur);
			}{
				~lastID !? {
					s.sendMsg("/n_set", "default", ~lastID + 1, "gate", 0);
				};
				~lastID = ev.id.postln;
			};
			~lastDegree = ev.degree;
			ev.postln
	})
) <> Pbind(\dur, 1/2, \degree, Pwhite(0,3))
).play
)

Which works because of a hack (the part ~lastID + 1 ), since the node id does not seem to take the value of \id which i assign to it.
So a new question has come up, why is the node id which i assign not used?

Hi,

an interesting thread in which you’re raising two big topics with patterns, that have been discussed a lot before –

Tying notes is a natural thing coming from musical thinking, but not easy to address within the pattern framework. Actually you would rather have to decide at the beginning of a note if you’d want to tie, not in the middle (as your concrete example suggests). This conflicts with the standard way Patterns are used in Pbind and messages are sent. In some older threads James Harkins suggested further solutions for this, I can’t remember where to find though. You might also want to check PmonoArtic.

Alternatively you could change the structure of the patterns for duration and/or degree or couple them etc. @semiquaver gave one possibility. That’s probably less hassle with a similar or equal result.

The second topic arising here is that Patterns/EventStreamPlayers, by default, don’t have a memory – but this is exactly what you’d need if you’d want to decide “in the middle”.

At least for this miSCellaneous_lib quark contains PSrecur with which you refer to former items of a Stream.

(
Pbind(
	\degree, PSrecur({ |x| 
		var y = rand(4);	
		(y == x[0].value).if { Rest(y) }{ y } 
	}), 
	\dur, 1/8
).trace.play;
)

Instead of rand(4) you could refer to a Stream from a Pattern. This could be combined with your approach but I have no time at the moment to look into the setting thing – anyway I suppose the “early decision” approach is more feasible (unless you have other reasons to avoid it).

For an Event of type \note (the default), Node ID’s are assigned in the Event’s type Function when the Synths are created. The Function doesn’t do anything with the values you assign to key \id in an Event.

In contrast, Event type \set does use the value of key \id to specify an already-existing Node to act upon, which may be where you’ve seen “id” used in Patterns before.

It’s certainly possible to add an Event type which would enable you to specify the ID’s of any Nodes it creates using the \id key, and in a larger sense, the kind of behavior you’re looking for is possible to achieve by defining your own Event types, but it’s a fair amount of work to get away from SC’s default assumption that you always know the duration of a “note” at the start of that note.

Since Events of type \note work by scheduling two messages to the Server (let’s call them “note on” and “note off”), one approach you could try would be to use some kind of client-side data structure to keep track of currently playing notes. Then instead of scheduling “note off” messages directly, a custom Event type could check with that “bookkeeping” object for whatever information it needs in order to decide whether a note gets “tied” (which in this context would mean that its original scheduled “note off” message gets dropped and a new one gets scheduled).

I’ve experimented with this kind of thing in the past while writing Classes to support fixed polyphony and voice stealing and it’s certainly doable but it’s not something that SC necessarily makes “easy”.

A solution is to compute the degree pattern in advance so you can detect repeating sequences:

(
	~pTie = { arg pat;
		Prout({ arg ev;
			var str = pat.asStream;
			var futurVal;
			var val;
			var tieCount = 0;
			val = str.next;
			loop {
				while({
					futurVal = str.next;
					futurVal == val
				}) {
					tieCount = tieCount + 1;
				};
				ev.legato = ev.legato + tieCount;
				ev = val.yield;
				tieCount.collect({
					ev[\type] = \rest;
					ev = val.yield;
				});
				tieCount = 0;
				val = futurVal;
			}
		});
	};

Pdef(\zed, 
	Pbind(
		\instrument, \default,
		\degree, ~pTie.(Pwhite(0,3)),
		\dur, 1/4,
		\amp, 0.1,
	).trace
).play;
);