;;;;;;;;;;;;;;;; SCIMP ;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;; an impromptu sc server client library ;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;; (c) ixi audio, 2010 - GPL > google it ;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;; www.ixi-audio.net - thor@ixi-audio.net ;;;;;;;;;;;;;;;;;;;;
;;; note -> works only with Impromptu 2.5 and later :::::::::
;;;;;;;;;;;;;;;;; SERVER MAINTAINANCE
(define *scserver* (cons "localhost" 57110))
(define sc:server:start-impromptu-osc
(lambda()
(io:osc:start-server 57180)
(io:osc:send-from-server-socket? #t)))
(define sc:server:address
(lambda (ip port)
(set! *scserver* (cons ip port))))
(define sc:server:quit
(lambda ()
(io:osc:send (now) *scserver* "/quit")))
(define sc:server:notify
(lambda (arg)
(io:osc:send (now) *scserver* "/notify" arg)))
(define sc:server:status
(lambda ()
(io:osc:send (now) *scserver* "/status")))
(define sc:server:cmd
(lambda (args)
(io:osc:send (now) *scserver* "/cmd" args)))
(define sc:server:dumpOSC
(lambda (args)
(io:osc:send (now) *scserver* "/dumpOSC" args)))
(define sc:server:sync
(lambda (id)
(io:osc:send (now) *scserver* "/sync" id)))
(define sc:server:clearSched
(lambda ()
(io:osc:send (now) *scserver* "/clearSched")))
(define sc:server:error
(lambda (mode)
(io:osc:send (now) *scserver* "/error" mode)))
;;;;;;;;;;;;;; RECEIVE
(define (io:osc:receive time address . args)
(print 'receiving-OSC-from-SC-server)
(cond ((string=? address "/status.reply")
(let loop ((statit '("? : " "UGens : " "Synths : " "Groups : " "SynthDefs : " "Avg CPU : " "Peak CPU : " "Sample Rate : " "Actual Sample Rate : " )) (stats args) )
(if (not (null? statit))
(begin (print (car statit) (car stats))(loop (cdr statit) (cdr stats))))))
((string=? address "/done")
(print "done : " args))
((string=? address "/fail")
(print "fail : " args))
((string=? address "/notify")
(print "oo" args))
((string=? address "/synced")
(print "synced" args))
((string=? address "/done")
(print "done " args))
((string=? address "/late")
(print "command received late " args))
((string=? address "/n_info")
(print " n info : " args))
((string=? address "/g_dumpTree.reply")
(print " n info : " args))
((string=? address "/g_queryTree.reply")
(print " queryTree : " args))
((string=? address "/b_info")
(print " buffer info (bufnum frames channels sample rate) : " args))
((string=? address "/n_go")
(print " node started : " args))
((string=? address "/n_end")
(print " node ended : " args))
((string=? address "/n_off")
(print " node turned off : " args))
((string=? address "/n_on")
(print " node turned on : " args))
((string=? address "/n_move")
(print " node moved : " args))
(else (print address '-> args))))
;;;;;;;;;;;;;; SYNTH DEFINITION COMMANDS
; not working (and won't work for now, check Rohan Drape's rsc3 library)
(define sc:synthdef:receive
(lambda (id)
(io:osc:send (now) *scserver* "/d_recv" bytes)))
(define sc:synthdef:load
(lambda (path)
(io:osc:send (now) *scserver* "/d_load" path)))
(define sc:synthdef:loadDir
(lambda (dirpath)
(io:osc:send (now) *scserver* "/d_loadDir" dirpath)))
(define sc:synthdef:free
(lambda (defname)
(io:osc:send (now) *scserver* "/d_free" defname)))
;;;;;;;;;;;;;; NODE
;; incrementer for node-id
(define next-node-id
(let ((node-id 1000))
(lambda ()
(set! node-id (+ node-id 1))
node-id)))
(define sc:node:free
(lambda (id)
(io:osc:send (now) *scserver* "/n_free" id)))
(define sc:node:run
(lambda (id val)
(io:osc:send (now) *scserver* "/n_run" id val)))
(define sc:node:set ; supporting multiple args
(lambda (time id message . val)
(if (= (length val) 1)
(io:osc:send time *scserver* "/n_set" id message val)
(apply io:osc:send time *scserver* "/n_set" id message val))))
(define sc:node:setn
(lambda (time id args)
(apply io:osc:send time *scserver* "/n_setn" id args)))
(define sc:node:fill
(lambda (id args)
(apply io:osc:send (now) *scserver* "/n_fill" id args)))
(define sc:node:map
(lambda (id controlname bus)
(io:osc:send (now) *scserver* "/n_map" id controlname bus)))
(define sc:node:mapn
(lambda (id args)
(apply io:osc:send (now) *scserver* "/n_mapn" id args)))
(define sc:node:mapa
(lambda (id controlname bus)
(io:osc:send (now) *scserver* "/n_mapa" id controlname bus)))
(define sc:node:mapan
(lambda (id args)
(apply io:osc:send (now) *scserver* "/n_mapan" id args)))
(define sc:node:before
(lambda (id tgt)
(io:osc:send (now) *scserver* "/n_before" id tgt)))
(define sc:node:after
(lambda (time id tgt)
(io:osc:send time *scserver* "/n_after" id tgt)))
(define sc:node:query
(lambda (id)
(io:osc:send (now) *scserver* "/n_query" id)))
(define sc:node:trace
(lambda (id)
(io:osc:send (now) *scserver* "/n_trace" id)))
(define sc:node:order
(lambda (addact tgt nodeids)
(apply io:osc:send (now) *scserver* "/n_order" addact tgt nodeids)))
(define sc:node:free
(lambda (id)
(io:osc:send (now) *scserver* "/n_free" id)))
;;;;;;;;;;;;;; SYNTH
;;;;;;; polymorphic synth
(define sc:synth:new
(lambda (time id synthdef addAction . (tgt . args))
(if (string? id)
(let ((node-id 0))
(set! node-id (next-node-id))
(apply io:osc:send time *scserver* "/s_new" id node-id synthdef addAction tgt args)
node-id)
(apply io:osc:send time *scserver* "/s_new" synthdef id addAction tgt args)
)))
(define sc:synth:grain
(lambda (time synthdef . args)
(apply io:osc:send time *scserver* "/s_new" synthdef -1 0 0 args)
))
; same as sc:node:set
(define (sc:synth:set time id message . val)
(apply io:osc:send time *scserver* "/n_set" id message val))
; same as sc:node:free
(define sc:synth:free
(lambda (time id)
(io:osc:send time *scserver* "/n_free" id)))
(define sc:synth:get
(lambda (id . args)
(apply io:osc:send (now) *scserver* "/s_get" id args)))
(define sc:synth:getn
(lambda (id message controlindex num)
(apply io:osc:send (now) *scserver* "/s_getn" id controlindex num)))
(define sc:synth:nold
(lambda (id)
(io:osc:send (now) *scserver* "/s_nold" id )))
;;;;;;;;;;;;;;;;;;;;;;;;;; GROUP
(define sc:group:new
(lambda (id addaction tgt)
(io:osc:send (now) *scserver* "/g_new" id addaction tgt)))
(define sc:group:head
(lambda (group-id node-id)
(io:osc:send (now) *scserver* "/g_head" group-id node-id)))
(define sc:group:tail
(lambda (id action tgt)
(io:osc:send (now) *scserver* "/g_tail" group-id node-id)))
(define sc:group:freeAll
(lambda (id)
(io:osc:send (now) *scserver* "/g_freeAll" id)))
(define sc:group:deepFree
(lambda (id)
(io:osc:send (now) *scserver* "/g_deepFree" id)))
(define sc:group:dumpTree
(lambda (id)
(io:osc:send (now) *scserver* "/g_dumpTree" id)))
(define sc:group:queryTree
(lambda (id)
(io:osc:send (now) *scserver* "/g_queryTree" id)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BUFFER
(define next-buffer-num
(let ((buffer-num 1000))
(lambda ()
(set! buffer-num (+ buffer-num 1))
buffer-num)))
(define sc:buffer:alloc
(lambda (num frames channels)
(io:osc:send (now) *scserver* "/b_alloc" num frames channels)))
(define sc:buffer:allocRead
(lambda (num path startframe frames)
(io:osc:send (now) *scserver* "/b_allocRead" num path startframe frames)))
(define sc:buffer:read
(lambda (num path startframe frames)
(io:osc:send (now) *scserver* "/b_allocRead" num path startframe frames)))
(define sc:synth:read
(lambda (num path startframe . frames)
(if (string? num)
(let ((buffer-num 0))
(set! buffer-num (next-buffer-num))
(apply io:osc:send (now) *scserver* "/b_allocRead" buffer-num num path startframe frames)
buffer-num)
(apply io:osc:send (now) *scserver* "/b_allocRead" num path startframe frames))))
(define sc:buffer:allocReadChannel
(lambda (num path start frames chnl)
(io:osc:send (now) *scserver* "/b_allocReadChannel" num path start frames chnl)))
(define sc:buffer:b-read
(lambda (num path startframe frames bufstartframe open)
(io:osc:send (now) *scserver* "/b_read" num path startframe frames bufstartframe open)))
(define sc:buffer:b-readChannel
(lambda (num path startframe frames bufstartframe open)
(io:osc:send (now) *scserver* "/b_readChannel" num path startframe frames bufstartframe open)))
(define sc:buffer:write
(lambda (num path headerformat sampleformat numframes startframe open)
(io:osc:send (now) *scserver* "/b_write" num path headerformat sampleformat numframes startframe open)))
(define sc:buffer:free
(lambda (num)
(io:osc:send (now) *scserver* "/b_free" num)))
(define sc:buffer:zero
(lambda (num)
(io:osc:send (now) *scserver* "/b_zero" num)))
(define sc:buffer:set
(lambda (num index val)
(io:osc:send (now) *scserver* "/b_set" num index val)))
(define sc:buffer:setn
(lambda (num index vals)
(io:osc:send (now) *scserver* "/b_setn" num index vals)))
(define sc:buffer:fill
(lambda (num index samples val)
(io:osc:send (now) *scserver* "/b_fill" num index samples val)))
(define sc:buffer:close
(lambda (num)
(io:osc:send (now) *scserver* "/b_close" num)))
; need to create the responder:
(define sc:buffer:query
(lambda (num)
(io:osc:send (now) *scserver* "/b_query" num)))
; need to create the responder:
(define sc:buffer:get
(lambda (num index)
(io:osc:send (now) *scserver* "/b_get" num index)))
; need to create the responder:
(define sc:buffer:getn
(lambda (num index numsamples)
(io:osc:send (now) *scserver* "/b_getn" num index numsamples)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CONTROL BUS
(define sc:controlbus:set
(lambda (time index val)
(io:osc:send time *scserver* "/c_set" index val)))
(define sc:controlbus:setn
(lambda (time index args)
(apply io:osc:send time *scserver* "/c_setn" index args)))
(define sc:controlbus:fill
(lambda (index args)
(apply io:osc:send (now) *scserver* "/c_fill" index args)))
(define sc:controlbus:get
(lambda (index)
(io:osc:send (now) *scserver* "/c_get" index)))
(define sc:controlbus:getn
(lambda (index args)
(apply io:osc:send (now) *scserver* "/c_getn" index args)))