From 9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22 Mon Sep 17 00:00:00 2001 From: Richard Date: Sun, 13 Apr 2025 18:48:02 +0100 Subject: initial --- site/udo/sequencing_table.udo | 370 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 370 insertions(+) create mode 100755 site/udo/sequencing_table.udo (limited to 'site/udo/sequencing_table.udo') diff --git a/site/udo/sequencing_table.udo b/site/udo/sequencing_table.udo new file mode 100755 index 0000000..8ef40dc --- /dev/null +++ b/site/udo/sequencing_table.udo @@ -0,0 +1,370 @@ +#ifndef UDO_SEQUENCING_TABLE +#define UDO_SEQUENCING_TABLE ## +/* + Table sequencing + + This file is part of the SONICS UDO collection by Richard Knight 2022 + License: GPL-2.0-or-later + http://1bpm.net +*/ + + +#include "sequencing.udo" + + +gifn_tabseq_all = ftgen(0, 0, -4, -2, 1, 1, 1, 1) ; 4 quarter notes to allow for swing + +/* + +TODO: write to database + +gistfn_kick1 ftgen 0, 0, -16, -2, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 +gistfn_kick2 ftgen 0, 0, -16, -2, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0 +gistfn_kick3 ftgen 0, 0, -16, -2, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0 + +*/ + + +/* + Fill a table with random boolean values, generating the table if ifn is -1 + + ifnout _seq_randtable_bool ilen, ifn, ichance + + ifnout the resulting table + ilen length of table to create, if generating + ifn existing table or -1 to generate + ichance chance of random assignment: -1 defaults to 0.5, 1 is fill all values, 0 is fill no values +*/ +opcode _seq_randtable_bool, i, iii + ilen, ifn, ichance xin + ichance = (ichance == -1) ? 0.5 : ichance + if (ifn == -1) then + ifn ftgen 0, 0, -ilen, -2, 0 + endif + index = 0 + while (index < ftlen(ifn)) do + ivalue = (random(0, 1) <= ichance) ? 1 : 0 + tableiw ivalue, index, ifn + index += 1 + od + xout ifn +endop + + +/* + Fill a table with random numeric values, generating the table if ifn is -1 + + ifnout _seq_randtable_bool ilen, ifn, ichance + + ifnout the resulting table + ilen length of table to create, if generating + ifn existing table or -1 to generate + iminvalue minimuma value to assign + imaxvalue maximum value to assign + irounded 1 = integer values, 0 = float values +*/ +opcode _seq_randtable_numeric, i, iiiii + ilen, ifn, iminvalue, imaxvalue, irounded xin + if (ifn == -1) then + ifn ftgen 0, 0, -ilen, -2, 0 + endif + index = 0 + while (index < ftlen(ifn)) do + ivalue = random(iminvalue, imaxvalue) + tableiw ((irounded == 1) ? round(ivalue) : ivalue), index, ifn + index += 1 + od + xout ifn +endop + + +/* + Generate a table with random boolean values + + ifn seq_randtablegen ilen, ichance + + ifn the resulting table + ilen length of table to create + ichance chance of random assignment: -1 defaults to 0.5, 1 is fill all values, 0 is fill no values +*/ +opcode seq_randtablegen, i, ij + ilen, ichance xin + ifn _seq_randtable_bool ilen, -1, ichance + xout ifn +endop + + +/* + Fill an existing table with random boolean values + + seq_randtable ifn, ichance + + ifn the table to fill + ichance chance of random assignment: -1 defaults to 0.5, 1 is fill all values, 0 is fill no values +*/ +opcode seq_randtable, 0, ij + ifn, ichance xin + ifn _seq_randtable_bool -1, ifn, ichance +endop + + + +/* + Generate a table with random numeric values + + ifn seq_randtablegen_numeric ilen, iminvalue, imaxvalue, irounded + + ifnout the resulting table + ilen length of table to create + iminvalue minimuma value to assign + imaxvalue maximum value to assign + irounded 1 = integer values, 0 = float values +*/ +opcode seq_randtablegen_numeric, i, iiii + ilen, iminvalue, imaxvalue, irounded xin + ifn _seq_randtable_numeric ilen, -1, iminvalue, imaxvalue, irounded + xout ifn +endop + + + +/* + Fill an existing table with random numeric values + + seq_randtable_numeric ifn, iminvalue, imaxvalue, irounded + + ifn the table to fill + iminvalue minimuma value to assign + imaxvalue maximum value to assign + irounded 1 = integer values, 0 = float values +*/ +opcode seq_randtable_numeric, 0, iiii + ifn, iminvalue, imaxvalue, irounded xin + ifn _seq_randtable_numeric -1, ifn, iminvalue, imaxvalue, irounded +endop + + +/* + Fill an existing table with random boolean values at k-rate on receipt of a trigger + + seq_randtable kfn, ktrig, kchance + + kfn the table to fill + ktrig repopulate the table when 1 + kchance chance of random assignment: -1 defaults to 0.5, 1 is fill all values, 0 is fill no values +*/ +opcode seq_randtable, 0, kkV + kfn, ktrig, kchance xin + kchance = (kchance == -1) ? 0.5 : kchance + if (ktrig == 1) then ; && changed:k(ktrig) == 1) then + kindex = 0 + while (kindex < tableng:k(kfn)) do + kvalue = (random:k(0, 1) <= kchance) ? 1 : 0 + tablewkt kvalue, kindex, kfn + kindex += 1 + od + endif +endop + + +/* +opcode seq_table_numeric, k, i + ifn xin + ilen tableng ifn + kindex init 0 + as, a_ syncphasor gkseq_beathz*4, a(gkseq_beat) + kt trigger k(as), 0.05, 0 ; was 0.005.. works? + if (kt == 1) then + koutvalue table kindex, ifn + + if (kindex < klength - 1) then + kindex += 1 + else + kindex = 0 + endif + endif + koutvalue +endop +*/ + + + + +/* + Trigger and index output table sequencer + + ktrig, kindex seq_table ifn [, kreset=0, kdivisions=4, kchanceon=1, kchanceoff=1, klength=ftlen(ifn), kswing=gkseq_swing, kbeathz=gkseq_beathz, inosync=0] + ktrig seq_table ifn [, kreset=0, kdivisions=4, kchanceon=1, kchanceoff=1, klength=ftlen(ifn), kswing=gkseq_swing, kbeathz=gkseq_beathz, inosync=0] + + ktrig the sequence trigger + kindex current index (max = klength-1) + + ifn the table containing boolean positions + kreset if above 0 and changed since last value, then reset sequence index to 0 + kdivisions how many points feature in one beat + kchanceon chance of an on point being on (1 = always, 0 = never) + kchanceoff chance of an off point being off (1 = always, 0 = never) + klength the maximum number of points in the table to use + kswing the swing amount to apply + kbeathz trigger rate in Hz + inosync do not sync to the sequencer beat clock +*/ +opcode seq_table, kk, iOJPPJJJo + ifn, kreset, kdivisions, kchanceon, kchanceoff, klength, kswing, kbeathz, inosync xin + ilen = ftlen(ifn) + + kdivisions = (kdivisions == -1) ? 4 : kdivisions + klength = (klength == -1) ? ilen : min(ilen, klength) + kswing = (kswing == -1) ? gkseq_swing : kswing + kbeathz = (kbeathz == -1) ? gkseq_beathz : kbeathz + + kindex init 0 + klaunchindex init 0 + + if (kreset >= 0 && changed:k(kreset) == 1) then + kindex = 0 + endif + + if (inosync == 1) then + kt metro kbeathz * kdivisions + else + as, a_ syncphasor kbeathz * kdivisions, a(gkseq_beat) + kt trigger k(as), 0.05, 0 ; was 0.005.. works? + endif + ktrigout = 0 + if (kt == 1) then + ktrigout tab kindex, ifn + if (ktrigout == 1 && kchanceon < 1) then + if (random:k(0, 1) > kchanceon) then + ktrigout = 0 + endif + elseif (ktrigout == 0 && kchanceoff < 1) then + if (random:k(0, 1) > kchanceoff) then + ktrigout = 1 + endif + endif + klaunchindex = kindex + if (kindex < klength - 1) then + kindex += 1 + else + kindex = 0 + endif + endif + + ktrigout = vdel_k(ktrigout, seq_swingtime(0, ((kindex-1)/kdivisions)*4, kswing), 1) + xout ktrigout, klaunchindex +endop + +; override for single output +opcode seq_table, k, iOJPPJJJ + ifn, kreset, kdivisions, kchanceon, kchanceoff, klength, kswing, kbeathz xin + ktrig, kindex seq_table ifn, kreset, kdivisions, kchanceon, kchanceoff, klength, kswing, kbeathz + xout ktrig +endop + + +/* + Numeric output table sequencer + + kvalout seq_table_numeric ifntrig, ifnval [, kreset=0, kdivisions=4, kchanceon=1, kchanceoff=1, klength=ftlen(ifn), kswing=gkseq_swing] + + kvalout the numeric output + + ifntrig table containing boolean positions + ifnval table containing values to return + kreset if above 0 and changed since last value, then reset sequence index to 0 + kdivisions how many points feature in one beat + kchanceon chance of an on point being on (1 = always, 0 = never) + kchanceoff chance of an off point being off (1 = always, 0 = never) + klength the maximum number of points in the table to use + kswing the swing amount to apply +*/ +opcode seq_table_numeric, k, iiOJPPJJ + ifntrig, ifnval, kreset, kdivisions, kchanceon, kchanceoff, klength, kswing xin + + if (ftlen(ifnval) != ftlen(ifntrig)) then + prints "seq_table_numeric: ifntrig and ifnval are not the same length\n\n" + exitnow + endif + + kvalout = -1 + ktrig, kindex seq_table ifntrig, kreset, kdivisions, kchanceon, kchanceoff, klength, kswing + + if (ktrig == 1) then + kvalout tab kindex, ifnval + endif + + xout kvalout +endop + + +/* + Table sequencer which calls the instrument with number instrnum when ifntrig is 1 for the current index. + The instrument is passed the following parameters: + p4 index of playback + p5 value of kp5 from opcode parameters + + seq_table_scheduler instrnum, ifntrig, [ifnstart=-1, ifndur=-1, kp5=0, kreset=0, kdivisions=4, kchanceon=1, kchanceoff=1, klength=ftlen(ifn), kswing=gkseq_swing] + + instrnum instrument number to schedule + ifntrig table containing boolean triggers per position. + ifnstart table containing start times (offset from current position). If -1, all instances have the start time 0 + ifndur table containing durations per position. If -1, all instances have the duration 1 + kp5 value to be passed to instrument as p5 if required + kreset if above 0 and changed since last value, then reset sequence index to 0 + kdivisions how many points feature in one beat + kchanceon chance of an on point being on (1 = always, 0 = never) + kchanceoff chance of an off point being off (1 = always, 0 = never) + klength the maximum number of points in the table to use + kswing the swing amount to apply +*/ +opcode seq_table_scheduler, 0, iijjOOJPPJJ + instrnum, ifntrig, ifnstart, ifndur, kp5, kreset, kdivisions, kchanceon, kchanceoff, klength, kswing xin + + if (ifnstart != -1 && ftlen(ifnstart) != ftlen(ifntrig)) then + prints "seq_table_scheduler: ifntrig and ifnstart are not the same length\n\n" + exitnow + endif + + if (ifndur != -1 && ftlen(ifndur) != ftlen(ifntrig)) then + prints "seq_table_scheduler: ifntrig and ifndur are not the same length\n\n" + exitnow + endif + + ktrig, kindex seq_table ifntrig, kreset, kdivisions, kchanceon, kchanceoff, klength, kswing + + if (ktrig == 1) then + schedulek instrnum,\ + (ifnstart == -1) ? 0 : tab:k(kindex, ifnstart),\ + (ifndur == -1) ? 1 : tab:k(kindex, ifndur),\ + kindex, kp5 + endif +endop + + +/* + Table sequencer which calls the instrument with name Sinstrument when ifntrig is 1 for the current index. + The instrument is passed the following parameters: + p4 index of playback + p5 value of kp5 from opcode parameters + + seq_table_scheduler instrnum, ifntrig, [ifnstart=-1, ifndur=-1, kp5=0, kreset=0, kdivisions=4, kchanceon=1, kchanceoff=1, klength=ftlen(ifn), kswing=gkseq_swing] + + Sinstrument instrument name to schedule + ifntrig table containing boolean triggers per position. + ifnstart table containing start times (offset from current position). If -1, all instances have the start time 0 + ifndur table containing durations per position. If -1, all instances have the duration 1 + kp5 value to be passed to instrument as p5 if required + kreset if above 0 and changed since last value, then reset sequence index to 0 + kdivisions how many points feature in one beat + kchanceon chance of an on point being on (1 = always, 0 = never) + kchanceoff chance of an off point being off (1 = always, 0 = never) + klength the maximum number of points in the table to use + kswing the swing amount to apply +*/ +opcode seq_table_scheduler, 0, SijjOOJPPJJ + Sinstrument, ifntrig, ifnstart, ifndur, kp5, kreset, kdivisions, kchanceon, kchanceoff, klength, kswing xin + seq_table_scheduler nstrnum(Sinstrument), ifntrig, ifnstart, ifndur, kp5, kreset, kdivisions, kchanceon, kchanceoff, klength, kswing +endop + +#end -- cgit v1.2.3