diff options
author | Richard <q@1bpm.net> | 2025-04-13 18:48:02 +0100 |
---|---|---|
committer | Richard <q@1bpm.net> | 2025-04-13 18:48:02 +0100 |
commit | 9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22 (patch) | |
tree | 291bd79ce340e67affa755a8a6b4f6a83cce93ea /site/udo/pvs_tabproc.udo | |
download | apps.csound.1bpm.net-9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22.tar.gz apps.csound.1bpm.net-9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22.tar.bz2 apps.csound.1bpm.net-9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22.zip |
initial
Diffstat (limited to 'site/udo/pvs_tabproc.udo')
-rwxr-xr-x | site/udo/pvs_tabproc.udo | 640 |
1 files changed, 640 insertions, 0 deletions
diff --git a/site/udo/pvs_tabproc.udo b/site/udo/pvs_tabproc.udo new file mode 100755 index 0000000..dc2dc04 --- /dev/null +++ b/site/udo/pvs_tabproc.udo @@ -0,0 +1,640 @@ +#ifndef UDO_PVSTABPROC
+#define UDO_PVSTABPROC ##
+/*
+ Frame based PVS processing
+
+ ksmps must be 64 or lower: setksmps(64) can be set in the calling instrument if required
+
+ tpv data tables have the following indexes:
+ 0: number of channels
+ 1: amp left
+ 2: amp right
+ 3: frequency left
+ 4: frequency right
+
+ This file is part of the SONICS UDO collection by Richard Knight 2021, 2022, 2024, 2025
+ License: GPL-2.0-or-later
+ http://1bpm.net
+*/
+
+/*
+ Make container for processing tables and information
+ itpvdata tpv_makecontainer ichannels, inumbins
+
+ itpvdata tpv information for subsequent opcodes
+ ichannels number of channels to account for
+ inumbins number of frequency bins
+*/
+opcode tpv_makecontainer, i, ii
+ ichannels, inumbins xin
+ itpv ftgentmp 0, 0, -5, -2, ichannels
+ index = 1
+ while (index < 5) do
+ if (ichannels == 1 && (index == 2 || index == 4)) then
+ ival = 0
+ else
+ ival ftgentmp 0, 0, -inumbins, -2, 0
+ endif
+ tabw_i ival, index, itpv
+ index += 1
+ od
+ xout itpv
+endop
+
+/*
+ Shorthand to get tpv data items
+ ichannels, isize, ifnampL, ifnampR, ifnfreqL, ifnfreqR tpv_get itpvdata
+
+ ichannels number of channels
+ isize bin size
+ ifnampL left amp table
+ ifnampR right amp table
+ ifnfreqL left freq table
+ ifnfreqR right freq table
+ iptvdata tpv data table
+*/
+opcode tpv_get, iiiiii, i
+ itpvdata xin
+ ifnAmpL = tab_i(1, itpvdata)
+ xout tab_i(0, itpvdata), ftlen(ifnAmpL), ifnAmpL, tab_i(2, itpvdata), tab_i(3, itpvdata), tab_i(4, itpvdata)
+endop
+
+/*
+ Analyse f-signal to table (mono)
+ kready, itpvdata tpv_anal fsrc
+
+ fsrc source f-signal
+ kready done trigger
+ iptvdata tpv analysis data
+*/
+opcode tpv_anal, ki, f
+ fsrc xin
+ ioverlap, inumbins, iwinsize, iformat pvsinfo fsrc
+ itpvdata tpv_makecontainer 1, inumbins
+ kready pvsftw fsrc, tab_i(1, itpvdata), tab_i(3, itpvdata)
+ xout kready, itpvdata
+endop
+
+/*
+ Analyse f-signal to table (stereo)
+ kready, itpvdata tpv_anal fsrcL, fsrcR
+
+ fsrcL source f-signal left
+ fsrcR source f-signal right
+ kready done trigger
+ iptvdata tpv analysis stream handles for use in other opcodes
+*/
+opcode tpv_anal, ki, ff
+ fsrcL, fsrcR xin
+ ioverlap, inumbins, iwinsize, iformat pvsinfo fsrcL
+ itpvdata tpv_makecontainer 2, inumbins
+ kreadyL pvsftw fsrcL, tab_i(1, itpvdata), tab_i(3, itpvdata)
+ kreadyR pvsftw fsrcR, tab_i(2, itpvdata), tab_i(4, itpvdata)
+ xout (kreadyL & kreadyR), itpvdata
+endop
+
+/*
+ Reform tpv data (mono). Input and output f-signals must be the same.
+
+ foutM tpv_resynth itpvdata, foutM
+
+ itpvdata tpv analysis stream handles
+ foutM f-signal to write to
+*/
+opcode tpv_resynth, f, if
+ itpvdata, foutM xin
+ pvsftr foutM, tab_i(1, itpvdata), tab_i(3, itpvdata)
+ xout foutM
+endop
+
+/*
+ Reform tpv data (stereo). Input and output f-signals must be the same.
+ foutL, foutR tpv_resynth itpvdata, foutL, foutR
+
+ itpvdata tpv analysis stream handles
+ foutL f-signal to write to left
+ foutR f-signal to write to right
+*/
+opcode tpv_resynth, ff, iff
+ itpvdata, foutL, foutR xin
+ pvsftr foutL, tab_i(1, itpvdata), tab_i(3, itpvdata)
+ pvsftr foutR, tab_i(2, itpvdata), tab_i(4, itpvdata)
+ xout foutL, foutR
+endop
+
+/*
+ Smear frames
+ tpv_smear kready, itpvdata, imaxframes, kframes, kavgfreqs, kincludeoriginal
+
+ kready done trigger from tpv_anal
+ itpvdata tpv analysis stream handles
+ imaxframes maximum frames for smearage
+ kframes frames of smearage to apply
+ kavgfreqs average frequencies as well as smearing amplitudes (bool)
+ kincludeoriginal include the original frame in output
+*/
+opcode tpv_smear, 0, kijJOP
+ kready, itpvdata, imaxframes, kframes, kavgfreqs, kincludeoriginal xin
+ imaxframes = (imaxframes == -1) ? 8 : imaxframes
+ kframes = (kframes < 1 || kframes > imaxframes) ? imaxframes: kframes
+ ichans, isize, ifnampL, ifnampR, ifnfreqL, ifnfreqR tpv_get itpvdata
+ itpvtemps ftgentmp 0, 0, -imaxframes, -2, 0
+ index = 0
+ while (index < imaxframes) do
+ tabw_i(tpv_makecontainer(ichans, isize), index, itpvtemps)
+ index += 1
+ od
+ kindexframew init 0
+
+ if (kready == 1) then
+ ktpvfnw = tab:k(kindexframew, itpvtemps)
+ tablecopy tablekt:k(1, ktpvfnw), ifnampL
+ tablecopy tablekt:k(3, ktpvfnw), ifnfreqL
+ if (ichans == 2) then
+ tablecopy tablekt:k(2, ktpvfnw), ifnampR
+ tablecopy tablekt:k(4, ktpvfnw), ifnfreqR
+ endif
+
+ kindexframer = (kindexframew - 1 < 0) ? imaxframes - 1 : kindexframew - 1
+ kframescale = 1 / kframes
+ kindex = 0
+ while (kindex < isize) do
+ kampL = (kincludeoriginal == 1) ? tab:k(kindex, ifnampL) : 0
+ kfreqL = (kincludeoriginal == 1) ? tab:k(kindex, ifnfreqL) : 0
+ if (ichans == 2) then
+ kampR = (kincludeoriginal == 1) ? tab:k(kindex, ifnampR) : 0
+ kfreqR = (kincludeoriginal == 1) ? tab:k(kindex, ifnfreqR) : 0
+ endif
+ kindexframeabs = 0
+ while (kindexframeabs < kframes) do
+ kcurscale = (kframescale * (kframes - kindexframeabs))
+ ktpvframe tab kindexframer, itpvtemps
+ ;kampL = (kampL + tablekt:k(kindex, ktpvframe)) * 0.5
+ kampL += tablekt:k(kindex, tablekt:k(1, ktpvframe)) * kcurscale
+ if (kavgfreqs == 1) then
+ kfreqL = (kfreqL + tablekt:k(kindex, tablekt:k(3, ktpvframe))) * 0.5
+
+ endif
+ if (ichans == 2) then
+ kampR += tablekt:k(kindex, tablekt:k(2, ktpvframe)) * kcurscale
+ if (kavgfreqs == 1) then
+ kfreqR = (kfreqR + tablekt:k(kindex, tablekt:k(4, ktpvframe))) * 0.5
+ endif
+ endif
+ kindexframer = (kindexframer - 1 < 0) ? imaxframes - 1 : kindexframer - 1
+ kindexframeabs += 1
+ od
+
+ tabw kampL, kindex, ifnampL
+ if (kavgfreqs == 1) then
+ tabw kfreqL, kindex, ifnfreqL
+ endif
+ if (ichans == 2) then
+ tabw kampR, kindex, ifnampR
+ if (kavgfreqs == 1) then
+ tabw kfreqR, kindex, ifnfreqR
+ endif
+ endif
+ kindex += 1
+ od
+ if (kindexframew + 1 < imaxframes) then
+ kindexframew += 1
+ else
+ kindexframew = 0
+ endif
+ endif
+endop
+
+/*
+ Wrap spectrum
+ tpv_wrap kready, itpvdata, kwrapstart
+
+ kready done trigger from tpv_anal
+ itpvdata tpv analysis stream handles
+ kwrapAmpBin start bin for amplitude wrapping
+ kwrapFreqBin start bin for frequency wrapping
+*/
+opcode tpv_wrap, 0, kikk
+ kready, itpvdata, kwrapAmpBin, kwrapFreqBin xin
+ ichans, isize, ifnampL, ifnampR, ifnfreqL, ifnfreqR tpv_get itpvdata
+ itpvdatatemp tpv_makecontainer ichans, isize
+ i_, i_, ifnampLtemp, ifnampRtemp, ifnfreqLtemp, ifnfreqRtemp tpv_get itpvdatatemp
+
+ if (kready == 1) then
+ tablecopy ifnampLtemp, ifnampL
+ tablecopy ifnfreqLtemp, ifnfreqL
+ if (ichans == 2) then
+ tablecopy ifnampRtemp, ifnampR
+ tablecopy ifnfreqRtemp, ifnfreqR
+ endif
+
+ kindex = 0
+ while (kindex < isize) do
+ kwrapAmpIndexW = (kwrapAmpBin + kindex) % isize
+ kwrapFreqIndexW = (kwrapFreqBin + kindex) % isize
+
+ tabw tab:k(kindex, ifnampLtemp), kwrapAmpIndexW, ifnampL
+ tabw tab:k(kindex, ifnfreqLtemp), kwrapFreqIndexW, ifnfreqL
+
+ if (ichans == 2) then
+ tabw tab:k(kindex, ifnampRtemp), kwrapAmpIndexW, ifnampR
+ tabw tab:k(kindex, ifnfreqRtemp), kwrapFreqIndexW, ifnfreqR
+ endif
+ kindex += 1
+ od
+ endif
+endop
+
+/*
+ Set random bin amplitudes to 0. Ported from pvtool
+ tpv_bubble kready, itpvdata, kchance, kstereounique
+
+ kready done trigger from tpv_anal
+ itpvdata tpv analysis stream handles
+ kchance chance of applying bin amplitude, between 0 and 1
+ kstereounique whether to apply the effect channel independently
+*/
+opcode tpv_bubble, 0, kikP
+ kready, itpvdata, kchance, kstereounique xin
+ ichans, isize, ifnampL, ifnampR, ifnfreqL, ifnfreqR tpv_get itpvdata
+ kreplacement init 0
+ if (kready == 1) then
+ kindex = 0
+ while (kindex < isize) do
+ kapplyL = (random:k(0, 1) <= kchance) ? 1 : 0
+ if (ichans == 1) then
+ if (kapplyL == 1) then
+ tabw 0, kindex, ifnampL
+ endif
+ else
+ if (kstereounique == 0) then
+ if (kapplyL == 1) then
+ tabw kreplacement, kindex, ifnampL
+ tabw kreplacement, kindex, ifnampR
+ endif
+ else
+ if (kapplyL == 1) then
+ tabw kreplacement, kindex, ifnampL
+ endif
+ if (random:k(0, 1) <= kchance) then
+ tabw kreplacement, kindex, ifnampR
+ endif
+ endif
+ endif
+ kindex += 1
+ od
+ endif
+
+endop
+
+/*
+ Swap spectrum areas
+ tpv_swap kready, itpvdata, kampStart, kampLength, kampTarget, kfreqStart, kfreqLength, kfreqTarget [, kwrapmode = 1]
+
+ kready done trigger from tpv_anal
+ itpvdata tpv analysis stream handles
+ kampStart bin start for amplitude
+ kampLength bins length for amplitude
+ kampTarget bin target start for amplitude
+ kfreqStart bin start for frequency
+ kfreqLength bins length for frequency
+ kfreqTarget bin target start for frequency
+ kwrapmode wrap mode: 0 = limit; 1 = wrap
+*/
+opcode tpv_swap, 0, kikOkkOkP
+ kready, itpvdata, kampStart, kampLength, kampTarget, kfreqStart, kfreqLength, kfreqTarget, kwrapmode xin
+ ichans, isize, ifnampL, ifnampR, ifnfreqL, ifnfreqR tpv_get itpvdata
+ itpvdatatemp tpv_makecontainer ichans, isize
+ i_, i_, ifnampLtemp, ifnampRtemp, ifnfreqLtemp, ifnfreqRtemp tpv_get itpvdatatemp
+
+ kampLength = (kampLength == 0) ? isize : kampLength
+ kfreqLength = (kfreqLength == 0) ? isize : kfreqLength
+
+ if (kready == 1) then
+ tablecopy ifnampLtemp, ifnampL
+ tablecopy ifnfreqLtemp, ifnfreqL
+ if (ichans == 2) then
+ tablecopy ifnampRtemp, ifnampR
+ tablecopy ifnfreqRtemp, ifnfreqR
+ endif
+
+ kampStartW = min:k(kampStart, kampTarget)
+ kampTargetW = max:k(kampStart, kampTarget)
+ kfreqStartW = min:k(kfreqStart, kfreqTarget)
+ kfreqTargetW = max:k(kfreqStart, kfreqTarget)
+
+ kindex = 0
+ while (kindex < isize) do
+ if (kwrapmode == 1) then
+ kampStartW = kampStartW % isize
+ kampEndW = (kampStartW + kampLength) % isize
+ kampTargetW = (kampTargetW + kindex) % isize
+
+ kfreqStartW = kfreqStartW % isize
+ kfreqEndW = (kfreqStartW + kfreqLength) % isize
+ kfreqTargetW = (kfreqTargetW + kindex) % isize
+ else
+ kampStartW = (kampStartW >= isize) ? isize - 1 : kampStart
+ kampEnd = kampStartW + kampLength
+ kampEndW = (kampEnd >= isize) ? isize - 1 : kampEnd
+ kampTargetW = (kampTargetW + kindex >= isize) ? isize - 1 : kampTargetW + kindex
+
+ kfreqStartW = (kfreqStartW >= isize) ? isize - 1 : kfreqStart
+ kfreqEnd = kfreqStartW + kfreqLength
+ kfreqEndW = (kfreqEnd >= isize) ? isize - 1 : kfreqEnd
+ kfreqTargetW = (kfreqTargetW + kindex >= isize) ? isize - 1 : kfreqTargetW + kindex
+ endif
+
+ if (kindex >= kampStartW && kindex < kampEndW) then
+ tabw tab:k(kindex, ifnampLtemp), kampTargetW, ifnampL
+ tabw tab:k(kampTargetW, ifnampLtemp), kindex, ifnampL
+ if (ichans == 2) then
+ tabw tab:k(kindex, ifnampRtemp), kampTargetW, ifnampR
+ tabw tab:k(kampTargetW, ifnampRtemp), kindex, ifnampR
+ endif
+ endif
+
+ if (kindex >= kfreqStartW && kindex < kfreqEndW) then
+ tabw tab:k(kindex, ifnfreqLtemp), kfreqTargetW, ifnfreqL
+ tabw tab:k(kfreqTargetW, ifnfreqLtemp), kindex, ifnfreqL
+ if (ichans == 2) then
+ tabw tab:k(kindex, ifnfreqRtemp), kfreqTargetW, ifnfreqR
+ tabw tab:k(kfreqTargetW, ifnfreqRtemp), kindex, ifnfreqR
+ endif
+ endif
+ kindex += 1
+ od
+ endif
+endop
+
+/*
+ Invert spectrum
+ tpv_invert kready, itpvdata, [kinvertamp, kinvertfreq]
+
+ kready done trigger from tpv_anal
+ itpvdata tpv analysis stream handles
+ kinvertamp whether to invert amp or not (1 or 0)
+ kinvertfreq whether to invert frequency or not (1 or 0)
+*/
+opcode tpv_invert, 0, kiPP
+ kready, itpvdata, kinvertamp, kinvertfreq xin
+ ichans, isize, ifnampL, ifnampR, ifnfreqL, ifnfreqR tpv_get itpvdata
+ if (kready == 1) then
+ kindex = 0
+ while (kindex < isize) do
+ if (kinvertamp == 1) then
+ tabw tab:k(isize-kindex, ifnampL), kindex, ifnampL
+ endif
+
+ if (kinvertfreq == 1) then
+ tabw tab:k(isize-kindex, ifnfreqL), kindex, ifnfreqL
+ endif
+
+ if (ichans == 2) then
+ if (kinvertamp == 1) then
+ tabw tab:k(isize-kindex, ifnampR), kindex, ifnampR
+ endif
+
+ if (kinvertfreq == 1) then
+ tabw tab:k(isize-kindex, ifnfreqR), kindex, ifnfreqR
+ endif
+ endif
+
+ kindex += 1
+ od
+ endif
+endop
+
+/*
+ Filter bins with a ftable mask
+ tpv_binfilter kready, itpvdata, ifnamps
+
+ kready done trigger from tpv_anal
+ itpvdata tpv analysis stream handles
+ ifnamps ftable containing amplitude values per bin
+*/
+opcode tpv_binfilter, 0, kii
+ kready, itpvdata, ifnamps xin
+ ichans, isize, ifnampL, ifnampR, ifnfreqL, ifnfreqR tpv_get itpvdata
+ if (kready == 1) then
+ kindex = 0
+ while (kindex < isize) do
+ tabw tab:k(kindex, ifnampL) * tab:k(kindex, ifnamps), kindex, ifnampL
+
+ if (ichans == 2) then
+ tabw tab:k(kindex, ifnampR) * tab:k(kindex, ifnamps), kindex, ifnampR
+ endif
+ kindex += 1
+ od
+ endif
+endop
+
+/*
+ Allow bins over or below a certain threshold; a spectral gate
+ tpv_threshold kready, itpvdata, kthreshold, kabove
+
+ kready done trigger from tpv_anal
+ itpvdata tpv analysis stream handles
+ kthreshold amplitude threshold to apply
+ kabove above or below threshold will be let through the gate (1 = above, 0 = below)
+*/
+opcode tpv_threshold, 0, kikO
+ kready, itpvdata, kthresh, kabove xin
+ ichans, isize, ifnampL, ifnampR, ifnfreqL, ifnfreqR tpv_get itpvdata
+ if (kready == 1) then
+ kindex = 0
+ while (kindex < isize) do
+
+ kvalL tab kindex, ifnampL
+ if ((kabove == 0 && kvalL < kthresh) || (kabove == 1 && kvalL > kthresh)) then
+ tabw 0, kindex, ifnampL
+ tabw 0, kindex, ifnfreqL
+ endif
+
+ if (ichans == 2) then
+ kvalR tab kindex, ifnampR
+ if ((kabove == 0 && kvalR < kthresh) || (kabove == 1 && kvalR > kthresh)) then
+ tabw 0, kindex, ifnampR
+ tabw 0, kindex, ifnfreqR
+ endif
+ endif
+
+ kindex += 1
+ od
+ endif
+endop
+
+/*
+ Scramble amplitude and/or frequency
+ tpv_scramble kready, itpvdata, kstepratio, kdoamp, kdofreq
+
+ kready done trigger from tpv_anal
+ itpvdata tpv analysis stream handles
+ kstepratio partitioning ratio
+ kdoamp scramble amplitudes (bool)
+ kdofreq scramble frequencies (bool)
+*/
+opcode tpv_scramble, 0, kiJPP
+ kready, itpvdata, kstepratio, kdoamp, kdofreq xin
+ ichans, isize, ifnampL, ifnampR, ifnfreqL, ifnfreqR tpv_get itpvdata
+ kstep = (kstepratio == -1) ? 1 : max:k(round:k(kstepratio * isize), 1)
+ if (kready == 1) then
+ kindex = 0
+ while (kindex < isize) do
+ kdest = int:k(random:k(kstep, isize)) - kstep
+ kindex2 = 0
+ while (kindex2 < kstep) do
+
+ if (kdoamp == 1) then
+ kval table kindex+kindex2, ifnampL, 0, 0, 1
+ kcurrentval table kdest+kindex2, ifnampL, 0, 0, 1
+ tablew (kval+kcurrentval)/2, kdest+kindex2, ifnampL, 0, 0, 1
+ if (ichans == 2) then
+ kval table kindex+kindex2, ifnampR, 0, 0, 1
+ kcurrentval table kdest+kindex2, ifnampR, 0, 0, 1
+ tablew (kval+kcurrentval)/2, kdest+kindex2, ifnampR, 0, 0, 1
+ endif
+ endif
+
+ if (kdofreq == 1) then
+ kval table kindex+kindex2, ifnfreqL, 0, 0, 1
+ kcurrentval table kdest+kindex2, ifnfreqL, 0, 0, 1
+ tablew (kval+kcurrentval)/2, kdest+kindex2, ifnfreqL, 0, 0, 1
+ if (ichans == 2) then
+ kval table kindex+kindex2, ifnfreqR, 0, 0, 1
+ kcurrentval table kdest+kindex2, ifnfreqR, 0, 0, 1
+ tablew (kval+kcurrentval)/2, kdest+kindex2, ifnfreqR, 0, 0, 1
+ endif
+ endif
+ kindex2 += 1
+ od
+ kindex += kstep
+ od
+ endif
+endop
+
+
+
+
+opcode tpv_freeze1, 0, kikPPP
+ kready, itpvdata, kfreeze, kfreezeamp, kfreezefreq, kcrossfade xin
+ ichans, isize, ifnampL, ifnampR, ifnfreqL, ifnfreqR tpv_get itpvdata
+ itpvtemp tpv_makecontainer ichans, isize
+ i_, i_, ifnampLtemp, ifnampRtemp, ifnfreqLtemp, ifnfreqRtemp tpv_get itpvtemp
+
+ if (kready == 1) then
+ kindex = 0
+ while (kindex < isize) do
+ if (kfreeze >= 0) then
+ kamount min kfreeze-1, 1
+
+ if (kfreezeamp == 1) then
+ if (kcrossfade == 1) then
+ tabw ((1-kamount)*tab:k(kindex, ifnampL) + (kamount * tab:k(kindex, ifnampLtemp))), kindex, ifnampL
+ if (ichans == 2) then
+ tabw ((1-kamount)*tab:k(kindex, ifnampR) + (kamount * tab:k(kindex, ifnampRtemp))), kindex, ifnampR
+ endif
+ else
+ tabw tab:k(kindex, ifnampLtemp), kindex, ifnampL
+ if (ichans == 2) then
+ tabw tab:k(kindex, ifnampRtemp), kindex, ifnampR
+ endif
+ endif
+ endif
+
+ if (kfreezefreq == 1) then
+ if (kcrossfade == 1) then
+ tabw ((1-kamount)*tab:k(kindex, ifnfreqL) + (kamount * tab:k(kindex, ifnfreqLtemp))), kindex, ifnfreqL
+ if (ichans == 2) then
+ tabw ((1-kamount)*tab:k(kindex, ifnfreqR) + (kamount * tab:k(kindex, ifnfreqRtemp))), kindex, ifnfreqR
+ endif
+ else
+ tabw tab:k(kindex, ifnfreqLtemp), kindex, ifnfreqL
+ if (ichans == 2) then
+ tabw tab:k(kindex, ifnfreqRtemp), kindex, ifnfreqR
+ endif
+ endif
+ endif
+
+ else
+ tabw tab:k(kindex, ifnampL), kindex, ifnampLtemp
+ tabw tab:k(kindex, ifnfreqL), kindex, ifnfreqLtemp
+
+ if (ichans == 2) then
+ tabw tab:k(kindex, ifnampR), kindex, ifnampRtemp
+ tabw tab:k(kindex, ifnfreqR), kindex, ifnfreqRtemp
+ endif
+ endif
+ kindex += 1
+ od
+ endif
+endop
+
+
+
+opcode tpv_average, 0, kikPPO
+ kready, itpvdata, kmax, kavgamp, kavgfreq, ktrig xin
+ ichans, isize, ifnampL, ifnampR, ifnfreqL, ifnfreqR tpv_get itpvdata
+ itpvtemp tpv_makecontainer ichans, isize
+ i_, i_, ifnampLtemp, ifnampRtemp, ifnfreqLtemp, ifnfreqRtemp tpv_get itpvtemp
+
+ kcount init 1
+ if (kready == 1) then
+ kindex = 0
+ while (kindex < isize) do
+
+ ; store to average
+ tabw tab:k(kindex, ifnampL), kindex, ifnampLtemp
+ tabw tab:k(kindex, ifnfreqL), kindex, ifnfreqLtemp
+
+ ; read average
+ if (kavgamp == 1) then
+ tabw tab:k(kindex, ifnampLtemp) / kcount, kindex, ifnampL
+ endif
+
+ if (kavgfreq == 1) then
+ tabw tab:k(kindex, ifnfreqLtemp) / kcount, kindex, ifnfreqL
+ endif
+
+ if (ichans == 2) then
+
+ ; store to average
+ tabw tab:k(kindex, ifnampR), kindex, ifnampRtemp
+ tabw tab:k(kindex, ifnfreqR), kindex, ifnfreqRtemp
+
+ ; read average
+ if (kavgamp == 1) then
+ tabw tab:k(kindex, ifnampRtemp) / kcount, kindex, ifnampR
+ endif
+
+ if (kavgfreq == 1) then
+ tabw tab:k(kindex, ifnfreqRtemp) / kcount, kindex, ifnfreqR
+ endif
+ endif
+
+ kindex += 1
+ od
+
+ if (kcount >= kmax || ktrig == 1) then
+ kindex = 0
+ while (kindex < isize) do
+
+ ; empty
+ tabw 0, kindex, ifnampLtemp
+ tabw 0, kindex, ifnfreqLtemp
+
+ if (ichans == 2) then
+ tabw 0, kindex, ifnampRtemp
+ tabw 0, kindex, ifnfreqRtemp
+ endif
+
+ kindex += 1
+ od
+ kcount = 1
+ else
+ kcount += 1
+ endif
+ endif
+endop
+
+#end
|