defaultxr / cl-patterns

Library for writing patterns to generate or process (a)musical sequences of mathematically (un)related (non-)compound values in Lisp.

Home Page:https://w.struct.ws/cl-patterns

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Getting the value of other keys in a pbind

ntrocado opened this issue · comments

Is it possible to do the equivalent of the following SuperCollider code?

Pbind(
	\freq, Pseq([ 440, 330, Pfuncn({ 550.rand + 40 }, 1)], inf),
	\amp, Pfunc({ arg event; 
			event.postln; 
			if(event.freq > 350, {
				"here".postln; 
				rrand(0.1,0.5);
			}, 0.05); 
		})
).play

I tried to access *event* but it always yields nil...

How did you translate this to cl-patterns? Here is how I would do it, and it seems to work for me:

(pb :foo
  :freq (pseq (list 440 330 (pfin (pfunc (lambda () (+ 40 (random 550)))) 1)))
  :amp (pfunc (lambda ()
                (print *event*)
                (if (> (event-value *event* :freq) 350)
                    (progn
                      (print 'here)
                      (random-range 0.1 0.5))
                    0.05))))

Once you eval that, you can just do (play :foo).

pb is basically pbind and pdef combined, it makes it easier to start/stop patterns since you can just refer to them by name.

I haven't added pfuncn yet so you have to do (pfin (pfunc ...) 1) for now. Thanks for pointing it out though; I'll add it soon.

Let me know if that doesn't work for you.

Thank you for the quick answer!
I was doing something very similar, but for some reason the clock had stopped running, hence the nils! Embarrassing...

No prob! Glad to hear it was something simple at least. Though it is strange that it would result in nils if the clock wasn't running. Maybe it would be a good idea for me to implement some kind of warning or error if something is played when the clock is stopped.

I've been trying to reproduce how I got to that state but without success. At a certain point I had a bunch of clock threads running, so I went and manually destroyed them, then forgot to make a new clock, but this doesn't get the same error. Anyway I believe this is irrelevant for the normal use of library… other than deliberately or accidentally killing the thread is it even possible to stop the clock? And if the clock isn't initialized you get an error (maybe it should be initialized by default when loading the library?)
Anyway, thanks again (for the answer and for creating this project)!

I think if an error happens in a pattern and you pick "abort" as the restart instead of "skip event" or "remove task" then the clock will be stopped. Otherwise, you're correct that there isn't really any way to manually stop it.

Starting the clock when the library is loaded does have the appeal of making things simpler, but I think there are some use cases where people might not want that (i.e. they might want to advance the clock themselves to keep it in sync with something else, like a game's loop or the like), so I'm avoiding that. But I think it is true that right now there is too much boilerplate to making a project with cl-patterns/cl-collider. Reducing it is one of the things I'm thinking about and hopefully the big refactoring I'm working on will make use of the library simpler overall while also being more flexible.

No problem again, and thanks for checking it out! Don't hesitate to open another issue if you have any other problems or suggestions.