GithubHelp home page GithubHelp logo

aartaka / cl-pure-data Goto Github PK

View Code? Open in Web Editor NEW
4.0 2.0 1.0 111 KB

Common Lisp bindings for libpd, the data-processing layer of PureData.

License: BSD 2-Clause "Simplified" License

Common Lisp 100.00%

cl-pure-data's Introduction

cl-pure-data – Common Lisp bindings for libpd.

This is a chaotic set of bindings for libpd, the data-processing interface for PureData. This library does not emit any sound or picture – you have to create images and sounds yourself.

Getting Started

Clone the repository:

git clone https://github.com/aartaka/cl-pure-data

Load the library into your Lisp image:

(asdf:load-asd #p"/path/to/cl-pure-data/cl-pure-data.asd")
(asdf:load-asd :cl-pure-data)

The dependencies are CFFI and Alexandria, they are easy to reach in almost any implementation. Additionally, make sure libpd is in your cffi:*foreign-library-directories*.

After it loads fine, you can start hacking:

;; Initialize hooks to print everything out.
(pd:init-default-hooks)
;; Initialize audio to two input, two outputs and sample rate of 44100.
(pd:init-audio 2 2 44100)
;; Load a patch from somewhere in the filesystem.
(pd:open-patch #p"/nested/directories/and/whatever.pd")
;; Enable Direct Sound Processing (e.g. playback of the data you feed into libpd).
(pd:message "pd" "dsp" 1)
;; Feed the data for three ticks into the image.
;; DOES NOT PLAY ANY AUDIO :(
(pd:process #(3.0 4.3 1.0 ...) 3)

And then do whatever you want with the data you get!

Proxies

cl-pure-data exposes the defproxy macro to define proxies – patch-backed Lisp code seamlessly translating into PD code. It’s somewhat restricted at the moment, but is also working for dynamic patching (pun intended) of PD files and on-the-fly processing.

To see how that works, try (taken from the defproxy documentation)

;; Assuming you initialized cl-pure-data as in previous snippets already.
(pd:init-default-hooks)
(pd:init-audio 0 1 44100)
(pd:message "pd" "dsp" 1)
;;
;; This creates two functions, bloopy and bloopy-off, loading and
;; unloading the generated patch respectively. The contents of the
;; patch are the PD commands generated from the Lisp code in the body.
(pd:defproxy bloopy ()
  (dac~ (osc~ (+~ (*~ (samphold~ (noise~) (phasor~ 6)) 200) 440))))
;; Start bloopy. You won't hear anything, but `ps:process' will start returning different values
(bloopy)
;; Make it emit sound. Ensure you have cl-pure-data/asla or an equivalent loaded!
(loop repeat 1000 do (pd:process #()))
;; Disable bloopy.
(bloopy-off)

;; Create an even simpler proxy, yet having an argument.
(pd:defproxy osc (&optional (freq 440))
  (dac~ (osc~ freq)))
;; Initialize it and make it play sound. Use the default frequency.
(osc)
(loop repeat 500 do (pd:process #()))
;; Now change the frequency to something audibly higher.
(osc 600)
(loop repeat 500 do (pd:process #()))
;; Don't run this -- for the safety of your ears!
(osc 4000)
(loop repeat 1000 do (pd:process #()))

Structure of the library

  • Low-level API:
    libpd.lisp
    low-level bindings to libpd. C functions with lispy names, beware of malloc&free business!
  • High-level API:
    hooks.lisp
    high-level bindings to PD event hooks. Simply push your function into the hook you like, and you’ll see the effect the next time the event fires!
    arr.lisp
    high-level-ish bindings for PD arrays. Exposes arr to reference arrays by name, contents to get subsequences of those (literally the same set of arguments as subseq), and elem to reference just one element (think elt). Both contents and elem are setf-able.
    audio.lisp
    high-level API to PD audio processing capabilities. init-audio sets things up for processing, while process takes an input and produces and output, threading it all through PureData image.
    pure-data.lisp
    generic high-level macros (with-pd, defpdfun), patch handling (open-patch, close-patch, with-patch), message-sending (message), and cleanup (release).
    proxy.lisp
    Proxies (terminology taken from cl-collider) to express PD patches in Lisp code and dynamically modifying those. All with the help of defproxy macro.

Most of the cl-pure-data functions return

  • t (or other meaningful truthy value) on success
  • and nil on failure,
  • but some also signal conditions, so watch out!

Someday this will be more structured. Someday…

Thing that this library can do:

  • Directly interfacing with libpd.
    • libpd package with the function names mirroring the ones from libpd.
  • Initializing PureData instance.
    • happens automatically when you call any function from cl-pure-data package or via libpd:libpd-init.
  • Loading and unloading PureData patches (.pd) into the instance.
  • Binding hooks to PureData events.
    • Binding sensible default hooks via init-default-hooks.
    • Binding to individual hooks (from hooks.lisp) via simple (push #'handler hook).
  • Sending messages to the current instance via message.

Things that this library cannot do (yet?)

  • [X] Subscribing to messages sent by PD.
  • [ ] MIDI interfacing (I’ve been too lazy and MIDI-ignorant to do it…)
  • [ ] Wrapping messages the right way.
  • [ ] Concatenating print messages (although simply printing them to standard output works fine too…)
  • [ ] Conveniently managing instances. Right now instances are only swap-able when using libpd package. Ideally, this package should never be accessed by the end-user. Even though it’s exported.
  • [ ] Binding queued API for thread-safety.
  • [X] Producing sound (although using also-alsa or cl-portaudio should be pretty straightforward in this context).
    • [ ] There’s also-alsa-based backend now, but it only plays well with one output channel :D
    • [ ] Producing visuals is not an option either, until you leverage some image/video library.
  • [X] Making new PureData patches out of Lisp code.
    • [X] Should be relatively easy—take Lisp code, process it into .pd code format, write it into a file, and load it into the current instance.
      • [ ] Now, how do we express self-referential and multiple-output nodes in essentially non-cyclical code…
  • [ ] Signaling recoverable conditions for some exceptional case, like broken messages.

cl-pure-data's People

Contributors

aartaka avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

jgarte

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.