Git Product home page Git Product logo

defaultxr / cl-patterns Goto Github PK

View Code? Open in Web Editor NEW
73.0 9.0 10.0 1.43 MB

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

License: MIT License

Common Lisp 96.29% Emacs Lisp 3.71%
supercollider lisp synth sequencer patterns music music-composition incudine common-lisp audio

cl-patterns's Issues

Changing arguments interactively

Hi, is it possible to change the steps in the pbjorklund function interactively? For example, using this script, if I change 7 to some other integer while the pattern is playing and eval the expression, the pattern doesn't change. How do I do this?

(pb :pattern
  :instrument :block
  :embed (pbjorklund 7 16 :dur 4))
                     ^

Also, I was reading your tutorial and found a function that changes the pitch by moving the mouse/trackpad up and down, similar to a knob. Is it possible to do the same, but changing the steps instead in the pbjorklund function?

(proxy :foo (sin-osc.ar 440 0 0.2))
(proxy :foo (saw.ar (mouse-y.kr 20 10000 :exponential) 0.2))

Can't use list with a single value as midinote

Hi!
The following patterns

(pb :pow
    :instrument :saw
    :quant 4
    :dur 1/4
    :midinote (list 60))

gives an error:

The value
  (60)
is not of type
  NUMBER
when binding SB-KERNEL::X
   [Condition of type TYPE-ERROR]

