aboutsummaryrefslogtreecommitdiff
path: root/site/udo/sequencing_table.udo
diff options
context:
space:
mode:
Diffstat (limited to 'site/udo/sequencing_table.udo')
-rwxr-xr-xsite/udo/sequencing_table.udo370
1 files changed, 370 insertions, 0 deletions
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