From 9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22 Mon Sep 17 00:00:00 2001 From: Richard Date: Sun, 13 Apr 2025 18:48:02 +0100 Subject: initial --- site/udo/scss/mixer/base.udo | 253 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100755 site/udo/scss/mixer/base.udo (limited to 'site/udo/scss/mixer/base.udo') diff --git a/site/udo/scss/mixer/base.udo b/site/udo/scss/mixer/base.udo new file mode 100755 index 0000000..9721357 --- /dev/null +++ b/site/udo/scss/mixer/base.udo @@ -0,0 +1,253 @@ +#ifndef UDO_SCSS_MIXER_BASE +#define UDO_SCSS_MIXER_BASE ## +/* + SCSS mixer and dynamic insert system + + This file is part of the SONICS UDO collection by Richard Knight 2022 + License: GPL-2.0-or-later + http://1bpm.net +*/ + +#include "/bussing.udo" +#include "/interop.udo" + + + +gSchannelHeader = {{ + ichannelindex = p4 + kamp chnget sprintf("mxamp%d", ichannelindex) + kpan chnget sprintf("mxpan%d", ichannelindex) + aL, aR bus_read sprintf("mxchan%d", ichannelindex) + kenv linsegr 0, 0.05, 1, p3, 1, 0.1, 0 +}} + + +gSchannelFooter = {{ + bus_masterout(aL*kenv*(1-kpan)*kamp, aR*kenv*kpan*kamp) +endin +}} + + +; default globals: set in mx_boot +gichannelnumber = -1 +gisendchannels = -1 +gimixermaxinserts = -1 +giinserts[][] init 1, 1 +gimxinitialised[] init 1, 1 + + +; actual effects and definitions +#include "/scss/mixer/_effects.udo" +/* + Set insert for channel and insert index ; apply defaults +*/ +opcode apply_insert, 0, iii + iinsertdefindex, ichannelindex, iinsertindex xin + + giinserts[ichannelindex][iinsertindex] = iinsertdefindex + + ; set defaults + iJparams = jsonptr(giJinsertDefs, sprintf("/effects/%d/parameters", iinsertdefindex)) + index = 0 + while (index < jsonsize(iJparams)) do + iJparam jsonget iJparams, index ;jsonptr(iJparams, sprintf("/%d", index)) + SparameterName jsongetval iJparam, "name" + idefault jsongetval iJparam, "default" + chnset idefault, sprintf("fxi_%s_%d_%d", SparameterName, ichannelindex, iinsertindex) + jsondestroy(iJparam) + index += 1 + od + jsondestroy(iJparams) + + ; initial state is on + chnset 1, sprintf("fxi_on_%d_%d", ichannelindex, iinsertindex) +endop + + + +instr mx_effect_definitions_get + icbid = p4 + iJson = jsonloads(gSeffectDefs) + jsoninsertval iJson, "cbid", icbid + io_sendstring("callback", jsondumps(iJson, 0)) + turnoff +endin + +instr mx_insert_info_get + icbid = p4 + indexchan = p5 + + inserts[] init gimixermaxinserts + indexinsert = 0 + while (indexinsert < gimixermaxinserts) do + inserts[indexinsert] = giinserts[indexchan][indexinsert] + indexinsert += 1 + od + iJson = jsoninit() + jsoninsertval iJson, "cbid", icbid + jsoninsertval iJson, "inserts", inserts + io_sendstring("callback", jsondumps(iJson, 0)) + turnoff +endin + + +/* + recompile channel instrument, inserting insert effects as specified +*/ +instr mx_recompile_channel + ichannelindex = p4 + SinstrName = sprintf("mixer_channel%d", ichannelindex) + Sinstr = sprintf("instr %s\n%s", SinstrName, gSchannelHeader) + index = 0 + while (index < gimixermaxinserts) do + iinsert = giinserts[ichannelindex][index] + if (iinsert != -1) then + Sopcode jsonptrval giJinsertDefs, sprintf("/effects/%d/opcode", iinsert) + Sinstr = strcat(Sinstr, sprintf("aL, aR %s aL, aR, ichannelindex, %d\n", Sopcode, index)) + endif + index += 1 + od + + ; initial amps and pans if not initialised + if (gimxinitialised[ichannelindex] == 0) then + gimxinitialised[ichannelindex] = 1 + chnset 0.8, sprintf("mxamp%d", ichannelindex) + chnset 0.5, sprintf("mxpan%d", ichannelindex) + endif + + ; channel footer with global sends + SchannelFooter = "" + isendindex = 0 + if (gisendchannels != 0 && ichannelindex < gichannelnumber - 1) then + SchannelFooter = "" + while (isendindex < gisendchannels) do + SchannelFooter = strcat(SchannelFooter, sprintf("ksend%d chnget sprintf(\"mxsend%%d_%d\", ichannelindex)\nbus_mix \"mxchan%d\", aL*ksend%d, aR*ksend%d\n", isendindex, isendindex, gichannelnumber + isendindex, isendindex, isendindex)) + isendindex += 1 + od + Sinstr = strcat(Sinstr, SchannelFooter) + endif + Sinstr = strcat(Sinstr, gSchannelFooter) + ires compilestr Sinstr + turnoff2 SinstrName, 0, 1 + schedule SinstrName, 0.02, 3600, ichannelindex + turnoff +endin + + +instr mx_setstate + Sjson = p4 + iJson = jsonloads(Sjson) + +endin + + +instr mx_getstate + iJsonCSChannels = jsoninit() + iJsonBlankArray = jsonloads("[]") + iJsonInserts = jsonloads("[]") + ichannelindex = 0 + SchanDefaults[] fillarray "mxamp", "mxpan" + while (ichannelindex < gichannelnumber + gisendchannels) do + ichandefaultindex = 0 + while (ichandefaultindex < lenarray(SchanDefaults)) do + jsoninsertval iJsonCSChannels, sprintf("%s%d", SchanDefaults[ichandefaultindex], ichannelindex), chnget:i(sprintf("%s%d", SchanDefaults[ichandefaultindex], ichannelindex)) + ichandefaultindex += 1 + od + + jsonptradd iJsonInserts, sprintf("/%d", ichannelindex), iJsonBlankArray + + indexinsert = 0 + while (indexinsert < gimixermaxinserts) do + iinsert = giinserts[ichannelindex][indexinsert] + jsonptraddval iJsonInserts, sprintf("/%d/%d", ichannelindex, indexinsert), iinsert + if (iinsert != -1) then + iJparams = jsonptr(giJinsertDefs, sprintf("/effects/%d/parameters", iinsert)) + index = 0 + while (index < jsonsize(iJparams)) do + iJparam jsonget iJparams, index + SparameterName jsongetval iJparam, "name" + SparameterChan = sprintf("fxi_%s_%d_%d", SparameterName, ichannelindex, indexinsert) + jsoninsertval iJsonCSChannels, SparameterChan, chnget:i(SparameterChan) + jsondestroy(iJparam) + index += 1 + od + jsondestroy(iJparams) + + endif + indexinsert += 1 + od + + ichannelindex += 1 + od + iJson = jsoninit() + jsoninsertval iJson, "channelnumber", gichannelnumber + jsoninsertval iJson, "sendchannels", gisendchannels + jsoninsertval iJson, "maxinserts", gimixermaxinserts + jsoninsert iJson, "cschannels", iJsonCSChannels + jsoninsert iJson, "inserts", iJsonInserts + + prints jsondumps(iJson, 1) + + jsondestroy(iJsonBlankArray) + jsondestroy(iJsonCSChannels) + jsondestroy(iJsonInserts) + jsondestroy(iJson) + turnoff + +endin + + +instr mx_alter_insert + ichannelindex = p4 + iinsertindex = p5 + iinsertdefindex = p6 + + apply_insert iinsertdefindex, ichannelindex, iinsertindex + + ;schedule "mx_sendstate", 0, 1 + schedule "mx_recompile_channel", 0, 1, ichannelindex + turnoff +endin + +instr mx_move_insert + ichannelindex = p4 + iinsertindex_from = p5 + iinsertindex_to = p6 + + ; keep state... +endin + + +/* + set up channels +*/ +instr mx_boot + gichannelnumber = (p4 == 0) ? 12 : p4 + gisendchannels = (p5 == 0) ? 2 : p5 + gimixermaxinserts = (p6 == 0) ? 6 : p6 + + giinserts[][] init gichannelnumber + gisendchannels, gimixermaxinserts + + ; set all to -1 as 0 is a valid entry + index1 = 0 + while (index1 < lenarray(giinserts, 1)) do + index2 = 0 + while (index2 < lenarray(giinserts, 2)) do + giinserts[index1][index2] = -1 + index2 += 1 + od + index1 += 1 + od + + ; if initialised, don't reset amp/pan etc + gimxinitialised[] init gichannelnumber + gisendchannels + + ichannelindex = 0 + while (ichannelindex < gichannelnumber + gisendchannels) do + schedule "mx_recompile_channel", 0, 1, ichannelindex + ichannelindex += 1 + od + turnoff +endin + +#end -- cgit v1.2.3