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
|