aboutsummaryrefslogtreecommitdiff
path: root/site/udo/pvs_fulltabproc.udo
blob: ccd862785a64894c7a105a1ab1a2d9b45a79fc2a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#ifndef UDO_PVSFPROC
#define UDO_PVSFPROC ##
/*
	Full table based PVS processing, for reading a complete file to a series of frames in tables

	ksmps must be 64 or lower: setksmps(64) can be set in the calling instrument if required

	This file is part of the SONICS UDO collection by Richard Knight 2024
		License: GPL-2.0-or-later
		http://1bpm.net
*/


opcode tpvf_destroy, 0, i
	itpvHandle xin
	ifnamp tab_i 2, itpvHandle
	ifnfreq tab_i 3, itpvHandle
	if (ifnamp > 0) then
		ftfree ifnamp, 0
	endif
	if (ifnfreq > 0) then
		ftfree ifnfreq, 0
	endif
	ftfree itpvHandle, 0
endop

opcode tpvf_clone, i, i
	itpvHandle xin
	ifnamp tab_i 2, itpvHandle
	ifnfreq tab_i 3, itpvHandle
	ilen = ftlen(ifnamp)
	ifnampNew ftgen 0, 0, -ilen, -2, 0
	ifnfreqNew ftgen 0, 0, -ilen, -2, 0
	itpvHandleNew ftgen 0, 0, -5, -2, tab_i(0, itpvHandle), tab_i(1, itpvHandle), ifnampNew, ifnfreqNew, tab_i(4, itpvHandle)	
	tableicopy ifnampNew, ifnamp
	tableicopy itpvHandleNew, ifnfreq
	xout itpvHandleNew
endop

opcode tpvf_tablen, i, iii
	ifnaudiolen, ifftsize, ifftdecimation xin
	xout round(ifnaudiolen / (ifftsize / ifftdecimation)) * (ifftsize / 2)
endop

opcode tpvf_framecount, i, i
	itpvHandle xin
	ifftsize tab_i 0, itpvHandle
	ifnamp tab_i 2, itpvHandle
	xout ftlen(ifnamp) / (ifftsize / 2)
endop

opcode tpvf_analyse, ki, ijj
	ifn, ifftsize, ifftdecimation xin
	istatus = 1
	itpvHandle = -1
	ifftsize = (ifftsize == -1) ? 512: ifftsize
	ifftdecimation = (ifftdecimation == -1) ? 8: ifftdecimation
	ifnlen = ftlen(ifn)
	ifnsr = ftsr(ifn)
	
	ifoutlen = tpvf_tablen(ifnlen, ifftsize, ifftdecimation)

	itpvHandle ftgen 0, 0, -5, -2, ifftsize, ifftdecimation, -1, -1, -1
	ifnampTemp ftgentmp 0, 0, -(ifftsize / 2), -2, 0
	ifnfreqTemp ftgentmp 0, 0, -(ifftsize / 2), -2, 0

	ifnamp ftgen 0, 0, -ifoutlen, -2, 0
	ifnfreq ftgen 0, 0, -ifoutlen, -2, 0
	tabw_i ifnamp, 2, itpvHandle
	tabw_i ifnfreq, 3, itpvHandle
	tabw_i (ifnlen / ifnsr), 4, itpvHandle

	ikcycles = ifnlen / ksmps
	kcycle init 0
	ktimek timeinstk
	if (ktimek == 1) then
		kwriteindex = 0
		while (kcycle < ikcycles) do
			apos lphasor 1
			asig table3 apos, ifn
			fsig pvsanal asig, ifftsize, ifftsize / ifftdecimation, ifftsize, 1
			kready pvsftw fsig, ifnampTemp, ifnfreqTemp
			if (kready == 1) then
				kreadindex = 0
				while (kreadindex < ftlen(ifnampTemp)) do
					tablew tab:k(kreadindex, ifnampTemp), kwriteindex, ifnamp ; overshoots write
					tablew tab:k(kreadindex, ifnfreqTemp), kwriteindex, ifnfreq ; overshoots write
					kwriteindex += 1
					kreadindex += 1
				od
			endif
			kcycle += 1
		od
	else
		kdone = 1
	endif
	xout kdone, itpvHandle
