How could patterns be better?

Tidal Cycles, for example.

I’ve seen several simpler DSLs. I remember some code with strings using in “.” and “_” and nothing more.

Maybe we could make a list with examples

1 Like

That would be very cool… perhaps quite a grand project though.

… I wonder if we had an FFI you could just launch tidal cycles from within supercollider and communicate with it… (probably another thread!).

I havent said, you should use a DAW instead :slight_smile:
I just think that DAWs are more easy to use to create formal structures. use what you want :slight_smile:

With patterns variation is simple but goal driven development of formal structures couldnt be much more difficult.

I dont know if you are familiar with the midi tools which are available in Live 12.1.
To come up with variation in a DAW couldnt be more easy nowadays.

The practical guide to patterns is really good, and I’ve got a lot out of it. I do think that some of it could be directly linked to from the class documentation - might sound redundant but I would find it useful, as when I’m searching documentation I always look at the class documentation first. Idk… a lot of it is probably user error on my behalf, and I’ve mostly managed to get the answers I’m looking for, but some of it has taken some hardcore forum diving.

it’s regrettable that it cost you so much time to find that out, but the information was actually there – just poorly indexed, I guess.)

I used the .next(()); example for Pbind specifically because the class documentation says this, as the first example:

(
a = Pbind(\x, Pseq([1, 2, 3]), \y, Prand([100, 300, 200], inf), \zzz, 99);
x = a.asStream;
)
​
x.next(()); // pass in an event ()
x.next(());
x.next(());
x.next(()); // end: nil

this is exactly the answer I was looking for, but could be better signposted with “in comparison to calling next on an eventstream, this is how you do it on Pbind” - or whatever the correct technical specification is.

There are lots of other examples in the documentation like this. I just looked up Plazy and there is basically no way you could work out what the class does from the documentation if you were a beginner imo (I learned how the class works from one of Eli’s pattern tutorial videos).

You would need ghci (haskell interpreter). it works sending osc messages to sclang

But I guess you also meant that sclang could have a good parser combinator. With that leverage, I could see a lot of possibilities for merging patterns and DSLs.

Supercollider would greatly benefit from a library equivalent to Parsec and others.

Parsec does not have a concept of tokenization. It just works like building Lego. It fits what we do way more than old-style tools used by ScDoc (bison, lexer, etc).

My goodness so much of this resonates with me! In particular, the bit about the difference between Event, Stream, and Pattern (including the need for .next(())). I also strongly agree that the default \amp value of 1 would be a good call.

If I could throw my own two cents in, I think the following would be quite useful to the general userbase:

  • Additional methods of pattern composition where appropriate. I’ve recently been trying to write some event types that output midi CC and midi note values at the same time, but this feels clunky to develop from the ground up. Since \dur is often such a crucial unifying factor in writing parallel Pbind style patterns, some kind of composition method that doesn’t necessitate writing a separate Pattern type in another variable and re-referencing it multiple times would be great.
  • ^ I suppose this also could take the form of greater flexibility in combining existing Event types, if that sort of thing is possible
  • Additional aliases a-la <> for Pchain would be great syntactic sugar/time saving. One particular place this comes to mind would be for Pbindf

Thanks for inquiring. Excited to see what developments come!

Correct me if I’m wrong, but I think that Pbindf can always be replaced with Pchain and is therefore entirely redundant:

(
a = Pbind(\degree, Pseq([1, 2, 3], inf), \dur, 1);
b = Pbindf(a, \detune, Pseq([-30, 0, 40], inf), \dur, Prand([0.2, 0.4], inf));
c = b.asStream;
)
c.next(())

is really the same as

(
a = Pbind(\degree, Pseq([1, 2, 3], inf), \dur, 1);
b = Pbind(\detune, Pseq([-30, 0, 40], inf), \dur, Prand([0.2, 0.4], inf)) <> a;
c = b.asStream;
)
c.next(())

Unfortunately, the help file does not mention this at all…

The reason for the default is to provide headroom for mixing. I think we should not eliminate headroom from SC’s default settings.

If it’s really felt strongly that events’ default amplitude should be 1, then I’d suggest to compensate by reducing the the server’s default volume by, oh, 12 dB or so…? I’ve always tended to work at about -18 dBFS (my current practice is, event amp = 0.5 ~= -6 dB and mixer channel volume = -12 dB, adding up to about -18) and when I post code examples here, almost always do a * 0.1 at the end of a synth so as not to blow anyone’s eardrums out.

hjh

I think you’re probably right about this on second thought. Despite my comparison before, I realised Ableton does do this in a way: by setting the velocity scale value on most instruments, and making default midi clip velocity 100.

Should we soft deprecate Pbindf? Perhaps by just mentioning this in the help file?

One of the reasons patterns are complex is due to the vast number of Pattern objects to learn and to search through.

I think so. Pchain resp. <> is definitely the more general solution.

@jamshark70 Am I right that Pbindf can be always replaced with Pchain? Or do you know of any differences in behavior?

I get your frustration, Dindoleon. I had been using SuperCollider for a while before I noticed that there is a very convenient way to specify multiple event keys from a single pattern when defining a Pbind. For example:

(
Pbind(
	#[degree, dur],    Pseq([[0,2],[3,1/2],[4,2]], inf)
).play;
)
1 Like

Couple small thoughts: It can be hard to find the right pattern or remember the names. We have Pbindef and Pbindf, Pser and Pseries etc. Longer names might be helpful - Pbind PbindMono PbindArtic - or flags could group silimar functions - Pbind( arrayOfPairs, mono:true). aside: It would also be nice if Pbind, Pmono and PmonoArtic had the same number of arguments! The P as a sort of pseudo-namespace is either too much or not enough depending how you look at it!

Put another way, could the library not be more clearly organized?

Regarding the default Event I really wish that it were necessary to opt-in via the type key! If ().play produced nothing and users had instead to do (type: \note).play to hear sound it would really help new users! Beyond that there is something sort of offensive about assuming that type here as all kinds of musical decisions are promoted as normal. I would rather see a more open neutral frame!

1 Like