From 9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22 Mon Sep 17 00:00:00 2001 From: Richard Date: Sun, 13 Apr 2025 18:48:02 +0100 Subject: initial --- site/udo/table_tools.udo | 244 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100755 site/udo/table_tools.udo (limited to 'site/udo/table_tools.udo') diff --git a/site/udo/table_tools.udo b/site/udo/table_tools.udo new file mode 100755 index 0000000..50f5997 --- /dev/null +++ b/site/udo/table_tools.udo @@ -0,0 +1,244 @@ +#ifndef UDO_TABLETOOLS +#define UDO_TABLETOOLS ## +/* + Table tools + + This file is part of the SONICS UDO collection by Richard Knight 2022, 2024 + License: GPL-2.0-or-later + http://1bpm.net +*/ + + +/* + Normalise an audio ftable to to between -1 and 1 + + ftnormalise ifn + + ifn ftable to analyse +*/ +opcode ftnormalise, 0, ip + ifn, iscaling xin + imaxpos = -999 + imaxneg = 999 + iendpoint = 0 + index = 0 + while (index < ftlen(ifn)) do + ival table index, ifn + if (ival > 0 && ival > imaxpos) then + imaxpos = ival + elseif (ival < 0 && ival < imaxneg) then + imaxneg = ival + endif + index += 1 + od + + + iscale = ((0.999/max(abs(imaxneg), abs(imaxpos)))) * iscaling + index = 0 + while (index < ftlen(ifn)) do + ival table index, ifn + tablew ival * iscale, index, ifn + index += 1 + od +endop + + +opcode tab_record, i, aj + ain, iduration xin + if (iduration == -1 || iduration > p3) then + iduration = p3 + endif + ifn ftgen 0, 0, -(iduration * sr), -2, 0 + apos lphasor 1 + tablew ain, apos, ifn + xout ifn +endop + +/* + Sample rate agnostic audio file loading +*/ +opcode tab_loadaudio, iik, S + Sfile xin + kdone init 0 + ilen = filelen(Sfile) + ilensamp = ilen * sr + ikcycles = ilen * kr + ichannels = filenchnls(Sfile) + ifnL ftgen 0, 0, ilensamp, 2, 0 + if (ichannels == 2) then + ifnR ftgen 0, 0, ilensamp, 2, 0 + else + ifnR = -1 + endif + ktimek timeinstk + kcount init 0 + if (ktimek == 1) then + while (kcount < ikcycles) do + apos linseg 0, ilen, ilensamp - 1 + if (ichannels == 1) then + asig soundin Sfile + tablew asig, apos, ifnL + else + aL, aR soundin Sfile + tablew aL, apos, ifnL + tablew aR, apos, ifnR + endif + kcount += 1 + od + else + kdone = 1 + endif + xout ifnL, ifnR, kdone +endop + + +opcode tab_samplerateconvert, iik, ijpj + ifnL, ifnR, ifreeafter, isourcesr xin + isr = (isourcesr == -1) ? ftsr(ifnL) : isourcesr + kdone init 0 + if (isr != sr) then + ilen = ftlen(ifnL) + ilens = ftlen(ifnL) / isr + inewlen = (sr / isr) * ilen + ifnnewL ftgen 0, 0, -inewlen, -2, 0 + if (ifnR != -1) then + ifnnewR ftgen 0, 0, -inewlen, -2, 0 + else + ifnnewR = -1 + endif + ktimek timeinstk + ikcycles = ilens * kr + if (ktimek == 1) then + kcount = 0 + while (kcount < ikcycles) do + aposw linseg 0, ilens, inewlen - 1 + aposr linseg 0, ilens, ilen - 1 + asig table3 aposr, ifnL + tablew asig, aposw, ifnnewL + if (ifnR != -1) then + asig table3 aposr, ifnR + tablew asig, aposw, ifnnewR + endif + kcount += 1 + od + else + kdone = 1 + endif + if (ifreeafter == 1) then + ftfree ifnL, 1 + if (ifnR != -1) then + ftfree ifnR, 1 + endif + endif + else + kdone init 1 + ifnnewL = ifnL + ifnnewR = ifnR + endif + xout ifnnewL, ifnnewR, kdone +endop + +opcode tab_samplerateconvert, ik, ipj + ifn, ifreeafter, isourcesr xin + ifnnew, i_, kdone tab_samplerateconvert ifn, -1, ifreeafter, isourcesr + xout ifnnew, kdone +endop + +; table +opcode tab_serialise, S, i + ifn xin + ilen = ftlen(ifn) + index = 0 + + Sout = "[" + while (index < ilen) do + if (index != 0) then + Sout = strcat(Sout, ",") + endif + ivalue = table:i(index, ifn) + SprintfChar = (frac(ivalue) == 0) ? "%d" : "%f" + Sout = strcat(Sout, sprintf(SprintfChar, ivalue)) + index += 1 + od + Sout = strcat(Sout, "]") + xout Sout +endop + + +opcode tab_unserialise, 0, Si + Sdata, ifn xin + ilen = strlen(Sdata) + ichar = 0 + inarray = 0 + ivalstart = -1 + index = 0 + while (ichar < ilen) do + Schar = strsub(Sdata, ichar, ichar + 1) + if (strcmp(Schar, "[") == 0) then + inarray = 1 + ivalstart = ichar + 1 + elseif (inarray == 1 && strcmp(Schar, "]") == 0) then + inarray = 0 + elseif (inarray == 1 && strcmp(Schar, ",") == 0) then + tablew strtod(strsub(Sdata, ivalstart, ichar)), index, ifn + ivalstart = ichar + 1 + index += 1 + endif + ichar += 1 + od +endop + + +opcode tab_bubblesort, 0, i + ifn xin + itemp = 0 + ilen = ftlen(ifn) + index1 = 0 + while (index1 < ilen - 1) do + index2 = 0 + while (index2 < ilen - 1 - index1) do + ival1 = tab_i(index2, ifn) + ival2 = tab_i(index2 + 1, ifn) + if (ival1 > ival2) then + itemp = ival1 + tabw_i ival2, index2, ifn + tabw_i itemp, index2 + 1, ifn + endif + index2 += 1 + od + index1 += 1 + od +endop + + +opcode tab_destroy, 0, i + ifn xin + if (ftexists(ifn) == 1) then + ftfree ifn, 0 + endif +endop + +/* + get condensed table eg for waveform view +*/ +opcode tab_overview, i, io + ifn, isamples xin + isamples = (isamples == 0) ? 256 : isamples + ifnlen = ftlen(ifn) + istep = round(ifnlen / isamples) + ifndata ftgen 0, 0, -isamples, 7, 0 + index = 0 + indexwrite = 0 + while (index < ifnlen) do + ival tab_i index, ifn + if (!(indexwrite > isamples - 1)) then + tabw_i ival, indexwrite, ifndata + endif + indexwrite += 1 + index += istep + od + xout ifndata +endop + + +#end -- cgit v1.2.3