supersonic-scsynth 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +27 -0
- package/README.md +320 -0
- package/dist/README.md +21 -0
- package/dist/supersonic.js +2411 -0
- package/dist/wasm/manifest.json +8 -0
- package/dist/wasm/scsynth-nrt.wasm +0 -0
- package/dist/workers/debug_worker.js +274 -0
- package/dist/workers/osc_in_worker.js +274 -0
- package/dist/workers/osc_out_worker.js +519 -0
- package/dist/workers/scsynth_audio_worklet.js +531 -0
- package/package.json +51 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
GNU GENERAL PUBLIC LICENSE
|
|
2
|
+
Version 3, 29 June 2007
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
|
5
|
+
Everyone is permitted to copy and distribute verbatim copies
|
|
6
|
+
of this license document, but changing it is not allowed.
|
|
7
|
+
|
|
8
|
+
This program is free software: you can redistribute it and/or modify
|
|
9
|
+
it under the terms of the GNU General Public License as published by
|
|
10
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+
(at your option) any later version.
|
|
12
|
+
|
|
13
|
+
This program is distributed in the hope that it will be useful,
|
|
14
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
GNU General Public License for more details.
|
|
17
|
+
|
|
18
|
+
You should have received a copy of the GNU General Public License
|
|
19
|
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
SuperSonic - WebAssembly synthesis engine
|
|
24
|
+
Copyright (C) 2025 Sam Aaron (where source differs from SuperCollider)
|
|
25
|
+
|
|
26
|
+
Based on SuperCollider's scsynth
|
|
27
|
+
Copyright (C) 2002-2023 James McCartney and SuperCollider contributors
|
package/README.md
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# SuperSonic
|
|
2
|
+
|
|
3
|
+
> **Warning - Super Alpha Status**: SuperSonic is currently in active development (v0.1.0). The API is likely to change between releases. Feedback welcome!
|
|
4
|
+
|
|
5
|
+
This is a WebAssembly port of SuperCollider's highly flexible and powerful synthesis engine scsynth.
|
|
6
|
+
|
|
7
|
+
SuperSonic's scsynth engine runs within a web AudioWorklet giving it access to a high-priority audio thread for real-time browser-based audio synthesis.
|
|
8
|
+
|
|
9
|
+
The main API for SuperSonic is scsynth's OSC API with support for immediate and scheduled execution of OSC messages and bundles. It's also possible to register a handler to receive OSC replies from scsynth in addition to debug messages that would normally have been printed to stdout.
|
|
10
|
+
|
|
11
|
+
Note: SuperSonic uses a SharedBuffer to send and receive OSC messages from scsynth which requires specific COOP/COEP headers to be set in your web browser (see below).
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
### Option 1: npm Package (Recommended)
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Core engine only (~2MB)
|
|
20
|
+
npm install supersonic-scsynth
|
|
21
|
+
|
|
22
|
+
# Or install everything (engine + synthdefs + samples)
|
|
23
|
+
npm install supersonic-scsynth-bundle
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Option 2: CDN (No build required)
|
|
27
|
+
|
|
28
|
+
```html
|
|
29
|
+
<script type="module">
|
|
30
|
+
import { SuperSonic } from 'https://unpkg.com/supersonic-scsynth@0.1.0';
|
|
31
|
+
|
|
32
|
+
const sonic = new SuperSonic({
|
|
33
|
+
audioBaseURL: 'https://unpkg.com/supersonic-scsynth-samples-bd@0.1.0/samples/'
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
await sonic.init();
|
|
37
|
+
|
|
38
|
+
// Load synthdefs from CDN
|
|
39
|
+
await sonic.loadSynthDefs(
|
|
40
|
+
['sonic-pi-beep'],
|
|
41
|
+
'https://unpkg.com/supersonic-scsynth-synthdefs@0.1.0/synthdefs/'
|
|
42
|
+
);
|
|
43
|
+
</script>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Option 3: Pre-built Distribution
|
|
47
|
+
|
|
48
|
+
The 'nightly' (i.e. for every new commit) pre-built distribution files are published here:
|
|
49
|
+
|
|
50
|
+
https://samaaron.github.io/supersonic/supersonic-dist.zip
|
|
51
|
+
|
|
52
|
+
## Package Structure
|
|
53
|
+
|
|
54
|
+
SuperSonic is published as multiple npm packages to keep the core engine small:
|
|
55
|
+
|
|
56
|
+
### Core Package
|
|
57
|
+
- **`supersonic-scsynth`** (~2MB) - The WebAssembly scsynth engine
|
|
58
|
+
- GPL-3.0-or-later license
|
|
59
|
+
|
|
60
|
+
### Resource Packages
|
|
61
|
+
- **`supersonic-scsynth-synthdefs`** (~7MB) - All 120 Sonic Pi synthdefs
|
|
62
|
+
- MIT license
|
|
63
|
+
- From [Sonic Pi](https://github.com/sonic-pi-net/sonic-pi)
|
|
64
|
+
|
|
65
|
+
- **`supersonic-scsynth-samples`** - Meta-package for all Sonic Pi samples
|
|
66
|
+
- CC0-1.0 license (public domain)
|
|
67
|
+
- Includes 18 category packages (install individually to save space):
|
|
68
|
+
- `supersonic-scsynth-samples-bd` - Bass drums
|
|
69
|
+
- `supersonic-scsynth-samples-sn` - Snares
|
|
70
|
+
- `supersonic-scsynth-samples-hat` - Hi-hats
|
|
71
|
+
- `supersonic-scsynth-samples-loop` - Drum loops
|
|
72
|
+
- `supersonic-scsynth-samples-ambi` - Ambient sounds
|
|
73
|
+
- `supersonic-scsynth-samples-bass` - Bass sounds
|
|
74
|
+
- `supersonic-scsynth-samples-elec` - Electronic sounds
|
|
75
|
+
- `supersonic-scsynth-samples-glitch` - Glitch sounds
|
|
76
|
+
- `supersonic-scsynth-samples-guit` - Guitar sounds
|
|
77
|
+
- `supersonic-scsynth-samples-perc` - Percussion
|
|
78
|
+
- `supersonic-scsynth-samples-misc` - Miscellaneous
|
|
79
|
+
- Plus: arovane, drum, mehackit, ride, tabla, tbd, vinyl
|
|
80
|
+
|
|
81
|
+
### Convenience Package
|
|
82
|
+
- **`supersonic-scsynth-bundle`** - Includes core + synthdefs + all samples
|
|
83
|
+
- Install this to get everything in one command
|
|
84
|
+
|
|
85
|
+
## Building from Source
|
|
86
|
+
|
|
87
|
+
If you are familiar with Docker, you can build and run the example using the following commands:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
docker build -t supersonic .
|
|
91
|
+
docker run --rm -it -p 8002:8002 supersonic
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Or to build and run locally follow the instructions below.
|
|
95
|
+
|
|
96
|
+
### 1. Build
|
|
97
|
+
|
|
98
|
+
**Prerequisites:**
|
|
99
|
+
- [Emscripten SDK](https://emscripten.org/docs/getting_started/downloads.html)
|
|
100
|
+
- [esbuild](https://esbuild.github.io/)
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# Activate Emscripten
|
|
104
|
+
source ~/path/to/emsdk_env.sh
|
|
105
|
+
|
|
106
|
+
# Build (compiles C++ to WASM and bundles JavaScript)
|
|
107
|
+
./build.sh
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Outputs to `dist/` directory (~1.5MB WASM + ~80KB JS).
|
|
111
|
+
|
|
112
|
+
### 2. Serve Demo
|
|
113
|
+
|
|
114
|
+
Start the basic Ruby webserver with the correct headers:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
ruby example/server.rb
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Open: http://localhost:8002/demo.html
|
|
121
|
+
|
|
122
|
+
## Browser Requirements
|
|
123
|
+
|
|
124
|
+
**Minimum Versions:**
|
|
125
|
+
- Chrome/Edge 92+
|
|
126
|
+
- Firefox 79+
|
|
127
|
+
- Safari 15.2+
|
|
128
|
+
|
|
129
|
+
**Required Features:**
|
|
130
|
+
- SharedArrayBuffer (requires COOP/COEP headers - see below)
|
|
131
|
+
- AudioWorklet
|
|
132
|
+
- WebAssembly with threads support
|
|
133
|
+
|
|
134
|
+
**Required HTTP Headers:**
|
|
135
|
+
|
|
136
|
+
Important: your server must send these headers for SharedArrayBuffer to work:
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
Cross-Origin-Opener-Policy: same-origin
|
|
140
|
+
Cross-Origin-Embedder-Policy: require-corp
|
|
141
|
+
Cross-Origin-Resource-Policy: cross-origin
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
See `example/server.rb` for a reference implementation.
|
|
145
|
+
|
|
146
|
+
## Basic Usage
|
|
147
|
+
|
|
148
|
+
### Minimal Example (Core Only)
|
|
149
|
+
|
|
150
|
+
```javascript
|
|
151
|
+
import { SuperSonic } from './dist/supersonic.js';
|
|
152
|
+
|
|
153
|
+
const sonic = new SuperSonic();
|
|
154
|
+
await sonic.init();
|
|
155
|
+
|
|
156
|
+
sonic.send('/notify', 1);
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### With Synthdefs and Samples (npm/CDN)
|
|
160
|
+
|
|
161
|
+
```javascript
|
|
162
|
+
import { SuperSonic } from 'https://unpkg.com/supersonic-scsynth@0.1.0';
|
|
163
|
+
|
|
164
|
+
// Configure sample path (required for buffer loading)
|
|
165
|
+
const sonic = new SuperSonic({
|
|
166
|
+
audioBaseURL: 'https://unpkg.com/supersonic-scsynth-samples-bd@0.1.0/samples/'
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
await sonic.init();
|
|
170
|
+
|
|
171
|
+
// Load synthdefs (baseUrl is required)
|
|
172
|
+
await sonic.loadSynthDefs(
|
|
173
|
+
['sonic-pi-beep', 'sonic-pi-tb303'],
|
|
174
|
+
'https://unpkg.com/supersonic-scsynth-synthdefs@0.1.0/synthdefs/'
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
// Play a synth
|
|
178
|
+
sonic.send('/s_new', 'sonic-pi-beep', -1, 0, 1, 'note', 60);
|
|
179
|
+
|
|
180
|
+
// Load and play a sample
|
|
181
|
+
await sonic.allocReadBuffer(0, 'bd_haus.flac');
|
|
182
|
+
sonic.send('/s_new', 'sonic-pi-basic_mono_player', -1, 0, 1, 'buf', 0);
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
See `example/demo.html` for a complete working example.
|
|
186
|
+
|
|
187
|
+
### API Reference
|
|
188
|
+
|
|
189
|
+
**SuperSonic Class:**
|
|
190
|
+
- `new SuperSonic(options)` - Create instance
|
|
191
|
+
- `options.audioBaseURL` - Base URL for sample files (required for buffer loading)
|
|
192
|
+
- `options.audioPathMap` - Custom mapping of sample names to URLs
|
|
193
|
+
- `async init()` - Initialize audio engine
|
|
194
|
+
- `async loadSynthDefs(names, baseUrl)` - Load synth definitions (baseUrl required)
|
|
195
|
+
- `async allocReadBuffer(bufnum, filename)` - Load audio file into buffer
|
|
196
|
+
- `send(address, ...args)` - Send OSC message (auto-detects types)
|
|
197
|
+
- `sendOSC(oscBytes, options)` - Send pre-encoded OSC bytes
|
|
198
|
+
- `onInitialized` - Callback when ready
|
|
199
|
+
- `onError(error)` - Error callback
|
|
200
|
+
- `onMessageReceived(msg)` - Incoming OSC message callback
|
|
201
|
+
- `onMessageSent(oscData)` - Outgoing OSC message callback
|
|
202
|
+
|
|
203
|
+
**Sending OSC Messages:**
|
|
204
|
+
```javascript
|
|
205
|
+
// Types are auto-detected: strings → 's', integers → 'i', floats → 'f'
|
|
206
|
+
sonic.send('/notify', 1);
|
|
207
|
+
sonic.send('/s_new', 'sonic-pi-beep', -1, 0, 0);
|
|
208
|
+
sonic.send('/n_set', 1000, 'freq', 440.0, 'amp', 0.5);
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Common OSC Commands:**
|
|
212
|
+
- `/d_recv` - Load synth definition
|
|
213
|
+
- `/s_new` - Create synth
|
|
214
|
+
- `/n_free` - Free node
|
|
215
|
+
- `/n_set` - Set node parameters
|
|
216
|
+
- `/notify` - Enable server notifications
|
|
217
|
+
|
|
218
|
+
See [SuperCollider Server Command Reference](https://doc.sccode.org/Reference/Server-Command-Reference.html) for full OSC API.
|
|
219
|
+
|
|
220
|
+
## Integration Guide
|
|
221
|
+
|
|
222
|
+
### Recommended: npm Packages
|
|
223
|
+
|
|
224
|
+
Install the core package and any resources you need:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
# Core engine
|
|
228
|
+
npm install supersonic-scsynth
|
|
229
|
+
|
|
230
|
+
# Synthdefs (optional)
|
|
231
|
+
npm install supersonic-scsynth-synthdefs
|
|
232
|
+
|
|
233
|
+
# Individual sample categories (optional)
|
|
234
|
+
npm install supersonic-scsynth-samples-bd
|
|
235
|
+
npm install supersonic-scsynth-samples-loop
|
|
236
|
+
|
|
237
|
+
# Or everything at once
|
|
238
|
+
npm install supersonic-scsynth-bundle
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Then use via CDN in your HTML:
|
|
242
|
+
|
|
243
|
+
```html
|
|
244
|
+
<script type="module">
|
|
245
|
+
import { SuperSonic } from 'https://unpkg.com/supersonic-scsynth@0.1.0';
|
|
246
|
+
|
|
247
|
+
const sonic = new SuperSonic({
|
|
248
|
+
audioBaseURL: 'https://unpkg.com/supersonic-scsynth-samples-bd@0.1.0/samples/'
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
await sonic.init();
|
|
252
|
+
await sonic.loadSynthDefs(
|
|
253
|
+
['sonic-pi-beep'],
|
|
254
|
+
'https://unpkg.com/supersonic-scsynth-synthdefs@0.1.0/synthdefs/'
|
|
255
|
+
);
|
|
256
|
+
</script>
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Alternative: Manual File Integration
|
|
260
|
+
|
|
261
|
+
If you're building from source or need local files, copy these from `dist/`:
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
dist/
|
|
265
|
+
├── supersonic.js # Main entry point (ES module)
|
|
266
|
+
├── wasm/
|
|
267
|
+
│ └── scsynth-nrt.wasm # Audio engine (~1.5MB)
|
|
268
|
+
└── workers/
|
|
269
|
+
├── osc_in_worker.js # OSC input handling
|
|
270
|
+
├── osc_out_worker.js # OSC output handling
|
|
271
|
+
├── debug_worker.js # Debug logging
|
|
272
|
+
└── scsynth_audio_worklet.js # AudioWorklet processor
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Resources (synthdefs/samples) are available separately via npm packages.
|
|
276
|
+
|
|
277
|
+
### Path Configuration
|
|
278
|
+
|
|
279
|
+
**Required Configuration:**
|
|
280
|
+
|
|
281
|
+
Sample and synthdef paths must be explicitly configured:
|
|
282
|
+
|
|
283
|
+
```javascript
|
|
284
|
+
const sonic = new SuperSonic({
|
|
285
|
+
audioBaseURL: 'https://unpkg.com/supersonic-scsynth-samples-bd@0.1.0/samples/'
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
await sonic.loadSynthDefs(
|
|
289
|
+
['sonic-pi-beep'],
|
|
290
|
+
'https://unpkg.com/supersonic-scsynth-synthdefs@0.1.0/synthdefs/'
|
|
291
|
+
);
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
**Engine Paths (Default):**
|
|
295
|
+
|
|
296
|
+
The core engine expects these files relative to your HTML:
|
|
297
|
+
- WASM: `./dist/wasm/scsynth-nrt.wasm`
|
|
298
|
+
- AudioWorklet: `./dist/workers/scsynth_audio_worklet.js`
|
|
299
|
+
- Workers: `./dist/workers/osc_out_worker.js`, `osc_in_worker.js`, `debug_worker.js`
|
|
300
|
+
|
|
301
|
+
**Custom Engine Paths:**
|
|
302
|
+
|
|
303
|
+
```javascript
|
|
304
|
+
const sonic = new SuperSonic();
|
|
305
|
+
sonic.config.wasmUrl = '/custom/path/scsynth-nrt.wasm';
|
|
306
|
+
sonic.config.workletUrl = '/custom/path/scsynth_audio_worklet.js';
|
|
307
|
+
await sonic.init();
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
**Note:** Worker paths are currently hardcoded to `./dist/workers/` and cannot be configured.
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
## License
|
|
314
|
+
|
|
315
|
+
GPL v3 - This is a derivative work of SuperCollider
|
|
316
|
+
|
|
317
|
+
## Credits
|
|
318
|
+
|
|
319
|
+
Based on [SuperCollider](https://supercollider.github.io/) by James McCartney and the SuperCollider community. This AudioWorklet port was massively inspired and motivated by
|
|
320
|
+
Hanns Holger Rutz who started the first port of scsynth to WASM and Dennis Scheiba who took the baton and continued this great work. Thank-you also to everyone in the SuperCollider community, you're all beautiful people.
|
package/dist/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# SuperSonic - Demonstration
|
|
2
|
+
|
|
3
|
+
A working example of SuperSonic in the browser.
|
|
4
|
+
|
|
5
|
+
Send and receive OSC, view debug, built-in scope and support for loading some of the Sonic Pi synthdefs to play with.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
For this example you need Ruby on your system - this is just so we can fire up a simple http server with the correct COOP/COEP headers set. If you're familiar with web server, you can easily fire up your own - ensure the headers are set and serve this example directory and everything should just work immedisatey.
|
|
10
|
+
|
|
11
|
+
## Running
|
|
12
|
+
|
|
13
|
+
Simple start the server with `ruby server.rb` and then go to the URL printed to the terminal.
|
|
14
|
+
|
|
15
|
+
## Enjoy
|
|
16
|
+
|
|
17
|
+
Have fun!
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|