- on github: https://github.com/badamson/patchosaur/
- demo video: http://www.youtube.com/watch?v=V7c3XwabUKM
- On Create Digital Music
Install node.js, git, dependencies
Do one of the following:
- clone mine:
git clone email@example.com:badamson/patchosaur.git
- fork it and clone that
Install patchosaur's node.js dependencies:
cd patchosaur npm update # install or update node.js dependencies from package.json
To start a patchosaur server:
Now open Chrome and visit http://localhost:7777. It might work in Firefox, haven't tried.
To start a local patchosaur server in production mode (js and css all concatted and minified):
To see a list of other tasks:
Press 'h' to toggle help. Double click to create a new object or to edit an existing one. To connect an inlet to and outlet, click an outlet (it should pulse), then click the inlet. To move an object, drag it. To create a comment, create an object starting with
c "this is a comment".
To remove an object or patchcord:
- On a Mac: alt-click on it
- Linux: ctrl-click on it
No real document support. After the app loads, the patch
documents/testDoc.json is loaded. Every time the patch is edited, it is saved to this file. To edit a new document, replace the contents of
. To "save," move the file.
Units that have audio inputs or outputs have a tilde suffix (
cycle~). Some of them do not work yet (any with multiple outputs, buffer stuff, callbacks). Most of them are directly wrapped from Audiolet. See the sections "DSP" and "Operators" in the Audiolet API Documentation for argument and inlet specifications.
For example, in the Audiolet API Documentation, under "DSP", the Lag constructor takes 3 arguments: audiolet, initial value (default 0), and lag time (default 1). The first argument, audiolet, is passed for you. Arguments (initial value, lag time) can be optionally passed as patchosaur arguments:
lag~ 0.5, 0.1. The inputs in the documentation are value and lag time. You can make patchcord connections to audio inputs from audio outputs, and to audiolet parameters from function inputs.
- object outlets are always called in right to left order, depth first, exactly as in Max or PD.
- The leftmost inlet is "hot", other inlets do not result in output (with a few exceptions)
- Unlike PD or Max which have space-delimited object arguments, in patchosaur everything after the first space is surrounded by square brackets and parsed as JSON.
route "ten", 11, 12will instantiate a
routeunit with arguments
["ten", 11, 12]
route "ten" 11 12fails to parse
- When a single object outlet is connected to multiple inlets, Max always works right to left. In PD, this isn't the case; you always need a
triggeror something to guarantee order. Patchosaur works like PD in this regard.
- That said,
tfor short) is different from its Max/PD cousins. It is meant only for message ordering, and takes one argument: the number of outlets. It repeats whatever it receives right-to-left from every outlet.
d) is similar to trigger, but outputs its arguments in right-to-left order whenever it receives any message.
dump true, 4, "hey there"will have 3 outlets, and when it hears any message in its inlet, will output "hey there" from outlet 2, then 4 from outlet 1, then true from outlet 0.
- That said,
gateshould be identical to Max's.
- A lot of basic Max/pd stuff is missing, but you can use the
csunit to define useful objects as coffeescript functions. The number of inlets is the number of arguments the function takes, there is always a single outlet, and the function isn't invoked until it hears something in the "hot" left inlet.
cs "(x, y) -> x + y"should be identical to
+. The function argument to
csis bound to a new empty object, so you can use
thisto remember stuff:
cs "(b) -> @x = (@x or 0) + 1"is a basic counter.
MIDI travels over websockets from the patchosaur server. See the
socket.io unit. This is just a proof of concept for now, but seems to work fine for input.
Units are little programs that can be connected by patchcords. They are all defined here, where there are many examples. To add a unit, define a class in the units directory that extends
patchosaur.Unit, add a
setup method, and then register it:
Units can change model attributes during setup, which will be reflected in the ui view:
- Set the number of inlets:
@objectModel.set numInlets: 3
- Set the number of outlets:
@objectModel.set numOutlets: 3
- Set an error (will make the object red in the ui view), which you should also log (
@objectModel.set error: "I've made a huge mistake."
- Set the id of a custom gui (unit adds this to the dom for now, moved and removed by ui view, see gui units):
@objectModel.set customGuiId: id
They can also expose attributes that do stuff:
@inlets = [inletFunc1, inletFunc2]: an array of functions to be called when something is connected to one of the unit's inlets (mapped by index).
- audiolet nodes to be connected and disconnected (see audio units):
@audioletOutputNodes = [audioletNode1, audioletNode2]
@audioletInputNodes = [audioletNode1, audioletNode2]
They should name themselves in a class variable (see examples,
@names = ['spigot', 'gate']).They can read arguments from the model (
@objectModel.get 'unitArgs'), which is an array. When an object is created, everything before the first space is set as
unitClass, which is used to look up a unit by name, and everything after is surrounded by square brackets and parsed as JSON.
route 1, 4, 5's args become [1, 4, 5], while
route 1 4 5 fails to parse.
In addition to setting
names as a class variable, units can set
help. This doesn't do anything yet, but in the future it will show in help (press 'h' to show, right now just displays a list of units).
- FIXME: write some in coffeescript as examples. SuperCollider's Leaky Integrator would be nice to have. This list of SC3 classes has a lot of cool stuff.
- make it puredata compatible
- more control objects
- more timing objects
- bang, loadbang
- better help (right now it just displays a list of units)
- more gui objects (number object like Max would be cool)
- better MIDI, including output
- static site with bootstrapped document (see
rake statifytask, which works except for ajax doc load)
- deploy to
- deploy to
- unit tests
- demo video
- infinite canvas scrolling (maybe click drag, and just move all the objects?)
- recording support: https://github.com/oampo/Audiolet/issues/11#issuecomment-2716776
- Document support, save and share patches:
- stored remotely (save and load to/from github pritave anonymous gists or google drive or something), would be nice for purely static server-less app
- filesystem, checked into repo (nice for example patches at least)
- localStorage or load and save from copypastad text
- have the app access a database, not sure I like this idea
- Static site generation with
wget --mirror, hosted on gh-pages, so anyone can try it out.
- Max-like subpatcher and abstraction support
- Collaborative patch editing (send model changes over socket.io)
- Undo support (backbone.memento?), would be nice if it worked with browser back button
- Easy patchosaur units in faust would be awesome. faust compiles to js, maybe add audiolet architecture files to faust? See this article.
Many of these are not working, and the list is probably out of date. The list is copied from the in-app help (press 'h')