Note: most hacking on WebPd is now occurring at Sébastien Piquemal's GitHub Fork
WebPd aims to allow a subset of Pure Data audio patches to run in the browser without plugins. Right now the focus is on DSP objects, to enable you to mock up audio engines in Pd, put them on the web, and control them with Javascript.
Here are the test pages (i.e. examples of Pd patches which run in a webpage on Firefox). To run these, you will need Firefox version 4. You can search for Firefox 4 and download it from the Mozilla homepage. More information about the Firefox Audio Data API is available.
If you want to keep abreast of the latest changes, here is the WebPd Google Code page. You might also like to check my blog.
Copyright Chris McCormick, 2010. Licensed under the terms of the AGPLv3 or a later version of that license.
Here is the official Pure Data documentation by Miller Puckette, the creator of Pure Data. Note: very little of the full Pure Data functionality has been implemented yet. Most things probably won't work.
Right now I'm really looking for people to contribute DSP/audio objects (or 'tilde' objects with names ending with '~'). The messaging side of Pd is only partially implemented. Here's how you can contribute code:
scrot -s my-test-patch.png
under linux and select the portion of your patch to use as a thumbnail.bzr add
and bzr commit
to commit your changes (or git commit
, svn commit
, whatever).bzr push
. Often the best way is to push it over sftp or ftp to a web-accessible directory, and then send me the URL. e.g. bzr push sftp://myserver.com/my/web/directory/
. If you are using git you can also push your changes into a github repository and I will merge them from there with git-svn.You can use SVN to get a read-only copy of the source code from http://code.google.com/p/web-pure-data/ with the command svn checkout http://web-pure-data.googlecode.com/svn/trunk/ webpd-readonly
. Feel free to send me patches using diff, or else I can give you commit access to Google Code repository.
You can use bzr to get the source code, which is what I use for local development.
apt-get install bzr
.bzr branch http://mccormick.cx/dev/webpd/
.The advantage of using bzr is that you can make local commits in your copy of the source, and once you are finished you can push those commits to me in one bunch. With SVN you can't push the changes back into the repository unless I give you commit access on the project.
You could also use git-svn to fetch a copy of the source from the google code repository, and I will merge git pushes if you make them available somewhere like github. Use the git-svn instructions from github if you'd like to do that.
Here is the source code of the [+~] object, which adds two audio inlets together, with verbose comments. You can find this code inside pd.js in the PdObjects array. The really important bit is the "dsptick" method which is where the actual audio processing goes on. You can copy and paste this object to implement new Pd objects.
// Use the object name as it appears in the Pd patch here
"+~": {
// Endpoints are special objects where audio finishes up and exits the patch.
// e.g. [dac~] (audio output), [outlet~] (output to another patch), and [print~] (output to the console)
// Most objects aren't endpoints.
"endpoint": false,
// How many audio outlets i have - an audio buffer will be created for each outlet.
"buffers": 1,
// This method is run when the object is created.
// You can do stuff in here like read in the arguments and initialise variables.
"init": function(args) {
if (args.length >= 6) {
this.val = parseFloat(args[5]);
}
this.pd.log(this.inlets);
},
// This is the most important method, and gets called each time the dsp graph is computed (every frame).
// In here you should usually be taking a vector of audio data from your inlets with this.inletBuffer(0)
// and then applying some function to every piece of audio data, and then placing the resulting output
// into this object's outlet buffer.
"dsptick": function() {
// This part checks whether the object was initialised with a fixed float value. e.g. [+~ 0.5]
// If it has been initialised with a fixed float, then we want to multiply every piece of data
// in the audio buffer by that fixed value.
if (this.val) {
// Get the incoming data buffer.
var i1 = this.inletBuffer(0);
// Loop through the incoming data and multiply each value by our fixed integer.
// Store the result in our outlet buffer.
for (var i=0; i < i1.length; i++) {
this.outlets[0][i] = i1[i] + this.val;
}
// If we are instead multiplying two audio streams together we execute this bit.
} else {
// Get the incoming data buffers of both audio streams.
var i1 = this.inletBuffer(0);
var i2 = this.inletBuffer(1);
// Loop through the incoming data from both streams, multiplying them together.
// Store the result in our outlet buffer.
for (var i=0; i < i1.length; i++) {
this.outlets[0][i] = i1[i] + i2[i];
}
}
},
},
Have fun!
Implemented objects are prefixed with a '>', whilst unimplemented objects are prefixed with a '<'.
AUDIO MATH ---------- > +~ > -~ > *~ > /~ > max~ > min~ > clip~ < q8_rsqrt~ < q8_sqrt~ > wrap~ < fft~ < ifft~ < rfft~ < rifft~ > pow~ > log~ > exp~ > abs~ < framp~ > mtof~ > ftom~ > rmstodb~ > dbtorms~ > rmstopow~ > powtorms~ AUDIO GLUE ---------- > dac~ < adc~ > sig~ > line~ < vline~ < threshold~ < snapshot~ < vsnapshot~ < bang~ < samplerate~ < send~, s~ < receive~, r~ < throw~ < catch~ < block~ < switch~ < readsf~ < writesf~ AUDIO SOURCES ------------- > phasor~ > cos~ > osc~ < tabwrite~ < tabplay~ > tabread~ < tabread4~ < tabosc4~ < tabsend~ < tabreceive~ AUDIO FILTERS ------------- < vcf~ > noise~ < env~ > hip~ > lop~ < bp~ < biquad~ > samphold~ < print~ < rpole~ < rzero~ < rzero_rev~ < cpole~ < czero~ < czero_rev~ AUDIO DELAY ----------- < delwrite~ < delread~ < vd~ < pd > table < inlet < outlet < inlet~ < outlet~ GLUE ---- < bang, b, bng < float, f < symbol < int < send, s > receive, r > select, sel < route > pack > unpack > trigger, t > spigot < moses < until < print < makefilename < change < swap < value < toggle < list (prepend, append, trim, length) TIME ---- < delay, del < metro < line < timer < cputime < realtime < pipe MATH ---- > + < - > * < / < pow < == < != < > < < < >= < <= < & < && < | < || < % < mtof < powtodb < rmstodb < ftom < dbtopow < dbtorms < mod < div < sin < cos < tan < atan < atan2 < sqrt < log < exp < abs < random < max < min < clip < wrap MIDI ---- < notein < ctlin < pgmin < bendin < touchin < polytouchin < midiin < sysexin < noteout < ctlout < pgmout < bendout < touchout < polytouchout < midiout < makenote < stripnote TABLES ------ < tabread < tabread4 < tabwrite < soundfiler MISC ---- > loadbang < serial < netsend < netreceive < qlist < textfile < openpanel < savepanel < bag < poly < key < keyup < keyname < declare DATA STRUCTURES --------------- < struct < drawcurve < filledcurve < drawpolygon < filledpolygon < plot < drawnumber ACCESSING DATA -------------- < pointer < get < set < element < getsize < setsize < append < sublist OBSOLETE -------- < namecanvas < scalar < scope~ < template ;