l@271
|
1 [![build status](https://secure.travis-ci.org/russellmcc/node-osc-min.png)](http://travis-ci.org/russellmcc/node-osc-min) [![Coverage Status](https://coveralls.io/repos/russellmcc/node-osc-min/badge.png?branch=master)](https://coveralls.io/r/russellmcc/node-osc-min?branch=master) [![dependencies](https://david-dm.org/russellmcc/node-osc-min.png)](https://david-dm.org/russellmcc/node-osc-min)
|
l@271
|
2 # osc-min
|
l@271
|
3
|
l@271
|
4 _simple utilities for open sound control in node.js_
|
l@271
|
5
|
l@271
|
6 This package provides some node.js utilities for working with
|
l@271
|
7 [OSC](http://opensoundcontrol.org/), a format for sound and systems control.
|
l@271
|
8 Here we implement the [OSC 1.1][spec11] specification. OSC is a transport-independent
|
l@271
|
9 protocol, so we don't provide any server objects, as you should be able to
|
l@271
|
10 use OSC over any transport you like. The most common is probably udp, but tcp
|
l@271
|
11 is not unheard of.
|
l@271
|
12
|
l@271
|
13 [spec11]: http://opensoundcontrol.org/spec-1_1
|
l@271
|
14
|
l@271
|
15 ----
|
l@271
|
16 ## Installation
|
l@271
|
17
|
l@271
|
18 The easiest way to get osc-min is through [NPM](http://npmjs.org).
|
l@271
|
19 After install npm, you can install osc-min in the current directory with
|
l@271
|
20
|
l@271
|
21 ```
|
l@271
|
22 npm install osc-min
|
l@271
|
23 ```
|
l@271
|
24
|
l@271
|
25 If you'd rather get osc-min through github (for example, if you're forking
|
l@271
|
26 it), you still need npm to install dependencies, which you can do with
|
l@271
|
27
|
l@271
|
28 ```
|
l@271
|
29 npm install --dev
|
l@271
|
30 ```
|
l@271
|
31
|
l@271
|
32 Once you've got all the dependencies you should be able to run the unit
|
l@271
|
33 tests with
|
l@271
|
34
|
l@271
|
35 ```
|
l@271
|
36 npm test
|
l@271
|
37 npm run-script coverage
|
l@271
|
38 ```
|
l@271
|
39
|
l@271
|
40 ### For the browser
|
l@271
|
41 If you want to use this library in a browser, you can build a browserified file (`build/osc-min.js`) with
|
l@271
|
42
|
l@271
|
43 ```
|
l@271
|
44 npm install --dev
|
l@271
|
45 npm run-script browserify
|
l@271
|
46 ```
|
l@271
|
47
|
l@271
|
48 ----
|
l@271
|
49 ## Examples
|
l@271
|
50 ### A simple OSC printer;
|
l@271
|
51 ```javascript
|
l@271
|
52
|
l@271
|
53 sock = udp.createSocket("udp4", function(msg, rinfo) {
|
l@271
|
54 var error, error1;
|
l@271
|
55 try {
|
l@271
|
56 return console.log(osc.fromBuffer(msg));
|
l@271
|
57 } catch (error1) {
|
l@271
|
58 error = error1;
|
l@271
|
59 return console.log("invalid OSC packet");
|
l@271
|
60 }
|
l@271
|
61 });
|
l@271
|
62
|
l@271
|
63 sock.bind(inport);
|
l@271
|
64
|
l@271
|
65 ```
|
l@271
|
66 ### Send a bunch of args every two seconds;
|
l@271
|
67 ```javascript
|
l@271
|
68
|
l@271
|
69 sendHeartbeat = function() {
|
l@271
|
70 var buf;
|
l@271
|
71 buf = osc.toBuffer({
|
l@271
|
72 address: "/heartbeat",
|
l@271
|
73 args: [
|
l@271
|
74 12, "sttttring", new Buffer("beat"), {
|
l@271
|
75 type: "integer",
|
l@271
|
76 value: 7
|
l@271
|
77 }
|
l@271
|
78 ]
|
l@271
|
79 });
|
l@271
|
80 return udp.send(buf, 0, buf.length, outport, "localhost");
|
l@271
|
81 };
|
l@271
|
82
|
l@271
|
83 setInterval(sendHeartbeat, 2000);
|
l@271
|
84
|
l@271
|
85 ```
|
l@271
|
86 ### A simple OSC redirecter;
|
l@271
|
87 ```javascript
|
l@271
|
88
|
l@271
|
89 sock = udp.createSocket("udp4", function(msg, rinfo) {
|
l@271
|
90 var error, error1, redirected;
|
l@271
|
91 try {
|
l@271
|
92 redirected = osc.applyAddressTransform(msg, function(address) {
|
l@271
|
93 return "/redirect" + address;
|
l@271
|
94 });
|
l@271
|
95 return sock.send(redirected, 0, redirected.length, outport, "localhost");
|
l@271
|
96 } catch (error1) {
|
l@271
|
97 error = error1;
|
l@271
|
98 return console.log("error redirecting: " + error);
|
l@271
|
99 }
|
l@271
|
100 });
|
l@271
|
101
|
l@271
|
102 sock.bind(inport);
|
l@271
|
103
|
l@271
|
104 ```
|
l@271
|
105
|
l@271
|
106
|
l@271
|
107 more examples are available in the `examples/` directory.
|
l@271
|
108
|
l@271
|
109 ----
|
l@271
|
110 ## Exported functions
|
l@271
|
111
|
l@271
|
112 ------
|
l@271
|
113 ### .fromBuffer(buffer, [strict])
|
l@271
|
114 takes a node.js Buffer of a complete _OSC Packet_ and
|
l@271
|
115 outputs the javascript representation, or throws if the buffer is ill-formed.
|
l@271
|
116
|
l@271
|
117 `strict` is an optional parameter that makes the function fail more often.
|
l@271
|
118
|
l@271
|
119 ----
|
l@271
|
120 ### .toBuffer(object, [strict])
|
l@271
|
121 takes a _OSC packet_ javascript representation as defined below and returns
|
l@271
|
122 a node.js Buffer, or throws if the representation is ill-formed.
|
l@271
|
123
|
l@271
|
124 See "JavaScript representations of the OSC types" below.
|
l@271
|
125
|
l@271
|
126 ----
|
l@271
|
127 ### .toBuffer(address, args[], [strict])
|
l@271
|
128 alternative syntax for above. Assumes this is an _OSC Message_ as defined below,
|
l@271
|
129 and `args` is an array of _OSC Arguments_ or single _OSC Argument_
|
l@271
|
130
|
l@271
|
131 ----
|
l@271
|
132 ### .applyAddressTransform(buffer, transform)
|
l@271
|
133 takes a callback that takes a string and outputs a string,
|
l@271
|
134 and applies that to the address of the message encoded in the buffer,
|
l@271
|
135 and outputs an encoded buffer.
|
l@271
|
136
|
l@271
|
137 If the buffer encodes an _OSC Bundle_, this applies the function to each address
|
l@271
|
138 in the bundle.
|
l@271
|
139
|
l@271
|
140 There's two subtle reasons you'd want to use this function rather than
|
l@271
|
141 composing `fromBuffer` and `toBuffer`:
|
l@271
|
142 - Future-proofing - if the OSC message uses an argument typecode that
|
l@271
|
143 we don't understand, calling `fromBuffer` will throw. The only time
|
l@271
|
144 when `applyAddressTranform` might fail is if the address is malformed.
|
l@271
|
145 - Accuracy - javascript represents numbers as 64-bit floats, so some
|
l@271
|
146 OSC types will not be able to be represented accurately. If accuracy
|
l@271
|
147 is important to you, then, you should never convert the OSC message to a
|
l@271
|
148 javascript representation.
|
l@271
|
149
|
l@271
|
150 ----
|
l@271
|
151 ### .applyMessageTransform(buffer, transform)
|
l@271
|
152 takes a function that takes and returns a javascript _OSC Message_ representation,
|
l@271
|
153 and applies that to each message encoded in the buffer,
|
l@271
|
154 and outputs a new buffer with the new address.
|
l@271
|
155
|
l@271
|
156 If the buffer encodes an osc-bundle, this applies the function to each message
|
l@271
|
157 in the bundle.
|
l@271
|
158
|
l@271
|
159 See notes above for applyAddressTransform for why you might want to use this.
|
l@271
|
160 While this does parse and re-pack the messages, the bundle timetags are left
|
l@271
|
161 in their accurate and prestine state.
|
l@271
|
162
|
l@271
|
163 ----
|
l@271
|
164 ### .timetagToDate(ntpTimeTag)
|
l@271
|
165 Convert a timetag array to a JavaScript Date object in your local timezone.
|
l@271
|
166
|
l@271
|
167 Received OSC bundles converted with `fromBuffer` will have a timetag array:
|
l@271
|
168 [secondsSince1970, fractionalSeconds]
|
l@271
|
169 This utility is useful for logging. Accuracy is reduced to milliseconds.
|
l@271
|
170
|
l@271
|
171 ----
|
l@271
|
172 ### .dateToTimetag(date)
|
l@271
|
173 Convert a JavaScript Date to a NTP timetag array [secondsSince1970, fractionalSeconds].
|
l@271
|
174
|
l@271
|
175 `toBuffer` already accepts Dates for timetags so you might not need this function. If you need to schedule bundles with finer than millisecond accuracy then you could use this to help assemble the NTP array.
|
l@271
|
176
|
l@271
|
177 ----
|
l@271
|
178 ### .timetagToTimestamp(timeTag)
|
l@271
|
179 Convert a timetag array to the number of seconds since the UNIX epoch.
|
l@271
|
180
|
l@271
|
181
|
l@271
|
182 ----
|
l@271
|
183 ### .timestampToTimetag(timeStamp)
|
l@271
|
184 Convert a number of seconds since the UNIX epoch to a timetag array.
|
l@271
|
185
|
l@271
|
186
|
l@271
|
187 ----
|
l@271
|
188 ## Javascript representations of the OSC types.
|
l@271
|
189 See the [spec][spec] for more information on the OSC types.
|
l@271
|
190
|
l@271
|
191 + An _OSC Packet_ is an _OSC Message_ or an _OSC Bundle_.
|
l@271
|
192
|
l@271
|
193 + An _OSC Message_:
|
l@271
|
194
|
l@271
|
195 {
|
l@271
|
196 oscType : "message"
|
l@271
|
197 address : "/address/pattern/might/have/wildcards"
|
l@271
|
198 args : [arg1,arg2]
|
l@271
|
199 }
|
l@271
|
200
|
l@271
|
201 Where args is an array of _OSC Arguments_. `oscType` is optional.
|
l@271
|
202 `args` can be a single element.
|
l@271
|
203
|
l@271
|
204 + An _OSC Argument_ is represented as a javascript object with the following layout:
|
l@271
|
205
|
l@271
|
206 {
|
l@271
|
207 type : "string"
|
l@271
|
208 value : "value"
|
l@271
|
209 }
|
l@271
|
210
|
l@271
|
211 Where the `type` is one of the following:
|
l@271
|
212 + `string` - string value
|
l@271
|
213 + `float` - numeric value
|
l@271
|
214 + `integer` - numeric value
|
l@271
|
215 + `blob` - node.js Buffer value
|
l@271
|
216 + `true` - value is boolean true
|
l@271
|
217 + `false` - value is boolean false
|
l@271
|
218 + `null` - no value
|
l@271
|
219 + `bang` - no value (this is the `I` type tag)
|
l@271
|
220 + `timetag` - numeric value
|
l@271
|
221 + `array` - array of _OSC Arguments_
|
l@271
|
222
|
l@271
|
223 Note that `type` is always a string - i.e. `"true"` rather than `true`.
|
l@271
|
224
|
l@271
|
225 The following non-standard types are also supported:
|
l@271
|
226 + `double` - numeric value (encodes to a float64 value)
|
l@271
|
227
|
l@271
|
228
|
l@271
|
229 For messages sent to the `toBuffer` function, `type` is optional.
|
l@271
|
230 If the argument is not an object, it will be interpreted as either
|
l@271
|
231 `string`, `float`, `array` or `blob`, depending on its javascript type
|
l@271
|
232 (String, Number, Array, Buffer, respectively)
|
l@271
|
233
|
l@271
|
234 + An _OSC Bundle_ is represented as a javascript object with the following fields:
|
l@271
|
235
|
l@271
|
236 {
|
l@271
|
237 oscType : "bundle"
|
l@271
|
238 timetag : 7
|
l@271
|
239 elements : [element1, element]
|
l@271
|
240 }
|
l@271
|
241
|
l@271
|
242 `oscType` "bundle"
|
l@271
|
243
|
l@271
|
244 `timetag` is one of:
|
l@271
|
245 - `null` - meaning now, the current time.
|
l@271
|
246 By the time the bundle is received it will too late and depending
|
l@271
|
247 on the receiver may be discarded or you may be scolded for being late.
|
l@271
|
248 - `number` - relative seconds from now with millisecond accuracy.
|
l@271
|
249 - `Date` - a JavaScript Date object in your local time zone.
|
l@271
|
250 OSC timetags use UTC timezone, so do not try to adjust for timezones,
|
l@271
|
251 this is not needed.
|
l@271
|
252 - `Array` - `[numberOfSecondsSince1900, fractionalSeconds]`
|
l@271
|
253 Both values are `number`s. This gives full timing accuracy of 1/(2^32) seconds.
|
l@271
|
254
|
l@271
|
255 `elements` is an `Array` of either _OSC Message_ or _OSC Bundle_
|
l@271
|
256
|
l@271
|
257
|
l@271
|
258 [spec]: http://opensoundcontrol.org/spec-1_0
|
l@271
|
259
|
l@271
|
260 ----
|
l@271
|
261 ## License
|
l@271
|
262 Licensed under the terms found in COPYING (zlib license)
|