-
Notifications
You must be signed in to change notification settings - Fork 9
/
osc-tests.lisp
386 lines (324 loc) · 11.4 KB
/
osc-tests.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
;; -*- mode: lisp -*-
;;
;; Various tests for cl-osc using 5am
;;
;; Authors
;; - nik gaffney <[email protected]>
(defpackage :osc/tests
(:use :cl :osc :fiveam))
(in-package :osc/tests)
;; (in-package :osc)
;; (require "fiveam")
;; setup various test suites
(def-suite synchroscope
:description "OSC test suite(s).")
(def-suite data-encoding
:description "Test encoding and decoding of OSC data types." :in synchroscope)
(def-suite message-encoding
:description "Test encoding and decoding of OSC messages." :in synchroscope)
(def-suite protocol-v1.0
:description "OSC v1.0 compatibility." :in synchroscope)
(def-suite protocol-v1.1
:description "OSC v1.1 compatibility." :in synchroscope)
(def-suite interoperability
:description "Test interoperability (e.g. supercollider & pd)" :in synchroscope)
;; test todo
;; - negative floats, NaN +/- Inf, etc
;; - bignums
;; - blobs, and long args
;; - byte aligning 0,1,2,3,4 mod
;; - error catching, junk data
;; - edge cases?
(in-suite data-encoding)
(test osc-int32
"OSC int32 encoding tests."
(is (equalp
(osc::encode-int32 16843009) #(1 1 1 1)))
(is (equalp
(osc::decode-int32 #(127 255 255 255))
(osc::decode-uint32 #(127 255 255 255))))
(is (equalp
(osc::encode-int32 -16843010) #(254 254 254 254)))
(is (equalp
(osc::decode-int32 #(127 255 255 255)) #x7FFFFFFF))
(is (equalp
(osc::encode-int32 #xFFFFFFFF) #(255 255 255 255)))
(is (equalp
(osc::decode-int32 #(255 255 255 255)) -1))
(is (equalp
(osc::decode-uint32 #(255 255 255 255)) #xFFFFFFFF)))
(test osc-string
"OSC string encoding tests."
(is (equalp
(osc::decode-string #(110 117 108 108 32 112 97 100 100 101 100 0))
"null padded"))
(is (equalp
(osc::encode-string "OSC string encoding test")
#(79 83 67 32 115 116 114 105 110 103 32 101
110 99 111 100 105 110 103 32 116 101 115 116 0 0 0 0))))
;; blob
;; (osc::encode-blob "THE BLOB")
(test osc-blob
"OSC blob encoding tests."
(is (equalp
(osc::encode-blob #(1 1 1 1)) #(0 0 0 4 1 1 1 1))))
(test osc-timetag
"OSC timetag encoding tests."
(is (equalp
(osc::encode-timetag :now) #(0 0 0 0 0 0 0 1))))
(test osc-int64
"OSC int64 encoding tests."
(is (equalp
(osc::encode-int64 16843009) #(0 0 0 0 1 1 1 1)))
(is (equalp
(osc::decode-int64 #(1 1 1 1 1 1 1 1)) 72340172838076673))
(is (equalp
(osc::encode-int64 -8000000000000000008) #(144 250 74 98 196 223 255 248)))
(is (equalp
(osc::decode-int64 #(254 1 254 1 254 1 254 1)) -143554428589179391)))
;; floating point tests
;; these tests cover only encoding and representation, not computation.
(test osc-float32
"OSC float32 encoding tests."
(is (equalp
(osc::encode-float32 1.00001) #(63 128 0 84)))
(is (equalp
(osc::decode-float32 #(1 1 1 1)) 2.3694278s-38))
(is (equalp
(osc::encode-float32 -2.3694278s33) #(246 233 164 196)))
(is (equalp
(osc::decode-float32 #(254 255 255 255)) -1.7014117s38))
(is (equalp
(osc::decode-float32 #(127 255 255 255))
:NOT-A-NUMBER)))
(test osc-float64
"OSC float64 encoding tests."
(is (equalp
(osc::encode-float64 23.1d0) #(64 55 25 153 153 153 153 154)))
(is (equalp
(osc::decode-float64 #(64 55 25 153 153 153 153 154)) 23.1d0))
(is (equalp
(osc::decode-float64 #(1 1 1 1 1 1 1 1)) 7.748604185489348d-304))
(is (equalp
(osc::decode-float64 #(128 0 0 0 0 0 0 0)) -0.0d0))
(is (equalp
(osc::decode-float64 #(255 240 0 0 0 0 0 0))
:NEGATIVE-INFINITY))
(is (equalp
(osc::decode-float64 #(255 255 255 255 0 0 0 0))
:NOT-A-NUMBER)))
;; #+sbcl (osc::decode-float32 #(127 255 255 255)) -> #<SINGLE-FLOAT quiet NaN>
;; see also -> https://github.com/Shinmera/float-features/
;; single-float
(defun f32b (s) (write-to-string (osc::encode-float32 s ) :base 2))
(defun f64b (s) (write-to-string (osc::encode-float64 s ) :base 2))
(test single-float
"Various single floats of interest."
(is (equalp
(f32b 0.000000059604645s0) "#(110011 10000000 0 0)"))
(is (equalp
(f32b 0.000060975552s0) "#(111000 1111111 11000000 0)")))
(test float-features
#+sbcl (pass
(format nil "SBCL floating point modes: ~A~%" (sb-int:get-floating-point-modes))))
;; empty messages tagged T, F, N, I
(in-suite message-encoding)
;; messages
(test osc-message-1
"OSC message encoding tests. address and single int."
:suite 'message-encoding
(is (equalp
'("/test/int" -1)
(osc:decode-message #(47 116 101 115 116 47 105 110 116 0 0 0 44 105 0 0 255 255 255 255)))))
;; check padding boundaries. 1-3 or 1-4?
(test osc-t4
"OSC typetag encoding test. string, ints and floats."
(is (equalp
#(44 105 115 102 0 0 0 0)
(osc::encode-typetags '(1 "terrr" 3.4)))))
(test osc-t5
"OSC typetag encoding test. ints and floats."
(is (equalp
#(44 105 105 102 0 0 0 0)
(osc::encode-typetags '(1 2 3.3)))))
(test osc-t6
"OSC message decoding test. ints and floats."
(is (equalp
'("/test/one" 1 2 3.3)
(osc:decode-message
#(47 116 101 115 116 47 111 110
101 0 0 0 44 105 105 102
0 0 0 0 0 0 0 1
0 0 0 2 64 83 51 51)))))
(test osc-t7
"OSC bundle decoding test. strings, ints and floats."
(is (equalp
'(#(0 0 0 0 0 0 0 1)
("/voices/0/tm/start" 0.0)
("/foo/stringmessage" "a" "few" "strings")
("/documentation/all-messages"))
(osc:decode-bundle
#(#x23 #x62 #x75 #x6e
#x64 #x6c #x65 0
0 0 0 0
0 0 0 #x1
0 0 0 #x20
#x2f #x64 #x6f #x63
#x75 #x6d #x65 #x6e
#x74 #x61 #x74 #x69
#x6f #x6e #x2f #x61
#x6c #x6c #x2d #x6d
#x65 #x73 #x73 #x61
#x67 #x65 #x73 0
#x2c 0 0 0
0 0 0 #x2c
#x2f #x66 #x6f #x6f
#x2f #x73 #x74 #x72
#x69 #x6e #x67 #x6d
#x65 #x73 #x73 #x61
#x67 #x65 0 0
#x2c #x73 #x73 #x73
0 0 0 0
#x61 0 0 0
#x66 #x65 #x77 0
#x73 #x74 #x72 #x69
#x6e #x67 #x73 0
0 0 0 #x1c
#x2f #x76 #x6f #x69
#x63 #x65 #x73 #x2f
#x30 #x2f #x74 #x6d
#x2f #x73 #x74 #x61
#x72 #x74 0 0
#x2c #x66 0 0
0 0 0 0)))))
(test osc-t8
"OSC message encoding test. blob."
(is (equalp
(osc::encode-message "/blob/x" #(1 2 3 4 5 6 7 8 9))
#(47 98 108 111 98 47 120 0 44 98 0 0 0 0 0 9 1 2 3 4 5 6 7 8 9 0 0 0))))
(test osc-t9
"OSC message decoding test. blob."
(is (equalp
'("/blob/x" #(1 2 3 4 5 6 7 8 9))
(osc::decode-message
#(47 98 108 111 98 47 120 0 44 98 0 0 0 0 0 9 1 2 3 4 5 6 7 8 9 0 0 0)))))
(test osc-t10
"OSC message decoding test. blob, int, string."
(is (equalp '("/blob" #(1 29 32 43 54 66 78 81) "lop" 2)
(osc:decode-message
#(47 98 108 111 98 0 0 0 44 98 115 105 0 0 0
0 0 0 0 8 1 29 32 43 54 66 78 81
108 111 112 0 0 0 0 2)))))
;; (test osc-t11
;; "OSC bundle decoding test."
;; (is (equalp
;; '(#(0 0 0 0 0 0 0 1)
;; ("/string/a/ling" "slink" "slonk" "slank")
;; ("/we/wo/w" 1 2 3.4)
;; ("/blob" #(1 29 32 43 54 66 78 81 90) "lop" -0.44))
;; (osc:decode-bundle
;; #(35 98 117 110 100 108 101 0 0 0 0 0 0 0 0 1 0 0 0 40 47 98 108 111 98 0 0 0
;; 44 98 115 102 0 0 0 0 0 0 0 9 1 29 32 43 54 66 78 81 90 0 0 0 108 111 112 0
;; 190 225 71 174 0 0 0 32 47 119 101 47 119 111 47 119 0 0 0 0 44 105 105 102 0
;; 0 0 0 0 0 0 1 0 0 0 2 64 89 153 154 0 0 0 48 47 115 116 114 105 110 103 47 97
;; 47 108 105 110 103 0 0 44 115 115 115 0 0 0 0 115 108 105 110 107 0 0 0 115
;; 108 111 110 107 0 0 0 115 108 97 110 107 0 0 0)))))
;; equalp but not eql
(test osc-t13
"OSC message encoding test."
(is (equalp
(osc:encode-message "/asdasd" 3.6 4.5)
#(47 97 115 100 97 115 100 0 44 102 102 0 64 102 102 102 64 144 0 0))))
;; equal but not eql
(test osc-t14
"OSC message decoding test."
(is (equalp
(osc:decode-message
#(47 97 115 100 97 115 100 0 44 102 102 0 64 102 102 102 64 144 0 0))
(list "/asdasd" 3.6 4.5))))
;; symmetrical? how much of a issue is this?
(test osc-recode
"OSC message encoding & decoding symmetry test."
(let ((message (osc:decode-message
#(47 97 115 100 97 115 100 0 44 102 102 0 64 102 102 102 64 144 0 0))))
(is (equalp
message
(osc:decode-message
(apply #'osc:encode-message message))))))
;; partially pathological string tests...
(test osc-sp1
(is (equalp
(osc:encode-message "/s/t0" "four")
#(47 115 47 116 48 0 0 0 44 115 0 0 102 111 117 114 0 0 0 0)))
(is (equalp
(osc:decode-message #(47 115 47 116 48 0 0 0 44 115 0 0 102 111 117 114 0 0 0 0))
'("/s/t0" "four"))))
(test osc-sp2
(is (equalp
(osc:encode-message "/s/t0" 2 "xxxxx" 3)
#(47 115 47 116 48 0 0 0 44 105 115 105 0 0 0 0
0 0 0 2 120 120 120 120 120 0 0 0 0 0 0 3)))
(is (equalp
(osc:decode-message
#(47 115 47 116 48 0 0 0 44 105 115 105 0 0 0 0
0 0 0 2 120 120 120 120 120 0 0 0 0 0 0 3))
'("/s/t0" 2 "xxxxx" 3))))
;; (test osc-t16
;; "OSC message encoding & decoding symmetry test."
;; (let* ((packed-msg #(47 97 115 100 97 115 100 0 44 102 102 0 64 102 102 102 64 144 0 0))
;; (cons-msg (osc:decode-message packed-msg)))
;; (is (equalp
;; packed-msg
;; (osc:encode-message (values-list cons-msg))))))
;; v1.0 tests
(in-suite protocol-v1.0)
(test v1.0-required-types
"OSC data encoding test. All required types for v1.0"
(is (equalp
#(0 0 0 3 116 101 115 116 0 0 0 0 67 82 0 0 0 0 0 4 1 2 3 4)
(osc::encode-data '(3 "test" 2.1e2 #(1 2 3 4))))))
;; v1.1. tests
(in-suite protocol-v1.1)
(test v1.1-required-data-types
"OSC data encoding test. All required types for v1.1"
(is (equalp
#(44 105 104 115 102 100 98 0)
(osc::encode-typetags '(3
4294967297
"test"
2.1e2
2.1d23
#(1 2 3 4)
;; (osc::encode-timetag :now)
)))))
(test v1.1-keyword-typetags
"OSC typetag encoding test."
(is (equalp
(osc::encode-typetags '(:true :false :null :impulse))
#(44 84 70 78 73 0 0 0))))
;; (osc::encode-typetags '("s" 1))
;; play nicely with others
(in-suite interoperability)
(test hex-strings
"OSC data in hex."
(is (equalp
(osc::write-data-as-hex (osc::encode-string "hexadecimate"))
"#(68 65 78 61 64 65 63 69 6D 61 74 65 0 0 0 0)"))
(is (equalp
(osc::decode-string #(#x68 #x65 #x78 #x61 #x64 #x65 #x63 #x69
#x6D #x61 #x74 #x65 #x0 #x0 #x0 #x0))
"hexadecimate")))
#|
sc3 server
32 byte message:
2f (/) 6e (n) 5f (_) 73 (s)
65 (e) 74 (t) 0 () 0 ()
2c (,) 69 (i) 73 (s) 66 (f)
0 () 0 () 0 () 0 ()
0 () 0 () 1 () fffffff6 (?)
66 (f) 72 (r) 65 (e) 71 (q)
0 () 0 () 0 () 0 ()
3f (?) ffffff80 (?) 0 () 0 ()
/n_set 502 "freq" 1.000000
|#
(run! 'synchroscope)