osc 0.1.4

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.
data/README ADDED
@@ -0,0 +1,23 @@
1
+ OSC �⥸�塼��
2
+ ==============
3
+
4
+ OSC �ϥ��֥������Ȼظ�������ץȸ��� Ruby �Τ���Ρ��֥����ץ󥵥���ɡ�
5
+ ����ȥ�����ץ⥸�塼��Ǥ���
6
+
7
+
8
+ ���󥹥ȡ���
9
+ ------------
10
+
11
+ ������ץ� "install.rb" ��Ĥ����ޤ���
12
+
13
+ $ ruby install.rb config
14
+ $ ruby install.rb setup
15
+ ($ su)
16
+ # ruby install.rb install
17
+
18
+ ���路���ϡ�"ruby install.rb --help" �Ȥ��Ƥ���������
19
+
20
+
21
+ ������� (�դʤФ����褷)
22
+ mailto:tadf@funaba.org
23
+ http://www.funaba.org/
data/README.en ADDED
@@ -0,0 +1,23 @@
1
+ An "OSC" module
2
+ ==============
3
+
4
+ OSC is an "OpenSound Control" module for an object‐oriented
5
+ scripting language Ruby.
6
+
7
+
8
+ Install
9
+ ‐‐‐‐‐‐‐
10
+
11
+ Use the script "install.rb".
12
+
13
+ $ ruby install.rb config
14
+ $ ruby install.rb setup
15
+ ($ su)
16
+ # ruby install.rb install
17
+
18
+ For more information, type "ruby install.rb ‐‐help".
19
+
20
+
21
+ Tadayoshi Funaba
22
+ mailto:tadf@funaba.org
23
+ http://www.funaba.org/en/
data/lib/osc.rb ADDED
@@ -0,0 +1,377 @@
1
+ # osc.rb: Written by Tadayoshi Funaba 2005,2006
2
+ # $Id: osc.rb,v 1.4 2006-11-10 21:54:37+09 tadf Exp $
3
+
4
+ require 'forwardable'
5
+ require 'socket'
6
+ require 'thread'
7
+
8
+ module OSC
9
+
10
+ class OSCArgument
11
+
12
+ def initialize(val) @val = val end
13
+
14
+ attr_accessor :val
15
+
16
+ def to_i() @val.to_i end
17
+ def to_f() @val.to_f end
18
+ def to_s() @val.to_s end
19
+
20
+ def padding(s)
21
+ s + ("\000" * ((4 - (s.size % 4)) % 4))
22
+ end
23
+
24
+ private :padding
25
+
26
+ end
27
+
28
+ class OSCInt32 < OSCArgument
29
+
30
+ def tag() 'i' end
31
+ def encode() [@val].pack('N') end
32
+
33
+ end
34
+
35
+ class OSCFloat32 < OSCArgument
36
+
37
+ def tag() 'f' end
38
+ def encode() [@val].pack('g') end # fake
39
+
40
+ end
41
+
42
+ class OSCString < OSCArgument
43
+
44
+ def tag() 's' end
45
+ def encode() padding(@val.sub(/\000.*\z/, '') + "\000") end
46
+
47
+ end
48
+
49
+ class OSCBlob < OSCArgument
50
+
51
+ def tag() 'b' end
52
+ def encode() padding([@val.size].pack('N') + @val) end
53
+
54
+ end
55
+
56
+ class Packet
57
+
58
+ class PO
59
+
60
+ def initialize(str) @str, @index = str, 0 end
61
+ def rem() @str.length - @index end
62
+ def eof? () rem <= 0 end
63
+ def skip(n) @index += n end
64
+ def skip_padding() skip((4 - (@index % 4)) % 4) end
65
+
66
+ def getn(n)
67
+ raise EOFError if rem < n
68
+ s = @str[@index, n]
69
+ skip(n)
70
+ s
71
+ end
72
+
73
+ def getc
74
+ raise EOFError if rem < 1
75
+ c = @str[@index]
76
+ skip(1)
77
+ c
78
+ end
79
+
80
+ end
81
+
82
+ def self.decode_int32(io)
83
+ i = io.getn(4).unpack('N')[0]
84
+ i -= 2**32 if i > (2**31-1)
85
+ i
86
+ end
87
+
88
+ def self.decode_float32(io)
89
+ f = io.getn(4).unpack('g')[0]
90
+ f
91
+ end
92
+
93
+ def self.decode_string(io)
94
+ s = ''
95
+ until (c = io.getc) == 0
96
+ s << c
97
+ end
98
+ io.skip_padding
99
+ s
100
+ end
101
+
102
+ def self.decode_blob(io)
103
+ l = io.getn(4).unpack('N')[0]
104
+ b = io.getn(l)
105
+ io.skip_padding
106
+ b
107
+ end
108
+
109
+ def self.decode_timetag(io)
110
+ t1 = io.getn(4).unpack('N')[0]
111
+ t2 = io.getn(4).unpack('N')[0]
112
+ [t1, t2]
113
+ end
114
+
115
+ def self.decode2(time, packet, list)
116
+ io = PO.new(packet)
117
+ id = decode_string(io)
118
+ if id =~ /\A\#/
119
+ if id == '#bundle'
120
+ t1, t2 = decode_timetag(io)
121
+ if t1 == 0 && t2 == 1
122
+ time = nil
123
+ else
124
+ time = t1 + t2.to_f / (2**32)
125
+ end
126
+ until io.eof?
127
+ l = io.getn(4).unpack('N')[0]
128
+ s = io.getn(l)
129
+ decode2(time, s, list)
130
+ end
131
+ end
132
+ elsif id =~ /\//
133
+ address = id
134
+ if io.getc == ?,
135
+ tags = decode_string(io)
136
+ args = []
137
+ tags.scan(/./) do |t|
138
+ case t
139
+ when 'i'
140
+ i = decode_int32(io)
141
+ args << OSCInt32.new(i)
142
+ when 'f'
143
+ f = decode_float32(io)
144
+ args << OSCFloat32.new(f)
145
+ when 's'
146
+ s = decode_string(io)
147
+ args << OSCString.new(s)
148
+ when 'b'
149
+ b = decode_blob(io)
150
+ args << OSCBlob.new(b)
151
+ when /[htd]/; io.read(8)
152
+ when 'S'; decode_string(io)
153
+ when /[crm]/; io.read(4)
154
+ when /[TFNI\[\]]/;
155
+ end
156
+ end
157
+ end
158
+ list << [time, Message.new(address, nil, *args)]
159
+ end
160
+ end
161
+
162
+ private_class_method :decode_int32, :decode_float32, :decode_string,
163
+ :decode_blob, :decode_timetag, :decode2
164
+
165
+ def self.decode(packet)
166
+ list = []
167
+ decode2(nil, packet, list)
168
+ list
169
+ end
170
+
171
+ end
172
+
173
+ class Message < Packet
174
+
175
+ def initialize(address, tags=nil, *args)
176
+ @address = address
177
+ @args = []
178
+ args.each_with_index do |arg, i|
179
+ if tags && tags[i]
180
+ case tags[i]
181
+ when ?i; @args << OSCInt32.new(arg)
182
+ when ?f; @args << OSCFloat32.new(arg)
183
+ when ?s; @args << OSCString.new(arg)
184
+ when ?b; @args << OSCBlob.new(arg)
185
+ when ?*; @args << arg
186
+ else; raise ArgumentError, 'unknown type'
187
+ end
188
+ else
189
+ case arg
190
+ when Integer; @args << OSCInt32.new(arg)
191
+ when Float; @args << OSCFloat32.new(arg)
192
+ when String; @args << OSCString.new(arg)
193
+ when OSCArgument; @args << arg
194
+ end
195
+ end
196
+ end
197
+ end
198
+
199
+ attr_accessor :address
200
+
201
+ def tags() ',' + @args.collect{|x| x.tag}.join end
202
+
203
+ def encode
204
+ s = OSCString.new(@address).encode
205
+ s << OSCString.new(tags).encode
206
+ s << @args.collect{|x| x.encode}.join
207
+ end
208
+
209
+ def to_a() @args.collect{|x| x.val} end
210
+
211
+ extend Forwardable
212
+ include Enumerable
213
+
214
+ de = (Array.instance_methods - self.instance_methods)
215
+ de -= %w(assoc flatten flatten! pack rassoc transpose)
216
+ de += %w(include? sort)
217
+
218
+ def_delegators(:@args, *de)
219
+
220
+ undef_method :zip
221
+
222
+ end
223
+
224
+ class Bundle < Packet
225
+
226
+ def encode_timetag(t)
227
+ case t
228
+ when NIL # immediately
229
+ t1 = 0
230
+ t2 = 1
231
+ when Numeric
232
+ t1, fr = t.divmod(1)
233
+ t2 = (fr * (2**32)).to_i
234
+ when Time
235
+ t1, fr = (t.to_f + 2208988800).divmod(1)
236
+ t2 = (fr * (2**32)).to_i
237
+ else
238
+ raise ArgumentError, 'invalid time'
239
+ end
240
+ [t1, t2].pack('N2')
241
+ end
242
+
243
+ private :encode_timetag
244
+
245
+ def initialize(timetag=nil, *args)
246
+ @timetag = timetag
247
+ @args = args
248
+ end
249
+
250
+ attr_accessor :timetag
251
+
252
+ def encode()
253
+ s = OSCString.new('#bundle').encode
254
+ s << encode_timetag(@timetag)
255
+ s << @args.collect{|x|
256
+ x2 = x.encode; [x2.size].pack('N') + x2}.join
257
+ end
258
+
259
+ extend Forwardable
260
+ include Enumerable
261
+
262
+ def to_a() @args.collect{|x| x.to_a} end
263
+
264
+ de = (Array.instance_methods - self.instance_methods)
265
+ de -= %w(assoc flatten flatten! pack rassoc transpose)
266
+ de += %w(include? sort)
267
+
268
+ def_delegators(:@args, *de)
269
+
270
+ undef_method :zip
271
+
272
+ end
273
+
274
+ class SimpleServer
275
+
276
+ def initialize(port)
277
+ @so = UDPSocket.new
278
+ @so.bind('', port)
279
+ @cb = []
280
+ @qu = Queue.new
281
+ end
282
+
283
+ def add_method(pat, obj=nil, &proc)
284
+ case pat
285
+ when NIL; re = pat
286
+ when Regexp; re = pat
287
+ when String
288
+ pat = pat.dup
289
+ pat.gsub!(/[.^(|)]/, '\\1')
290
+ pat.gsub!(/\?/, '[^/]')
291
+ pat.gsub!(/\*/, '[^/]*')
292
+ pat.gsub!(/\[!/, '[^')
293
+ pat.gsub!(/\{/, '(')
294
+ pat.gsub!(/,/, '|')
295
+ pat.gsub!(/\}/, ')')
296
+ pat.gsub!(/\A/, '\A')
297
+ pat.gsub!(/\z/, '\z')
298
+ re = Regexp.new(pat)
299
+ else
300
+ raise ArgumentError, 'invalid pattern'
301
+ end
302
+ unless ( obj && !proc) ||
303
+ (!obj && proc)
304
+ raise ArgumentError, 'wrong number of arguments'
305
+ end
306
+ @cb << [re, (obj || proc)]
307
+ end
308
+
309
+ def sendmesg(mesg)
310
+ @cb.each do |re, obj|
311
+ if re.nil? || re =~ mesg.address
312
+ obj.send(if Proc === obj then :call else :accept end, mesg)
313
+ end
314
+ end
315
+ end
316
+
317
+ def dispatcher
318
+ loop do
319
+ time, mesg = @qu.pop
320
+ now = Time.now.to_f + 2208988800
321
+ diff = if time.nil?
322
+ then 0 else time - now end
323
+ if diff <= 0
324
+ sendmesg(mesg)
325
+ else
326
+ Thread.fork do
327
+ sleep(diff)
328
+ sendmesg(mesg)
329
+ Thread.exit
330
+ end
331
+ end
332
+ end
333
+ end
334
+
335
+ def detector
336
+ loop do
337
+ pa = @so.recv(16384)
338
+ begin
339
+ Packet.decode(pa).each{|x| @qu.push(x)}
340
+ rescue EOFError
341
+ end
342
+ end
343
+ end
344
+
345
+ private :sendmesg, :dispatcher, :detector
346
+
347
+ def run
348
+ Thread.fork do
349
+ begin
350
+ dispatcher
351
+ rescue
352
+ Thread.main.raise $!
353
+ end
354
+ end
355
+ begin
356
+ detector
357
+ rescue
358
+ Thread.main.raise $!
359
+ end
360
+ end
361
+
362
+ end
363
+
364
+ class SimpleClient
365
+
366
+ def initialize(host, port)
367
+ @so = UDPSocket.new
368
+ @so.connect(host, port)
369
+ end
370
+
371
+ def send(mesg)
372
+ @so.send(mesg.encode, 0)
373
+ end
374
+
375
+ end
376
+
377
+ end
@@ -0,0 +1,21 @@
1
+ # dumbserver.rb: Written by Tadayoshi Funaba 2005,2006
2
+ # $Id: dumbserver.rb,v 1.3 2006-03-11 10:03:36+09 tadf Exp $
3
+
4
+ require 'osc'
5
+ require 'gopt'
6
+ include OSC
7
+
8
+ def usage
9
+ warn 'usage: dumbserver [-l lport]'
10
+ exit 1
11
+ end
12
+
13
+ usage unless opt = Gopt.gopt('l:')
14
+
15
+ lport = (opt[:l] || '10000').to_i
16
+
17
+ ss = SimpleServer.new(lport)
18
+ ss.add_method(nil) do |mesg|
19
+ p [mesg.address, mesg.to_a]
20
+ end
21
+ ss.run
data/sample/getmjd.ens ADDED
Binary file
data/sample/getmjd.mxt ADDED
@@ -0,0 +1,59 @@
1
+ max v2;
2
+ #N vpatcher 424 40 805 528;
3
+ #P origin 0 -149;
4
+ #P window setfont "Sans Serif" 9.;
5
+ #P newex 250 267 68 9109513 osc-route /mjd;
6
+ #P newex 242 233 81 9109513 osc-route /getmjd;
7
+ #P newex 98 206 27 9109513 t b f;
8
+ #P newex 139 207 27 9109513 t b f;
9
+ #P button 117 37 15 0;
10
+ #P newex 101 123 52 9109513 unpack i i i;
11
+ #P message 112 65 26 9109513 date;
12
+ #P newex 107 93 40 9109513 date;
13
+ #P user incdec 64 157 15 15 0 0;
14
+ #P user incdec 110 157 15 15 0 0;
15
+ #P user incdec 156 157 15 15 0 0;
16
+ #P button 279 333 15 0;
17
+ #P newex 121 345 27 9109513 t b s;
18
+ #P number 268 302 35 9 0 0 0 139 0 0 0 221 221 221 222 222 222 0 0 0;
19
+ #P newex 242 197 80 9109513 opensoundcontrol;
20
+ #P newex 246 163 71 9109513 udp-read 10000;
21
+ #P newex 75 417 124 9109513 udp-write 192.168.1.2 10000;
22
+ #P message 86 314 98 9109513 /getmjd/civil \$1 \$2 \$3;
23
+ #P button 49 245 15 0;
24
+ #P number 161 183 35 9 1 31 3 139 0 0 0 221 221 221 222 222 222 0 0 0;
25
+ #P number 115 183 35 9 1 12 3 139 0 0 0 221 221 221 222 222 222 0 0 0;
26
+ #P number 69 183 35 9 1950 2050 3 139 0 0 0 221 221 221 222 222 222 0 0 0;
27
+ #P newex 106 282 48 9109513 pack f f f;
28
+ #P newex 97 380 80 9109513 opensoundcontrol;
29
+ #P comment 32 183 100 9109513 civil;
30
+ #P comment 234 302 100 9109513 mjd;
31
+ #P comment 78 37 100 9109513 today;
32
+ #P connect 24 0 8 0;
33
+ #P connect 23 0 8 0;
34
+ #P connect 18 0 5 0;
35
+ #P connect 21 2 5 0;
36
+ #P connect 3 0 10 0;
37
+ #P connect 4 0 9 0;
38
+ #P connect 14 1 3 0;
39
+ #P connect 14 0 3 0;
40
+ #P connect 6 0 24 0;
41
+ #P connect 19 0 21 0;
42
+ #P connect 5 0 4 0;
43
+ #P connect 8 0 4 0;
44
+ #P connect 20 0 19 0;
45
+ #P connect 22 0 20 0;
46
+ #P connect 17 0 6 0;
47
+ #P connect 21 0 6 0;
48
+ #P connect 9 0 14 0;
49
+ #P connect 24 1 4 1;
50
+ #P connect 7 0 23 0;
51
+ #P connect 23 1 4 2;
52
+ #P connect 16 0 7 0;
53
+ #P connect 21 1 7 0;
54
+ #P connect 11 0 12 0;
55
+ #P connect 12 1 25 0;
56
+ #P connect 25 0 26 0;
57
+ #P connect 26 0 13 0;
58
+ #P connect 13 0 15 0;
59
+ #P pop;
data/sample/getmjd.pd ADDED
@@ -0,0 +1,38 @@
1
+ #N canvas 387 154 557 361 10;
2
+ #X obj 213 296 sendOSC;
3
+ #X floatatom 221 113 2 1 12 0 - - -;
4
+ #X floatatom 252 113 2 1 31 0 - - -;
5
+ #X obj 386 128 dumpOSC 10000;
6
+ #X msg 75 59 disconnect;
7
+ #X floatatom 411 238 5 30000 80000 0 - - -;
8
+ #X floatatom 179 113 4 1950 2050 0 - - -;
9
+ #X obj 161 181 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
10
+ -1;
11
+ #X text 134 111 civil;
12
+ #X text 375 236 mjd;
13
+ #X obj 422 271 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
14
+ -1;
15
+ #X msg 18 25 connect 192.168.1.2 10000;
16
+ #X obj 199 221 pack f f f;
17
+ #X msg 145 257 send /getmjd/civil \$1 \$2 \$3;
18
+ #X obj 250 141 t b f;
19
+ #X obj 201 141 t b f;
20
+ #X obj 377 164 OSCroute /getmjd;
21
+ #X obj 386 202 OSCroute /mjd;
22
+ #X connect 1 0 15 0;
23
+ #X connect 2 0 14 0;
24
+ #X connect 3 0 16 0;
25
+ #X connect 4 0 0 0;
26
+ #X connect 5 0 10 0;
27
+ #X connect 6 0 12 0;
28
+ #X connect 6 0 7 0;
29
+ #X connect 7 0 12 0;
30
+ #X connect 11 0 0 0;
31
+ #X connect 12 0 13 0;
32
+ #X connect 13 0 0 0;
33
+ #X connect 14 0 7 0;
34
+ #X connect 14 1 12 2;
35
+ #X connect 15 0 7 0;
36
+ #X connect 15 1 12 1;
37
+ #X connect 16 0 17 0;
38
+ #X connect 17 0 5 0;
data/sample/getmjd.rb ADDED
@@ -0,0 +1,41 @@
1
+ # getmjd.rb: Written by Tadayoshi Funaba 2005
2
+ # $Id: getmjd.rb,v 1.2 2005-08-06 15:32:23+09 tadf Exp $
3
+
4
+ require 'osc'
5
+ require 'date'
6
+ require 'gopt'
7
+ include OSC
8
+
9
+ class GetMJD
10
+
11
+ def initialize(sc)
12
+ @sc = sc
13
+ end
14
+
15
+ def accept(mesg)
16
+ civil = mesg.collect{|x| x.to_i}
17
+ begin
18
+ mjd = Date.new(*civil).mjd
19
+ rescue
20
+ mjd = 0
21
+ end
22
+ @sc.send(Message.new('/getmjd/mjd', nil, mjd.to_f))
23
+ end
24
+
25
+ end
26
+
27
+ def usage
28
+ warn 'usage: getmjd [-h rhost] [-p rport] [-l lport]'
29
+ exit 1
30
+ end
31
+
32
+ usage unless opt = Gopt.gopt('h:p:l:')
33
+
34
+ rhost = (opt[:h] || 'localhost')
35
+ rport = (opt[:p] || '10000').to_i
36
+ lport = (opt[:l] || rport).to_i
37
+
38
+ ss = SimpleServer.new(lport)
39
+ sc = SimpleClient.new(rhost, rport)
40
+ ss.add_method('/getmjd/civil', GetMJD.new(sc))
41
+ ss.run
@@ -0,0 +1,43 @@
1
+ # joy-test.rb: Written by Tadayoshi Funaba 2005
2
+ # $Id: joy-test.rb,v 1.2 2005-08-06 15:28:49+09 tadf Exp $
3
+
4
+ require 'osc'
5
+ require 'gopt'
6
+ include OSC
7
+
8
+ def usage
9
+ warn 'usage: joy-test [-h rhost] [-p rport]'
10
+ exit 1
11
+ end
12
+
13
+ usage unless opt = Gopt.gopt('h:p:')
14
+
15
+ rhost = (opt[:h] || 'localhost')
16
+ rport = (opt[:p] || '10000').to_i
17
+
18
+ sc = SimpleClient.new(rhost, rport)
19
+
20
+ btns = [0] * 10
21
+ btns[0] = 1
22
+
23
+ sc.send(Message.new('/joy/buttons', 'f'*10, *btns))
24
+ (-2**15).step(2**15, 2**11) do |i|
25
+ sc.send(Message.new('/joy/pos', 'f'*3, i, 0, 0))
26
+ sleep 0.1
27
+ end
28
+ (-2**15).step(2**15, 2**11) do |i|
29
+ sc.send(Message.new('/joy/pos', 'f'*3, 0, i, 0))
30
+ sleep 0.1
31
+ end
32
+ sc.send(Message.new('/joy/pos', 'f'*3, 0, 0, 0))
33
+ (6..9).each do |i|
34
+ btns[i] = 1
35
+ sc.send(Message.new('/joy/buttons', 'f'*10, *btns))
36
+ btns[i] = 0
37
+ sleep 2.0
38
+ end
39
+ btns[4] = 1
40
+ sc.send(Message.new('/joy/buttons', 'f'*10, *btns))
41
+ sleep 2.0
42
+ btns = [0] * 10
43
+ sc.send(Message.new('/joy/buttons', 'f'*10, *btns))
data/sample/joy.ens ADDED
Binary file