# @supercollider/server-plus [![NPM downloads][npm-downloads-image]][npm-url] [![MIT License][license-image]][license-url] Server class with added methods for Group, Synth and SynthDef creation This extends the `Server` class from `@supercollider/server`, adding methods for commonly used constructs. Each method returns a Promise that resolves when the resource is successfully created. Each method accepts Promises as arguments. ```js const sc = require("supercolliderjs"); sc.server.boot().then(async server => { // Compile synthDef from a file, returning a Promise const synthDef = server.loadSynthDef("formant", "./formant.scd"); // Map 0..1 to an exponential frequency range from 100..8000 const randFreq = () => sc.map.mapWithSpec(Math.random(), { minval: 100, maxval: 8000, warp: "exp", }); const synthPromise = server.synth( // The promise will be resolved before the command to create the synth // is sent. synthDef, { fundfreq: randFreq(), formantfreq: randFreq(), bwfreq: randFreq(), pan: sc.map.linToLin(0, 1, -1, 1, Math.random()), }, ); // await a promise to get it's value const synth = await synthPromise; // This continues execution after the "node is playing" response is received. console.log(synth); }); ``` source ## synth Spawn a synth ```js synth( synthDef: SynthDef, args: Params = {}, group?: Group, addAction: number = msg.AddActions.TAIL, ): Promise; ``` ## group A collection of other nodes organized as a linked list. The Nodes within a Group may be controlled together, and may be both Synths and other Groups. Groups are thus useful for controlling a number of nodes at once, and when used as targets can be very helpful in controlling order of execution. ```js group(group?: Group, addAction: number = msg.AddActions.TAIL): Promise; ``` ## synthDefs Compile multiple SynthDefs either from source or path. If you have more than one to compile then always use this as calling `server.synthDef` multiple times will start up multiple supercollider interpreters. This is harmless, but very inefficient. defs - An object with `{defName: spec, ...}` where spec is an object like `{source: "SynthDef('noise', { ...})"}` or `{path: "./noise.scd"}` Returns an object with the synthDef names as keys and Promises as values. Each Promise will resolve with a SynthDef. Each Promises can be supplied directly to `server.synth()` ```js synthDefs(defs: { [defName: string]: SynthDefCompileRequest }): { [defName: string]: Promise } ``` ## loadSynthDef Load and compile a SynthDef from path and send it to the server. ```js loadSynthDef(defName: string, path: string): Promise; ``` ## synthDef Compile a SynthDef from supercollider source code and send it to the server. ```js synthDef(defName: string, sourceCode: string): Promise; ``` ## buffer Allocate a Buffer on the server. ```js buffer(numFrames: number, numChannels = 1): Promise; ``` ## audioBus Allocate an audio bus. ```js audioBus(numChannels = 1): AudioBus; ``` ## controlBus Allocate a control bus. ```js controlBus(numChannels = 1): ControlBus; ``` ## readBuffer Allocate a Buffer on the server and load a sound file into it. Problem: scsynth uses however many channels there are in the sound file, but the client (sclang or supercolliderjs) doesn't know how many there are. ```js readBuffer(path: string, numChannels = 2, startFrame = 0, numFramesToRead = -1): Promise; ``` ### Kitchen sink ```js // @supercollider/server-plus interface const sc = require("supercolliderjs"); sc.server.boot().then(async server => { // Compile a SynthDef from inline SuperCollider language code and send it to the server const def = await server.synthDef( "formant", `{ |out=0, fundfreq=440, formantfreq=440, bwfreq=100, timeScale=1, pan=0| var saw, envd, panned; saw = Formant.ar(fundfreq, formantfreq, bwfreq); envd = saw * EnvGen.kr(Env.sine(0.1, 0.2), timeScale: timeScale, doneAction: 2); panned = Pan2.ar(envd * AmpCompA.kr(fundfreq, 0.2, 0.7), pan); OffsetOut.ar(out, panned); }`, ); // Create group at the root const group = server.group(); const freqSpec = { minval: 100, maxval: 8000, warp: "exp", }; // Map 0..1 to an exponential frequency range from 100..8000 const randFreq = () => sc.map.mapWithSpec(Math.random(), freqSpec); // function to spawn one synth event const spawn = dur => { server.synth( def, { fundfreq: randFreq(), formantfreq: randFreq(), bwfreq: randFreq(), pan: sc.map.linToLin(0, 1, -1, 1, Math.random()), timeScale: dur, // spawn each synth into the same group }, group, ); const next = Math.random() * 0.25; // Schedule this function again: setTimeout(() => spawn(next), next * 1000); }; // spawn the first event spawn(Math.random()); }, console.error); ``` source Documentation ------------- [Documentation](https://crucialfelix.github.io/supercolliderjs/#/packages/server-plus/api) Compatibility ------------- Works on Node 10+ Source code is written in TypeScript and is usable in JavaScript [es2018](https://2ality.com/2017/02/ecmascript-2018.html) or [TypeScript](https://www.typescriptlang.org/docs/home.html) projects. Contribute ---------- - Issue Tracker: https://github.com/crucialfelix/supercolliderjs/issues - Source Code: https://github.com/crucialfelix/supercolliderjs License ------- MIT license [license-image]: http://img.shields.io/badge/license-MIT-blue.svg?style=flat [license-url]: LICENSE [npm-url]: https://npmjs.org/package/@supercollider/server-plus [npm-version-image]: http://img.shields.io/npm/v/@supercollider/server-plus.svg?style=flat [npm-downloads-image]: http://img.shields.io/npm/dm/@supercollider/server-plus.svg?style=flat [travis-url]: http://travis-ci.org/crucialfelix/supercolliderjs [travis-image]: https://travis-ci.org/crucialfelix/supercolliderjs.svg?branch=master