aboutsummaryrefslogtreecommitdiff
path: root/site/udo/fx_autoglitchbeat.udo
diff options
context:
space:
mode:
Diffstat (limited to 'site/udo/fx_autoglitchbeat.udo')
-rwxr-xr-xsite/udo/fx_autoglitchbeat.udo168
1 files changed, 168 insertions, 0 deletions
diff --git a/site/udo/fx_autoglitchbeat.udo b/site/udo/fx_autoglitchbeat.udo
new file mode 100755
index 0000000..a39988c
--- /dev/null
+++ b/site/udo/fx_autoglitchbeat.udo
@@ -0,0 +1,168 @@
+#ifndef UDO_FXAUTOGLITCHBEAT
+#define UDO_FXAUTOGLITCHBEAT ##
+
+/*
+ Autoglitch effects, quantised
+
+ This file is part of the SONICS UDO collection by Richard Knight 2024
+ License: GPL-2.0-or-later
+ http://1bpm.net
+*/
+
+#include "pvs_tabproc.udo"
+#include "sequencing.udo"
+#include "frequency_tools.udo"
+
+
+/*
+ beat based autoglitcher in the style of dBlue Glitch
+
+ aoutL, aoutR fx_autoglitchbeat aL, aR, krandomisetrig, ipatternlength
+
+ aoutL, aoutR outputs
+ aL, aR inputs
+ krandomisetrig trigger to randomise the pattern
+ ipatterlength pattern length in semiquavers, defaults to 32
+*/
+opcode fx_autoglitchbeat, aa, aaOj
+ aL, aR, krandomisetrig, ipatternlength xin
+
+ ipatternlength = (ipatternlength == -1) ? 32 : ipatternlength
+ ifnpatterns = ftgentmp(0, 0, -ipatternlength, -7, 0)
+ ifnparams = ftgentmp(0, 0, -(ipatternlength * 2), -7, 0)
+ ifnbufferL = ftgentmp(0, 0, -44100, -7, 0)
+ ifnbufferR = ftgentmp(0, 0, -44100, -7, 0)
+ imaxeffect = 7; 5 for no tpv
+
+ kbeat init 0
+ knexteffect init 0
+ klasteffect init 0
+ kinit init 1
+ kwriting init 1
+ kparam0 init 0
+ kparam1 init 0
+ keffect init 0
+
+ if (kwriting == 1) then
+ awritepos, a_ syncphasor 1, a(gkseq_beat)
+ tablew aL, awritepos, ifnbufferL, 1
+ tablew aR, awritepos, ifnbufferR, 1
+ endif
+
+
+ if (krandomisetrig == 1 || kinit == 1) then
+ kindex = 0
+ while (kindex < ipatternlength) do
+ ksame = (kindex != 0 && random:k(0, 1) > 0.7) ? 1 : 0
+
+ if (ksame == 0) then
+ keffect = round:k(random:k(0, imaxeffect))
+ if (keffect == 0) then ; freqshift
+ kparam0 = random:k(-1000, 50)
+ elseif (keffect == 1) then ; ring mod
+ kparam0 = random:k(110, 440)
+ elseif (keffect == 2) then ; bit crush
+ kparam0 = random:k(4, 32)
+ elseif (keffect == 3 || keffect == 4 || keffect == 5) then ; retriggers and stretches
+ kparam0 = pow:k(2, round:k(random:k(1, 3))) ; division time ; was up to 4
+ if (random:k(0, 1) > 0.8) then ; reverse parameter
+ kparam1 = 1
+ else
+ kparam1 = 0
+ endif
+ endif
+ endif
+
+ tabw keffect, kindex, ifnpatterns
+ tabw kparam0, kindex, ifnparams
+ tabw kparam1, kindex + (1 * ftlen(ifnpatterns)), ifnparams
+
+ kindex += 1
+ od
+ kinit = 0
+ endif
+
+ ktime timeinsts
+
+ if (gkseq_beat == 1) then
+ kcurrenteffect tab kbeat, ifnpatterns
+ klasteffect tab (kbeat - 1 < 0) ? ipatternlength - 1 : kbeat - 1, ifnpatterns
+ kparam0 tab kbeat, ifnparams
+ kparam1 tab kbeat + (1 * ftlen(ifnpatterns)), ifnparams
+ kbeat = (kbeat + 1 < ipatternlength) ? kbeat + 1 : 0
+
+ if (kcurrenteffect != klasteffect) then
+ kwriting = 1
+ kwritestart = ktime
+ endif
+ endif
+
+
+ if (kwriting == 1 && ktime - kwritestart >= gkseq_beattime) then ; record for one beat
+ kwriting = 0
+ endif
+
+ if (kcurrenteffect == 0) then ; freqshift
+ aL, aR freqshift1 aL, aR, kparam0
+
+ elseif (kcurrenteffect == 1) then ; ring mod
+ aL, aR ringmod1 aL, aR, kparam0
+
+ elseif (kcurrenteffect == 2) then ; bit crush
+ aL, aR bitcrush aL, aR, kparam0
+
+ elseif (kcurrenteffect == 3 || kcurrenteffect == 4) then ; retriggers
+ kdivisiontime = gkseq_beattime / kparam0
+ ;kwriting vdel_k 0, kdivisiontime, 1
+ kwritelength = kdivisiontime
+ if (kparam1 == 0) then
+ aposraw = phasor(gkseq_beathz * kparam0)
+ else
+ aposraw = 1 - phasor(gkseq_beathz * kparam0)
+ endif
+
+ if (kcurrenteffect == 4) then
+ aposaug = abs:a(oscil:a(1, gkseq_beathz / 8))
+ apos = aposaug * (aposraw * kdivisiontime * ftsr(ifnbufferL))
+ else
+ apos = aposraw * kdivisiontime * ftsr(ifnbufferL)
+ endif
+
+ aL tablei apos, ifnbufferL
+ aR tablei apos, ifnbufferR
+
+ elseif (kcurrenteffect == 5) then ; stretch
+ kdivisiontime = gkseq_beattime / kparam0
+ if (kparam1 == 0) then
+ aposraw = phasor(gkseq_beathz / kparam0)
+ else
+ aposraw = 1 - phasor(gkseq_beathz / kparam0)
+ endif
+ atime = aposraw * kdivisiontime
+ kpitch init 1
+ aL mincer atime, 1, kpitch, ifnbufferL, 1
+ aR mincer atime, 1, kpitch, ifnbufferL, 1
+
+ elseif (kcurrenteffect == 6 || kcurrenteffect == 7) then
+ ir = 512
+ finputL pvsanal aL * 1.5, ir, ir/4, ir, 1
+ finputR pvsanal aR * 1.5, ir, ir/4, ir, 1
+ kready, itpvL tpv_anal finputL
+ kready, itpvR tpv_anal finputR
+
+ tpv_scramble kready, itpvL, 1
+ tpv_scramble kready, itpvR, 1
+
+ finputL tpv_resynth itpvL, finputL
+ finputR tpv_resynth itpvR, finputR
+ aL pvsynth finputL
+ aR pvsynth finputR
+
+ endif
+ xout aL, aR
+endop
+
+
+
+#end
+