Transient sample slicing using gen~ and groove~

Uasmi Nasser's icon

Hi everyone,

I'm trying to slice a sample based on transient detection. I currently have a gen~ patch (attached) that detects transients and their position in samples (using accum).
What I'm struggling to do right now is to tie it to a groove~ position (from 0. to 1.) I've tried using delta~, but I get a lot of noise when I try to move it from MSP to Max world.

So, ideally, I would like to store indexes (slice numbers) inside coll, where each row will contain slice number and position in range of 0. to 1. (rather than in samples).

For example:
0, 0.2345 (first transient)
1, 0.342 (second transient)
etc.

Max Patch
Copy patch and select New From Clipboard in Max.

Graham Wakefield's icon

To convert a position in samples to a position in 0-1 phase, just divide the sample position by the buffer length.

Your patch might have a mistake. If you wanted to ensure that segments are at least 1000 samples long, to avoid capturing too many transients, then I think the [or] should be [and] and the [< 1000] should be [> 1000].

The [> 0.] after the [or] is unnecessary; the output of logic ops like [or] are always either 0 or 1.

BTW you could do the analysis inside of gen~, without needing groove~, and it would simplify a lot: add a [buffer sample] and use a [counter dim(sample)] into a [peek sample] to feed into your transient detector. If the transient is detected, then the value of the counter *is* the sample index. If you want it as phase just divide by the buffer length, e.g. [/ dim(sample)]. The counter's middle outlet can be used as the reset signal to replace in 2.

Graham Wakefield's icon

Here's an example. It also dumps the results into a buffer~ (rather than a coll).

I don't think the delta to abs to > sensitivity is the best transient detector though -- you might want to look into some alternatives there.

Max Patch
Copy patch and select New From Clipboard in Max.

Uasmi Nasser's icon

Hey Graham, thanks a lot for the example, exactly what I was talking about. Also, outputting to a buffer is a great idea.

Asher's icon

Hey, I've also been working on this problem too – I ported Rodrigo/Pierre Alexandre Tremblay's onset detection algorithm into gen from this thread: https://cycling74.com/forums/rich-onset-detection-%C2%ABaudio-descriptorsfeatures-from-percussion%C2%BB. I then wanted to be able to analyse an entire buffer for onset times OR be able to access onset times as they occur during recording into a circular buffer.

This implementation uses a circular buffer for the array of onset times too, which you can then play back with a simpleish slicer. you could substitute the detection algorithm for another one, I think this works rather well. Only bug I've found so far is that it will always detect the 0 index as a new onset on patch open.

I have forgotten all most of my jitter knowledge, so If anyone knows how to make the jit.buffer/display part look a bit better please show me how!

live_onset_detection_slicer_gen.zip
application/zip 8.69 KB

Hannes d'Hoine's icon

Hello @Graham or (anyone else),

I have made some adjustements (as suggested by ersatz_ben in his excellent youtube video) to your transient detector from the patch you posted above. The transient detector works pretty accurate as you can see now in the attached patch. However, there seems to be something wrong with the buffer now, it doesn't record anymore. Must be something I'm overlooking but I can't find it. Would you mind to take a quick look?

EDIT: Nevermind, I found it. It is really accurate and elegantly simple. Thanks for this!

Here's the final result for the transient detector, should anyone ever need one:

Max Patch
Copy patch and select New From Clipboard in Max.