aboutsummaryrefslogtreecommitdiff
path: root/site/udo/bsamp.udo
blob: a31cede40b7f0b5b1873dd6957fb974939de1d0a (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
198
199
200
201
202
203
204
205
206
#ifndef UDO_BSAMP
#define UDO_BSAMP ##
/*
	Live buffer sampling and glitch out playback

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


#include "bussing.udo"
#include "tab2wav.udo"

#ifndef BSAMP_BUFFERNUM
#define BSAMP_BUFFERNUM #8#
#end

#ifndef BSAMP_CHANNELS
#define BSAMP_CHANNELS #1#
#end

#ifndef BSAMP_BUFFERLENGTH
#define BSAMP_BUFFERLENGTH #8#
#end

#ifndef BSAMP_IOPROCRATE
#define BSAMP_IOPROCRATE #10#
#end

#ifndef BSAMP_IOBLOCKSIZE
#define BSAMP_IOBLOCKSIZE #2048#
#end


gibsamp_buffernum = $BSAMP_BUFFERNUM
gibsamp_channels = $BSAMP_CHANNELS
gibsamp_buffers[][] init gibsamp_buffernum, gibsamp_channels
gibsamp_bufferused[] init gibsamp_buffernum


isize = sr * $BSAMP_BUFFERLENGTH
index = 0
while (index < gibsamp_buffernum) do
	indexchan = 0
	while (indexchan < gibsamp_channels) do
		gibsamp_buffers[index][indexchan] = ftgen(0, 0, isize, 2, 0)
		gibsamp_bufferused[index] = isize
		indexchan += 1
	od
	index += 1
od

instr _bsamp_setbufferusedsize
	ibufferindex = p4
	ilens = p5
	gibsamp_bufferused[ibufferindex] = round(ilens * sr)
	turnoff
endin


opcode bsamp_save, k, iSjj
	ibufferindex, Spath, iprocrate, iblocksize xin

	if (gibsamp_channels == 2) then
		SpathL = sprintf("%s.L", Spath)
		SpathR = sprintf("%s.R", Spath)
	else
		SpathL = Spath
		SpathR = Spath
	endif

	kdoneL tab2wav gibsamp_buffers[ibufferindex][0], SpathL, gibsamp_bufferused[ibufferindex], $BSAMP_IOPROCRATE, $BSAMP_IOBLOCKSIZE
	if (gibsamp_channels == 2) then
		kdoneR tab2wav gibsamp_buffers[ibufferindex][1], SpathR, gibsamp_bufferused[ibufferindex], $BSAMP_IOPROCRATE, $BSAMP_IOBLOCKSIZE
	else
		kdoneR init 1
	endif

	xout (kdoneL & kdoneR)
endop


opcode bsamp_load, k, iSjj
	ibufferindex, Spath, iprocrate, iblocksize xin
	SpathR = sprintf("%s.R", Spath)
	if (filevalid(SpathR) == 1) then
		SpathL = sprintf("%s.L", Spath)
	else
		SpathL = Spath
		SpathR = Spath
	endif

	gibsamp_bufferused[ibufferindex] = min(round(filelen(SpathL) * sr), ftlen(gibsamp_buffers[ibufferindex][0]))

	kdoneL wav2tab SpathL, gibsamp_buffers[ibufferindex][0], 0, $BSAMP_IOPROCRATE, $BSAMP_IOBLOCKSIZE
	if (gibsamp_channels == 2) then
		kdoneR wav2tab SpathR, gibsamp_buffers[ibufferindex][1], 1, $BSAMP_IOPROCRATE, $BSAMP_IOBLOCKSIZE
	else
		kdoneR init 1
	endif

	xout (kdoneL & kdoneR)
endop


instr bsamp_record
	ibufferindex = p4
	Sbus = strget(p5)

	
	ifnL = gibsamp_buffers[ibufferindex][0]
	if (gibsamp_channels == 2) then
		ifnR = gibsamp_buffers[ibufferindex][1]
	else
		ifnR = -1
	endif

	ilen = ftlen(ifnL)
	apos lphasor 1

	aL, aR bus_tap Sbus

	tablew aL, apos, ifnL, 0, 0, 1
	if (gibsamp_channels == 2) then
		tablew aR, apos, ifnR, 0, 0, 1
	endif

	ktimes timeinsts

	kreleasing init 0 
	if (release:k() == 1 && kreleasing == 0) then
		kreleasing = 1
		if (ktimes > $BSAMP_BUFFERLENGTH) then
			ktimes = ktimes % $BSAMP_BUFFERLENGTH
			if (ktimes == 0) then
				ktimes = $BSAMP_BUFFERLENGTH
			endif
		endif
		schedulek("_bsamp_setbufferusedsize", 0, 1, ibufferindex, ktimes)
	endif
endin


opcode bsamp_clear, 0, i
	ibufferindex xin
	gibsamp_bufferused[ibufferindex] = 0
	ftset gibsamp_buffers[ibufferindex][0], 0
	if (gibsamp_channels == 2) then
		ftset gibsamp_buffers[ibufferindex][1], 0
	endif
endop


opcode bsamp_play, aa, ikkOo
	ibufferindex, kreadstart, ktriglen, kreverse, iratiotimes xin

	ifnL = gibsamp_buffers[ibufferindex][0]
	if (gibsamp_channels == 2) then
		ifnR = gibsamp_buffers[ibufferindex][1]
	else
		ifnR = -1
	endif

	ilen = gibsamp_bufferused[ibufferindex] ; ftlen(ifn)
	ilens = ilen / sr


	areadstart = upsamp(kreadstart)
	if (iratiotimes == 0) then
		areadstart = areadstart / ilens
	else
		ktriglen *= ilens
	endif

	klenchanger metro 1 / ktriglen	
	async upsamp klenchanger

	irate = (1 / ((ilen) / sr))
	apos, a_ syncphasor irate, async
	
	;aamp triglinseg klenchanger, 0, 0.001, 1, 3600, 1
		;kamp loopseg 0.01, klenchanger, 0, 0, 0.01, 1, 3600, 1
		;aamp = upsamp(kamp)
	aamp init 1
	
	apos += areadstart
	apos *= ilen

	if (kreverse == 1) then
		apos = ilen - apos
	endif

	aL tablei apos, ifnL, 0, 0, 1
	aL *= aamp
	if (gibsamp_channels == 2) then
		aR tablei apos, ifnR, 0, 0, 1
		aR *= aamp
	else
		aR = aL
	endif

	xout aL, aR
endop

#end