@@ -4,6 +4,8 @@ var osc = osc || {};
4
4
5
5
"use strict" ;
6
6
7
+ osc . SEVENTY_YEARS_SECS = 2208988800 ;
8
+
7
9
// Unsupported, non-API function.
8
10
osc . isArray = function ( obj ) {
9
11
return obj && Object . prototype . toString . call ( obj ) === "[object Array]" ;
@@ -105,6 +107,7 @@ var osc = osc || {};
105
107
return arr ;
106
108
} ;
107
109
110
+ // Unsupported, non-API function.
108
111
osc . readPrimitive = function ( dv , readerName , numBytes , offsetState ) {
109
112
var val = dv [ readerName ] ( offsetState . idx , false ) ;
110
113
offsetState . idx += numBytes ;
@@ -151,6 +154,30 @@ var osc = osc || {};
151
154
return osc . writePrimitive ( val , dv , "setInt32" , 4 , offset ) ;
152
155
} ;
153
156
157
+ /**
158
+ * Reads an OSC int64 ("h") value.
159
+ *
160
+ * @param {DataView } dv a DataView containing the raw bytes
161
+ * @param {Object } offsetState an offsetState object used to store the current offset index into dv
162
+ * @return {Number } the number that was read
163
+ */
164
+ // TODO: Unit tests.
165
+ osc . readInt64 = function ( dv , offsetState ) {
166
+ return osc . readPrimitive ( dv , "getInt64" , 8 , offsetState ) ;
167
+ } ;
168
+
169
+ /**
170
+ * Writes an OSC int64 ("h") value.
171
+ *
172
+ * @param {Number } val the number to write
173
+ * @param {DataView } [dv] a DataView instance to write the number into
174
+ * @param {Number } [offset] an offset into dv
175
+ */
176
+ // TODO: Unit tests.
177
+ osc . writeInt64 = function ( val , dv , offset ) {
178
+ return osc . writePrimitive ( val , dv , "setInt64" , 8 , offset ) ;
179
+ } ;
180
+
154
181
/**
155
182
* Reads an OSC float32 ("f") value.
156
183
*
@@ -173,6 +200,61 @@ var osc = osc || {};
173
200
return osc . writePrimitive ( val , dv , "setFloat32" , 4 , offset ) ;
174
201
} ;
175
202
203
+ /**
204
+ * Reads an OSC float64 ("d") value.
205
+ *
206
+ * @param {DataView } dv a DataView containing the raw bytes
207
+ * @param {Object } offsetState an offsetState object used to store the current offset index into dv
208
+ * @return {Number } the number that was read
209
+ */
210
+ // TODO: Unit tests.
211
+ osc . readFloat64 = function ( dv , offsetState ) {
212
+ return osc . readPrimitive ( dv , "getFloat64" , 8 , offsetState ) ;
213
+ } ;
214
+
215
+ /**
216
+ * Writes an OSC float64 ("d") value.
217
+ *
218
+ * @param {Number } val the number to write
219
+ * @param {DataView } [dv] a DataView instance to write the number into
220
+ * @param {Number } [offset] an offset into dv
221
+ */
222
+ // TODO: Unit tests.
223
+ osc . writeFloat64 = function ( val , dv , offset ) {
224
+ return osc . writePrimitive ( val , dv , "setFloat64" , 8 , offset ) ;
225
+ } ;
226
+
227
+ /**
228
+ * Reads an OSC 32-bit ASCII character ("c") value.
229
+ *
230
+ * @param {DataView } dv a DataView containing the raw bytes
231
+ * @param {Object } offsetState an offsetState object used to store the current offset index into dv
232
+ * @return {String } a string containing the read character
233
+ */
234
+ // TODO: Unit tests.
235
+ osc . readChar32 = function ( dv , offsetState ) {
236
+ var charCode = osc . readPrimitive ( dv , "getUint32" , 4 , offsetState ) ;
237
+ return String . fromCharCode ( charCode ) ;
238
+ } ;
239
+
240
+ /**
241
+ * Writes an OSC 32-bit ASCII character ("c") value.
242
+ *
243
+ * @param {String } str the string from which the first character will be written
244
+ * @param {DataView } [dv] a DataView instance to write the character into
245
+ * @param {Number } [offset] an offset into dv
246
+ * @return {String } a string containing the read character
247
+ */
248
+ // TODO: Unit tests.
249
+ osc . readChar32 = function ( str , dv , offset ) {
250
+ var charCode = str . charCodeAt ( 0 ) ;
251
+ if ( charCode === undefined || charCode < - 1 ) {
252
+ return undefined ;
253
+ }
254
+
255
+ return osc . writePrimitive ( charCode , dv , "setUint32" , 4 , offsetState ) ;
256
+ } ;
257
+
176
258
/**
177
259
* Reads an OSC blob ("b") (i.e. a Uint8Array).
178
260
*
@@ -246,12 +328,65 @@ var osc = osc || {};
246
328
return 1.0 ;
247
329
} ;
248
330
331
+ /**
332
+ * Reads an OSC time tag.
333
+ *
334
+ * @param {DataView } dv the DataView instance to read from
335
+ * @param {Object } offsetState an offset state object containing the current index into dv
336
+ * @param {Object } a time tag object containing both the raw NTP as well as the converted native (i.e. JS/UNIX) time
337
+ */
249
338
osc . readTimeTag = function ( dv , offsetState ) {
250
- // TODO: Implement.
339
+ var secs1900 = osc . readPrimitive ( dv , "getUint32" , 4 , offsetState ) ,
340
+ frac = osc . readPrimitive ( dv , "getUint32" , 4 , offsetState ) ,
341
+ native = osc . ntpToJSTime ( secs1900 , frac ) ;
342
+
343
+ return {
344
+ raw : [ secs1900 , frac ] ,
345
+ native : native
346
+ } ;
251
347
} ;
252
348
349
+ // TODO: Unit tests.
253
350
osc . writeTimeTag = function ( timeTag ) {
254
- // TODO: Implement.
351
+ var raw = timeTag . raw ? timeTag . raw : osc . jsTimeToNTP ( timeTag . native ) ,
352
+ arr = new Uint8Array ( 8 ) , // Two Unit32s.
353
+ dv = new DataView ( arr . buffer ) ;
354
+
355
+ osc . writeInt32 ( raw [ 0 ] , dv , 0 ) ;
356
+ osc . writeInt32 ( raw [ 1 ] , dv , 4 ) ;
357
+
358
+ return arr ;
359
+ } ;
360
+
361
+ // TODO: Unit tests.
362
+ osc . futureTimeTag = function ( secs ) {
363
+ var ms = sec * 1000 ,
364
+ futureMS = Date . now ( ) + ms ;
365
+
366
+ return {
367
+ native : futureMS
368
+ } ;
369
+ } ;
370
+
371
+ // TODO: Unit tests.
372
+ osc . ntpToJSTime = function ( secs1900 , frac ) {
373
+ var secs1970 = secs1900 - osc . SEVENTY_YEARS_SECS ,
374
+ ms1970 = secs1970 * 1000 ,
375
+ decimals = ( frac / 4294967296 ) * 1000 ,
376
+ msTime = ms1970 + decimals ;
377
+
378
+ return msTime ;
379
+ } ;
380
+
381
+ // TODO: Unit tests.
382
+ osc . jsTimeToNTP = function ( jsTime ) {
383
+ var ms = jsTime | 0 ,
384
+ secs = ( ms / 1000 ) | 0 ,
385
+ secs1900 = secs + osc . SEVENTY_YEARS_SECS ,
386
+ fracMs = jsTime - ms ,
387
+ fracSec = ( ( fracMs / 1000 ) * 4294967296 ) | 0 ;
388
+
389
+ return [ secs1900 , fracSec ] ;
255
390
} ;
256
391
257
392
/**
@@ -446,12 +581,21 @@ var osc = osc || {};
446
581
} ,
447
582
I : {
448
583
reader : "readImpulse"
584
+ } ,
585
+ h : {
586
+ reader : "readInt64" ,
587
+ writer : "writeInt64"
588
+ } ,
589
+ d : {
590
+ reader : "readFloat64" ,
591
+ writer : "writeFloat64"
592
+ } ,
593
+ c : {
594
+ reader : "readChar32" ,
595
+ writer : "writeChar32"
449
596
}
450
597
451
598
// Missing optional OSC 1.0 types:
452
- // h: "readInt64",
453
- // d: "readFloat64",
454
- // c: "readChar32",
455
599
// r: "readColor",
456
600
// m: "readMIDI"
457
601
} ;
@@ -488,7 +632,7 @@ var osc = osc || {};
488
632
if ( ! osc . isArray ( args ) ) {
489
633
args = [ args ] ;
490
634
}
491
-
635
+
492
636
var annotated = [ ] ;
493
637
for ( var i = 0 ; i < args . length ; i ++ ) {
494
638
var arg = args [ i ] ,
0 commit comments