Transient Detector that will record only once and switch off once recorded

    Dec 15 2011 | 1:51 pm
    Hi there,
    I'm Matt and extremely noobish at Max but desperately want to get better. I have a problem.. I found a transient detector that triggers a bang when the sound is above a certain level, however i've hooked this up to my record object and it needs another bang to turn off which is a problem, and I also want it to record only once.
    My aim is to record in 4 different samples for 4 different buffers. I'm making a drum sequencer with live samples basically.
    Another way to do this live sampling would maybe be to beatbox a beat and then make it slice up the audio into 4 different buffers but I have no idea how to go about doing that. The first option seems simpler?
    Many Thanks

    • Dec 17 2011 | 2:46 pm
      please help! AHH
    • Dec 17 2011 | 3:24 pm
      Hi I feel your frustration! I've not done this kind of thing with Max, but I've been trawling the forum long enough to know that you should search forum/google for bonk~ and analyzer~, two externals that allow you to extract info from audio (realtime or not, I don't know); a simple solution might also be:
      >~ 0.1 (or whatever value) --> [edge~]; this will give you 'true or false' bangs.
      Get this solved first, and then repost under a different topic for details on slicing into different buffers.
      HTH Brendan
    • Dec 17 2011 | 3:41 pm
      Slicing up a sample based on transients is easy with rm.slice although it just sticks the times in a [coll]. I've used it before to slice up a single bar drumbeat and re-sequence my own patterns using the slices. It's available here:
    • Dec 17 2011 | 3:43 pm
      It's also relatively easy to trim off any silence at the beginning of recordings if you need to do that. It's probably one of the most useful tools I've used!
    • Dec 17 2011 | 4:49 pm
      ah thanks a lot guys, i'll give it a go!
    • Dec 19 2011 | 12:49 pm
      Okay guys, i had a go at making my own transient detector recorder. There may be a couple of unnecessary connections, but it has all the ingredients I believe! I just can't get it to record! I think it must be a small problem but i can't figure it out.
      Here's my transient detector recorder 2.0 lol
    • Dec 19 2011 | 2:14 pm
      Also unless I'm being stupid it seems bonk~ fiddle~ and rm.slice no longer exist. I tried with and without the tilde and the max window didn't recognise it
    • Dec 19 2011 | 6:58 pm
      Have you looked at MaxObjects?
    • Dec 19 2011 | 11:17 pm
      here's something using max 'native' objects-- it does transient detection OK but I can't seem to get it to record into a buffer (something silly you can fix yourself...(just read your post again and you can't get it to record either - sorry I didn't answer that question...)) hope it makes sense-- it needs cleaning up and other tweaking but at least illustrates the principles of high pass filtering to isolate transients, using averaging of the signal over a time window (256 samps), use of average amplitude threshold and hysteresis, debouncing the recording trigger (or gate) using the del object
      OK I better do some real work and stop procrastinating
    • Dec 22 2011 | 7:25 pm
      i need the patch in my last post to record when a transient comes in and then allow me to turn it off without turning off the dac ^
    • Dec 22 2011 | 7:27 pm
      or if this can't be done, can someone show me how to slice silence from the beginning of a recording?
    • Dec 22 2011 | 7:38 pm
      oo some interesting objects Terry, thanks!
      And yes people I have looked at max objects and I just can't seem to find any use out of it. Seeing as some of the objects don't exist
    • Dec 22 2011 | 9:32 pm
      rm.slice seems to still be available at the link I had above. To trim silence: generally the second time it puts into [coll] will be where you need to trim. On a patch I worked on recently, I programmed it to get that time and give it to my playback objects as soon as recording was finished, it's pretty efficient and may eliminate your transient detection need.
    • Dec 22 2011 | 9:57 pm
      I'd really like to use that, but max isn't recognising rm.slice it can only find zl.slice for lists. Would you be able to copy the object in here? would be much appreciated
    • Dec 23 2011 | 3:40 am
      And yes people I have looked at max objects and I just can't seem to find any use out of it. Seeing as some of the objects don't exist
      While does list objects that are included with Max, it also lists 3rd party objects that you need to download if you want to use them (each object listing on should have a download link—sometiems they are old, but many of them are good).
      You should be able to find rm.slice from the link dickmedd provided, or you can follow this link to my download page:
      See this thread for some info about some warnings rm.slice will print to the Max window that can be safely ignored (you can also download the a zip containing rm.slice from that thread, but the download link I provided or is the way to go because I will be updaing that object sometime next week).
      A few brief thoughts on this issue: while it is good to detect an attack and sync the triggered recording with a zero crossing, your use of zerox~ is not accomplishing this. You have the output of zerox~ going into record~ which will just record a series of numbers (representing the number of zero-crossings) into the buffer~. Check out this thread for some thoughts on syncing recording to zero-crossings:
      You are on the right track using thresh~ vs the use of >~ in the original example you linked because to detect a transient, you need to see when a signal goes above and below a threshold. You may want to think about using edge~ to covert the output from thresh~ into something you can use to trigger your recording. The problem with using edge~ is you are not working at signal rate and so the actual recording could be triggered sometime after the threshold was crossed (again, see this thread for some discussion about managin that:
      Also, as in your Terry's example and the original, some sort of averaging/envelope following of the signal you are analyzing for transients could be useful but may not be necessary depending what you are trying to accomplish. If you do no envelope following, you sould at least run your signal through abs~ to get the absolute value of the signal you are processing (because if you have a threshold of 0.5, you want -0.6 to still trigger recording).
      Something else to keep in mind is that after you have detected a transient, that transient you wanted to record will have already passed, so you will need some sort of delay on the signal being recorded to compensate (it won't be possible to get this delay exact, but this could work well combined with techniques for starting recordings at zero crossings I linked above).
      What you are trying to accomplish involves a few steps and I would take them one at a time.
      1. You need a some sort of gate system to prevent recording for being triggered more than once. Get this working first just with some toggles and using your mouse.
      2. You need some way of deciding when to stop recording, either manually, with a fixed time delay, when your signal goes below a threshold, or some combination of crossing below a threshold and a timed delay.
      3. You need the actual transient detector
      4. If you want to trigger recording at signal rate, you will need to manage that (again, see the link posted above
      5. Delaying the signal being recorded so you can capture the transient your are using to trigger the recording
      or if this can't be done, can someone show me how to slice silence from the beginning of a recording?
      As I've outlined this certainly can be done, but if your goal is avoiding silence at the beginning of a recording, it is probably simpler and more effective to do it post-recording with something like rm.slice.
      It's probably one of the most useful tools I've used!
      Thanks :) stay tuned for updates on rm.slice coming soon! (I mean it this time, after Christmas have some time to work on my own projects)
    • Dec 23 2011 | 3:51 am
      Wow, I guess not so brief—I'm sometimes more verbose than normal when I'm tired.
    • Dec 23 2011 | 12:32 pm
      Wow lol thanks for your time. It's a shame rm.slice is a download because I would have to provide my lecturers with it when I hand in my work. The gate system is what I'm working on at the moment. Quite a pain to figure out. I'll take a look at the links you provided. Thanks a lot.
      Hope I'm not trying to accomplish too much lol. All I want to do is live sampling! Never thought it would be this hard
    • Dec 23 2011 | 1:08 pm
      Are they really not letting you include externals in your patch? So many of the projects I work on in Max require at least one external at some point, I find it hard to believe your lecturers wouldn't understand that fact!
    • Dec 23 2011 | 1:31 pm
      We can give them externals, it's just a bit of a pain to tell them where to install them etc. If that turns out to be the best option though, i'll definitely do that!
    • Dec 23 2011 | 1:37 pm
      That's good news. I'm sure they can handle it ;)
    • Dec 23 2011 | 1:53 pm
      yea I think they can haha :P
      i don't want to put these files in the wrong folders, so just to check the java file goes into:
      Max 6 > Cycling 74 > Java > Lib
      and the help file into: Java > help
    • Dec 24 2011 | 5:48 pm
      I'm not at a computer right now, so I cannot say for sure, but Max6/Cycling '74/Java/lib should work (I don't know I sure just because normally I have other folders I put my external java stuff in and set the path Max6/Cycling '74/Java/
      You can also put any external patches or objects in the same folder as your patch which may be more convenient to hand in a folder with a patch and any external objects you require (although putting things in a more general location like you suggest may be more convenient since any patch you work on would be able to access those objects). Putting a java external in the same folder with should be no problem for simple objects like rm.slice but for more complicated Java libraries with many objects that depend on each other you may need the library to be in a general library location like you suggest (loading Java objects from the same folder as your patch uses a special work around with the Java class loader that can behave a little differently than the normal class loaders use for tha lib folder or other folders you list in but off the top of my head I don't remember what the differences are and when they matter but I know the same folder trick works for rm.slice because that is how the included help patch works).
      Unless your teacher had asked you not to, I wouldn't worry about uses 3rd party objects in your class work because that is a fairly normal workflow for using Max. I often teach bonk~ and fiddle~/pitch~ to my students and encourage them to browse the forums and and sometimes they have found some interesting externals I had not heard of.
    • Jul 06 2013 | 9:46 pm
      Hi Roth,
      I'm really loving rm.slice... its super useful. I'm wondering if there would be any way of reversing the calculation process somewhat, ie specify the number of slices that you would like to be calculated from a particular audio file. Would this be possible? Thanks, Hugh
    • Mar 15 2015 | 8:54 pm
      rm.slice works really well, thanks for that!
      It looks like the key to writing a really intelligent object will be to automatically detect the relative silence threshold. For example, sometimes a signal has noise from an instrument amp or reverb or delay or release tails from previous notes which may always be above a static threshold value. This might produce a waveform like the attached screenshot from Ableton Live.
      Notice in the screenshot how Ableton has somehow calculated the transients even though there is a significant amount of signal noise between the transients. Does anyone know how they did this? Is it possibly just the minimum amplitude in the buffer plus a little extra to account for variation? Feeding a dynamic threshold value to rm.slice would make for a really intelligent recording algorithm.
      Thoughts? Abjections? I'm feeling this out as I go.
    • Mar 15 2015 | 9:08 pm
      It's all about volume differential and not an absolute threshold. So the change between whatever is happening and what's coming next. That way you can have a loud noise floor and still detect onsets.
      This is what I use for nearly everything (tweaked from a Peter McCulloch patch):
    • Mar 15 2015 | 9:10 pm
      A follow up. I use rm.slice for when I want to retroactively determine when attacks happen in a recorded file, and the onset detection above to detect when onsets are happening in REALTIME to trigger stuff.
    • Mar 15 2015 | 9:25 pm
      Thanks Rodrigo! Yeah "volume differential" is what I was grasping at with the phrase "relative threshold," but I don't really know what I'm talking about ...yet.
      There are a few objects.concepts that I'm not familiar with in there, like slide~. Some questions:
      - Would you mind giving an english summary of the "just attack" side? Does it just compare an initial amplitude as the low value and look for an increase above the threshold? - What kind of latency can we expect when using the final bang to trigger a record~? - If record-start latency is an issue, could you give some tips to use this in a post-processing situation? For example I'm not sure how to step through the buffer's waveform performing these calculations? Maybe it's more practical to just trigger record-start with a little latency?
      Thank you so much! Great thread!
    • Mar 16 2015 | 9:58 pm
      Well, it turns out that the real-time attack detection is fast enough to pass for my sampler. I didn't even adjust the attack and release thresholds. It obviously works well when there are reverb/delay/release trails from previous notes as well, which can lead to some interesting creative stuff.
      Very cool! Thanks!