Giter Club home page Giter Club logo

cl-collider's Introduction

cl-collider

A SuperCollider client for CommonLisp.
It is an experimental project, so changes to the API are possible.

Videos:

Dependencies:

Contrib:

If you have your own additional libraries, please report me. I will add here.

Usage:

  • package: sc, sc-user (use this package)
  • named-readtable: sc
(ql:quickload :cl-collider)

(in-package :sc-user)
(named-readtables:in-readtable :sc)

;; please check *sc-synth-program*, *sc-plugin-paths*, *sc-synthdefs-path*
;; if you have different path then set to
;;
;; (setf *sc-synth-program* "/path/to/scsynth")
;; (setf *sc-plugin-paths* (list "/path/to/plugin_path" "/path/to/extension_plugin_path"))
;; (setf *sc-synthdefs-path* "/path/to/synthdefs_path")

;; `*s*` defines the server for the entire session
;; functions may use it internally.

(setf *s* (make-external-server "localhost" :port 48800))
(server-boot *s*)

;; in Linux, maybe you need to call this function
#+linux
(jack-connect)

;; Hack music
(defvar *synth*)
(setf *synth* (play (sin-osc.ar [320 321] 0 .2)))

;; Stop music
(free *synth*)

;; Quit SuperCollider server
(server-quit *s*)

Create SynthDef

(defsynth sine-wave ((note 60))
  (let* ((freq (midicps note))
         (sig (sin-osc.ar [freq (+ freq 2)] 0 .2)))
     (out.ar 0 sig)))

