From 36d38b8350949114b03416123b438b23143f818a Mon Sep 17 00:00:00 2001 From: mwinter Date: Sat, 3 Jun 2023 20:45:44 +0200 Subject: [PATCH] developing for live setup: mixer and playback controls - initial work --- openstagecontrol/custom_module_hdp.js | 50 +++ openstagecontrol/mixer_transport.json | 569 ++++++++++++++++++++++++++ python/vernier_tracker.py | 2 +- supercollider/berger_knuth_tiling.scd | 1 - supercollider/live_utilities.scd | 105 +++++ supercollider/main.scd | 2 +- 6 files changed, 726 insertions(+), 3 deletions(-) create mode 100644 openstagecontrol/custom_module_hdp.js create mode 100644 openstagecontrol/mixer_transport.json create mode 100644 supercollider/live_utilities.scd diff --git a/openstagecontrol/custom_module_hdp.js b/openstagecontrol/custom_module_hdp.js new file mode 100644 index 0000000..1a1f677 --- /dev/null +++ b/openstagecontrol/custom_module_hdp.js @@ -0,0 +1,50 @@ +module.exports = { + + init: function(){ + // this will be executed once when the osc server starts + }, + + oscInFilter:function(data) { + + var {host, port, address, args} = data + + if (address === '/playing') { + console.log(args) + receive("/measure", args[0].value) + receive("/beat", args[1].value) + receive("/visual_click", 1) + } + + return + + }, + + oscOutFilter:function(data) { + + var {host, port, address, args} = data + + if (address.substring(1, 6) == 'mixer') { + tokens = address.split('/') + ins = tokens[2] + type = tokens[3] + index = tokens[4] + val = args[0].value + args = [{'type': 's', 'value': ins}, {'type': 's', 'value': type}, {'type': 's', 'value': index}, {'type': 'f', 'value': val}] + //console.log(data) + address = '/mixer' + return {host, port, address, args} + } + + if (address === '/transport') { + return {host, port, address, args} + } + + return + + }, + + unload: function(){ + // this will be executed when the custom module is reloaded + }, + +} diff --git a/openstagecontrol/mixer_transport.json b/openstagecontrol/mixer_transport.json new file mode 100644 index 0000000..1459f91 --- /dev/null +++ b/openstagecontrol/mixer_transport.json @@ -0,0 +1,569 @@ +{ + "createdWith": "Open Stage Control", + "version": "1.24.0", + "type": "session", + "content": { + "type": "root", + "lock": false, + "id": "root", + "visible": true, + "interaction": true, + "comments": "", + "width": "auto", + "height": "auto", + "colorText": "auto", + "colorWidget": "auto", + "alphaFillOn": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "tabsPosition": "top", + "hideMenu": false, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "matrix", + "top": 240, + "left": 40, + "lock": false, + "id": "mixer/berger/pan", + "visible": true, + "interaction": true, + "comments": "", + "width": 570, + "height": 50, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "horizontal", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "tabsPosition": "top", + "variables": "@{parent.variables}", + "traversing": false, + "widgetType": "knob", + "quantity": 6, + "props": {}, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [], + "tabs": [] + }, + { + "type": "matrix", + "top": 20, + "left": 40, + "lock": false, + "id": "mixer/berger/volume", + "visible": true, + "interaction": true, + "comments": "", + "width": 570, + "height": 220, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "horizontal", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "tabsPosition": "top", + "variables": "@{parent.variables}", + "traversing": false, + "widgetType": "fader", + "quantity": 6, + "props": {}, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [], + "tabs": [] + }, + { + "type": "matrix", + "top": 290, + "left": 40, + "lock": false, + "id": "mixer/berger/mute", + "visible": true, + "interaction": true, + "comments": "", + "width": 570, + "height": 40, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "horizontal", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "tabsPosition": "top", + "variables": "@{parent.variables}", + "traversing": false, + "widgetType": "button", + "quantity": 6, + "props": {}, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [], + "tabs": [] + }, + { + "type": "panel", + "top": 20, + "left": 610, + "lock": false, + "id": "mixer/string/master_panel", + "visible": true, + "interaction": true, + "comments": "", + "width": 60, + "height": 310, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "tabsPosition": "top", + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "fader", + "top": 0, + "left": 0, + "lock": false, + "id": "mixer/berger/volume/master", + "visible": true, + "interaction": true, + "comments": "", + "width": "auto", + "height": 300, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "design": "default", + "knobSize": "auto", + "horizontal": false, + "pips": false, + "dashed": false, + "gradient": [], + "snap": false, + "spring": false, + "doubleTap": false, + "range": { + "min": 0, + "max": 1 + }, + "logScale": false, + "sensitivity": 1, + "steps": "", + "origin": "auto", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "onTouch": "" + } + ], + "tabs": [] + }, + { + "type": "button", + "top": 520, + "left": 40, + "lock": false, + "id": "transport", + "visible": true, + "interaction": true, + "comments": "", + "width": 80, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorTextOn": "auto", + "label": "#{@{this} == 0 ? \"play\" : \"stop\"}", + "vertical": false, + "wrap": false, + "on": 1, + "off": 0, + "mode": "toggle", + "doubleTap": false, + "decoupled": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 0, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "if(value === 1){\n send(false, \"/transport\", 1);\n} else {\n send(false, \"/transport\", 0);\n}" + }, + { + "type": "panel", + "top": 330, + "left": 40, + "lock": false, + "id": "metronome", + "visible": true, + "interaction": true, + "comments": "", + "width": 630, + "height": 190, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "tabsPosition": "top", + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "input", + "top": 0, + "left": 0, + "lock": false, + "id": "measure", + "visible": true, + "interaction": true, + "comments": "", + "width": 250, + "height": 180, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": ":host {\n font-size: 120rem;\n}", + "align": "center", + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "value": 10, + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + }, + { + "type": "text", + "top": 10, + "left": 250, + "lock": false, + "id": "text_3", + "visible": true, + "comments": "", + "width": 50, + "height": 130, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": ":host {\n font-size: 120rem;\n}", + "vertical": false, + "wrap": false, + "align": "center", + "value": ":", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "" + }, + { + "type": "input", + "top": 0, + "left": 300, + "lock": false, + "id": "beat", + "visible": true, + "interaction": true, + "comments": "", + "width": 120, + "height": 180, + "expand": false, + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": ":host {\n font-size: 120rem;\n}", + "align": "center", + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "value": 10, + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + }, + { + "type": "led", + "top": 10, + "left": 430, + "lock": false, + "id": "visual_click", + "visible": true, + "comments": "", + "width": 180, + "height": 160, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "mode": "intensity", + "range": { + "min": 0, + "max": 1 + }, + "alphaRange": { + "min": 0, + "max": 1 + }, + "logScale": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "target": "", + "onCreate": "", + "onValue": "var fallTime = 0.3,\nfps = 24,\nmaxValue = 1,\nstep = maxValue / fps / fallTime\n\nsetTimeout(()=>{\n if (value <= 0) clearTimeout()\n set(\"this\", value - step)\n}, 1000 / fps)" + } + ], + "tabs": [] + } + ], + "tabs": [] + } +} \ No newline at end of file diff --git a/python/vernier_tracker.py b/python/vernier_tracker.py index 4678f22..0fb5ac7 100644 --- a/python/vernier_tracker.py +++ b/python/vernier_tracker.py @@ -18,7 +18,7 @@ port = 57120 client = SimpleUDPClient(ip, port) # Create client # Read video (eventually will be the live capture from the camera) -video = cv2.VideoCapture("/home/mwinter/Portfolio/a_history_of_the_domino_problem/a_history_of_the_domino_problem_git_rebase/recs/a_history_of_the_domino_problem_final_documentation_hq.mp4") +video = cv2.VideoCapture("/home/mwinter/Portfolio/a_history_of_the_domino_problem/a_history_of_the_domino_problem_source/recs/a_history_of_the_domino_problem_final_documentation_hq.mp4") # Exit if video not opened. if not video.isOpened(): diff --git a/supercollider/berger_knuth_tiling.scd b/supercollider/berger_knuth_tiling.scd index 840797b..89f78e9 100644 --- a/supercollider/berger_knuth_tiling.scd +++ b/supercollider/berger_knuth_tiling.scd @@ -316,5 +316,4 @@ Ppar(finSeqs); }; - ) \ No newline at end of file diff --git a/supercollider/live_utilities.scd b/supercollider/live_utilities.scd new file mode 100644 index 0000000..dcf30f5 --- /dev/null +++ b/supercollider/live_utilities.scd @@ -0,0 +1,105 @@ +( + +~bergerBusArray = 6.collect({Bus.audio(s, 1)}); + +Event.addEventType(\osc, { + if (~addr.postln.notNil) { + ~msg.postln; + ~addr.sendMsg(~path, *~msg); + }; +}); + +//create synth defs +~bergerCreateSynthsForLive = {arg b; + // this creates a different waveform for each sonification of each part + Buffer.freeAll(s); + b = 8.collect({var buf = Buffer.alloc(s, 512, 1); buf.sine1(1.0 / 5.collect({arg i; pow(i + 1, 5.0.rand + 1)}), true, true, true)}); + + SynthDef(\berger, {arg freq, amp = 0.2, del = 5, gate = 1, sustain = 1, buf = 0, out = 0; + Out.ar(out, Osc.ar(Select.kr(buf, b), freq, 0, amp) * EnvGen.kr(Env.adsr(0.05, sustain, 0.25, 0.1), gate, 1, 0, 1, doneAction: 2)); + }).add; +}; + +//sonify musical data +~bergerCreatePatternsForLive = {arg seqs, group, addr; + var pBinds, transportPattern; + pBinds = seqs.collect({arg r, i; + Pbind(\instrument, \berger, + //\buf, Pseq((i - ((0..(r.slice(nil, 2).flat.size - 1)) / 10).trunc.asInteger) % 8), + \group, group, + \buf, i, + \out, ~bergerBusArray[i], + //\freq, Pseq(55 * r[1]), + \freq, Pseq((55 * r[1]).cpsmidi.round(0.5).midicps), + \dur, Pseq(r[0]), + \sustain, Pseq(r[0]), + \amp, Pseq(r[2] / 1) //4) + ) + }); + + transportPattern = Pbind( + \type, \osc, + \addr, addr, + \path, "/playing", + \msg, Pseq(seqs[0][6].collect({arg beats, measure; beats.asInteger.collect({arg beat; [measure + 1, beat + 1]})}).flatten;, 1), + \dur, 1 + ); + + Ppar(pBinds.add(transportPattern)); +}; + + +SynthDef(\mixer, {arg freq, gate = 1, sustain, amp, dur, out; + var nameSpaces, sigs; + + sigs = [~bergerBusArray].collect({arg busArray, i; + var nameSpace, sig; + nameSpace = ['berger', 'sine', 'bass', 'hdust', 'sampler'][i]; + sig = busArray.collect({arg bus, c; In.ar(bus, 1) * NamedControl.kr(\ ++ nameSpace ++ '_volume_' ++ c, 1, 0.1)}); + sig = sig.collect({arg channel, c; Pan2.ar(channel, NamedControl.kr(\ ++ nameSpace ++ '_pan_' ++ c, i / (busArray.size - 1), 0.1) * 2 - 1)}); + sig = sig.collect({arg channel, c; channel * NamedControl.kr(\ ++ nameSpace ++ '_mute_' ++ c, 1, 0.1)}); + sig = Mix.ar(sig) * pow(NamedControl.kr(\ ++ nameSpace ++ '_volume_master', 1, 0.5), 2); + }); + + sigs = Mix.ar(sigs / 6); + Out.ar(0, sigs) +}).add; + +) + +( + +var group, berger, mixer, player; + +group = Group.new; +berger = Synth.tail(group, \berger); +mixer = Synth.tail(group, \mixer); + +OSCdef(\mixer, {arg msg, time, addr, port; + msg.postln; + mixer.set((msg[1] ++ '_' ++ msg[2] ++ '_' ++ msg[3]), msg[4]) +}, \mixer); + +OSCdef(\transport, {arg msg, time, addr, port; + msg.postln; + if(msg[1] == 0, { + group.set(\release, 2); + group.set(\gate, 0); + player.stop; + }, { + var patterns = ~bergerCreatePatternsForLive.value(~bergerMusic, group, addr); + player = Pfset(pattern: patterns, cleanupFunc: { + addr.sendMsg("/transport", 0); + }); + player = player.play + }); +}, \transport); + +) + +/* +~bergerCreateSynthsForLive.value; +~patterns = ~bergerCreatePatternsForLive.value(~bergerMusic); +~patterns.play +~bergerMusic[0][6].collect({arg beats, measure; beats.asInteger.collect({arg beat; [measure + 1, beat + 1]})}).flatten; +*/ \ No newline at end of file diff --git a/supercollider/main.scd b/supercollider/main.scd index 81fbe4e..3a538c1 100644 --- a/supercollider/main.scd +++ b/supercollider/main.scd @@ -2,7 +2,7 @@ ~seed = 11735; ~dir = thisProcess.nowExecutingPath.dirname; -PathName.new(~dir).files.do({arg path; if((path.fileName != "main.scd") && (path.fileName != "installation_control.scd"), {path.fileName.loadRelative})}); +PathName.new(~dir).files.do({arg path; if((path.fileName != "main.scd") && (path.fileName != "installation_control.scd") && (path.fileName != "visualize_legacy.scd"), {path.fileName.loadRelative})}); ~bergerTiling = ~berger.value(500, 500, true);