[New MSP Extern:] rez~ - sample-accurate looper - need beta-testing

Hi, i got this minimal design for a looper-external in Max, thinking it might find wide-spread use if i can tighten it up for general public… so if you use Max/MSP and feel like beta-testing, i’d love your input:


(it’s main benefits are that it’s sample-accurate and takes care of de-clicking for you… but also has a ‘oneshot’ mode(triggered sample-accurately too), and hopefully will be pretty simple to use… i’m not sure if i created the best helpfile to show the simplicity, though :sweat_smile:)

Hope it proves ya great fun :love_you_gesture:

15 Likes

@rajaTheResidentAlien you might have an interesting time looking at softcut-lib (also a sample accurate looper) if you haven’t before - the new version (in the dev branch i think) has a facy feature to duck between multiple playheads crossing over each other to prevent that click bug you described

1 Like

thank you, ya, i heard so much about softcut over the years, even looked at the code before, but i still need to learn C++ better to know my way around - it does look like softcut uses something similar: computes difference between the heads and then uses that difference to drive windowing, which is what my code does(but mine uses a regular cosine-based window, whereas softcut i think uses a ‘raised-cosine’ window(?)), but i’ll keep looking to see what the exact windowing and methods are(i realize this isn’t something the Lines community would be into since softcut already exists, but just looking for help beta-testing my own design here).

dude it’s all good

i think plenty of us wanna check this out

2 Likes

actually the fade shapes used are identical; both use what i would call “raised cosine” for crossfade windows. (“raised” just meaning that it’s scaled to [0, 1] rather than [-1, 1].)

they are just written differently.
[https://github.com/monome/softcut-lib/blob/dev/softcut-lib/include/softcut/Fades.h]
[https://github.com/RajaRez/rez/blob/main/rez~.c#L96-L101]

elsewhere in softcut we do use equal-power curves rather than equal-gain curves like these. (e.g. for panning.)

selection of appropriate xfade curve for perceptual linearity is a kinda tricky question. it really requires knowing whether the summed signals are correlated or not. if they are totally correlated, equal-gain is correct; if totally uncorrelated, then equal-power is probably better. the general assumption in e.g. pan laws is that musical signals are uncorrelated. but often we are actually dealing with bits of the same periodic signal that are well correlated, and i found that an EP curve tended to have unpleasant volume bumps. i’d rather have a dip when working with noisy signals than a bump with tonal signals, but it would probably be nice to make these more dynamically adjustable.

anyways, we can always use more loop externals, right? thanks for sharing raj.

one thing that softcut cannot offer in its current state is sample-accurate one-shot triggering. position changes are executed at the top of an audio buffer, unless they are initiated internally by the phase crossing a loop point. of course in a MSP external it makes sense to accept audio-rate triggers.

i actually haven’t got the ducking behavior working to my full satisfaction yet, and this has been one of the main hangups to releasing the latest version on norns. its a simple heuristic (attenuate by a function of proximity of the two heads) and it works most of the time but isn’t totally smooth on some edge cases when one or both heads are close to a loop point. (it’s past time to give up on this and hope to fix that case in the future.) i do find that this “ducking by proximity” is nicer on my ears than the classic switch-and-ramp. a final point is that it’s not computationally feasible to do something like this (at least on norns) without buffering a lot of state. (head positions etc.)

3 Likes

ah, interesting, ya i was working off that pan-law-based assumption(plus, when i test, i never use perfectly correlated signals… assuming i might hear it more the way people will use it, didn’t realize that about ‘bits of the same periodic signal’, now that you mention it, it does actually make sense with sampling of tonal material, in particular)… and i agree: i’d even say there’s a ‘feel’(performance-wise) of more ease to “have a dip when working with noisy signals than a bump with tonal signals”

i also tried this:

interpExponentialEaseInOut(value) {
	result = value;
	if (value>  0 &&  value<  0.5) {
		result = 0.5 * pow(2, (20 * value) - 10);
	} else if (value<  1 &&  value>  0.5) {
		result = -0.5 * pow(2, (-20 * value) + 10) + 1;
	}
	return result;
} 

and this:

interpQuinticEaseInOut(value)
{
result = value;

if (value < 0.5) {
result = 16 * value * value * value * value * value;
} else {
tempValue = ((2 * value) - 2);
result = 0.5 * tempValue * tempValue * tempValue * tempValue * tempValue + 1;
}

return result;
}

and they both were more ‘bumpy’ than the simpler cosine(which is what i didn’t like about switch&ramp, too - i think no matter how smooth, too abrupt a change might be too abrupt a change… but of course, always on the lookout for anything more ideal).
[Edit: and also with this:

i’m running into that prob, too, plus i realize now i need to add checks for sample-accurately triggering one head to cut too close to the other for a complete/smooth duck to occur :sweat_smile: ]

anyways, thanks for sharing your thoughts, @zebra …helps me keep looking/thinking on this :+1: