Cynical is a Native Client (NaCl) wrapper for the ZenGarden Pure Data (Pd) runtime. It allows Pd patches to be run in the Google Chrome webbrowser and exposes a simple JavaScript API for creating, querying, and modifying them in real time.
-
Download the NaCl SDK. http://code.google.com/chrome/nativeclient/docs/download.html
-
You might as well read the tutorial. http://code.google.com/chrome/nativeclient/docs/tutorial.html
-
Be sure to read the requirements to run NaCl plugins in Chrome. http://code.google.com/chrome/nativeclient/docs/running.html
-
You must be using at least Chrome v13, and have Native Client enabled in about:flags and about:plugins.
-
Build the project with scons.
-
...
There is currently a very primitive JavaScript API available. Please note the restrictions and limitations listed below.
A single graph can be easily loaded with new newGraph
command. The netlist (as written in a .pd file) is provided as is, and will be parsed by ZenGarden.
function newGraph(netlist) {
ZgnaclModule.postMessage("newGraph:" + netlist);
}
Messages may be sent to the graph with the sendMessage
command. The receiver name, timestamp at which the message should be delivered, and the message formatted as a string are required arguments. In practice the timestamp should always be zero (i.e. 0.0
) such that the message is delivered immediately. The message string can be anything that describes a valid Pd message. Examples include:
0 0 0
: a message with three floats, each equal to zero.hello world 0
: a message with three elements, the first two are strings and the last one is a float.!
: a message with one bang element
// the message is delivered immediately (when in doubt, use this function)
function sendMessage(receiverName, timestamp, messageString) {
ZgnaclModule.postMessage("sendMessage:" + receiverName + ":0:" + messageString);
}
function sendMessageWithTimestamp(receiverName, timestamp, messageString) {
ZgnaclModule.postMessage("sendMessage:" + receiverName + ":" + timestamp + ":" + messageString);
}
In order to receive messages sent from ZenGarden to JavaScript, an external receiver must be registered. For instance, if a receiver named "toJs" is registered, then every message sent to that receiver in ZenGarden (perhaps via a [s toJs]
object) will also be sent to JavaScript. External receivers may be registered and unregistered at any time.
function registerReceiver(receiverName) {
ZgnaclModule.postMessage("registerReceiver:" + receiverName);
}
function unregisterReceiver(receiverName) {
ZgnaclModule.postMessage("unregisterReceiver:" + receiverName);
}
Audio can be easily started and stopped via the play
and pause
commands, their function being self-explanatory. Note that when Cynical is paused, neither audio nor messages are processed. Cynical will behave as if time were standing still. If some kind of mute functionality is desired, while messages continue to be processed, this must be build directly into the patch.
function play() {
ZgnaclModule.postMessage("play");
}
function pause() {
ZgnaclModule.postMessage("pause");
}
For experts only. Messages sent in the reverse direction are polled by a reader thread. This function allows the poll interval (given in milliseconds) to be adjusted. The default interval is 50ms (20Hz). In this case, messages are delivered to JavaScript with up to a 50ms delay (+ a small delay added by Native Client).
function setPipeReadInterval(intervalMs) {
ZgnaclModule.postMessage("setPipeReadInterval:" + intervalMs);
}
// TODO(mhroth)
Currenty there are a number of important limitations to the implementation. These are due to technical hurdles which can be overcome, with the exception of the last point.
Messages cannot be sent from ZenGarden to JavaScript. This includes the output of objects such as [print], or messages sent to external receivers.- This issue is no longer a problem. Arbitrary messages may be sent to ZenGarden from JavaScript (forward direction), and from ZenGarden to JavaScript (reverse direction). In order to receive messages sent in the reverse direction, a receiver name must be registered with ZenGarden. Print statements will also be sent to JavaScript.
- The loaded patch cannot refer to any abstractions. Subpatches are acceptable.
- Binary assets, such as samples, cannot be loaded.
- Microphone or line input is not available. This is unlikely to change soon, if at all, and is due to security issues raised by allowing automatic access to the system microphone in the browser.
Cynical is currently best suited for making synthesizers.
The ZgnaclInstance class contains most of the wrapper code. Start there for an overview. If you just want to use the library and start hacking away in JavaScript, see zgnacl.html for a basic example.
-
Download the NaCl SDK. http://code.google.com/chrome/nativeclient/docs/download.html
-
Ensure you have downloaded the ZenGarden submodule into your zgnacl directory
-
(Whilst cd'd into your zgnacl directory) git submodule init
- git submodule update
- if you get 'Permission denied (publickey), follow the following instructions http://help.github.com/linux-key-setup/
-
In your zgnacl directory edit 'scons' (using vi or nano or any other text editor)
- vi scons
- edit the line beginning "export NACL_SDK_ROOT=/Users…" to reflect the path to the NaCl SDK on your machine e.g. export NACL_SDK_ROOT=/Users/[yourusername]/[pathto]/native_client_sdk_0_5_1052
- exit your text editor
-
Check this has worked by cleaning the target repository
- ./scons -c
-
To build
- ./scons
- You should now see the files being compiled in your terminal window (may take 5-10 minutes)
- Once that has finished there should be (among others) four .nexe files in your zgnacl directory
-
Create a symlink to your zgnacl directory in the examples folder of the NaCl SDK
- ln -s /Users/[yourusername]/[pathto]/zgnacl /Users/[yourusername]/[pathto]/native_client_sdk_0_5_1052/examples
-
Start the NaCl web server
- python /Users/[yourusername]/[pathto]/native_client_sdk_0_5_1052/examples/httpd.py
- note down the port number
-
Run your plug-in in Chrome
- go to http://localhost:[portnumber] (from previous step)
- your zgnacl project should appear here, along with the other example projects
- if it does not, simply append /zgnacl/zgnacl.html to http://localhost:[portnumber]
http://code.google.com/p/nativeclient/
http://www.chromium.org/nativeclient/native-client-documentation-index
http://code.google.com/chrome/nativeclient/
http://code.google.com/chrome/nativeclient/docs/technical_overview.html