Simple visual sequencer example?

It was on the default so I guess 200ms. I changed it to 70ms and I have the feeling it’s running smoother already :slight_smile:

About the issue discussed above, I really have the feeling I did not have this issue before I introduced the inter-note rests…

Could you check if I am doing something obviously wrong in the updated loop?

// can't just Pseq because we need to account for insertions
		this.pattern = Prout { |inval|

			//Starting variables
			var item, node,
			clock = TempoClock,
			barline = clock.nextBar,
			nextTime, delta, restTime, endTime;
			baseBarBeat = barline;

			//start with the first node in the sequence
			node = sequence.nodeAt(0);
			while {
				//While we have items in the sequence do this loop (infinite)
				item = node.tryPerform(\obj);
				item.notNil
			} {
				//Our next event's start-time
				nextTime = barline + item[\time];

				//if this is bigger then current beats this means we are in the start of our loop ->
				//so we yield silence till the first event starts
				if(clock.beats < nextTime) {
					inval = Event.silent(nextTime - clock.beats).yield;
				};

				// now we arrived at the event
				//calculate the end time of the event
				endTime = item[\time] + item[\sustain];

				// calculate the "rest" time after this node.
				// if it's last in sequence we substract it with the 'next-bar' time a.k.a. sequence length
				if(node.next.notNil) {
					restTime = node.next.obj[\time] - endTime;
					delta =  node.next.obj[\time] - item[\time]; //used for next-barline calculation
				} {
					restTime = patternDur - endTime;
					delta =  patternDur - item[\time]; //used for next-barline calculation
				};

				//we need to update the 'next-bar' variable once we will reach the end of the current bar-sequence
				if(clock.beats + delta - barline >= patternDur) {
					barline = barline + patternDur;
					baseBarBeat = barline;
				};

				//we prepare our Event
				if( midiOut.notNil, {
					inval = item.copy.put(\type, \midi).put(\midiout, midiOut).put(\channel, 1).put(\midinote, 0);
				},{
					inval = item.copy.put(\type, \note).put(\instrument, synthDef).put(\note, 0);
				});

				//whenever there is a crossover with notes (multi-voiced) we need to calculate the duration and legato
				if( node.next.notNil and: {  node.next.obj[\time] <  endTime } , {

					var dur, legato;
					dur = node.next.obj[\time] - item[\time];
					legato = item[\sustain] / dur;

					//simply play the note until start of the next note - the legato will take care of the crossover part
					inval = inval.copy.put(\dur, dur).put(\legato, legato).yield;

				}, {
					//smoothly lined up with rests so we simply take the note's duration as \dur argument
					inval = inval.copy.put(\dur, item[\sustain]).yield;

					//we also need to play the silent event after the note is finished until reaching to the next one
					inval =  Event.silent( restTime ).yield;
				});

				//continue the loop
				node = node.next;
				if(node.isNil) { node = sequence.nodeAt(0) };
			}
		};

		this.stream = pattern.asStream;

Thnx a million!