endop

opcode tpvf_resynth, aak, ijojo
	itpvHandle, ifnBinSelection, iuseadsyn, isplitselection, istartframe xin
	ifftsize tab_i 0, itpvHandle
	ifftdecimation tab_i 1, itpvHandle
	ifnamp tab_i 2, itpvHandle
	ifnfreq tab_i 3, itpvHandle
	
	if (ifnBinSelection > 0 && isplitselection == 1) then
		ibslen = ftlen(ifnBinSelection)
		ifnBinSelectionInverse ftgentmp 0, 0, -(ibslen), -2, 0
		index = 0
		while (index < ibslen) do
			tabw_i -(tab_i(index, ifnBinSelection)), index, ifnBinSelectionInverse
			index += 1
		od
	endif

	ifnampTemp ftgentmp 0, 0, -(ifftsize / 2), -2, 0
	ifnfreqTemp ftgentmp 0, 0, -(ifftsize / 2), -2, 0

	anull init 0
	aoutinverse = anull
	fsig pvsanal anull, ifftsize, ifftsize / ifftdecimation, ifftsize, 1
	kready pvsftw fsig, ifnampTemp, ifnfreqTemp
	kwriteindex = 0
	kreadindex init istartframe * (ifftsize / 2)
	if (kreadindex >= ftlen(ifnamp)) then
		kdone = 1
		aout = anull
	else
		kdone = 0
		if (kready == 1) then
			while (kwriteindex < (ifftsize / 2)) do
				tabw tab:k(kreadindex, ifnamp), kwriteindex, ifnampTemp
				tabw tab:k(kreadindex, ifnfreq), kwriteindex, ifnfreqTemp
				kreadindex += 1
				kwriteindex += 1
			od
		endif
		pvsftr fsig, ifnampTemp, ifnfreqTemp
		if (ifnBinSelection > 0) then
			fproc pvsmaska fsig, ifnBinSelection, 1
			if (iuseadsyn == 1) then
				aout pvsadsyn fproc, ifftsize / 2, 1
			else
				aout pvsynth fproc
			endif
			if (isplitselection == 1) then
				fprocinverse pvsmaska fsig, ifnBinSelectionInverse, 1
				if (iuseadsyn == 1) then
					aoutinverse pvsadsyn fprocinverse, ifftsize / 2, 1
				else
					aoutinverse pvsynth fprocinverse
				endif
			endif
		else
			if (iuseadsyn == 1) then
				aout pvsadsyn fsig, ifftsize / 2, 1
			else
				aout pvsynth fsig
			endif
		endif
	endif
	xout aout, aoutinverse, kdone
endop

opcode tpvf_resynth, ak, ijoj
	itpvHandle, ifnBinSelection, iuseadsyn, istartframe xin
	aout, a_, kdone tpvf_resynth itpvHandle, ifnBinSelection, iuseadsyn, istartframe
	xout aout, kdone
endop

opcode tpvf_resynth_offline, ik, io
	itpvHandle, iuseadsyn xin
	ifftsize tab_i 0, itpvHandle
	ifftdecimation tab_i 1, itpvHandle
	ifnamp tab_i 2, itpvHandle
	ifnfreq tab_i 3, itpvHandle
	ifndurations tab_i 4, itpvHandle
	ifnout ftgen 0, 0, -(round(ifndurations * sr)), -2, 0
	ikcycles = floor(ifndurations * kr)
	kdone = 0
	ktimek timeinstk
	if (ktimek == 1) then
		kcycle = 0
		while (kcycle < ikcycles) do
			apos lphasor 1
			asig, k_ tpvf_resynth itpvHandle, -1, iuseadsyn
			tabw asig, apos, ifnout
			kcycle += 1
		od
	else
		kdone = 1
	endif
	xout ifnout, kdone
endop

#end