{"id":13442683,"url":"https://github.com/byulparan/cl-collider","last_synced_at":"2025-03-20T15:30:24.450Z","repository":{"id":2136780,"uuid":"14809757","full_name":"byulparan/cl-collider","owner":"byulparan","description":"A SuperCollider client for CommonLisp","archived":false,"fork":false,"pushed_at":"2024-02-21T10:47:55.000Z","size":495,"stargazers_count":206,"open_issues_count":1,"forks_count":23,"subscribers_count":22,"default_branch":"master","last_synced_at":"2024-04-18T04:20:04.305Z","etag":null,"topics":["cl-collider"],"latest_commit_sha":null,"homepage":"","language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/byulparan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-11-29T20:35:17.000Z","updated_at":"2024-05-29T21:40:39.518Z","dependencies_parsed_at":"2023-01-14T10:58:21.559Z","dependency_job_id":"f0f27f21-0018-45fc-aa45-73cb39a8f8e7","html_url":"https://github.com/byulparan/cl-collider","commit_stats":{"total_commits":383,"total_committers":15,"mean_commits":"25.533333333333335","dds":0.6344647519582245,"last_synced_commit":"01e92914df1eca31155c6e8cea4d56615c9aefd5"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byulparan%2Fcl-collider","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byulparan%2Fcl-collider/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byulparan%2Fcl-collider/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byulparan%2Fcl-collider/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/byulparan","download_url":"https://codeload.github.com/byulparan/cl-collider/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244639815,"owners_count":20485932,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cl-collider"],"created_at":"2024-07-31T03:01:49.103Z","updated_at":"2025-03-20T15:30:24.444Z","avatar_url":"https://github.com/byulparan.png","language":"Common Lisp","funding_links":[],"categories":["Common Lisp","Libraries and tools","Expert Systems"],"sub_categories":[],"readme":"# cl-collider\n\nA \u003ca href=\"http://supercollider.github.io/\"\u003eSuperCollider\u003c/a\u003e client for \u003ca href=\"https://www.common-lisp.net/\"\u003eCommon Lisp\u003c/a\u003e.\nIt is an experimental project, so changes to the API are possible.\n\n## Videos:\n\n- [tempo-clock on cl-collider](https://youtu.be/3Lo7yyZcSzU)   \n- [cl-collider on Windows10](https://youtu.be/pCEfV4jOdUA)  \n- [Tutorial](https://www.youtube.com/watch?v=JivNMDUqNQc) - Due to API changes, this video is deprecated. A new tutorial video is coming soon.  \n- [Live Coding Demo 1](https://www.youtube.com/watch?v=xzTH_ZqaFKI)  \n- [Live Coding Demo 2](https://www.youtube.com/watch?v=pZyuHjztARY)  \n\n## Dependencies:\n\n- [SuperCollider](http://supercollider.github.io)\n- [Quicklisp](http://www.quicklisp.org)\n- [ClozureCL](http://www.clozure.com/clozurecl.html) or [SBCL](http://www.sbcl.org) or [ECL](https://common-lisp.net/project/ecl/)\n- [Jack](https://jackaudio.org/) - Only on GNU/Linux and BSD distributions.\n- [net-tools](https://net-tools.sourceforge.io/) - On Windows, scsynth should bind to a port before sending a message to CL.\n\n## Contrib:\n\nIf you have your own additional libraries, please report me. I will add here.\n\n- [sc-extensions](https://github.com/byulparan/sc-extensions) - extension library\n- [cl-patterns](https://github.com/defaultxr/cl-patterns) - patterns/sequencing library\n- [bdef](https://github.com/defaultxr/bdef) - file/buffer management/convenience library\n- [sc-vst](https://github.com/byulparan/sc-vst) - VSTPlugin support library\n\n## Usage:\n\n- package: `sc`, `sc-user` (use this package)\n- named-readtable: `sc`\n\n```cl\n(ql:quickload :cl-collider)\n\n(in-package :sc-user)\n(named-readtables:in-readtable :sc)\n\n;; please check *sc-synth-program*, *sc-plugin-paths*, *sc-synthdefs-path*\n;; if you have different path then set to\n;;\n;; (setf *sc-synth-program* \"/path/to/scsynth\")\n;; (setf *sc-plugin-paths* (list \"/path/to/plugin_path\" \"/path/to/extension_plugin_path\"))\n;; (setf *sc-synthdefs-path* \"/path/to/synthdefs_path\")\n\n;; `*s*` defines the server for the entire session\n;; functions may use it internally.\n\n(setf *s* (make-external-server \"localhost\" :port 48800))\n(server-boot *s*)\n\n;; in Linux, maybe you need to call this function\n#+linux\n(jack-connect)\n\n;; Hack music\n(defvar *synth*)\n(setf *synth* (play (sin-osc.ar [320 321] 0 .2)))\n\n;; Stop music\n(free *synth*)\n\n;; Quit SuperCollider server\n(server-quit *s*)\n```\n\n### Create SynthDef\n\n```cl\n(defsynth sine-wave ((note 60))\n  (let* ((freq (midicps note))\n         (sig (sin-osc.ar [freq (+ freq 2)] 0 .2)))\n     (out.ar 0 sig)))\n\n(setf *synth* (synth 'sine-wave))\n(ctrl *synth* :note 72)\n(free *synth*)\n```\n\n### Create Proxy\n\n```cl\n(proxy :sinesynth\n  (sin-osc.ar [440 441] 0 .2))\n\n(proxy :sinesynth\n  (with-controls ((lfo-speed 4))\n    (sin-osc.ar (* [440 441] (range (lf-pulse.ar [lfo-speed (+ lfo-speed .2)]) 0 1)) 0 .2))\n  :fade 8.0)\n   \n(ctrl :sinesynth :lfo-speed 8)\n(ctrl :sinesynth :gate 0)\n```\n\n### Create Musical Sequence\n\n```cl\n(defsynth saw-synth ((note 60) (dur 4.0))\n  (let* ((env (env-gen.kr (env [0 .2 0] [(* dur .2) (* dur .8)]) :act :free))\n         (freq (midicps note))\n    \t (sig (lpf.ar (saw.ar freq env) (* freq 2))))\n\t(out.ar 0 [sig sig])))\n\n(defun make-melody (time n \u0026optional (offset 0))\n  (when (\u003e n 0)\n    (at time (synth 'saw-synth :note (+ offset (alexandria:random-elt '(62 65 69 72)))))\n      (let ((next-time (+ time (alexandria:random-elt '(0 1 2 1.5)))))\n        (callback next-time #'make-melody next-time (- n 1) offset))))\n\n(make-melody (quant 4) 16)\n(make-melody (+ 4 (quant 4)) 16 12)\n```\n\n### Non-real-time Rendering to File\n\n```cl\n(setf *synth-definition-mode* :load)\n\n;; Redefine the saw-synth ugen\n;; The SynthDef file will be written to the *sc-synthdefs-path*\n(defsynth saw-synth ((note 60) (dur 4.0))\n  (let* ((env (env-gen.kr (env [0 .2 0] [(* dur .2) (* dur .8)]) :act :free))\n         (freq (midicps note))\n         (sig (lpf.ar (saw.ar freq env) (* freq 2))))\n    (out.ar 0 [sig sig])))\n\n;; We can use a similar function to make a melody, but we don't need to schedule the callbacks\n(defun make-melody (time n \u0026optional (offset 0))\n  (when (\u003e n 0)\n    (at time (synth 'saw-synth :note (+ offset (alexandria:random-elt '(62 65 69 72)))))\n      (let ((next-time (+ time (alexandria:random-elt '(0 1 2 1.5)))))\n        (make-melody next-time (- n 1) offset))))\n\t\n;; Render audio file\n(with-rendering (\"~/Desktop/foo.aiff\" :pad 60)\n  (make-melody 0.0d0 32)\n  (make-melody 8.0d0 32 12)\n  (make-melody 16.0d0 32 24))\n```\n\n### Record Audio Output\n\n```cl\n;;; write a single channel to disk\n\n;; we can write to buffer number out_buf_num by reading in from the 0 bus\n(defsynth disk_writer ((out_buf_num 99))\n    (disk-out.ar out_buf_num (in.ar 0)))\n\n(setf mybuffer (buffer-alloc (expt 2 17))) \nmybuffer\n\n;; start a disk_writer synth\n(setf writer_0 (synth 'disk_writer))\n\n;; make it output to buffer you allocated\n(ctrl writer_0 :out_buf_num (bufnum mybuffer))\n\n;; continuously write the buffer contents to a file\n(buffer-write mybuffer \"/tmp/foo.aiff\" :leave-open-p t)\n\n;; now play whatever sounds you like\n\n;; e.g.\n(proxy :blah (sin-osc.ar 440))\n(free :blah)\n\n;; then when you are done\n\n;; stop the disk_writer synth\n(free writer_0)\n\n;; close and free the buffer\n(buffer-close mybuffer)\n(buffer-free mybuffer)\n\n;; then you can play what you recorded with a utility like mpv:\n;;     mpv /tmp/foo.aiff\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbyulparan%2Fcl-collider","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbyulparan%2Fcl-collider","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbyulparan%2Fcl-collider/lists"}