# @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