(setf *synth* (synth 'sine-wave))
(ctrl *synth* :note 72)
(free *synth*)

Create Proxy

(proxy :sinesynth
  (sin-osc.ar [440 441] 0 .2))

(proxy :sinesynth
  (with-controls ((lfo-speed 4))
    (sin-osc.ar (* [440 441] (range (lf-pulse.ar [lfo-speed (+ lfo-speed .2)]) 0 1)) 0 .2))
  :fade 8.0)
   
(ctrl :sinesynth :lfo-speed 8)
(ctrl :sinesynth :gate 0)

Create Musical Sequence

(defsynth saw-synth ((note 60) (dur 4.0))
  (let* ((env (env-gen.kr (env [0 .2 0] [(* dur .2) (* dur .8)]) :act :free))
         (freq (midicps note))
    	 (sig (lpf.ar (saw.ar freq env) (* freq 2))))
	(out.ar 0 [sig sig])))

(defun make-melody (time n &optional (offset 0))
  (when (> n 0)
    (at time (synth 'saw-synth :note (+ offset (alexandria:random-elt '(62 65 69 72)))))
      (let ((next-time (+ time (alexandria:random-elt '(0 1 2 1.5)))))
        (callback next-time #'make-melody next-time (- n 1) offset))))

(make-melody (quant 4) 16)
(make-melody (+ 4 (quant 4)) 16 12)

Non-real-time Rendering to File

(setf *synth-definition-mode* :load)

;; Redefine the saw-synth ugen
;; The SynthDef file will be written to the *sc-synthdefs-path*
(defsynth saw-synth ((note 60) (dur 4.0))
  (let* ((env (env-gen.kr (env [0 .2 0] [(* dur .2) (* dur .8)]) :act :free))
         (freq (midicps note))
         (sig (lpf.ar (saw.ar freq env) (* freq 2))))
    (out.ar 0 [sig sig])))

;; We can use a similar function to make a melody, but we don't need to schedule the callbacks
(defun make-melody (time n &optional (offset 0))
  (when (> n 0)
    (at time (synth 'saw-synth :note (+ offset (alexandria:random-elt '(62 65 69 72)))))
      (let ((next-time (+ time (alexandria:random-elt '(0 1 2 1.5)))))
        (make-melody next-time (- n 1) offset))))
	
;; Render audio file
(with-rendering ("~/Desktop/foo.aiff" :pad 60)
  (make-melody 0.0d0 32)
  (make-melody 8.0d0 32 12)
  (make-melody 16.0d0 32 24))

Record Audio Output

;;; write a single channel to disk

;; we can write to buffer number out_buf_num by reading in from the 0 bus
(defsynth disk_writer ((out_buf_num 99))
    (disk-out.ar out_buf_num (in.ar 0)))

(setf mybuffer (buffer-alloc (expt 2 17))) 
mybuffer

;; start a disk_writer synth
(setf writer_0 (synth 'disk_writer))

;; make it output to buffer you allocated
(ctrl writer_0 :out_buf_num (bufnum mybuffer))

;; continuously write the buffer contents to a file
(buffer-write mybuffer "/tmp/foo.aiff" :leave-open-p t)

;; now play whatever sounds you like

;; e.g.
(proxy :blah (sin-osc.ar 440))
(free :blah)


;; then when you are done

;; stop the disk_writer synth
(free writer_0)

;; close and free the buffer
(buffer-close mybuffer)
(buffer-free mybuffer)


;; then you can play what you recorded with a utility like mpv:
;;     mpv /tmp/foo.aiff

cl-collider's People

Contributors

byulparan avatar defaultxr avatar diasbruno avatar einsiedlerspiel avatar jgarte avatar justin2004 avatar mlang avatar ntrocado avatar paullucas avatar vaclavsynacek avatar vrx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cl-collider's Issues

Export PATH?

The symbol path, for the accessor to the path of a file loaded in a buffer, isn't exported. Is there a reason for this?

Env.asSignal equivalent

Is there a way to convert an env into a list (or array...) that can be sent to a buffer for waveshaping or wavetable lookup synthesis?

"There is no thread support in this instance. [Condition of type BORDEAUX-THREADS::BORDEAUX-MP-CONDITION]"

Hi!

I've just installed everything and I'm trying to boot the server, but I get this error:
There is no thread support in this instance.
[Condition of type BORDEAUX-THREADS::BORDEAUX-MP-CONDITION]

Restarts:
0: [RETRY] Retry SLIME interactive evaluation request.
1: [*ABORT] Return to SLIME's top level.
2: [REMOVE-FD-HANDLER] Remove #<SB-IMPL::HANDLER INPUT on descriptor 8: #<CLOSURE (LABELS SWANK/SBCL::RUN :IN SWANK/BACKEND:ADD-FD-HANDLER) {15C3490D}>>
3: [ABORT] Exit debugger, returning to top level.

Backtrace:
0: (BORDEAUX-THREADS::%MAKE-THREAD # #)
1: (SCHEDULER:SCHED-RUN #<SCHEDULER:SCHEDULER {1404B051}>)
2: ((:METHOD SERVER-BOOT (RT-SERVER)) #) [fast-method]
3: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SERVER-BOOT S) #)
4: (EVAL (SERVER-BOOT S))
There is no thread support in this instance.
[Condition of type BORDEAUX-THREADS::BORDEAUX-MP-CONDITION]

Restarts:
0: [RETRY] Retry SLIME interactive evaluation request.
1: [*ABORT] Return to SLIME's top level.
2: [REMOVE-FD-HANDLER] Remove #<SB-IMPL::HANDLER INPUT on descriptor 8: #<CLOSURE (LABELS SWANK/SBCL::RUN :IN SWANK/BACKEND:ADD-FD-HANDLER) {15C3490D}>>
3: [ABORT] Exit debugger, returning to top level.

Backtrace:
0: (BORDEAUX-THREADS::%MAKE-THREAD # #)
1: (SCHEDULER:SCHED-RUN #<SCHEDULER:SCHEDULER {1404B051}>)
2: ((:METHOD SERVER-BOOT (RT-SERVER)) #) [fast-method]
3: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SERVER-BOOT S) #)
4: (EVAL (SERVER-BOOT S))
5: (SWANK::EVAL-REGION "(server-boot s)")
Locals:
SB-DEBUG::ARG-0 = "(server-boot s)"
6: ((LAMBDA NIL :IN SWANK:INTERACTIVE-EVAL-REGION))
7: (SWANK::CALL-WITH-RETRY-RESTART "Retry SLIME interactive evaluation request." #<CLOSURE (LAMBDA NIL :IN SWANK:INTERACTIVE-EVAL-REGION) {149A227D}>)
8: (SWANK::CALL-WITH-BUFFER-SYNTAX NIL #<CLOSURE (LAMBDA NIL :IN SWANK:INTERACTIVE-EVAL-REGION) {149A226D}>)
9: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK:INTERACTIVE-EVAL-REGION "(server-boot s)") #)
10: (EVAL (SWANK:INTERACTIVE-EVAL-REGION "(server-boot s)"))
11: (SWANK:EVAL-FOR-EMACS (SWANK:INTERACTIVE-EVAL-REGION "(server-boot s)") ":sc" 12)
12: (SWANK::PROCESS-REQUESTS T)
13: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
14: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
15: (SWANK/SBCL::CALL-WITH-BREAK-HOOK # #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {1499FDB5}>)
16: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGER-HOOK :IN "/Users/ze/slime/swank/sbcl.lisp") # #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {1499FDB5}>)
17: (SWANK::HANDLE-REQUESTS #<SWANK::SINGLETHREADED-CONNECTION {15C34881}> T)
18: ((LABELS SWANK/SBCL::RUN :IN SWANK/BACKEND:ADD-FD-HANDLER) 8)
19: (SB-IMPL::SUB-SUB-SERVE-EVENT NIL NIL)
20: (SB-IMPL::SUB-SERVE-EVENT NIL NIL NIL)
21: (SB-SYS:WAIT-UNTIL-FD-USABLE 0 :INPUT NIL T)
22: (SB-IMPL::REFILL-INPUT-BUFFER #<SB-SYS:FD-STREAM for "standard input" {11AE4D99}>)
23: (SB-IMPL::INPUT-CHAR/UTF-8 #<SB-SYS:FD-STREAM for "standard input" {11AE4D99}> NIL #:EOF-OBJECT)
24: ((LAMBDA (&REST REST) :IN SB-IMPL::GET-EXTERNAL-FORMAT) #<SB-SYS:FD-STREAM for "standard input" {11AE4D99}> NIL #:EOF-OBJECT)
25: (READ-CHAR #<SB-SYS:FD-STREAM for "standard input" {11AE4D99}> NIL #:EOF-OBJECT #)
26: (READ-CHAR #<SYNONYM-STREAM :SYMBOL SB-SYS:STDIN {100EA651}> NIL #:EOF-OBJECT #)
27: (SB-IMPL::%READ-PRESERVING-WHITESPACE #<SYNONYM-STREAM :SYMBOL SB-SYS:STDIN {100EA651}> NIL (NIL) T)
28: (SB-IMPL::%READ-PRESERVING-WHITESPACE #<SYNONYM-STREAM :SYMBOL SB-SYS:STDIN {100EA651}> NIL (NIL) NIL)
29: (READ #<SYNONYM-STREAM :SYMBOL SB-SYS:STDIN {100EA651}> NIL (NIL) NIL)
30: (SB-IMPL::REPL-READ-FORM-FUN #<SYNONYM-STREAM :SYMBOL SB-SYS:STDIN {100EA651}> #)
31: (SB-IMPL::REPL-FUN NIL)
32: ((LAMBDA NIL :IN SB-IMPL::TOPLEVEL-REPL))
33: (SB-IMPL::%WITH-REBOUND-IO-SYNTAX #<CLOSURE (LAMBDA NIL :IN SB-IMPL::TOPLEVEL-REPL) {145F6945}>)
34: (SB-IMPL::TOPLEVEL-REPL NIL)
35: (SB-IMPL::TOPLEVEL-INIT)
36: ((FLET #:WITHOUT-INTERRUPTS-BODY-42 :IN SB-EXT:SAVE-LISP-AND-DIE))
37: ((LABELS SB-IMPL::RESTART-LISP :IN SB-EXT:SAVE-LISP-AND-DIE))

any tips? (running everything with SBCL 1.1.6.0-3c5581a on OSX 10.9.5)

Thank you!

Example on how to get left and right channel from multiout-ugen

I have a stereo signal and would like to pass left and right into balance2.ar but can't figure out how to separate the channels. In sclang it's an array index sig[0] and sig[1].

Sorry if this is the wrong venue for such questions, happy to post or go elsewhere. Thanks, really amazing lib.

`buffer-get-to-list` error: Invalid range requested

Hi!
Consider the following code:

(defconstant +sample-rate+ (parse-integer (uiop:run-program "jack_samplerate" :output :string))) ; 48000
(defvar *b* (buffer-alloc (* 1 +sample-rate+)))
(buffer-fill *b* :sine (list 1))
(buffer-write *b* "/tmp/foo.wav") ; works fine, Audacity shows nice sine wave
(buffer-get-to-list *b*)

buffer-get-to-list gives me the following error:

Invalid range requested (START (48000) must be greater than END (48000)).
   [Condition of type SIMPLE-ERROR]

Restarts:
 0: [CONTINUE] Retry assertion with new values for CL-COLLIDER::START, CL-COLLIDER::END.
 1: [RETRY] Retry SLY interactive evaluation request.
 2: [*ABORT] Return to SLY's top level.
 3: [ABORT] abort thread (#<THREAD "slynk-worker" RUNNING {1006FCF503}>)

Backtrace:
 0: (SB-KERNEL:ASSERT-ERROR (> CL-COLLIDER::END CL-COLLIDER::START) 2 CL-COLLIDER::END 48000 CL-COLLIDER::START 48000 (CL-COLLIDER::START CL-COLLIDER::END) "Invalid range requested (START (~a) must be gre..
 1: (BUFFER-GETN #<CL-COLLIDER::BUFFER :server #<CL-COLLIDER::EXTERNAL-SERVER cl-collider-0.0.0.0:4444> :bufnum 0 :frames 48000 :channels 1 :samplerate 48000.0 :path NIL> 48000 48000 NIL)
 2: (BUFFER-GET-TO-LIST #<CL-COLLIDER::BUFFER :server #<CL-COLLIDER::EXTERNAL-SERVER cl-collider-0.0.0.0:4444> :bufnum 0 :frames 48000 :channels 1 :samplerate 48000.0 :path NIL> :START 0 :END NIL)
 3: (SB-INT:SIMPLE-EVAL-IN-LEXENV (BUFFER-GET-TO-LIST *B*) #<NULL-LEXENV>)
 4: (EVAL (BUFFER-GET-TO-LIST *B*))
 5: ((LAMBDA NIL :IN SLYNK:INTERACTIVE-EVAL))
 --more--

@defaultxr it seems like a +1 error?

Question about missing macros

Hi, I have been wondering about a couple of macros definitions I saw on your videos missing on cl-collider and I was wondering if you can provide the source or an idea on how implement it. Thanks in advance, this project is awesome and help me get into lisp.

  • tr - not really sure what this does
  • with-grid - this one seems to be used to define list and reuse them on a proxy
  • scale/chord - for this one I think I can use overtone or common music as a source to build my own

Problems with recent commits

Hi,

I'm getting some errors after pulling the latest commit (ea6ba04):

  • When booting the server as normal with server-boot, I get an error saying SC-REPLY-THREAD is undefined.
SC> (setf *sc-plugin-paths* (list
                         ;; "/usr/share/SuperCollider/Extensions/"
                         "/usr/lib/SuperCollider/plugins/"
                         "/usr/share/SuperCollider/Extensions/"))
(setf *sc-synth-program* "/usr/bin/scsynth")
(setf *s* (make-external-server "localhost" :port 4444))
#<EXTERNAL-SERVER localhost-127.0.0.1:4444>
SC> (server-boot *s*)

The error:

The function CL-COLLIDER::SC-REPLY-THREAD is undefined.
   [Condition of type UNDEFINED-FUNCTION]

Restarts:
 0: [CONTINUE] Retry calling SC-REPLY-THREAD.
 1: [USE-VALUE] Call specified function.
 2: [RETURN-VALUE] Return specified values.
 3: [RETURN-NOTHING] Return zero values.
 4: [RETRY] Retry SLIME REPL evaluation request.
 5: [*ABORT] Return to SLIME's top level.
 --more--

Backtrace:
  0: ("undefined function" #<EXTERNAL-SERVER localhost-127.0.0.1:4444>)
  1: (SYNC #<EXTERNAL-SERVER localhost-127.0.0.1:4444>)
  2: (MAKE-GROUP :ID 1 :SERVER NIL :POS :HEAD :TO 0)
  3: (GROUP-FREE-ALL #<EXTERNAL-SERVER localhost-127.0.0.1:4444>)
  4: ((:METHOD SERVER-BOOT (RT-SERVER)) #<EXTERNAL-SERVER localhost-127.0.0.1:4444>) [fast-method]
  5: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SERVER-BOOT *S*) #<NULL-LEXENV>)
  6: (EVAL (SERVER-BOOT *S*))
  • I've also recently been getting errors more often about the server already having too many clients, which I think is happening because quitting Lisp doesn't terminate the SuperCollider server. I think this started happening after the commits made on July 18.

Running SBCL 1.4.8 on Arch Linux, if that matters.

Windows paths

Even though I have SuperCollider installed in the default directories, quickloading cl-collider was failing on my system, because the paths for plugins and synthdefs are set relative to the home directory ("~/"), and assuming that this directory is the same as %userprofile%, which wasn't the case.

Due to the complications (to say the leastโ€ฆ) of configuring "home" in Windows, because often the os, emacs, sbcl and quicklisp don't agree on its location, do you think it's better to use the strategy below (with uiop:get-folder-path :local-appdata)? It should spare most Windows users from having to manually edit server.lisp before using the library.

   server.lisp
@@ -16,12 +16,14 @@
   #+linux (list "/usr/local/lib/SuperCollider/plugins/"
 		"/usr/local/share/SuperCollider/Extensions/")
   #+windows (list "c:/Program Files/SuperCollider-3.9.3/plugins/"
-		  "~/AppData/Local/SuperCollider/Extensions/"))
+		  (full-pathname (merge-pathnames #P"SuperCollider/Extensions/"
+						  (uiop:get-folder-path :local-appdata)))))
 
 (defvar *sc-synthdefs-path*
   #+darwin (full-pathname "~/Library/Application Support/SuperCollider/synthdefs")
   #+linux (full-pathname "~/.local/share/SuperCollider/synthdefs/")
-  #+windows (full-pathname "~/AppData/Local/SuperCollider/synthdefs/")
+  #+windows (full-pathname (merge-pathnames #P"SuperCollider/synthdefs/"
+					    (uiop:get-folder-path :local-appdata)))
   "The directory where the scsyndef files for synthdefs are saved.")

Let me know if a PR is welcomed.

Mapping a control bus to a synth's args

I'm working through the examples in the Supercollider Book, using cl.
I'm having trouble translating how to route a control bus in real time.
The example is:

~kbus3 = Bus.control; // a control bus
~kbus4 = Bus.control; // a control bus
{Out.kr (~kbus3, SinOsc.kr(3).range(340, 540))}.play;
{Out.kr (~kbus4, LFPulse.kr(6).range(240, 640))}.play;
SynthDef("Switch", {arg freq = 440; Out.ar(0, SinOsc.ar(freq, 0, 0.3)) }).add
x = Synth("Switch"); //default
x.map(\freq, ~kbus3)
x.map(\freq, ~kbus4)

In cl I'm doing:

(defparameter *kbus3* (bus-control))
(defparameter *kbus4* (bus-control))
(play (out.kr *kbus3* (range (sin-osc.ar 3) 340 540)))
(play (out.kr *kbus4* (range (lf-pulse.kr 6) 240 640)))
(defsynth switch (&key (freq 440))
  (out.ar 0 (sin-osc.ar freq 0 0.3)))
(defparameter *x* (switch))

But what to do with the map part?

Quicklisp

I think it would be convenient if cl-collider were available on Quicklisp. It would be easier for users to install it, and it would let other projects depend on this library.

I think there are 3 main issues that would prevent cl-collider from being accepted into Quicklisp right now:

  • cl-collider uses its own osc package. Quicklisp also has an osc library available, and since they both share the same name, it may cause confusion or possible conflicts if users want to use the one on quicklisp. I think the best solution for this would be to rename cl-collider's osc package to sc-osc instead.

  • Quicklisp will not accept libraries that print warnings during compilation. Right now cl-collider prints some warnings. You can see these by running (ql:quickload :sc :verbose t) to load cl-collider. Here are the warnings I see on my system when I run that:

CL-USER> (ql:quickload :sc :verbose t)
To load "sc":
  Load 1 ASDF system:
    sc
; Loading "sc"
..
WARNING: redefining OSC::CAT in DEFUN
WARNING: redefining OSC::ENCODE-TYPETAGS in DEFUN
WARNING: redefining OSC:ENCODE-MESSAGE in DEFUN
WARNING: Implicitly creating new generic function OSC::ENCODE-ADDRESS-EXT.
WARNING: redefining OSC::ENCODE-DATA in DEFUN
WARNING: redefining OSC::DECODE-TAGED-DATA in DEFUN
WARNING: redefining OSC::ENCODE-INT64 in DEFUN
WARNING: redefining OSC::DECODE-UINT64 in DEFUN
WARNING: redefining OSC::ENCODE-BLOB in DEFUN
WARNING: redefining OSC::ENCODE-TIMETAG in DEFUN
WARNING: redefining OSC::DECODE-TIMETAG in DEFUN
WARNING: Implicitly creating new generic function FLEXI-STREAMS::READ-SEQUENCE*.
WARNING: Implicitly creating new generic function FLEXI-STREAMS::CHECK-IF-OPEN.
WARNING:
   Implicitly creating new generic function FLEXI-STREAMS::TRANSFORM-OCTET.
WARNING:
   Implicitly creating new generic function
   FLEXI-STREAMS:MAKE-IN-MEMORY-INPUT-STREAM.
WARNING:
   Implicitly creating new generic function
   FLEXI-STREAMS:GET-OUTPUT-STREAM-SEQUENCE.
WARNING:
   Implicitly creating new generic function
   FLEXI-STREAMS:OUTPUT-STREAM-SEQUENCE-LENGTH.
STYLE-WARNING:
   Generic function CLOSE clobbers an earlier FTYPE proclamation
   (FUNCTION (STREAM &KEY (:ABORT T)) (VALUES (MEMBER T) &OPTIONAL)) for the
   same name with (FUNCTION (T &KEY (:ABORT T)) *).
STYLE-WARNING:
   Generic function OPEN-STREAM-P clobbers an earlier FTYPE proclamation
   (FUNCTION (STREAM) (VALUES BOOLEAN &OPTIONAL)) for the same name with
   (FUNCTION (T) *).
WARNING: Implicitly creating new generic function FLEXI-STREAMS::READ-BYTE*.
WARNING: Implicitly creating new generic function FLEXI-STREAMS:UNREAD-BYTE.
WARNING: Implicitly creating new generic function FLEXI-STREAMS:PEEK-BYTE.
WARNING:
   Implicitly creating new generic function FLEXI-STREAMS::RESET-INPUT-STATE.
WARNING:
   Implicitly creating new generic function FLEXI-STREAMS::RESET-OUTPUT-STATE.
WARNING: Implicitly creating new generic function SC::CAT.
WARNING: Implicitly creating new generic function SC:SERVER-BOOT.
WARNING: Implicitly creating new generic function SC:SERVER-QUIT.
WARNING: Implicitly creating new generic function SC:BUFFER-FREE.
WARNING: Implicitly creating new generic function SC::SOURCE.
WARNING: Implicitly creating new generic function SC::NUM-OUTPUTS.
WARNING: Implicitly creating new generic function SC::OUTPUT-INDEX.
WARNING: Implicitly creating new generic function SC::COLLECT-CONSTANTS.
WARNING: Implicitly creating new generic function SC::OPTIMIZE-GRAPH.
WARNING:
   Implicitly creating new generic function SC::PERFORM-DEAD-CODE-ELIMINATION.
WARNING: Implicitly creating new generic function SC::MAKE-AVAILABLE.
WARNING: Implicitly creating new generic function SC::INPUT-SPEC.
WARNING: Implicitly creating new generic function SC::WRITE-DEF-UGEN-VERSION1.
WARNING: Implicitly creating new generic function SC::WRITE-DEF-UGEN-VERSION2.
WARNING: Implicitly creating new generic function SC::REPLACE-UGEN.
WARNING: Implicitly creating new generic function SC::CHECK-INPUTS.
WARNING: Implicitly creating new generic function SC::BUILD-SYNTHDEF.
WARNING: Implicitly creating new generic function SC::LOAD-SYNTHDEF.
WARNING: Implicitly creating new generic function SC::RECV-SYNTHDEF.
WARNING: redefining SC::OPTIMIZE-GRAPH in DEFGENERIC
WARNING: Implicitly creating new generic function SC::_RANGE.
WARNING: Implicitly creating new generic function SC::_EXP-RANGE.
WARNING: Implicitly creating new generic function SC::DUPLICATE.
WARNING: Implicitly creating new generic function SC:PVCALC.
WARNING: Implicitly creating new generic function SC:PVCALC2.
WARNING: Implicitly creating new generic function SC:PV-COLLECT.
WARNING: Implicitly creating new generic function SC::PV-COLLECT2.
WARNING: Implicitly creating new generic function SC:ENV-SHAPE-NUMBER.
WARNING: Implicitly creating new generic function SC::MINVAL.
WARNING: Implicitly creating new generic function SC:FOLD.
WARNING: Implicitly creating new generic function SC:WRAP.
WARNING: Implicitly creating new generic function SC:CLIP2.

(:SC)

Most of these warnings look like very minor issues that can be easily fixed without having to change much functionality of the library.

  • cl-collider depends on scheduler. So scheduler would need to be added to quicklisp as well. I checked and it doesn't look like any warnings are printed for that library, so it should be easy to have it added to quicklisp.

If it's alright with you, I'd like to make these changes to cl-collider so it can be accepted on quicklisp. If that is okay, let me know and I'll submit a pull request here once I'm done.

Additionally, I would be willing to submit the request for scheduler and cl-collider to be included in quicklisp. Let me know if that is alright with you.

Thank you for making this library.

P.S. I'm also working on a tutorial for using cl-collider. It's not done yet but I'm going to keep working on it.

full-pathname pb when directory do not exist

In server.lisp


(defvar *sc-synthdefs-path*
  #+darwin (full-pathname "~/Library/Application Support/SuperCollider/synthdefs")
  #+linux (full-pathname "~/.local/share/SuperCollider/synthdefs/")
  #+windows (full-pathname "~/AppData/Local/SuperCollider/synthdefs/")
  "The directory where the scsyndef files for synthdefs are saved.")

can actually yield some problems as full-pathname will produce an error if the directory does not exist.
it is moreover a bit tricky to spot, so probably at least an informative warning should be printed.
one solution of course is to:
mkdir -p ~/.local/share/SuperCollider/synthdefs/

ecl, pileup problem

CL-COLLIDER> (setf s (make-external-server "localhost" :port 48800))

Condition of type: UNBOUND-VARIABLE
The variable PILEUP::%SIZE is unbound.

"with-rendering" not working?

I get an error if the output file doesn't exist yet:

; Debugger entered on #<TYPE-ERROR expected-type:
; (OR (VECTOR CHARACTER) (VECTOR NIL) BASE-STRING PATHNAME FILE-STREAM)
;
; datum: NIL>

If I create a blank file then I get:

There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION CL-COLLIDER::SC-REPLY-THREAD (1)>
when called with arguments
(#<CL-COLLIDER::NRT-SERVER {10064E0123}>).

There's also a style warning:

; caught STYLE-WARNING:
; The function has an odd number of arguments in the keyword portion.

This is about this line. I think it's just missing the :id keyword.

Steps to reproduce: follow the instructions on README.
System: Win10, SBCL, Sly, Supercollider 3.9.3

AmpCompA

(defugen (amp-comp-a "AmpCombA")
should be
(defugen (amp-comp-a "AmpCompA")

* exception in GraphDef_Load: UGen 'Control' not installed.

Facing this issue with the newest SuperCollider engine version 3.11.2.
Before system upgrade everything was working smoothly.

An attempt to create any synthdef with cl-collider fails with the exception:

  • exception in GraphDef_Recv: UGen 'Control' not installed.

Opening an issue to cl-collider, as this is the only environment I can reproduce the issue with. SuperCollider IDE and Tidal Cycles work fine.

Here how I initiate the connection:

(ql:quickload :cl-collider)                                                                                             
(ql:quickload :sc-extensions)                                                                                           
(in-package :sc-user)                                                                                                   
(use-package :sc-extensions)                                                                                            
(named-readtables:in-readtable :sc)                                                                                     
(setf *s* (make-external-server "localhost" :port 57880))                                                               
(server-boot *s*)                                                                                                       
(jack-connect) 

The terminal output is:

This is SBCL 2.0.1-5.fc34, an implementation of ANSI Common Lisp.                                                       
More information about SBCL is available at <http://www.sbcl.org/>.                                                     
                                                                                                                        
SBCL is free software, provided as is, with absolutely no warranty.                                                     
It is mostly in the public domain; some portions are provided under                                                     
BSD-style licenses.  See the CREDITS and COPYING files in the                                                           
distribution for more information.                                                                                      
(ql:quickload :cl-collider)                                                                                             
(ql:quickload :sc-extensions)                                                                                           
;(ql:quickload :cl-patterns/supercollider)                                                                              
;(cl-patterns:start-backend :supercollider)  ;; start supercollider and jackd via patterns library                      
(in-package :sc-user)                                                                                                   
To load "cl-collider":                                                                                                  
  Load 1 ASDF system:                                                                                                   
    cl-collider                                                                                                         
; Loading "cl-collider"                                                                                                 
(use-package :sc-extensions)                                                                                            
(named-readtables:in-readtable :sc)                                                                                     
;                                                                                                                       
(setf *s* (make-external-server "localhost" :port 57880))                                                               
(server-boot *s*)                                                                                                       
(jack-connect)                                                                                                          
......                                                                                                                  
(:CL-COLLIDER)                                                                                                                  
* To load "sc-extensions":                                                                                              
  Load 1 ASDF system:                                                                                                   
    sc-extensions                                                                                                       
; Loading "sc-extensions"                                                                                               
                                                                                                                        
(:SC-EXTENSIONS)                                                                                                        
* #<PACKAGE "SC-USER">                                                                                                  
* T                                                                                                                                                                                           
* #<NAMED-READTABLE :SC {10051CF9B3}>                                                                                                                                                         
* #<CL-COLLIDER::EXTERNAL-SERVER localhost-127.0.0.1:57880>                                                                                                                                   
* JackDriver: client name is 'SuperCollider'                                                                                                                                                  
SC_AudioDriver: sample rate = 48000.000000, driver's block size = 1024                                                                                                                        
SuperCollider 3 server ready.                                                                                                                                                                 
#<CL-COLLIDER::EXTERNAL-SERVER localhost-127.0.0.1:57880>                                                                                                                                     
* JackDriver: max output latency 21.3 ms                                                                                                                                                      
NIL                                                                                                                                                                                           
* Zeroconf: registered service 'SuperCollider'     

Then an attempt to define a synthdef:

;; Simple synth                                                                                                         
(defsynth :my-synth ((freq 440) (out 0) (gate 1) (pan 0) (amp .5))                                                      
   (let* ((env (env-gen.kr (adsr .001 .1 .4 .6) :gate gate :act :free))                                                 
          (sig (* (sin-osc.ar freq) 0.3))                                                                               
          (sig (+ sig (* (sin-osc.ar (* freq 2)) 0.2)))                                                                 
          (sig (+ sig (* (sin-osc.ar (* freq 3)) 0.1)))                                                                 
          (sig (+ sig (* (pulse.ar (* freq 1/2)) 0.03)))                                                                
          )                                                                                                             
     (out.ar out (pan2.ar sig pan (* amp env))) ))     

Results in

;; Simple synth                                                                                                         
(defsynth :my-synth ((freq 440) (out 0) (gate 1) (pan 0) (amp .5))                                                      
   (let* ((env (env-gen.kr (adsr .001 .1 .4 .6) :gate gate :act :free))                                                 
          (sig (* (sin-osc.ar freq) 0.3))                                                                                                                                                     
          (sig (+ sig (* (sin-osc.ar (* freq 2)) 0.2)))                                                                 
          (sig (+ sig (* (sin-osc.ar (* freq 3)) 0.1)))                                                                 
          (sig (+ sig (* (pulse.ar (* freq 1/2)) 0.03)))                                                                
          )                                                                                                             
     (out.ar out (pan2.ar sig pan (* amp env))) ))                                                                      
exception in GraphDef_Recv: UGen 'Control' not installed.                                                               
#<CL-COLLIDER::SYNTHDEF :name "my-synth">    

The synthdef is not available then.

* (synth :my-synth)                                                                                                     
#<CL-COLLIDER::NODE :server #<CL-COLLIDER::EXTERNAL-SERVER localhost-127.0.0.1:57880> :id 1000 :name "my-synth">        
* *** ERROR: SynthDef my-synth not found                                                                                
FAILURE IN SERVER /s_new SynthDef not found   

Tried re-installing SuperCollider engine and cl-collider (deleting whole quicklisp folder), but this didn't help.
The SuperCollider is installed as a system package of Fedora 34.

Found a few mentions of the similar issue with SC in the past, but it doesn't seem to apply, I removed all previously installed SC plugins. Also the fact that SC works fine outside of cl-collider scope is strange...

Thanks!

P.S. To my surprise I faced the same issue with Overtone 0.10.6, but not with the older version (0.10.3).

cl-collider 3.9.0-rc1 segfaults when play macro is used

Hello,

scsynth3.9 segfaults when trying to play a simple synth
(play (sin-osc.ar 440))
scsynth[13946]: segfault at ffffffffffffffff ip 00007fd8cfa50854 sp 00007fd8d4d0ab48 error 5 in IOUGens.so[7fd8cfa4e000+5000]

but

(defsynth sine-wave (&key (note 60))
(let* ((freq (midicps note))
(sig (sin-osc.ar [freq (+ freq 2)] 0 .2)))
(out.ar 0 sig)))
(defparameter synth (sine-wave))

works fine

at macro no longer working

The at macro does not appear to be working after the OSC changes in commit 8a43727. This is the error and backtrace I get when I run (at (1+ (now)) (synth 'default)):

The value
  9
is not of type
  SEQUENCE
   [Condition of type TYPE-ERROR]

Restarts:
 0: [RETRY] Retry SLIME REPL evaluation request.
 1: [*ABORT] Return to SLIME's top level.
 2: [ABORT] abort thread (#<THREAD "new-repl-thread" RUNNING {100607FA73}>)

Backtrace:
  0: (OSC::ENCODE-ADDRESS 9)
  1: (OSC:ENCODE-MESSAGE 9 "default" 1001 0 1)
  2: (OSC::ENCODE-BUNDLE-ELT (9 "default" 1001 0 1))
  3: (SC-OSC::ENCODE-BUNDLE ((9 "default" 1001 0 1)) 1.520403573342347d9)
  4: (SC-OSC:SEND-BUNDLE 1.520403573342347d9 #<SC-OSC:OSC-DEVICE {10054A9653}> (9 "default" 1001 0 1))
  5: ((LAMBDA ()))
  6: (SB-INT:SIMPLE-EVAL-IN-LEXENV (AT (1+ (NOW)) (SYNTH (QUOTE DEFAULT))) #<NULL-LEXENV>)
  7: (EVAL (AT (1+ (NOW)) (SYNTH (QUOTE DEFAULT))))

When I revert back to commit 2c8babe it appears to work fine, so it looks like it was the most recent commit that caused this.

I tried to fix it myself but the OSC code is still a bit beyond me.

Is this client complete?

Hello,
I badly want to program with supercollider, but want to do it with lisp. Is this client complete? Is it missing any big noticeable features to stop it from allowing supercollider to be used to its fullest?

Thank you very much for your time.

unable to boot server

Hi!

Just starting out with the tutorials. This issue comes up when attempting (server-boot *s*).
Running on SBCL 1.4.16 and SLIME 2.23.

Looking forward to do some interesting livecoding! :)

Subprocess with command "\"/usr/local/bin/scsynth\" -u 40555 -c 16384 -a 1024 -i 2 -o 2 -z 64 -S 0 -b 1024 -n 1024 -d 1024 -m 8192 -w 64 -r 64 -D 1 -R 1 -l 1 -V 0 -U \"/usr/local/lib/SuperCollider/plugins/:/usr/local/share/SuperCollider/Extensions/\" "
 exited with error code 1
   [Condition of type UIOP/RUN-PROGRAM:SUBPROCESS-ERROR]

Restarts:
 0: [CONTINUE] IGNORE-ERROR-STATUS
 1: [ABORT] abort thread (#<THREAD "scsynth" RUNNING {1005568853}>)

Backtrace:
  0: (UIOP/RUN-PROGRAM::%CHECK-RESULT 1 :COMMAND "\"/usr/local/bin/scsynth\" -u 40555 -c 16384 -a 1024 -i 2 -o 2 -z 64 -S 0 -b 1024 -n 1024 -d 1024 -m 8192 -w 64 -r 64 -D 1 -R 1 -l 1 -V 0 -U \"/usr/local/l..
  1: (UIOP/RUN-PROGRAM::%USE-SYSTEM "\"/usr/local/bin/scsynth\" -u 40555 -c 16384 -a 1024 -i 2 -o 2 -z 64 -S 0 -b 1024 -n 1024 -d 1024 -m 8192 -w 64 -r 64 -D 1 -R 1 -l 1 -V 0 -U \"/usr/local/lib/SuperColli..
  2: ((LAMBDA NIL :IN BORDEAUX-THREADS::BINDING-DEFAULT-SPECIALS))
  3: ((FLET SB-UNIX::BODY :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
  4: ((FLET "WITHOUT-INTERRUPTS-BODY-4" :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
  5: ((FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
  6: ((FLET "WITHOUT-INTERRUPTS-BODY-1" :IN SB-THREAD::CALL-WITH-MUTEX))
  7: (SB-THREAD::CALL-WITH-MUTEX #<CLOSURE (FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE) {7F90AF07EDCB}> #<SB-THREAD:MUTEX "thread result lock" owner: #<SB-THREAD:THR..
  8: (SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE #<SB-THREAD:THREAD "scsynth" RUNNING {1005568853}> NIL #<CLOSURE (LAMBDA NIL :IN BORDEAUX-THREADS::BINDING-DEFAULT-SPECIALS) {10055687FB}> NIL)
  9: ("foreign function: call_into_lisp")
 10: ("foreign function: new_thread_trampoline")

buffer copy

I found it very useful to add a copy-buffer function (way faster than getting and setting)
something like that
(defun copy-buffer (bufnum-src bufnum-dst start-dst start-src nframes)
(apply #'send-message
s
(append (list "\b_gen" bufnum-dst "copy" start-dst bufnum-src start-src nframes)))
(sync s)
)

osc for ecl

in ecl-extension.lisp a few changes must be made

(defun osc::encode-float32 (f)
(osc::encode-int32 (single-float-bits f)))

(defun osc::decode-float32 (s)
(make-single-float (osc::decode-int32 s)))

buffer-get-list fails when attempting to get a large range.

To reproduce:

  1. Load a large buffer:
    (defparameter buffer (buffer-read "/path/to/file.wav")
  2. Attempt to get a large number of samples from it. 1000 should be enough to trigger it:
    (buffer-get-list buffer 0 1000)

I get an error that looks like this:

The bounding indices 0 and 4 are bad for a sequence of length 0.
   [Condition of type SB-KERNEL:BOUNDING-INDICES-BAD-ERROR]
See also:
  Common Lisp Hyperspec, bounding index designator [:glossary]
  Common Lisp Hyperspec, SUBSEQ-OUT-OF-BOUNDS:IS-AN-ERROR [:issue]

Restarts:
 0: [ABORT] abort thread (#<THREAD "OSC device receive thread" RUNNING {10025EF053}>)

Backtrace:
  0: (SB-KERNEL:VECTOR-SUBSEQ* #<unavailable argument> #<unavailable argument> #<unavailable argument>)
  1: ((LAMBDA (SC-OSC::X) :IN SC-OSC::SC-DECODE-TAGED-DATA) 102)
  2: ((FLET SB-IMPL::F :IN SB-IMPL::VECTOR-MAP-INTO/SIMPLE-VECTOR) 102)
  3: (SB-KERNEL:%MAP-FOR-EFFECT-ARITY-1 #<CLOSURE (FLET SB-IMPL::F :IN SB-IMPL::VECTOR-MAP-INTO/SIMPLE-VECTOR) {7FFFF546656B}> #(105 105 105 102 102 102 ...))
  4: (SB-KERNEL:%MAP NIL #<CLOSURE (FLET SB-IMPL::F :IN SB-IMPL::VECTOR-MAP-INTO/SIMPLE-VECTOR) {7FFFF546656B}> #(105 105 105 102 102 102 ...)) [more]
  5: (SB-IMPL::VECTOR-MAP-INTO/SIMPLE-VECTOR #(#(0 0 0 0 0 0 ...) #(0 0 1 149 59 180 ...) #(59 180 0 0 60 155 ...) #(60 155 0 0 59 211 ...) #(59 211 0 0 60 149 ...) #(60 149 128 0 59 233 ...) ...) 0 408 #<..
  6: (SC-OSC::SC-DECODE-TAGED-DATA #(44 105 105 105 102 102 ...))
  7: (SC-OSC::DECODE-MESSAGE #(47 98 95 115 101 116 ...))
  8: ((LAMBDA NIL :IN SC-OSC::MAKE-LISTENING-THREAD))
  9: ((LAMBDA NIL :IN BORDEAUX-THREADS::BINDING-DEFAULT-SPECIALS))
 10: ((FLET SB-UNIX::BODY :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
 11: ((FLET "WITHOUT-INTERRUPTS-BODY-4" :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
 12: ((FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
 13: ((FLET "WITHOUT-INTERRUPTS-BODY-1" :IN SB-THREAD::CALL-WITH-MUTEX))
 14: (SB-THREAD::CALL-WITH-MUTEX #<CLOSURE (FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE) {7FFFF5466D4B}> #<SB-THREAD:MUTEX "thread result lock" owner: #<SB-THREAD:THR..
 15: (SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE #<SB-THREAD:THREAD "OSC device receive thread" RUNNING {10025EF053}> NIL #<CLOSURE (LAMBDA NIL :IN BORDEAUX-THREADS::BINDING-DEFAULT-SPECIALS) {10025EEFF..
 16: ("foreign function: call_into_lisp")
 17: ("foreign function: new_thread_trampoline")

It seems to be a problem with the OSC code.

(server-status *s*) returns `; No value`

I test it on MacBook Air.
when I use (server-status *s*) or (server-query-all-nodes *s*) to list running id. They all returns ; No value. I have to run (server-quit *s*) to stop it and then boot server.
I watch your tutorial on YouTube, you can display running ids on it. Why id does not work on my computer. Thank you. :)

No sound

I'm trying to follow your tutorial (https://www.youtube.com/watch?v=JivNMDUqNQc):

(ql:quickload :sc)
(in-package :sc)
(setf *sc-synth-program* "/usr/bin/scsynth")
(push "/usr/lib/SuperCollider/plugins/" *sc-plugin-paths*)
(push "/usr/share/SuperCollider/Extensions/" *sc-plugin-paths*)
(setf *s* (make-external-server "localhost" :port 4444))
(server-boot *s*) ; returns nil
(play (sin-osc.ar [440 441] 0 .2)) ; nothing happens

cl-collider from git, arch-linux, sbcl 1.3.1, supercollider version: 3.6.6-2
scide makes sounds without problems.

Any ideas?

Compilation fails ....

Hi,

when trying to load cl-collider with quicklisp (ql:quickload "sc"), i get the following error message:

no symbol named "NOW" in "SCHEDULER"
   [Condition of type SB-KERNEL:SIMPLE-PACKAGE-ERROR]

Scheduler and Simple-Utils are both present and can be loaded ...

Any hints ?

add support for -H device flag

Could be nice to add support for -H flag forcing scsynth to boot :

on osx : on a specific device (sound card), actually quite useful for self-booting sound installations.
on linux : give a specific name to jack client (also quite useful)

in server-options.lisp

something like

"-H" (write-to-string (server-options-device server-options))

should the synth function take node-id, group-id and position as arguments?

it would be nice to be able to specify id, to and pos when creating a new synth with the synth function.
i wonder how to do that though as mixing &key and &rest is not quite recommended in cl.

my wish would be to be able to say for example
(defsynth mysynth ((amp 1) (freq 440)) (* amp (sin-osc.ar freq)))
(synth 'mysynth :to 2 :id 2000 :pos :after :amp 0.5)

and by the way how difficult would it be to be able to specify a ugen formula for a control parameter
like
(synth 'mysynth :to 2 :id 2000 :pos :after :amp (lf-saw.kr 1) )

No sound with default make-external-server on linux due to -H cl-collider option

I have no sound on linux after make-external-server and server-boot with default values. This is because of option -H cl-collider passed to scsynth. If I comment out this option everything works as expected.

The -H option and the default value of cl-collider was introduced in #62 by @vrx . I have no idea what this is needed for and especially I do not understand why one would want this default value. SuperCollider's documentation suggests a sane default is not to set this and use system default input and output devices instead.

Could we agree on either reverting #62 or changing the default to nil?

Mix.fill alternative

I'm reading supper collider tutorial and reproducing it in cl-collider.
There is an example:

(
    var n = 8;
    { Mix.fill(n, { SinOsc.ar(500 + 500.0.rand, 0, 1 / n) }) }.play;
)

I didn't find the mix.fill method and just used loop like this:

(let ((n 8)) 
       (play (loop repeat n
            collect (sin-osc.ar (+ 500 (random 500)) 0 (/ 1 n)))))

Is this is an idiomatic solution or I'm missing something?

IEnvGen

Hi,

Would it be possible for you to add IEnvGen to cl-collider? I was trying to add it myself like this:

(defugen (i-env-gen "IEnvGen")
    (envelope index &optional (mul 1.0) (add 0.0))
  ((:ar (madd (unbubble (mapcar #'process-env (multinew new 'ugen index
						  (make-env-array-from-env envelope)))) mul add))
   (:kr (madd (unbubble (mapcar #'process-env (multinew new 'ugen index
						  (make-env-array-from-env envelope)))) mul add))))

But neither that nor any of my other attempts seems to work...

Feature Request: make osc-device local port customizable

Hi!
I'm using Touch OSC as a controller.
I need to set both IP address and port in Touch OSC settings so I can receive messages in lisp.
Right now local port of the osc-device is set to 0:

(defmethod bootup-server-process ((rt-server external-server))
 ... snip ...
  (setf osc-device (sc-osc:osc-device (host rt-server) (port rt-server) :local-port 0))

That means that port is different every time socket is created.
Locally I solved that by setting a custom port number in my checkout of cl-collider.

I think it would be nice if one could pass it as an argument to (server-boot).

LispWorks error when evaluating (ql:quickload "cl-collider")

CL-USER 1 > (ql:quickload "cl-collider")
To load "cl-collider":
 Load 1 ASDF system:
   cl-collider
; Loading "cl-collider"
.
Creating foreign funcallable for signature (:INT :INT :INT :POINTER :INT) -> :INT
Creating foreign funcallable for signature (:POINTER :INT :POINTER) -> :VOID
Creating foreign funcallable for signature NIL -> :POINTER
Creating foreign funcallable for signature (:POINTER :POINTER :POINTER) -> :VOID
.
Error: External format (:UTF-8 :EOL-STYLE :LF) produces characters of type LISPWORKS:SIMPLE-CHAR, which is not a subtype of the specified element-type BASE-CHAR.
  1 (continue) Try loading /Users/gragan/.cache/common-lisp/lw-7.1.3-macosx-x64/Users/gragan/quicklisp/dists/quicklisp/software/cl-collider-20210807-git/ugens/BEQSuite.64xfasl again.
  2 Give up loading /Users/gragan/.cache/common-lisp/lw-7.1.3-macosx-x64/Users/gragan/quicklisp/dists/quicklisp/software/cl-collider-20210807-git/ugens/BEQSuite.64xfasl.
  3 Try loading another file instead of /Users/gragan/.cache/common-lisp/lw-7.1.3-macosx-x64/Users/gragan/quicklisp/dists/quicklisp/software/cl-collider-20210807-git/ugens/BEQSuite.64xfasl.
  4 Recompile ugens/BEQSuite and try loading it again
  5 Retry loading FASL for
  #<ASDF/LISP-ACTION:CL-SOURCE-FILE "cl-collider" "ugens/BEQSuite">.
  6 Continue, treating loading FASL for
  #<ASDF/LISP-ACTION:CL-SOURCE-FILE "cl-collider" "ugens/BEQSuite">
    as having been successful.
  7 Retry ASDF operation.
  8 Retry ASDF operation after resetting the configuration.
  9 Retry ASDF operation.
 10 Retry ASDF operation after resetting the configuration.
 11 (abort) Give up on "cl-collider"
 12 Register local projects and try again.
 13 Return to top loop level 0.


Here is the backtrace:

Call to ERROR
Call to STREAM::EXTERNAL-FORMAT-STREAM-DEFAULTED-ELEMENT-TYPE
Call to STREAM::EXTERNAL-FORMAT-OPEN
Call to OPEN
Call to ALEXANDRIA:READ-FILE-INTO-STRING
Call to READ-UGEN-DESCRIPTION
Call to (HARLEQUIN-COMMON-LISP:SUBFUNCTION 1 LOAD)
Call to LOAD
Call to (HARLEQUIN-COMMON-LISP:SUBFUNCTION 1 UIOP/LISP-BUILD:LOAD*)
Call to UIOP/UTILITY:CALL-WITH-MUFFLED-CONDITIONS
Call to UIOP/LISP-BUILD:LOAD*
Call to CLOS::NEXT-METHOD-CALL-2
Call to (HARLEQUIN-COMMON-LISP:SUBFUNCTION 1 ASDF/ACTION:CALL-WHILE-VISITING-ACTION)
Call to ASDF/SESSION:CALL-WITH-ASDF-SESSION
Call to ASDF/ACTION:CALL-WHILE-VISITING-ACTION
Call to CLOS::NEXT-METHOD-CALL-2
Call to (METHOD ASDF/ACTION:PERFORM-WITH-RESTARTS (ASDF/LISP-ACTION:LOAD-OP ASDF/LISP-ACTION:CL-SOURCE-FILE))
Call to CLOS::NEXT-METHOD-CALL-2
Call to (METHOD ASDF/ACTION:PERFORM-WITH-RESTARTS :AROUND (T T))
Call to (METHOD ASDF/PLAN:PERFORM-PLAN (T))
Call to CLOS::NEXT-METHOD-CALL-2
Call to (METHOD ASDF/PLAN:PERFORM-PLAN :AROUND (T))
Call to CLOS::GENERIC-FUNCTION-NON-DISCRIMINATOR
Call to (METHOD ASDF/OPERATE:OPERATE (ASDF/OPERATION:OPERATION ASDF/COMPONENT:COMPONENT))
Call to CLOS::NEXT-METHOD-CALL-3
Call to (HARLEQUIN-COMMON-LISP:SUBFUNCTION 1 (METHOD ASDF/OPERATE:OPERATE :AROUND (T T)))
Call to ASDF/SESSION:CALL-WITH-ASDF-SESSION
Call to (METHOD ASDF/OPERATE:OPERATE :AROUND (T T))
Call to (METHOD ASDF/OPERATE:OPERATE (SYMBOL T))
Call to CLOS::NEXT-METHOD-CALL-3
Call to (HARLEQUIN-COMMON-LISP:SUBFUNCTION 1 (METHOD ASDF/OPERATE:OPERATE :AROUND (T T)))
Call to ASDF/SESSION:CALL-WITH-ASDF-SESSION
Call to (METHOD ASDF/OPERATE:OPERATE :AROUND (T T))
Call to (HARLEQUIN-COMMON-LISP:SUBFUNCTION 2 (HARLEQUIN-COMMON-LISP:SUBFUNCTION 1 (METHOD ASDF/OPERATE:OPERATE :AROUND (T T))))
Call to ASDF/SESSION:CALL-WITH-ASDF-SESSION
Call to (HARLEQUIN-COMMON-LISP:SUBFUNCTION 1 (METHOD ASDF/OPERATE:OPERATE :AROUND (T T)))
Call to ASDF/SESSION:CALL-WITH-ASDF-SESSION
Call to (METHOD ASDF/OPERATE:OPERATE :AROUND (T T))
Call to ASDF/OPERATE:LOAD-SYSTEM
Call to QUICKLISP-CLIENT::CALL-WITH-MACROEXPAND-PROGRESS
Call to QUICKLISP-CLIENT::AUTOLOAD-SYSTEM-AND-DEPENDENCIES
Call to (METHOD QL-IMPL-UTIL::%CALL-WITH-QUIET-COMPILATION (T T))
Call to (METHOD QUICKLISP-CLIENT:QUICKLOAD (T))
Call to CLOS::NEXT-METHOD-CALL-2
Call to QL-DIST::CALL-WITH-CONSISTENT-DISTS
Call to CLOS::GENERIC-FUNCTION-NON-DISCRIMINATOR
Call to EVAL
Call to CAPI::CAPI-TOP-LEVEL-FUNCTION
Call to CAPI::INTERACTIVE-PANE-TOP-LOOP
Call to MP::PROCESS-SG-FUNCTION

Plotting and debugging

In sclang one can plot ugens. It seems that this can be very useful for beginners like myself.
I understand that it can be tricky to implement though. Maybe there is a simpler way of getting intuition about values of various parts of the system? Thank you for the amazing project!

sound-in

in audioin.lisp
sound-in-prim should be

(defun sound-in-prim (chan-offset bus mul add)
(if (not (listp bus)) (sc::madd (in.ar (sc::add chan-offset bus) 1) mul add)
(if (equal bus (loop repeat (length bus) for i from (car bus) collect i))
(sc::madd (in.ar (sc::add chan-offset (car bus)) (length bus)) mul add)
(sc::madd (in.ar (sc::add chan-offset bus)) mul add))))

server.lisp

shouldn't :
(loop :for i :upto (server-options-num-output-bus options)
:do (get-next-bus rt-server :audio 1 i))
(loop :for i :upto (server-options-num-input-bus options)
:do (get-next-bus rt-server :audio 1 (+ i (server-options-num-output-bus options))))))

be replaced by
(loop :for i :from 1 :upto (server-options-num-output-bus options)
:do (get-next-bus rt-server :audio 1))
(loop :for i :from 1 :upto (server-options-num-input-bus options)
:do (get-next-bus rt-server :audio 1))

?

A few suggestions

Hi,

First of all, thanks for writing this library! I've been writing a library of my own, cl-patterns, which uses cl-collider as a backend. My library is based off of SuperCollider's patterns system and it's built for sequencing. It's still in early stages and doesn't have a lot of features yet but your library has made it possible.

I've been using cl-collider and in the process I made a few changes to my fork before I realized you were updating this one again. Since you're still developing this, I'd like to suggest a few changes to cl-collider that I'd like to contribute to the project, if you're interested.

  1. There are a few grammar errors in the english in this library and I'd be willing to fix those for you and submit the changes as a pull request.

  2. For consistency, I think the library should try to use SuperCollider's names for functionality. For example, having free and release functions instead of using bye to stop synths. free could be a generic function with methods for buffers, synths, and proxies. Additionally, it may be best to continue to use names like sin-osc.ar instead of sin-osc for ugen consistency and to avoid possible name clashes for ugens with common names like out.ar.

  3. Have a synth function instead of generating specific functions for each synth. This would make it easier to start synths programmatically, i.e. from my patterns system. That way, it's not necessary to use apply to call an arbitrary synth from a function. I've already written this function in my fork of cl-collider here. It uses a function called make-synth-msg-2 which eliminates need for using apply for synth arguments. It's defined here.

  4. Make a separate sc-user package for the user to use instead of being in sc directly. That way, if you still want to keep the functions generated for each synth, they can be defined in sc-user instead of sc and reduce the chance of clashing with already-existing functions in sc.

  5. Use named-readtables for the #! and [ syntaxes and any other syntax shortcuts, and make them available in sc-user instead of globally, so that libraries that require cl-collider won't automatically have it added to their readtables.

Let me know if you'd be interested in these changes, and I'd be more than happy to start contributing them so that cl-collider is even better for users and works even better for libraries that build off of your work. Thanks again.

Recording output in real-time

Hi, I noticed that diskout.ar isn't defined. Is there a better way to go about recording audio in real-time in cl-collider?
I wrote the following pseudocode using HSC3 as a reference:

(setq *rec-nc* 2)
(setq *rec-node-id* 2001)
(setq *rec-buf-id* 2001)
(setq *rec-buf-frames* 65536)

;; initialize recording
(defsynth sc3-record
    (&key (bufnum 0) (bus 0))
  (diskout.ar bufnum (in.ar  bus *rec-nc*)))
(buffer-alloc *rec-buf-frames* *rec-nc* *rec-node-id*)
(buffer-save *rec-node-id* "/tmp/sc3-recorder.wav" *rec-buf-frames*)

;; start recording
(sc3-record *rec-node-id*)

;; stop recording
(free *rec-node-id*)
(buffer-free *rec-buf-id*)

Some systems failed to build for Quicklisp dist

Building with SBCL 2.0.5 / ASDF 3.3.1 for quicklisp dist creation.

Trying to build commit id e7a3843

cl-collider fails to build with the following error:

Unhandled SB-INT:SIMPLE-FILE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {10008D8083}>: Failed to find the TRUENAME of /home/quicklisp/quicklisp-controller/dist/build-cache/cl-collider/2e609597811a946b6a2e568486e2e7cdb83e1e63/cl-collider-20201219-git/ugens/BufIO.lisp: No such file or directory

Full log here

Suddenly no sound during playing, and (SERVER-STATUS *S*) gives no output.

As described, the system works fine for some time then abruptly fall to silence (with a hard-cut-to-zero audio glitch sound). I then try (server-status *s*), (server-query-all-nodes), all gives no output. (They were giving out put when it's normally making sound)

I know this might not be so informative, but is there anyway to get more detailed error messages? (like, from a log somewhere). The scsynth process is still running, just not making sound.

I'm on macOS 10.14, with SuperCollider 3.11.0 and Clozure CL 1.11.6

Cannot define some synths outside sc-user package

Description

The error seems to happen with the synths using "[" on the definition. Like env. If I switch to sc-user the defsynth works. See below example.

Use case

It is useful mix libraries like CM with cl-collider. And while I can use "in-package" to switch I don't think is ideal.

Error

On the repl I try:

TESTSC> (defsynth saw-synth ((note 60) (dur 4.0))
  (let* ((env (env-gen.kr (env [0 .2 0] [(* dur .2) (* dur .8)]) :act :free))
         (freq (midicps note))
    	 (sig (lpf.ar (saw.ar freq env) (* freq 2))))
	(out.ar 0 [sig sig])))

On a error window I get:

The variable [0 is unbound.
   [Condition of type UNBOUND-VARIABLE]

Restarts:
 0: [CONTINUE] Retry using [0.
 1: [USE-VALUE] Use specified value.
 2: [STORE-VALUE] Set specified value and use it.
 3: [RETRY] Retry SLIME REPL evaluation request.
 4: [*ABORT] Return to SLIME's top level.
 5: [ABORT] Exit debugger, returning to top level.

Backtrace:
  0: ((LAMBDA ()))
  1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (DEFSYNTH SAW-SYNTH ((NOTE 60) (DUR 4.0)) (LET* (# # #) (OUT.AR 0 [SIG SIG]))) #<NULL-LEXENV>)
  2: (EVAL (DEFSYNTH SAW-SYNTH ((NOTE 60) (DUR 4.0)) (LET* (# # #) (OUT.AR 0 [SIG SIG]))))
  3: (SWANK::EVAL-REGION "(defsynth saw-synth ((note 60) (dur 4.0)) ..)
  4: ((LAMBDA NIL :IN SWANK-REPL::REPL-EVAL))
  5: (SWANK-REPL::TRACK-PACKAGE #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::REPL-EVAL) {1004D4FB8B}>)
  6: (SWANK::CALL-WITH-RETRY-RESTART "Retry SLIME REPL evaluation request." #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::REPL-EVAL) {1004D4FB2B}>)
  7: (SWANK::CALL-WITH-BUFFER-SYNTAX NIL #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::REPL-EVAL) {1004D4FB0B}>)
  8: (SWANK-REPL::REPL-EVAL "(defsynth saw-synth ((note 60) (dur 4.0)) ..)
  9: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK-REPL:LISTENER-EVAL "(defsynth saw-synth ((note 60) (dur 4.0)) ..)
 10: (EVAL (SWANK-REPL:LISTENER-EVAL "(defsynth saw-synth ((note 60) (dur 4.0)) ..)
 11: (SWANK:EVAL-FOR-EMACS (SWANK-REPL:LISTENER-EVAL "(defsynth saw-synth ((note 60) (dur 4.0)) ..)
 12: (SWANK::PROCESS-REQUESTS T)
 13: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
 14: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))

testcl.asd

(asdf:defsystem "testsc"
  :description "Describe somecepl here"
  :author "Your Name <[email protected]>"
  :license "Specify license here"
  :depends-on (
               #:sc
               )
  :serial t
  :components ((:file "package")
               ))

package.lisp

(uiop:define-package testsc
  (:use #:cl #:sc)
)

local-buf not working ?

(local-buf 2048)
sends :

There is no applicable method for the generic function:
#<STANDARD-GENERIC-FUNCTION SC::MAX-LOCAL-BUFS #x30200156DAFF>
when called with arguments:
(NIL)

Error when quickloading the library

I get the following error. I'm on Win10/Slime/SBCL. What's going on?

CL-USER> (ql:quickload :sc)
To load "sc":
  Load 1 ASDF system:
    sc
; Loading "sc"
; 
; caught ERROR:
;   (during macroexpansion of (SETF *SC-PLUGIN-PATHS*))
;   error while parsing arguments to DESTRUCTURING-BIND:
;     too few elements in
;       (*SC-PLUGIN-PATHS*)
;     to satisfy lambda list
;       (SB-IMPL::PLACE SB-IMPL::VALUE-FORM . SB-IMPL::MORE):
;     at least 2 expected, but got 1
....; 
    ; compilation unit aborted
    ;   caught 2 fatal ERROR conditions
    ;   caught 1 ERROR condition
; Evaluation aborted on #<UIOP/LISP-BUILD:COMPILE-FILE-ERROR {100BE26223}>.

Weird error output when using tempo-clock

Hi! I've been trying to study cl-collider and a simple test with tempo-clock resulted in a weird error. The sound is audible but I get this on my slime REPL:

Error "The value #<CL-COLLIDER::NODE :server #<CL-COLLIDER::EXTERNAL-SERVER localhost-127.0.0.1:4444> :id 1032 :name "foo"> is not of type SYMBOL" in Tempo-Clock thread

Here's the code:

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


(clock-bpm 60)

(defsynth foo ((freq 220) (dur 1) (gain 1) (pan 0))
  (let* ((env (line.kr .2 .0 dur :act :free))
         (sig (sin-osc.ar freq 0 env)))
    (out.ar 0 (pan2.ar sig pan gain))))

;; NOTE: For testing 1 hit:
(at-beat (clock-quant 4) (synth 'foo :freq 220 :dur (clock-tm 5))

(defun syncd-seq (beat &optional (dur 1) (i 0))
  (at-beat beat (synth 'foo :dur (clock-tm .5) :gain .5))
  (let* ((next (+ beat dur)))
    (clock-add next 'syncd-seq next dur (+ i 1))))

;; NOTE: 4ths:
(syncd-seq (clock-quant 4))

Am I doing something completely stupid or is this a proper error on some obscure behavior? :)

Running on:

Windows 10, SBCL 1.4.14

How to define these type of ugens?

https://github.com/redFrik/f0plugins/blob/5e684d755b6576f99331995f59f33cade61bfda6/source/Nes2/sc/Nes2.sc#L15

Nes2Square {
	*ar {|trig= 0, dutycycle= 0, loopenv= 0, envdecay= 0, vol= 10, sweep= 0, sweeplen= 0, sweepdir= 0, sweepshi= 0, freq= 100, vbl= 0|
		var a0, a1, a2, a3;
		a0= Clip.kr(dutycycle.round, 0, 3)*64;
		a0= a0|(Clip.kr(loopenv.round, 0, 1)*32);
		a0= a0|(Clip.kr(envdecay.round, 0, 1)*16);
		a0= a0|Clip.kr(vol.round, 0, 15);
		a1= Clip.kr(sweep.round, 0, 1)*128;
		a1= a1|(Clip.kr(sweeplen.round, 0, 7)*16);
		a1= a1|(Clip.kr(sweepdir.round, 0, 1)*8);
		a1= a1|Clip.kr(sweepshi.round, 0, 7);
		a2= freq.max(0).round%256;
		a3= Clip.kr((freq/256).floor, 0, 7);
		a3= a3|(Clip.kr(vbl.round, 0, 31)*8);
		^Nes2.ar(trig, a0, a1, a2, a3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
	}
	*categories {^#["UGens>Emulators"]}
}

Not sure how to define this or if it is a ugen or something I can do with defsynth. It looks like it uses SC "|" (bitwise or) which I don't see on cl-collider ugens. Please help.

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.