#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