Restarts:
 0: [SKIP-EVENT] Skip this event, preserving the task on the clock so it can be run again.
 1: [REMOVE-TASK] Remove this task from the clock.
 2: [ABORT] abort thread (#<THREAD "cl-patterns clock-loop" RUNNING {100238F493}>)

Backtrace:
 0: (SB-KERNEL:TWO-ARG-- (60) 69.0d0) [external]
 1: (MIDINOTE-FREQ (60))
 2: (EVENT-VALUE (EVENT :PDEF :POW :INSTRUMENT :SAW :QUANT (4) :DUR 1/4 :ATK 0.01 :DEC 0.5 :SUS 0.1 :REL 0.1 :AMP 0.2 :MIDINOTE (60) :BEAT-AT-START 81/10 :TIMESTAMP-AT-START @2021-03-26T20:45:45.570964+01..
 3: ((:METHOD BACKEND-INSTRUMENT-ARGS-LIST (T T T)) :SAW (EVENT :PDEF :POW :INSTRUMENT :SAW :QUANT (4) :DUR 1/4 :ATK 0.01 :DEC 0.5 :SUS 0.1 :REL 0.1 :AMP 0.2 :MIDINOTE (60) :BEAT-AT-START 81/10 :TIMESTAMP..
 4: ((:METHOD BACKEND-PLAY-EVENT (T T T)) (EVENT :PDEF :POW :INSTRUMENT :SAW :QUANT (4) :DUR 1/4 :ATK 0.01 :DEC 0.5 :SUS 0.1 :REL 0.1 :AMP 0.2 :MIDINOTE (60) :BEAT-AT-START 81/10 :TIMESTAMP-AT-START @2021..
 5: ((:METHOD CLOCK-PROCESS-EVENT (T T T T)) #<unused argument> #<TASK :ITEM #<PDEF-PSTREAM :POW>> (EVENT :PDEF :POW :INSTRUMENT :SAW :QUANT (4) :DUR 1/4 :ATK 0.01 :DEC 0.5 :SUS 0.1 :REL 0.1 :AMP 0.2 :MID..
 6: ((FLET SB-THREAD::WITH-RECURSIVE-LOCK-THUNK :IN CLOCK-PROCESS))
 7: ((FLET "WITHOUT-INTERRUPTS-BODY-11" :IN SB-THREAD::CALL-WITH-RECURSIVE-LOCK))
 8: (SB-THREAD::CALL-WITH-RECURSIVE-LOCK #<FUNCTION (FLET SB-THREAD::WITH-RECURSIVE-LOCK-THUNK :IN CLOCK-PROCESS) {7F7E64F9664B}> #<SB-THREAD:MUTEX "Anonymous recursive lock" owner: #<SB-THREAD:THREAD "cl..
 9: (CLOCK-PROCESS #<CLOCK :tempo 1 :beat 8.0> 1/10)
10: (CLOCK-LOOP #<CLOCK :tempo 1 :beat 8.0> :GRANULARITY NIL)
11: ((LAMBDA NIL :IN START-CLOCK-LOOP))
12: ((LAMBDA NIL :IN BORDEAUX-THREADS::BINDING-DEFAULT-SPECIALS))
13: ((FLET SB-UNIX::BODY :IN SB-THREAD::RUN))
14: ((FLET "WITHOUT-INTERRUPTS-BODY-11" :IN SB-THREAD::RUN))
15: ((FLET SB-UNIX::BODY :IN SB-THREAD::RUN))
16: ((FLET "WITHOUT-INTERRUPTS-BODY-4" :IN SB-THREAD::RUN))
17: (SB-THREAD::RUN)
18: ("foreign function: call_into_lisp")
19: ("foreign function: funcall1")

Some systems failed to build for Quicklisp dist

Building with SBCL 2.3.6.173-55d27b14b / ASDF 3.3.5 for quicklisp dist creation.

Trying to build commit id 02e7a5f

cl-patterns fails to build with the following error:

; caught WARNING:
;   Derived type of (SEARCH " current " CL-PATTERNS::SCREEN-STR) is (VALUES NULL &OPTIONAL), conflicting with its asserted type NUMBER.
;   See also:
;     The SBCL Manual, Node "Handling of Types"
...
Unhandled UIOP/LISP-BUILD:COMPILE-FILE-ERROR in thread #<SB-THREAD:THREAD tid=2281347 "main thread" RUNNING {1001710003}>: COMPILE-FILE-ERROR while compiling #<CL-SOURCE-FILE "cl-patterns" "patterns" "patterns">

cl-patterns/debug fails to build because of a failure in cl-patterns.

cl-patterns/generic-cl fails to build because of a failure in cl-patterns.

cl-patterns/midifile fails to build because of a failure in cl-patterns.

cl-patterns/supercollider fails to build because of a failure in cl-patterns.

cl-patterns/tests fails to build because of a failure in cl-patterns.

Full log here

Saving output to file

How can I save an excerpt of the output to an audio file? For example, using this example:

(ql:quickload :cl-collider)
(in-package #:cl-collider)

(setf *s* (make-external-server "localhost" :port 4444))
(server-boot *s*)
(jack-connect)

(defsynth beep ((gain 1))
  (let* ((env (line.kr 4 0 .03 :act :free))
         (sig (sin-osc.ar 500 0 env)))
    (out.ar 0 (pan2.ar sig 0 gain))))

(ql:quickload :cl-patterns/supercollider)
(cl-patterns:backend-start :supercollider)
(in-package #:cl-patterns)
(start-clock-loop :tempo 110/60)

(pb :beat
  :embed (pcycles "x-xx-x-xx-xx" :dur 3)
  :instrument :beep)

(play (list :beat))

Can't change tempo of running clock loop

When I attempt to change the tempo of a running clock loop there is an error.

Start the clock loop:
(start-clock-loop :tempo 110/60)

Then I try to change it using one of these functions:
(play (event :type :tempo :tempo 60/60))
(tempo 90/60)

Both of those throw this error:

There is no applicable method for the generic function
  #<STANDARD-GENERIC-FUNCTION CL-PATTERNS::BACKEND-TIMESTAMPS-FOR-EVENT (1)>
when called with arguments
  ((EVENT :TYPE :TEMPO :TEMPO 3/2 :BEAT-AT-START 191/60 :TIMESTAMP-AT-START @2023-01-08T22:06:14.017817-05:00)
   #<CL-PATTERNS::TASK :ITEM #<T-PSTREAM (EVENT :TYPE :TEMPO :TEMPO 3/2) 1>>
   #<CL-PATTERNS::SUPERCOLLIDER {700B1F1C63}>).
   [Condition of type SB-PCL::NO-APPLICABLE-METHOD-ERROR]
Restarts: 
  0: [RETRY] Retry calling the generic function.
  1: [SKIP-EVENT] Skip this event, preserving the task on the clock so it can be run again.
  2: [REMOVE-TASK] Remove this task from the clock.
  3: [ABORT] abort thread (#<THREAD "cl-patterns clock-loop" RUNNING {700737DCA3}>)

Stack Trace: 
  0: ((:METHOD NO-APPLICABLE-METHOD (T)) #<STANDARD-GENERIC-FUNCTION CL-PATTERNS::BACKEND-TIMESTAMPS-FOR-EVENT (1)> (EVENT :TYPE :TEMPO :TEMPO 3/2 :BEAT-AT-START 191/60 :TIMESTAMP-AT-START @2023-01-08T22:0..
  1: (SB-PCL::CALL-NO-APPLICABLE-METHOD #<STANDARD-GENERIC-FUNCTION CL-PATTERNS::BACKEND-TIMESTAMPS-FOR-EVENT (1)> ((EVENT :TYPE :TEMPO :TEMPO 3/2 :BEAT-AT-START 191/60 :TIMESTAMP-AT-START @2023-01-08T22:0..
  2: ((:METHOD CL-PATTERNS::CLOCK-PROCESS-EVENT (T T T (EQL :TEMPO))) #<CL-PATTERNS::CLOCK :TEMPO 11/6 (110 BPM) :BEAT 3.0> #<CL-PATTERNS::TASK :ITEM #<T-PSTREAM (EVENT :TYPE :TEMPO :TEMPO 3/2) 1>> (EVENT ..
  3: ((FLET SB-THREAD::WITH-RECURSIVE-LOCK-THUNK :IN CLOCK-PROCESS))
  4: ((FLET "WITHOUT-INTERRUPTS-BODY-11" :IN SB-THREAD::CALL-WITH-RECURSIVE-LOCK))
  5: (SB-THREAD::CALL-WITH-RECURSIVE-LOCK #<FUNCTION (FLET SB-THREAD::WITH-RECURSIVE-LOCK-THUNK :IN CLOCK-PROCESS) {1092C097B}> #<SB-THREAD:MUTEX "Anonymous recursive lock" owner: #<SB-THREAD:THREAD "cl-pa..
  6: (CLOCK-PROCESS #<CL-PATTERNS::CLOCK :TEMPO 11/6 (110 BPM) :BEAT 3.0> 1/10)
  7: (CLOCK-LOOP #<CL-PATTERNS::CLOCK :TEMPO 11/6 (110 BPM) :BEAT 3.0> :GRANULARITY NIL)
  8: ((LAMBDA NIL :IN START-CLOCK-LOOP))
  9: ((LAMBDA NIL :IN BORDEAUX-THREADS::BINDING-DEFAULT-SPECIALS))
  10: ((FLET SB-UNIX::BODY :IN SB-THREAD::RUN))
  11: ((FLET "WITHOUT-INTERRUPTS-BODY-127" :IN SB-THREAD::RUN))
  12: ((FLET SB-UNIX::BODY :IN SB-THREAD::RUN))
  13: ((FLET "WITHOUT-INTERRUPTS-BODY-120" :IN SB-THREAD::RUN))
  14: (SB-THREAD::RUN)

Thanks for your help and this amazing library!

Some systems failed to build for Quicklisp dist

Building with SBCL 2.2.4 / ASDF 3.3.5 for quicklisp dist creation.

Trying to build commit id db5630a

cl-patterns/supercollider fails to build with the following error:

; caught ERROR:
;   There is no function named DECLARE.  References to DECLARE in some contexts (like starts of blocks) are unevaluated expressions, but here the expression is being evaluated, which invokes undefined behaviour.
...
Unhandled UIOP/LISP-BUILD:COMPILE-FILE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1001C58003}>: COMPILE-FILE-ERROR while compiling #<CL-SOURCE-FILE "cl-patterns/supercollider" "src/backends/supercollider">

Full log here

:tempo key

From the documentation on special keys I got the impression that the following should work, but it doesn't:

(pb :foo
  :midinote 60
  :tempo 140/60)

The tempo is unchanged... Having each pb in its own tempo would be great, is it possible?

None of the examples in the supercollider example work for me

I can load the library fine, and compile the synths. However when I tried to run a pattern from the version in quicklisp, it would complain that
There is no applicable method for the generic function

So I tried the latest version in github instead, and I no longer get an error. However when I run the clock nothing happens. And if I try to call a synth directly as follows:
(synth 'default)

I get the error:

There is no applicable method for the generic function
  #<STANDARD-GENERIC-FUNCTION CL-COLLIDER::ID (2)>
when called with arguments
  (NIL).
   [Condition of type SB-PCL::NO-APPLICABLE-METHOD-ERROR]

This is on SBCL on the Mac (M1).

cl-patterns with alsa MIDI

Hi! I'm interested in using cl-patterns for controlling MIDI, but cl-alsaseq has disappeared. Any idea what happened to it? Do you happen to have a copy of it?

Can't build without xrandr

I maintain the ocicl package repo, which container cl-patterns. cl-patterns stopped building in a headless environment (our build container image on github actions) ever since xrandr was required at load/build time to get the screen size. It doesn't have to run. I just want to make sure it builds before packaging it.

About *alsa-midi-instrument-map*

Hi!
Recently *alsa-midi-instrument-map* was added and it looks like a really nice idea!

I have some immediate thoughts on it, which are of course specific to my workflow, but I guess it is quite common among hardware users.

So, right now to use MIDI device you need to do something like this:

(pb :kick
  :backend :alsa-midi
  :channel (1- 1)
  :quant 1
  :dur 1)

Or with *alsa-midi-instrument-map*:

(setf (alsa-midi-instrument-program-number :nord-kick) 30)

(pb :kick
  :instrument :nord-kick
  :channel (1- 1)
  :quant 1
  :dur 1)

It would be really cool if I could set MIDI channel once for my setup, and make program change more explicit, perhaps like this:

(setf (alsa-midi-instrument :nord-kick) '(:chan (1- 3)))

(pb :kick
  :instrument :nord-kick
  :program '(:pc 32 :msb 13 :lsb 3)
  :quant 1
  :dur 1)

Typically having only program change is not enough, as every device has it's own scheme of switching banks, using all sort of combinations of program change, msb and lsb (http://www.andrelouis.com/qws/art/art009.htm)

Cannot disable looping with loop-p

Hi!

(pb :foo
  :type :midi
  :channel 8
  :quant 1
  :dur 1
  :pfin 2
  :midinote 60)

(play :foo)

I assume this code should play 2 notes, but it loops forever. Am I missing something?

[Feature Request] Allow for :server-options key in start-backend

I've been having to launch the sc server with a few options disabled using sc-collider. So my make-external-server command has to be:

(setf *s* (cl-collider::make-external-server
                        "localhost"
                        :port 8000
                        :server-options (cl-collider::make-server-options
                                         :num-input-bus 0
                                         :load-synthdefs-p 0)))

I've noticed there is no way to pass these options into cl-patterns:start-backend. Any way to make these args available through the cl-patterns interface?

The test clock depends on backend :debug to be enables.

The test clock depends on the backend :debug to be enabled to work. The test enable-debug-backend enables :debug, but if clock runs without it or before it, it errors (it ends up calling /= with no arguments).

Adding (enable-backend :debug) at the beginning of the test fixes it for me.

Compiling with swank and later loading without fails

If you compile cl-patterns with swank loaded (i.e. ql:quickload it the first time), then later loading it without swank errors, because it looks for symbols in the "SWANK" package. That is because of the conditionalization of swank::compute-enriched-decoded-arglis in src/patterns/patterns.lisp.

Probably the best approach is to have a "swank-support.lisp" file, and use it only when swank is loaded.

[Feature Request] Allow CC only patterns

Hi again!

Consider the following example:

(progn
  (pb :kick
    :type :midi
    :channel (1- 1)
    :quant 1
    :embed (pbjorklund 17 32 :dur 16 :repeats 1)
    :dur 1/4
    :midinote 60)

  (pb :kick-lfo
    :type :midi
    :channel (1- 1)
    :quant 1
    :c-30 (ptrace (pwhite 30 80))
    :dur 1/8)

  (play (list :kick :kick-lfo)))

I'm trying to control CC parameter with an independent pattern, because I want it to run faster then notes themselves. But it seems that right now pattern always sends note-on events.

Instantaneous tempo changes

Is it possible to have a new tempo start immediately (restarting/resyncing the clock), instead of only changing on the next beat?

The lock in ipstream-stream is made a non-recursive, but is used as recursive

(lock :state t :initform (bt:make-lock "ipstream patterns slot lock")))

:lock (bt:make-lock "ipstream patterns slot lock"))))

(bt:with-recursive-lock-held (lock)

The lock in an ipstream-pstream is make by bt:make-lock, which creates a non-recursive lock, but it is then used as a recursive lock. When I try to run the tests on LispWorks it actually gets an error when it tries to lock it recursively.

It needs to use bt:make-recursive-lock instead.

Support NamedControl for cl-collider

Recently (named-control) was added to cl-collider.
When used with cl-patterns it throws an error.

I quickly fixed it on my end, but I'm not sure about string-upcase.

@@ -203,14 +203,14 @@ See also: `backend-play-event'"))
 (defmethod backend-instrument-args-list (instrument event backend)
   (if-let ((controls (backend-instrument-controls instrument backend)))
     (let ((instrument-params (remove-if (lambda (arg) ;; for parameters unspecified by the event, we fall back to the instrument's defaults, NOT the event's...
-                                          (unless (string= (symbol-name arg) "SUSTAIN") ;; ...with the exception of sustain, which the instrument should always get.
+                                          (unless (eq arg :sustain) ;; ...with the exception of sustain, which the instrument should always get.
                                             (multiple-value-bind (value key) (event-value event arg)
                                               (declare (ignore value))
                                               (eql key t))))
                                         (append controls (list :group :to :id))))) ;; FIX: this is for the supercollider backend; genericize this
       ;; get the value of each of the instrument's arguments from the event...
       (loop :for param :in instrument-params
-         :for sparam = (make-keyword param)
+         :for sparam = (make-keyword (string-upcase param))
          :for val = (backend-convert-object (event-value event sparam) sparam backend)
          :if (or (eql :gate sparam)
                  (not (null val)))

Some systems failed to build for Quicklisp dist

Building with SBCL 2.2.4 / ASDF 3.3.5 for quicklisp dist creation.

Trying to build commit id 6138c0a

cl-patterns/supercollider fails to build with the following error:

; caught ERROR:
;   return for unknown block: NOTE-MIDINOTE
...
Unhandled UIOP/LISP-BUILD:COMPILE-FILE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1001C58003}>: COMPILE-FILE-ERROR while compiling #<CL-SOURCE-FILE "cl-patterns/supercollider" "src/backends/supercollider">

Full log here

Warning or error if something is `play`ed when the clock is stopped.

This is still connected to the following post:

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.

Originally posted by @defaultxr in #3 (comment)

I forgot to create the clock and got the following error:

There is no applicable method for the generic function
  #<STANDARD-GENERIC-FUNCTION (SB-PCL::SLOT-ACCESSOR :GLOBAL
                               CL-PATTERNS::TASKS
                               SB-PCL::READER) (1)>
when called with arguments
  (NIL).
   [Condition of type SB-PCL::NO-APPLICABLE-METHOD-ERROR]

Maybe it's possible to have a more descriptive message that suggests the missing clock?

Error "There is no class named COMMON-LISP-USER::PBIND-PSTREAM."

Hi!
If I evaluate this code twice:

(play (pb :pulse
        :instrument :pulse
        :quant 1
        :db -12
        :octave 4
        :degree [0 3 7 10 12]))

I'm getting the following error:

There is no class named COMMON-LISP-USER::PBIND-PSTREAM.
   [Condition of type SB-PCL:CLASS-NOT-FOUND-ERROR]

Restarts:
 0: [ABORT] abort thread (#<THREAD "cl-patterns clock-loop" RUNNING {10051AD263}>)

Backtrace:
 0: (SB-PCL::FIND-CLASS-FROM-CELL PBIND-PSTREAM NIL T)
 1: ((:METHOD MAKE-INSTANCE (SYMBOL)) PBIND-PSTREAM :PLAY-QUANT (1) :END-QUANT (1) :END-CONDITION NIL :PARENT NIL :CLEANUP NIL :PSTREAM-COUNT 0 :METADATA #<HASH-TABLE :TEST EQL :COUNT 0 {10068028D3}> :PAI..
 2: ((:METHOD CL-PATTERNS:AS-PSTREAM :AROUND (T)) (CL-PATTERNS:PBIND :INSTRUMENT :PULSE :QUANT 1 :DB -12 :OCTAVE 4 :DEGREE (0 3 7 10 12))) [fast-method]
 3: ((:METHOD CL-PATTERNS:AS-PSTREAM :AROUND (CL-PATTERNS:PATTERN)) (CL-PATTERNS:PBIND :INSTRUMENT :PULSE :QUANT 1 :DB -12 :OCTAVE 4 :DEGREE (0 3 7 10 12))) [fast-method]
 4: ((:METHOD CL-PATTERNS:AS-PSTREAM (CL-PATTERNS:PDEF)) (CL-PATTERNS:PDEF :PULSE)) [fast-method]
 5: ((:METHOD CL-PATTERNS:AS-PSTREAM :AROUND (T)) (CL-PATTERNS:PDEF :PULSE)) [fast-method]
 6: ((:METHOD CL-PATTERNS:AS-PSTREAM :AROUND (CL-PATTERNS:PATTERN)) (CL-PATTERNS:PDEF :PULSE)) [fast-method]
 7: ((FLET SB-THREAD::WITH-RECURSIVE-LOCK-THUNK :IN CL-PATTERNS:CLOCK-PROCESS))
 8: ((FLET "WITHOUT-INTERRUPTS-BODY-11" :IN SB-THREAD::CALL-WITH-RECURSIVE-LOCK))
 9: (SB-THREAD::CALL-WITH-RECURSIVE-LOCK #<FUNCTION (FLET SB-THREAD::WITH-RECURSIVE-LOCK-THUNK :IN CL-PATTERNS:CLOCK-PROCESS) {7FB2197DE64B}> #<SB-THREAD:MUTEX "Anonymous recursive lock" owner: #<SB-THREA..
10: (CL-PATTERNS:CLOCK-PROCESS #<CL-PATTERNS::CLOCK :tempo 1 :beat 12.0> 1/10)
11: (CL-PATTERNS:CLOCK-LOOP #<CL-PATTERNS::CLOCK :tempo 1 :beat 12.0> :GRANULARITY NIL)
12: ((LAMBDA NIL :IN CL-PATTERNS:START-CLOCK-LOOP))
13: ((LAMBDA NIL :IN BORDEAUX-THREADS::BINDING-DEFAULT-SPECIALS))
14: ((FLET SB-UNIX::BODY :IN SB-THREAD::RUN))
15: ((FLET "WITHOUT-INTERRUPTS-BODY-11" :IN SB-THREAD::RUN))
16: ((FLET SB-UNIX::BODY :IN SB-THREAD::RUN))
17: ((FLET "WITHOUT-INTERRUPTS-BODY-4" :IN SB-THREAD::RUN))
18: (SB-THREAD::RUN)
19: ("foreign function: call_into_lisp")
 --more--

Failed to build for Quicklisp dist

Building with SBCL 2.0.9.5-442f54894 / ASDF 3.3.1 for quicklisp dist creation.

Commit id a49a715

cl-patterns/alsa-midi fails to build with the following error:

Unhandled ASDF/FIND-COMPONENT:MISSING-DEPENDENCY in thread #<SB-THREAD:THREAD "main thread" RUNNING {1001A50103}>: Component #:CL-ALSASEQ not found, required by #<SYSTEM "cl-patterns/alsa-midi">

cl-patterns/incudine fails to build with the following error:

Unhandled ASDF/FIND-COMPONENT:MISSING-DEPENDENCY in thread #<SB-THREAD:THREAD "main thread" RUNNING {1001A50103}>: Component #:INCUDINE not found, required by #<SYSTEM "cl-patterns/incudine">

Full log here

Forum Thread

Hello!
I have several questions which aren't big enough for their own issues, so I decided to put them here together.

How to stretch pbjorklund?

Docs says

... so it can be easily multiplied if you want it to be longer or shorter.

I came up with this:

(next-n (pbind :embed (pbjorklund 3 16) :dur (p* (pk :dur) 2)) 16)

Is there a simpler way do that?

How to use pmeta

For example there is a :stretch pmeta key, but I can't wrap my head around it.
Could you please give another example of pmeta usage?


Thank you!

stretch doesn't work

Hi!
Consider the following example:

Pdef(\stretch, Pbind(\midinote, 60, \stretch, 1/2)).play;

This works as expected and generates events twice per beat.

Similar example doesn't seem to be working:

(play
 (pb :stretch
   :instrument :default
   :midinote 60
   :stretch 1/2))

stretch value does nothing.

pnary doesn't work with prest

Hi! Here's a code example:

(play
 (pb :prest-test
   :instrument :default
   :dur 1/4
   :degree (p- (pseq (list (prest) 0 4 7)) 1)))

and error:

The value
  #<CL-PATTERNS:PREST {1004B4A5C3}>
is not of type
  NUMBER
when binding SB-KERNEL::X
   [Condition of type TYPE-ERROR]

Restarts:
 0: [SKIP-EVENT] Skip this event, preserving the task on the clock so it can be run again.
 1: [REMOVE-TASK] Remove this task from the clock.
 2: [ABORT] abort thread (#<THREAD "cl-patterns clock-loop" RUNNING {10094F00B3}>)

Backtrace:
 0: (SB-KERNEL:TWO-ARG-- #<CL-PATTERNS:PREST {1004B4A5C3}> 1) [external]
 1: (- #<CL-PATTERNS:PREST {1004B4A5C3}> 1)
 2: ((SB-PCL::EMF CL-PATTERNS:NEXT) #<unused argument> #<unused argument> #<CL-PATTERNS:PNARY-PSTREAM :NUMBER 0>)
 3: ((LABELS CL-PATTERNS::GET-VALUE-FROM-STACK :IN CL-PATTERNS:NEXT) #<CL-PATTERNS:PNARY-PSTREAM :NUMBER 0>)
 4: ((:METHOD CL-PATTERNS:NEXT :AROUND (CL-PATTERNS:PSTREAM)) #<CL-PATTERNS:PNARY-PSTREAM :NUMBER 0>) [fast-method]
 5: ((:METHOD CL-PATTERNS:NEXT (CL-PATTERNS:PBIND-PSTREAM)) #<CL-PATTERNS:PBIND-PSTREAM :INSTRUMENT :BASS :DUR 1/4 :DEGREE #<CL-PATTERNS:PNARY-PSTREAM :NUMBER 0>>) [fast-method]
 6: ((SB-PCL::EMF CL-PATTERNS:NEXT) #<unused argument> #<unused argument> #<CL-PATTERNS:PBIND-PSTREAM :INSTRUMENT :BASS :DUR 1/4 :DEGREE #<CL-PATTERNS:PNARY-PSTREAM :NUMBER 0>>)
 7: ((LABELS CL-PATTERNS::GET-VALUE-FROM-STACK :IN CL-PATTERNS:NEXT) #<CL-PATTERNS:PBIND-PSTREAM :INSTRUMENT :BASS :DUR 1/4 :DEGREE #<CL-PATTERNS:PNARY-PSTREAM :NUMBER 0>>)
 8: ((:METHOD CL-PATTERNS:NEXT :AROUND (CL-PATTERNS:PSTREAM)) #<CL-PATTERNS:PBIND-PSTREAM :INSTRUMENT :BASS :DUR 1/4 :DEGREE #<CL-PATTERNS:PNARY-PSTREAM :NUMBER 0>>) [fast-method]
 9: ((SB-PCL::EMF CL-PATTERNS:NEXT) #<unused argument> #<unused argument> #<CL-PATTERNS:PDEF-PSTREAM :PREST-TEST>)
10: ((LABELS CL-PATTERNS::GET-VALUE-FROM-STACK :IN CL-PATTERNS:NEXT) #<CL-PATTERNS:PDEF-PSTREAM :PREST-TEST>)
11: ((:METHOD CL-PATTERNS:NEXT :AROUND (CL-PATTERNS:PSTREAM)) #<CL-PATTERNS:PDEF-PSTREAM :PREST-TEST>) [fast-method]
12: ((FLET SB-THREAD::WITH-RECURSIVE-LOCK-THUNK :IN CL-PATTERNS:CLOCK-PROCESS))
13: ((FLET "WITHOUT-INTERRUPTS-BODY-11" :IN SB-THREAD::CALL-WITH-RECURSIVE-LOCK))
14: (SB-THREAD::CALL-WITH-RECURSIVE-LOCK #<FUNCTION (FLET SB-THREAD::WITH-RECURSIVE-LOCK-THUNK :IN CL-PATTERNS:CLOCK-PROCESS) {7F22D6B5E63B}> #<SB-THREAD:MUTEX "Anonymous recursive lock" owner: #<SB-THREA..
15: (CL-PATTERNS:CLOCK-PROCESS #<CL-PATTERNS::CLOCK :tempo 1 :beat 228.0> 1/10)
16: (CL-PATTERNS:CLOCK-LOOP #<CL-PATTERNS::CLOCK :tempo 1 :beat 228.0> :GRANULARITY NIL)
17: ((LAMBDA NIL :IN CL-PATTERNS:START-CLOCK-LOOP))
18: ((LAMBDA NIL :IN BORDEAUX-THREADS::BINDING-DEFAULT-SPECIALS))
19: ((FLET SB-UNIX::BODY :IN SB-THREAD::RUN))
 --more--

Add 12-tone matrix generator

This is a feature request. I'd like to generate 12-tone matrices. Something like:

(matrix (list (3 7 e 5 1 0 2 4 6 8 t 9)))

'((3 7 e 5 1 0 2 4 6 8 t 9)
  (e 3 7 1 9 8 t 0 2 4 6 5)
  (7 e 3 9 5 4 6 8 t 0 2 1)
  (1 5 9 3 e t 0 2 4 6 8 7)
  (5 9 1 7 3 2 4 6 8 t 0 e)
  (6 t 2 8 4 3 5 7 9 e 1 0)
  (4 8 0 6 2 1 3 5 7 9 e t)
  (2 6 t 4 0 e 1 3 5 7 9 8)
  (0 4 8 2 t 9 e 1 3 5 7 6)
  (t 2 6 0 8 7 9 e 1 3 5 4)
  (8 0 4 t 6 5 7 9 e 1 3 2)
  (9 1 5 e 7 6 8 t 0 2 4 3))

Then we could map each element to generate the music:

'((3 . "beat_00")
  (7 . "beat_01")
  (e . "beat_02")
  (5 . "beat_03")
  (1 . "beat_04")
  (0 . "beat_05")
  (2 . "beat_06")
  (4 . "beat_07")
  (6 . "beat_08")
  (8 . "beat_09")
  (t . "beat_10")
  (9 . "beat_11"))

WDYT?

Set default quant to 1

I noticed that I rarely ever use quant other then 1 or 4.
Here's what I do in order to change the default:

(defmethod initialize-instance :after ((p pbind) &key)
  (unless (slot-boundp p 'play-quant)
    (setf (quant p) 1)))

Putting it here just in case somebody else have similar needs.

Special Key 'Set' is not implemented yet. Is this still true?

From the special keys documentation it says:

set - NOTE: Not implemented yet. Only set the parameters of a synth; don’t start or stop any notes.

Is this still true. And if it is, what would it take to address this? This doesn't seem like it would be a particularly difficult problem to solve, and given I need this functionality I was wondering if this would be a simple thing to do?

Or is there some architectural issue here that I'm missing?

Getting the value of other keys in a pbind

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...

Sync MIDI and SuperCollider backends

Hi!
I'm trying to use both :alsa-midi and :supercollider backends at the same time and it seems I need to properly setup *latency* to make it play in sync.
If I set (setf *latency* 0) then midi stops playing. Any advice is appreciated!

Some systems failed to build for Quicklisp dist

Building with SBCL 2.3.11.165-7fa632585 / ASDF 3.3.5 for quicklisp dist creation.

Trying to build commit id 3ea0128

cl-patterns fails to build with the following error:

Unhandled UNDEFINED-FUNCTION in thread #<SB-THREAD:THREAD tid=1237930 "main thread" RUNNING {10017D8003}>: The function CL-PATTERNS::FIND-CLASS-SLOT is undefined.

cl-patterns/debug fails to build with the following error:

Unhandled UNDEFINED-FUNCTION in thread #<SB-THREAD:THREAD tid=1237922 "main thread" RUNNING {10017D8003}>: The function CL-PATTERNS::FIND-CLASS-SLOT is undefined.

cl-patterns/generic-cl fails to build with the following error:

Unhandled UNDEFINED-FUNCTION in thread #<SB-THREAD:THREAD tid=1237926 "main thread" RUNNING {10017D8003}>: The function CL-PATTERNS::FIND-CLASS-SLOT is undefined.

cl-patterns/midifile fails to build with the following error:

Unhandled UNDEFINED-FUNCTION in thread #<SB-THREAD:THREAD tid=1237914 "main thread" RUNNING {10017D8003}>: The function CL-PATTERNS::FIND-CLASS-SLOT is undefined.

cl-patterns/supercollider fails to build with the following error:

Unhandled UNDEFINED-FUNCTION in thread #<SB-THREAD:THREAD tid=1237918 "main thread" RUNNING {10017D8003}>: The function CL-PATTERNS::FIND-CLASS-SLOT is undefined.

cl-patterns/tests fails to build with the following error:

Unhandled UNDEFINED-FUNCTION in thread #<SB-THREAD:THREAD tid=1237910 "main thread" RUNNING {10017D8003}>: The function CL-PATTERNS::FIND-CLASS-SLOT is undefined.

Full log here

Using print representation of symbols

In patterns.lisp it generates the pstream class twice using mutility:concat:

(intern (concat name '-pstream) (symbol-package name))

(intern (concat name "-PSTREAM") (symbol-package name))

That is a problem because mutility:concat prints it argument using ~a, and for symbols that depends on the value of print-case. One of our customers who sets print-case to :downcase got an error because it was using pbind-PSTREAM instead PBIND-PSTREAM.

The proper fix is to have a function that generates the PSTREAM clas in a way that is independnet of global settings, e.g.:

(defun class-symbol-name-to-stream-class-name (class-symbol-name)
  (intern (concatenate 
           'string 
           (symbol-name class-symbol-name); make sure that symbol name not afected by *print-case*
           "-PSTREAM")
          (symbol-package class-symbol-name)))

And then use it in all cases when the class name is generated by code,. The places that I can see are the two lines above and:

(name-pstream (symbolicate name '-pstream))

(symbolicate (car superclasses) '-pstream))))

(let ((pstream-class (intern (concat (symbol-name pattern) "-PSTREAM") 'cl-patterns)))

Plazy fails with repeats=1

CL-PATTERNS> (next-upto-n (plazy (lambda () 'a)) 10)
(A A A A A A A A A A)
CL-PATTERNS> (next-upto-n (plazy (lambda () 'a) 1) 10)
NIL
CL-PATTERNS> (next-upto-n (plazy (lambda () 'a) 2) 10)
(A A)

I was expecting the second example to yield (A)...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.