|
|
(
|
|
|
name: 'grain_scatter',
|
|
|
func: {
|
|
|
| buf |
|
|
|
var bufnum, rawSig, sig;
|
|
|
// Кольцевой буфер (явно создаётся в скетче): RecordBuf пишет в
|
|
|
// живой вход, WarpZ читает с растяжением и рандомизацией позиции.
|
|
|
// Возвращает развёрнутый во времени сигнал, "разбросанный" по буферу.
|
|
|
|
|
|
bufnum = \bufnum.kr(0);
|
|
|
|
|
|
// Захват входа в кольцевой буфер. RecordBuf.ar() пишет в буфер
|
|
|
// как побочный эффект; результат не используется.
|
|
|
RecordBuf.ar(
|
|
|
buf,
|
|
|
bufnum,
|
|
|
doneAction: 0
|
|
|
);
|
|
|
|
|
|
// WarpZ: чтение с растяжением и рандомизацией позиции
|
|
|
rawSig = WarpZ.ar(
|
|
|
numChannels: 2,
|
|
|
bufnum: bufnum,
|
|
|
freq: \warpFreq.kr(40),
|
|
|
windowSize: \warpWindowSize.kr(0.15),
|
|
|
position: \positionJitter.kr(0.3),
|
|
|
posBase: \posBase.kr(0),
|
|
|
overlaps: \overlaps.kr(4),
|
|
|
windowRandRatio: \windowRandRatio.kr(0.2),
|
|
|
freqMul: \freqMul.kr(1),
|
|
|
interp: 2
|
|
|
);
|
|
|
|
|
|
// Duck на громкие моменты — общий паттерн для защиты от клиппинга
|
|
|
sig = rawSig * (1 - \duckOnLoud.kr(0).clip(0, 1) *
|
|
|
(Amplitude.kr(rawSig) > \duckThreshold.kr(0.95)).lag(0.05));
|
|
|
|
|
|
sig;
|
|
|
},
|
|
|
inChannels: 2,
|
|
|
outChannels: 2,
|
|
|
requiresBuffer: true,
|
|
|
specs: (
|
|
|
warpFreq: [1, 200, \exp, 1, 40],
|
|
|
warpWindowSize: [0.01, 0.5, \lin, 0.01, 0.15],
|
|
|
positionJitter: [0, 1, \lin, 0.01, 0.3],
|
|
|
posBase: [0, 1, \lin, 0.01, 0.5],
|
|
|
overlaps: [1, 16, \lin, 1, 4],
|
|
|
windowRandRatio: [0, 1, \lin, 0.01, 0.2],
|
|
|
freqMul: [0.25, 4, \exp, 0.01, 1],
|
|
|
duckOnLoud: [0, 1, \lin, 0.01, 0.5],
|
|
|
duckThreshold: [0, 1, \lin, 0.01, 0.95]
|
|
|
),
|
|
|
)
|