{
   "description" : "Event type for easy integration of SuperCollider with conTimbre ePlayer using OSC.  \r\n\r\nI'll update this accordingly.",
   "ancestor_list" : [],
   "name" : "Event type for conTimbre ePlayer",
   "author" : "xffff",
   "is_private" : null,
   "id" : "1-4Sb",
   "code" : "/*\r\nEvent type for easy integration of conTimbre with SC.\r\nJust supply an osc destination to the key \\oscout.\r\n\r\nFor example:\r\n\tPbind(\r\n\t\t\\type, \\ctevent,\r\n\t\t\\oscout, NetAddr(\"127.0.0.1\", 3000),\r\n\t\t\\osccmd, \\noteon,\r\n\t\t\\voicename, \\fl,\r\n                \\midinote, Prand((40..60),inf),\r\n\t\t\\dur, Prand([1,2,1/2],inf),\r\n\t\t\\amp, Pexprand(0.75,1.0,inf)\r\n\t)\r\n\r\nFurther information on specific commands can be found in the ePlayer manual.\r\n\r\nMike Murphy 2013\r\nhttp://www.contimbre.com\r\n*/\r\n\r\nEvent.addEventType(\\ctevent, {|server|\r\n\tvar freqs, lag, dur, sustain, strum;\r\n\tvar bndl, oscout, hasGate, osccmd;\r\n\tvar oscEventFunctions = (\r\n\t\t\\noteon:\r\n\t\t#{ arg voicename, midinote=60, amp=0.1;\r\n\t\t\t[voicename, midinote, asInteger((amp * 127).clip(0, 127))] },\r\n\t\t\\noteoff:\r\n\t\t#{ arg voicename, midinote=60;\r\n\t\t\t[voicename, midinote] },\r\n\t\t\\detuned_noteon:\r\n\t\t#{ arg voicename, midinote=60, detune=0, amp=0.1;\r\n\t\t\t[voicename, midinote, detune, asInteger((amp * 127).clip(0, 127))] },\r\n\t\t\\detuned_noteoff:\r\n\t\t#{ arg voicename, midinote=60, detune=0;\r\n\t\t\t[voicename, midinote, detune] },\r\n\t\t\\ctnote:\r\n\t\t#{ arg voicenumber=0, noteid=0, midinote=60, amp=0.1, duration=0;\r\n\t\t\t[voicenumber, noteid, midinote, asInteger((amp * 127).clip(0, 127)), duration] },\r\n\t\t\\ctnoteoff:\r\n\t\t#{ arg noteid=0;\r\n\t\t\t[noteid] },\r\n\t\t\\glissando:\r\n\t\t#{ arg voicename, midinote=60, interval=0, duration=0;\r\n\t\t\t[voicename, midinote, interval.clip(-24,24), duration] },\r\n\t\t\\ctglissando:\r\n\t\t#{arg noteid, interval=0, duration=0;\r\n\t\t\t[noteid, interval.clip(-24,24), duration] },\r\n\t\t\\detuned_glissando:\r\n\t\t#{arg voicename, midinote=60, detune=0, interval=0, duration=0;\r\n\t\t\t[voicename, midinote, detune, interval.clip(-24,24), duration] },\r\n\t\t\\voice_glissando:\r\n\t\t#{arg voicename, interval=0, duration=0;\r\n\t\t\t[voicename, interval.clip(-24,24), duration] },\r\n\t\t\\reverb_state:\r\n\t\t#{arg onoff=0; [onoff]},\r\n\t\t\\reverb_gain:\r\n\t\t#{arg gain=0; [gain]},\r\n\t\t\\reverb_out:\r\n\t\t#{arg output=0, onoff=0; [output,onoff]},\r\n\t\t\\reverb_voicegain:\r\n\t\t#{arg index=0, gain=0; [index,gain]},\r\n\t\t\\reverb_time:\r\n\t\t#{arg time=1.5; [time]},\r\n\t\t\\reverb_roomsize:\r\n\t\t#{arg size=80; [size]},\r\n\t\t\\reverb_damping:\r\n\t\t#{arg damping=0.75; [damping]},\r\n\t\t\\let_vibrate:\r\n\t\t#{arg midinote=60, fullshort=0.5; [midinote,fullshort]},\r\n\t\t\\program:\r\n\t\t#{ arg voicename, programname;\r\n\t\t\t[ voicename, programname ] },\r\n\t\t\\gain:\r\n\t\t#{ arg voicename, gain=0; // this is in dB\r\n\t\t\t[ voicename, gain ] },\r\n\t\t\\chordon:\r\n\t\t#{ arg voicename, pitchlist;\r\n\t\t\t[ voicename, pitchlist ] },\r\n\t\t\\allNotesOff:\r\n\t\t#{ arg null=0; [null] },\r\n\t\t\\kammerton:\r\n\t\t#{ arg freq=442; [freq]},\r\n\t\t\\rest:\r\n\t\t#{ arg null=0; [null]}\r\n\t);\r\n\r\n\tfreqs = ~freq = ~detunedFreq.value;\r\n\r\n\tif (freqs.isRest.not) {\r\n\t\t~amp = ~amp.value;\r\n\t\t~midinote = freqs.cpsmidi;\r\n\t\tstrum = ~strum;\r\n\t\tlag = ~lag;\r\n\t\tsustain = ~sustain = ~sustain.value;\r\n\t\toscout = ~oscout.value; // OSC address\r\n\t\thasGate = ~hasGate ? true;\r\n\t\tosccmd = ~osccmd;\r\n\t\tbndl = oscEventFunctions[osccmd].valueEnvir.asCollection;\r\n\r\n\t\tbndl = bndl.asControlInput.flop;\r\n\r\n\t\tbndl.do {|msgArgs, i|\r\n\t\t\tvar latency;\r\n\t\t\tvar message;\r\n\r\n\t\t\tmessage = Array.newClear(msgArgs.size+1);\r\n\t\t\tmessage[0]=osccmd.asString;\r\n\t\t\tmsgArgs.size.do{|i| message[i+1]=msgArgs[i]};\r\n\r\n\t\t\tlatency = i * strum + lag;\r\n\r\n\t\t\t// don't send anything if type is \\rest\r\n\t\t\tif(osccmd!=\\rest,{\r\n\t\t\t\tif(latency == 0.0) {\r\n\t\t\t\t\toscout.sendBundle(latency, message)\r\n\t\t\t\t} {\r\n\t\t\t\t\tthisThread.clock.sched(latency, {\r\n\t\t\t\t\t\toscout.sendBundle(latency, message)\r\n\t\t\t\t\t})\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\t// automatically deal with noteoff messages for each note-type\r\n\t\t\tcase\r\n\t\t\t{hasGate and: { osccmd === \\noteon }} {\r\n\t\t\t\tmessage[0]=\"noteoff\";\r\n\t\t\t\tthisThread.clock.sched(sustain + latency, {\r\n\t\t\t\t\toscout.sendBundle(latency, message)\r\n\t\t\t})}\r\n\t\t\t{hasGate and: { osccmd === \\detuned_noteon }} {\r\n\t\t\t\tmessage[0]=\"detuned_noteoff\";\r\n\t\t\t\tthisThread.clock.sched(sustain + latency, {\r\n\t\t\t\t\toscout.sendBundle(latency, message)\r\n\t\t\t})}\r\n\t\t\t{hasGate and: { osccmd === \\ctnote }} {\r\n\t\t\t\tmessage[0]=\"ctnoteoff\";\r\n\t\t\t\tthisThread.clock.sched(sustain + latency, {\r\n\t\t\t\t\toscout.sendBundle(latency, message)\r\n\t\t\t})};\r\n\t\t};\r\n\t}\r\n});",
   "labels" : [
      "sampler",
      "osc",
      "contimbre",
      "event type"
   ]
}
