Skip to content

Latest commit

 

History

History

lang

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

@supercollider/lang

NPM downloads MIT License

Client library for the SuperCollider language: sclang. This package enables calling SuperCollider code from JavaScript.

  • Spawns and manages one or more sclang processes.
  • Interpret SuperCollider code and return results as equivalent JavaScript objects.
  • Compile SynthDefs written in the SuperCollider language and return byte code.
  • Used by atom-supercollider

If you are building something that just needs to communicate with sclang then you can install just this package.

Usage

Boot

Start the sclang executable as a subprocess, returning a Promise.

const sc = require("supercolliderjs");

sc.lang.boot().then(
  function(lang) {
    // Up and ready for action
    console.log(lang);

    // quit the process programmatically
    lang.quit();
  },
  // Error handler if it fails to start or fails to compile
  error => console.error,
);

source

const Lang = require("supercolliderjs").lang.default;
const l = new Lang(options);
l.boot();

sclang will compile it's class library, and this may result in syntax or compile errors.

Resolves with a list of SuperCollider class file directories that were compiled:

{dirs: [/*compiled directories*/]}

or rejects with:

{
  dirs: [],
  compileErrors: [],
  parseErrors: [],
  duplicateClasses: [],
  errors[],
  extensionErrors: [],
  stdout: 'compiling class library...etc.'
}

See SclangCompileResult in packages/lang/src/internals/sclang-io.ts for full details.

Interpret simple async await style

const sc = require("supercolliderjs");

sc.lang.boot().then(async function(lang) {
  // This function is declared as `async`
  // so for any function calls that return a Promise we can `await` the result.

  // This is an `async` function, so we can `await` the results of Promises.
  const pyr8 = await lang.interpret("(1..8).pyramid");
  console.log(pyr8);

  const threePromises = [16, 24, 32].map(n => {
    return lang.interpret(`(1..${n}).pyramid`);
  });

  // `interpret` many at the same time and wait until all are fulfilled.
  // Note that `lang` is single threaded,
  // so the requests will still be processed by the interpreter one at a time.
  const pyrs = await Promise.all(threePromises);
  console.log(pyrs);

  // Get a list of all UGen subclasses
  const allUgens = await lang.interpret("UGen.allSubclasses");

  // Post each one to STDOUT
  allUgens.forEach(ugenClass => console.log(ugenClass));

  await lang.quit();
});

source

Interpret with full error handling

const sc = require("supercolliderjs");

function makePyramid(lang) {
  lang.interpret("(1..8).pyramid").then(
    function(result) {
      // result is a native javascript array
      console.log("= " + result);
      lang.quit();
    },
    function(error) {
      // syntax or runtime errors
      // are returned as javascript objects
      console.error(error);
    },
  );
}

// Verbose example to show Promises and full error handling
sc.lang.boot().then(
  // ok booted
  lang => {
    makePyramid(lang);
  },
  // failed to boot
  error => {
    console.error(error);
    // Either:
    // 1. The executable may be missing, incorrect path etc.
    // 2. The class library may have failed with compile errors
  },
);

source

Options

sc.lang.boot(options)
// or
const Lang = require("supercolliderjs").lang.default;
const l = new Lang(options);
l.boot();
{
  // post verbose messages to console
  debug: boolean;
  // echo all commands sent TO sclang to console
  echo: boolean;
  // provide an alternate console like object for logging. eg. winston
  log?: Console;
  // path to sclang executable
  sclang: string;
  // To start sclang and immediately execute one file
  executeFile?: string;
  // path to existing non-default conf file
  sclang_conf?: string;

  // post sclang stdin to console
  stdin: boolean;
  // if specifying a non-default conf file then you may wish to fail if you got the path wrong
  // rather than fall back to the default one
  failIfSclangConfIsMissing: boolean;
  // pass in a configuration without having to write it to a file
  conf: SCLangConf;
}

See: packages/lang/src/options.ts

executeFile

await lang.executeFile("./some-supercollider-piece.scd");

Documentation

Documentation

Compatibility

Works on Node 10+

Source code is written in TypeScript and is usable in JavaScript es2018 or TypeScript projects.

Contribute

License

MIT license