I’m working on a SynthDef that reads from a buffer using a Phasor-based looping system. The idea is to define a loop start point and a loop length (in milliseconds), and have the Phasor read from that region inside the buffer.
The server crahes when i play around with the loopSize after starting an instance.
I’m new to SuperCollider, but experienced in other programming languages. But i can’t find the problem. Can someone help me debug this?
(
b = Buffer.readChannel(s, "sndfl.wav", channels: 1);
w = Buffer.loadCollection(s, Signal.hanningWindow(4096));
)
(
SynthDef(\sndflLooper, {
arg buf, wbuf, speed = 1, loopSize = 100, loopStart = 0, bus = 0;
// calculate loop size
var bufSR = BufSampleRate.kr(buf);
var bufFrames = BufFrames.kr(buf);
//bufSizeInSecs = BufDur.kr(buf);
var loopSizeInSecs = loopSize / 1000;
var loopSizeInSamps = max(loopSizeInSecs * bufSR);
// calculate phasor increment
var phsIncr = (1 / loopSizeInSamps) * speed;
// main phasor
var phasor = Phasor.ar(0, phsIncr, 0, 1);
var delta = HPZ1.ar(phasor);
var startTrig = Impulse.ar(0);
var trig = (startTrig + (delta < 0)) > 0;
var pulseTrig = Trig1.ar(trig, SampleDur.ir);
// set loop start and end points
var startNew = loopStart * bufFrames;
var start = Latch.ar(startNew, pulseTrig);
var loopEndNew = loopStart + loopSizeInSamps;
var loopEnd = Latch.ar(loopEndNew, pulseTrig);
// read sndfl buf
var sndflBufSig = BufRd.ar(1, buf, start + (phasor * (loopEnd - start)), loop: 1, interpolation: 4);
// read wndw buf
var sizeWndwBuf = BufFrames.kr(wbuf);
var wndwBufSig = BufRd.ar(1, wbuf, phasor * sizeWndwBuf);
var snd = sndflBufSig * wndwBufSig;
Out.ar(bus, snd!2)
}).add;
)
~looper = Synth(\sndflLooper, [\buf, b, \wbuf, w, \loopSize, 100]);
~looper.set(\loopSize, 50);
Ah I see, I just tried you example now and it does work for me without crashing. I am not quite sure what you are wanting to do here, if I set the loopSize to the entire buffer (b.bufFrames), should it then play the whole sample (I used a different sample, but that should not matter)? In this case I don’t hear sound at all, I haven’t really checked the code yet, first I wanted to hear what you are trying to obtain.
loopSize expects a value in millieseconds. so, if you want to play the whole buffer you need to use b.duration * 1000. But then there is also the windowing function which is read once per phasor cycle, and with loop sizes this big you will have a lot of low sample values with a hanning window. this could explain the silence. The instrument is designed for smaller loops like under a second.
Could you play with different values for the loop size, under 2000ms and see if it’s crashing?
Yes now I could get it to break. I don’t have time to check the math right now but in these cases using buffers, crashes are almost always due to indexing outside the buffer, so maybe check your math or put in some safeguards. When I did this safeguard I could not get it to break:
However, some combos of setting the loopSize results in no sound and no sound no matter how I change the loopsize afterwards which probably has to do with your latching mechanism.
You can probably also just sample and hold the entire phase or the Bufrd, without having to convert to Audio rate and get rid of one of the Latch Ugens.