├── .gitignore ├── LICENCE ├── README.md ├── examples ├── before-after.js ├── before-after.js~ ├── run.js ├── run.js~ ├── set.js ├── set.js~ └── sine.sc ├── node_modules └── node-osc │ ├── README.rst │ ├── index.js │ └── lib │ ├── node-jspack │ ├── LICENSE │ ├── README │ └── jspack.js │ └── osc.js └── supercollider.js /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Konstantinos Patsourakis, George Stagakis 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Nodejs client for supercollider still in the very begining trying to implement some more of the basic sc messages... -------------------------------------------------------------------------------- /examples/before-after.js: -------------------------------------------------------------------------------- 1 | var sc = require('../supercollider')() 2 | 3 | // listen on all messages 4 | sc.on('message', function(message, address) { 5 | console.log('message:', message, address) 6 | }) 7 | 8 | // create synths 9 | lfo = sc.Synth('RingMod', [1,1,'freq',10]) 10 | sine = sc.Synth('sine', [1, 1, 'freq', 440, 'amp', 0.2]) 11 | 12 | 13 | //apply lfo 14 | setTimeout(function(){ 15 | sine.before(lfo.node) 16 | },1000) 17 | 18 | //move out lfo 19 | setTimeout(function(){ 20 | sine.after(lfo.node) 21 | },2000) 22 | 23 | 24 | 25 | // free 26 | setTimeout(function() { 27 | sine.free() 28 | lfo.free() 29 | process.exit(0) 30 | }, 3000) 31 | 32 | -------------------------------------------------------------------------------- /examples/before-after.js~: -------------------------------------------------------------------------------- 1 | var sc = require('../../supercollider')() 2 | 3 | // listen on all messages 4 | sc.on('message', function(message, address) { 5 | console.log('message:', message, address) 6 | }) 7 | 8 | // create synths 9 | lfo = sc.Synth('RingMod', [1,1,'freq',10]) 10 | sine = sc.Synth('sine', [1, 1, 'freq', 440, 'amp', 0.2]) 11 | 12 | 13 | //apply lfo 14 | setTimeout(function(){ 15 | sine.before(lfo.node) 16 | },1000) 17 | 18 | //move out lfo 19 | setTimeout(function(){ 20 | sine.after(lfo.node) 21 | },2000) 22 | 23 | 24 | 25 | // free 26 | setTimeout(function() { 27 | sine.free() 28 | lfo.free() 29 | process.exit(0) 30 | }, 3000) 31 | 32 | -------------------------------------------------------------------------------- /examples/run.js: -------------------------------------------------------------------------------- 1 | var sc = require('../supercollider')() 2 | 3 | // listen on all messages 4 | sc.on('message', function(message, address) { 5 | console.log('message:', message, address) 6 | }) 7 | 8 | // create a synth 9 | sine = sc.Synth('sine', [1, 1, 'freq', 440, 'amp', 0.2]) 10 | 11 | // change amp after 500 ms 12 | setTimeout(function() { 13 | sine.run(0) 14 | }, 500) 15 | 16 | // change amp after 500 ms 17 | setTimeout(function() { 18 | sine.run(1) 19 | }, 1000) 20 | 21 | // free after 3000 ms 22 | setTimeout(function() { 23 | sine.free() 24 | process.exit(0) 25 | }, 3000) -------------------------------------------------------------------------------- /examples/run.js~: -------------------------------------------------------------------------------- 1 | var sc = require('../supercollider')() 2 | 3 | // listen on all messages 4 | sc.on('message', function(message, address) { 5 | console.log('message:', message, address) 6 | }) 7 | 8 | // create a synth 9 | sine = sc.Synth('sine', [1, 1, 'freq', 440, 'amp', 0.2]) 10 | 11 | // change amp after 500 ms 12 | setTimeout(function() { 13 | sine.set('amp', 0.6) 14 | }, 500) 15 | 16 | // free after 3000 ms 17 | setTimeout(function() { 18 | sine.free() 19 | process.exit(0) 20 | }, 3000) -------------------------------------------------------------------------------- /examples/set.js: -------------------------------------------------------------------------------- 1 | var sc = require('../supercollider')() 2 | 3 | // listen on all messages 4 | sc.on('message', function(message, address) { 5 | console.log('message:', message, address) 6 | }) 7 | 8 | // create a synth 9 | sine = sc.Synth('sine', [1, 1, 'freq', 440, 'amp', 0.2]) 10 | 11 | // change amp after 500 ms 12 | setTimeout(function() { 13 | sine.set('freq', 200) 14 | }, 500) 15 | 16 | // free after 3000 ms 17 | setTimeout(function() { 18 | sine.free() 19 | process.exit(0) 20 | }, 3000) -------------------------------------------------------------------------------- /examples/set.js~: -------------------------------------------------------------------------------- 1 | var sc = require('../supercollider')() 2 | 3 | // listen on all messages 4 | sc.on('message', function(message, address) { 5 | console.log('message:', message, address) 6 | }) 7 | 8 | // create a synth 9 | sine = sc.Synth('sine', [1, 1, 'freq', 440, 'amp', 0.2]) 10 | 11 | // change amp after 500 ms 12 | setTimeout(function() { 13 | sine.set('amp', 0.6) 14 | }, 500) 15 | 16 | // free after 3000 ms 17 | setTimeout(function() { 18 | sine.free() 19 | process.exit(0) 20 | }, 3000) -------------------------------------------------------------------------------- /examples/sine.sc: -------------------------------------------------------------------------------- 1 | s = Server.local; 2 | s.boot; 3 | 4 | ( 5 | SynthDef("sine", { 6 | |freq=440, amp=0.1| 7 | var osc; 8 | osc = SinOsc.ar(freq, 0, amp); 9 | Out.ar(0, osc); 10 | }).send(s); 11 | ) 12 | 13 | 14 | ( 15 | SynthDef(\RingMod,{ 16 | |freq = 1000| 17 | var in = [0,1]; 18 | var out = [0,1]; 19 | var ring = SinOsc.kr(freq); 20 | 21 | var sound = In.ar(in); 22 | Out.ar(out, sound*ring); 23 | }).send(s); 24 | ) 25 | -------------------------------------------------------------------------------- /node_modules/node-osc/README.rst: -------------------------------------------------------------------------------- 1 | -------- 2 | node-osc 3 | -------- 4 | 5 | A very basic OSC client (so far) implementation based heavily on pyOSC_. 6 | 7 | 8 | Relies on current trunk of node.js for the dgram library. 9 | 10 | .. _pyOSC: https://trac.v2.nl/wiki/pyOSC 11 | 12 | Example 13 | ------- 14 | 15 | :: 16 | 17 | var osc = require('osc'); 18 | 19 | var client = osc.Client(10000, '127.0.0.1'); 20 | client.sendSimple('/oscAddress', [200]); 21 | 22 | // slightly more complex 23 | var msg = osc.Message('/oscAddress'); 24 | msg.append(200); 25 | msg.append(10); 26 | 27 | client.send(msg); 28 | 29 | You can also create a OSC server: 30 | 31 | :: 32 | 33 | var osc = require('osc'); 34 | 35 | var server = osc.Server(10001, '127.0.0.1'); 36 | 37 | server.addMsgHandler('/bang', function (args) { 38 | console.log('I got a bang!') 39 | }); 40 | 41 | Licensing 42 | --------- 43 | 44 | pyOSC looks to be GPL so I guess this is too. More formalities later on. 45 | -------------------------------------------------------------------------------- /node_modules/node-osc/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/osc.js') -------------------------------------------------------------------------------- /node_modules/node-osc/lib/node-jspack/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008, Fair Oaks Labs, Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are 5 | permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this list 8 | of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or other 12 | materials provided with the distribution. 13 | 14 | * Neither the name of Fair Oaks Labs, Inc. nor the names of its contributors may be 15 | used to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 25 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 26 | THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /node_modules/node-osc/lib/node-jspack/README: -------------------------------------------------------------------------------- 1 | Disclaimer: The jspack module and documentation are essentially ports of the 2 | Python struct module and documentation, with such changes as were necessary. 3 | If any Python people are miffed that I've ripped off their docs, let me know, 4 | and I'll gladly revise them. 5 | 6 | This module performs conversions between JavaScript values and C structs 7 | represented as octet arrays (i.e. JavaScript arrays of integral numbers 8 | between 0 and 255, inclusive). It uses format strings (explained below) as 9 | compact descriptions of the layout of the C structs and the intended conversion 10 | to/from JavaScript values. This can be used to handle binary data stored in 11 | files, or received from network connections or other sources. 12 | 13 | 14 | The module defines the following functions: 15 | 16 | Unpack(fmt, a, p) 17 | Return an array containing values unpacked from the octet array a, 18 | beginning at position p, according to the supplied format string. If there 19 | are more octets in a than required by the format string, the excess is 20 | ignored. If there are fewer octets than required, Unpack() will return 21 | undefined. If no value is supplied for the p argument, zero is assumed. 22 | 23 | PackTo(fmt, a, p, values) 24 | Pack and store the values array into the supplied octet array a, beginning 25 | at position p. If there are more values supplied than are specified in the 26 | format string, the excess is ignored. If there are fewer values supplied, 27 | PackTo() will return false. If there is insufficient space in a to store 28 | the packed values, PackTo() will return false. On success, PackTo() returns 29 | the a argument. If any value is of an inappropriate type, the results are 30 | undefined. 31 | 32 | Pack(fmt, values) 33 | Return an octet array containing the packed values array. If there are 34 | more values supplied than are specified in the format string, the excess is 35 | ignored. If there are fewer values supplied, Pack() will return false. If 36 | any value is of an inappropriate type, the results are undefined. 37 | 38 | CalcLength(fmt) 39 | Return the number of octets required to store the given format string. 40 | 41 | 42 | Format characters have the following meanings; the conversion between C and 43 | JavaScript values should be obvious given their types: 44 | 45 | Format | C Type | JavaScript Type | Size (octets) | Notes 46 | ------------------------------------------------------------------- 47 | A | char[] | Array | Length | (1) 48 | x | pad byte | N/A | 1 | 49 | c | char | string (length 1) | 1 | (2) 50 | b | signed char | number | 1 | (3) 51 | B | unsigned char | number | 1 | (3) 52 | h | signed short | number | 2 | (3) 53 | H | unsigned short | number | 2 | (3) 54 | i | signed long | number | 4 | (3) 55 | I | unsigned long | number | 4 | (3) 56 | l | signed long | number | 4 | (3) 57 | L | unsigned long | number | 4 | (3) 58 | s | char[] | string | Length | (2) 59 | f | float | number | 4 | (4) 60 | d | double | number | 8 | (5) 61 | 62 | Notes: 63 | 64 | (1) The "A" code simply returns a slice of the source octet array. This is 65 | primarily useful when a data structure contains bytes which are subject to 66 | multiple intepretations (e.g. unions), and the data structure is being 67 | decoded in multiple passes. 68 | 69 | (2) The "c" and "s" codes handle strings with codepoints between 0 and 255, 70 | inclusive. The data are not bounds-checked, so strings containing characters 71 | with codepoints outside this range will encode to "octet" arrays that contain 72 | values outside the range of an octet. Furthermore, since these codes decode 73 | octet arrays by assuming the octets represent UNICODE codepoints, they may 74 | not "correctly" decode bytes in the range 128-255, since that range is subject 75 | to multiple interpretations. Caveat coder! 76 | 77 | (3) The 8 "integer" codes clip their encoded values to the minima and maxmima 78 | of their respective types: If you invoke Struct.Pack('b', [-129]), for 79 | instance, the result will be [128], which is the octet encoding of -128, 80 | which is the minima of a signed char. Similarly, Struct.Pack('h', [-32769]) 81 | returns [128, 0]. Fractions are truncated. 82 | 83 | (4) Since JavaScript doesn't natively support 32-bit floats, whenever a float 84 | is stored, the source JavaScript number must be rounded. This module applies 85 | correct rounding during this process. Numbers with magnitude greater than or 86 | equal to 2**128-2**103 round to either positive or negative Infinity. The 87 | rounding algorithm assumes that JavsScript is using exactly 64 bits of 88 | floating point precision; 128-bit floating point will result in subtle errors. 89 | 90 | (5) This module assumes that JavaScript is using 64 bits of floating point 91 | precision, so the "d" code performs no rounding. 128-bit floating point will 92 | cause the "d" code to simply truncate significands to 52 bits. 93 | 94 | A format character may be preceded by an integral repeat count. For example, 95 | the format string "4h" means exactly the same thing as "hhhh". 96 | 97 | Whitespace characters between formats are ignored; a count and its format must 98 | not be separated by whitespace, however. 99 | 100 | For the "A" format character, the count is interpreted as the size of the 101 | array, not a repeat count as for the other format characters; for example, "10A" 102 | means a single 10-octet array. When packing, the Array is truncated or padded 103 | with 0 bytes as appropriate to make it conform to the specified length. When 104 | unpacking, the resulting Array always has exactly the specified number of bytes. 105 | As a special case, "0A" means a single, empty Array. 106 | 107 | For the "s" format character, the count is interpreted as the size of the 108 | string, not a repeat count as for the other format characters; for example, 109 | "10s" means a single 10-byte string, while "10c" means 10 characters. When 110 | packing, the string is truncated or padded with 0 bytes as appropriate to make 111 | it conform to the specified length. When unpacking, the resulting string always 112 | has exactly the specified number of bytes. As a special case, "0s" means a 113 | single, empty string (while "0c" means 0 characters). 114 | 115 | 116 | By default, C numbers are represented in network (or big-endian) byte order. 117 | Alternatively, the first character of the format string can be used to indicate 118 | byte order of the packed data, according to the following table: 119 | 120 | Character | Byte Order 121 | ---------------------------------- 122 | < | little-endian 123 | > | big-endian 124 | ! | network (= big-endian) 125 | 126 | If the first character is not one of these, "!" is assumed. 127 | -------------------------------------------------------------------------------- /node_modules/node-osc/lib/node-jspack/jspack.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stagas/node-supercollider/a18411368377bf57d48df6dad07128edfecce7fa/node_modules/node-osc/lib/node-jspack/jspack.js -------------------------------------------------------------------------------- /node_modules/node-osc/lib/osc.js: -------------------------------------------------------------------------------- 1 | require.paths.unshift(__dirname + '/node-jspack'); 2 | var buffer = require('buffer'); 3 | var dgram = require('dgram'); 4 | var sys = require('sys'); 5 | 6 | var jspack = require('jspack').jspack; 7 | 8 | //////////////////// 9 | // OSC Message 10 | //////////////////// 11 | 12 | var Message = function (address) { 13 | this.address = address; 14 | this.typetags = ','; 15 | this.message = []; 16 | } 17 | 18 | Message.prototype = { 19 | append: function (arg, typehint) { 20 | if (arg instanceof Array) { 21 | for (var i in arg) { 22 | this.append(arg[i], typehint); 23 | } 24 | return null; 25 | } 26 | if (typeof(arg) == 'object') { 27 | for (var k in arg) { 28 | this.append([k, arg[k]]); 29 | } 30 | return null; 31 | } 32 | 33 | if (typehint == 'b') { 34 | binary = OSCBlob(arg); 35 | tag = 'b'; 36 | } else if (typehint == 't') { 37 | binary = OSCTimeTag(arg); 38 | tag = 't'; 39 | } else { 40 | rv = OSCArgument(arg, typehint); 41 | tag = rv[0]; 42 | binary = rv[1]; 43 | } 44 | 45 | this.typetags += tag; 46 | this.message = this.message.concat(binary); 47 | }, 48 | toBinary: function () { 49 | var binary = OSCString(this.address); 50 | binary = binary.concat(OSCString(this.typetags)); 51 | binary = binary.concat(this.message); 52 | return binary; 53 | }, 54 | } 55 | exports.Message = Message; 56 | 57 | var Bundle = function (address, time) { 58 | Message.call(this, address); 59 | this.timetag = time || 0; 60 | } 61 | 62 | sys.inherits(Bundle, Message); 63 | 64 | Bundle.prototype.append = function (arg, typehint) { 65 | var binary; 66 | if (arg instanceof Message) { 67 | binary = OSCBlob(arg.toBinary()); 68 | } else { 69 | var msg = Message(this.address); 70 | if (typeof(arg) == 'Object') { 71 | if (arg.addr) { 72 | msg.address = arg.addr; 73 | } 74 | if (arg.args) { 75 | msg.append(arg.args, typehint); 76 | } 77 | } else { 78 | msg.append(arg, typehint); 79 | } 80 | binary = OSCBlob(msg.toBinary()); 81 | } 82 | this.message += binary; 83 | this.typetags += 'b'; 84 | }; 85 | 86 | Bundle.prototype.toBinary = function () { 87 | var binary = OSCString('#bundle'); 88 | binary = binary.concat(OSCTimeTag(this.timetag)); 89 | binary = binary.concat(this.message); 90 | return binary; 91 | }; 92 | 93 | exports.Bundle = Bundle; 94 | 95 | //////////////////// 96 | // OSC Message Encoding Functions 97 | //////////////////// 98 | 99 | var OSCString = function (next) { 100 | var len = Math.ceil((next.length + 1) / 4.0) * 4; 101 | var foo = jspack.Pack('>' + len + 's', [next]); 102 | return foo 103 | } 104 | 105 | var OSCBlob = function (next) { 106 | var binary; 107 | if (typeof(next) == 'String') { 108 | var len = Math.ceil((next.length) / 4.0) * 4; 109 | binary = jspack.Pack('>i' + len + 's', [len, next]); 110 | } else { 111 | binary = ''; 112 | } 113 | return binary; 114 | } 115 | 116 | var OSCArgument = function (next, typehint) { 117 | var binary, tag; 118 | if (!typehint) { 119 | if (typeof(next) == 'number') { 120 | if (next.toString().indexOf('.') != -1) { 121 | binary = jspack.Pack('>f', [next]); 122 | tag = 'f'; 123 | } else { 124 | binary = jspack.Pack('>i', [next]); 125 | tag = 'i'; 126 | } 127 | } else { 128 | binary = OSCString(next); 129 | tag = 's'; 130 | } 131 | } else if (typehint == 'd') { 132 | try { 133 | binary = jspack.Pack('>f', [parseFloat(next)]); 134 | tag = 'f'; 135 | } catch (e) { 136 | binary = OSCString(next); 137 | tag = 's'; 138 | } 139 | } else if (typehint == 'i') { 140 | try { 141 | binary = jspack.Pack('>i', [parseInt(next)]); 142 | tag = 'i'; 143 | } catch (e) { 144 | binary = OSCString(next); 145 | tag = 's'; 146 | } 147 | } else { 148 | binary = OSCString(next); 149 | tag = 's'; 150 | } 151 | return [tag, binary]; 152 | } 153 | 154 | var OSCTimeTag = function (time) { 155 | // Not Implemented Yet 156 | return jspack.Pack('>LL', 0, 1); 157 | } 158 | 159 | //////////////////// 160 | // OSC Client 161 | //////////////////// 162 | 163 | var Client = function (port, bindPort, host, debug) { 164 | var self = this; 165 | this.debug = debug; 166 | this._callbacks = []; 167 | this.port = port; 168 | this.host = host; 169 | this._sock = dgram.createSocket('udp4'); 170 | this._sock.bind(bindPort); 171 | this._sock.on('message', function (msg, rinfo) { 172 | // on every message sent through the UDP socket... 173 | // we decode the message getting a beautiful array with the form: 174 | // [
,