Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
148 lines (104 sloc) 7.24 KB

Cynical Overview

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.

How to Get Started

The JavaScript API

There is currently a very primitive JavaScript API available. Please note the restrictions and limitations listed below.

newGraph

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);
}

sendMessage

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);
}

registerReceiver

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);
}

play & pause

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");
}

setPipeReadInterval

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);
}

An Example

// TODO(mhroth)

Restrictions and Limitations

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.

Where the Action is

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.

Build the project with scons.

  • 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

  • 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

Testing your plug-in in the browser

  • 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
    • 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]

Native Client docs

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

Something went wrong with that request. Please try again.