What's the best approach to overdubbing/resampling?
What’s the best approach to overdubbing/resampling in Max5?
I have run many searches on the forum to find ananswer to this question and have found a number of topics which provide solutions – however I have not succeeded in making any solution work very well.
I am new to Max and am trying to make a simple drum pad using a keyboard/dancemat. When a key is triggered it plays a sample and what I want to be able to do is record and overdub these samples so a user can build up and layer a complex beat – whilst keeping perfect syncronization.
I have a working version which uses the Fripp~ object but this seems to subtly full out of sync which over a minute or so is very obvious and not at all useful. I have also played with xsample~ but not had much luck with that either. I read somewhere that PeRcolate’s frecord~ does exactly what I want but I can only find it for a Mac and I’m on a PC. Does anyone have this for PC?
All the topics on this forum relating to overdubbing seem quite dated and so I just thought it might be worth asking this question to see if I have missed something somewhere and there is an easy way to achieve this with Max 5 – or if there is a new object around which people are using?
If you have any suggestions or could share a patch which will help me it will be much appreciated. I have a presentation (at college) in a few days and this syncing issue is really the last thing I need to fix.
Any help will me much appreciated.
Using count~ and index~ is the tightest way of doing this type of thing. You could do it with play~ or groove~ as well, but index~ will give you the best audio quality in this situation. I’ve not used percolate’s recordf~, but as I understand it’s just record~ with a feedback loop, you could achieve essentially the same thing using the loop mode of record~, and using send~/receive~ to create a feedback loop, although this method would mean that each consecutive overdub would be one signal vector length of samples behind the existing audio……..maybe fripp~ uses a similar method hence the drifting out of time?
This patch has solid timing (it’s basically the same as the endless resampling patch posted by Andrew Benson, maybe you’ve seen it already and it’s not what you need). All it is is a circular buffer delay with a feedback amplitude of 1 so that it has no decay.
If this isn’t quite what you need help with, I’m sure you could modify the patch to do what you want, or post another question, maybe with your fripp~ patch to show what you mean.
----------begin_max5_patcher---------- 1160.3oc0YssihaCF9Z3ovhK6NK0GhygUUpuE8lppJShCS5jXiRB6LaWs7r2 DaCjv.CwAvoKWfiMFmu+u+i196ymsXk7Md0BvW.+IX1ruOe1L0PsCLyze1hB 1aw4rJ0zVDKKJ3h5EOo+sZ9a0pwK4axYwbvqY0OCpXEax4flQ91JV7K+99Ym JE0UY+Ku8efvKglg2vpieNSr9uK4w0ZvfoM+J.4qahTMXzRH3uL+Gw1hLQNu VgJjYvrDEVjq9mO6Q69RErB0KcwevKSXB1hiqhba89kA1N3OlOu8qmtQ9HoZ i8RMAoDThmtAauTSbiTWKWuNmue8zKV821v0hwhrFB4.lOm1Mpqbhg6+d3xI 57xBZDxhf+ZyR9dEHKd2XragcjLOzGqAwuWxHQtQC9J6q7TYYwtKpDSykrF6 5O7g7rJU6QscNaEOWipKyRAZ0enV8S8aa785vRq1llxKOH84R4AuoUqik4xR 8BAWhepyWcI5VEYmYdb7r3WJXkuzaUHQXDM3oK7zwEsbaNurqv0ScRMCtma6 8Jh7hfJbd5CcA8WaQWO1qqog24U+9lQq34MLblTz68BUxR.l5EodWFA594n7 K6ZV1KZEUksVvxOZeXgqDraPBOO6ckFQvPzckWfKoO.hIRGuTmajhsmWvSJu 7ocO.NQGQAqoFBYI0VNAMobRlHg+1NP23b2SOISRIc0EgivhA5F14RESkyEq aJqLS.p3wRQR0HJsB1oVCDx25RqvNJw7ErPXIwMwYeXQSP5bwTh87Rvj54rQ 9BuuiisAMLtEHZzGK6jyH69SpMwmdLVDHSY4DchW6CWfoSpIQijuC74GByXR 8pYFp86JE6MsLipBQY4N.9AZ2X1zNbD9SjoMOyu09A..MxjrLAHE+pLMcDaB LvDSU2PQ1amf+4Xe7ztB5H1GOF5lnAnGWUUlso3EYsRFENoAChkaE0M6Q4gR N5HkgQVmCAMskUTTUKaOEypqtYkCGGx3YIjtIbDlPin.D7cbKtMQ4gvkW4Hj FOwnSnPCr25wQIRJ3UUr0726akyYkWjVFCiPnlrpZhQa2DYAkLsAapAofzgd Tii2fIXP6++LNRNxOpQ9ZVjqyCqXh02TNoQVeJcRCmrojugKR.JY8d57XJIU eqCgAVSKS6AIpOL7qb5P2toiorc8MuENhCH41rcTumE4YhSuOREVaGuOyUI2 VFuW52emPfivMgWUmIXsmGdmI0d8JclzyYIIbQWApHKYirot2p8WavY0iCES sGb1vvD5LXBddLgoQsw2H5j.3PzgdNCsvgiVmfIhcX5DFD4c2XPxPPKxRzZv Wf5jX7Udl85fCUWNRnZZpN2nXzV780ECnaMDFh6c6Ax4RLgGp5F4LLgGjtC6 TdBSFptyc7T6tuuNlniJvBlX1Wm2gd2JCRGBZINUqNnnDJLgsmA80gl87Nz6 VYPughVG5qNjjamXn9+B+hST8ObL0OzvGfI2o67GBM41zQngDl0sPZHgsPtM r0fh6aGhH9pvTHrpTbbvwd2AirqY26V1ib+YudHpoyOl+e.3uLiK -----------end_max5_patcher-----------
timloyd – that is great – thanks! It’s exactly what I have been looking for and it looks so simple compared to some other solutions.
Just one question regarding the patch – how do I go about switching to ‘just playback’ and no recording – so a user can test out a beat before laying it down. At the moment i can toggle it to record on/off but is it easy to add a toggle for just playback?
Does anyone have any idea of how to add a playback (no record) feature to the patch timloyd shared? I am not familiar with the index/count method; I’ve been playing with adding this feature but am not sure how to do it. I think it is probably very simple to experienced users – but this is always the case when you know how to use a program.
Any help would be great – deadline looming :S
You could simply add a second [toggle]->[sig~] connected to the [count~ 0 1] object, as a play button.
While this toggle is on, the record toggle will function as punch in/out.
That did the trick – thanks mudang!
…and he’s getting some credit when you turn in your homework project, I assume….
Of course. However we are not marked on the code/software annoyingly – its purely on the finished sound output.
If sound quality is important, then you may prefer using wave~ rather than index~ as the latest object produces ugly artifacts when played at speeds different from 1.
unfortunately, wave~ needs to be driven by a 0-1 phasor. You can get both positions, i.e. sample position and 0-1 position, using something like this:
----------begin_max5_patcher---------- 1199.3oc2YtrjiZCEFds8SgJVkK83QWATdIlMoxlTSkBajcSJP3xRtldlol9 4HuO4EKHInG7zfM2ZLU1faAFyOe847qiN5qqW4sM+IgxC7af+DrZ0WWuZk8T lSrpb7Jurnm1kForeMuc4YYBo16A20zhmz1yCeGBbLWknSxkUWTdNK+rNUns 2Jr7rGiz6dLQd3uNI1ocOZJCtA9.fF3a9HjZNhQaffOVdOIw1GR91+9c3vpe 984RsLJSXuzeHNEGIipeMUxWrWCg2.+thRjUBBUInSBUwqTjQ50EEl6DUn4C X4AvGM2z2Vu1b3gQBML3SQeVAz4fCBMPEkcLULbJhnrZTDCQWEiASFFmPf7A 46+v98feRcTHhAnet+LHDaeqsgPHWXUqHfMSQRnxHZ+QGHIEepP4uBa5Smk6 dtYXgtBrfVXQcQJL7qfk6mQ+4iB2M3oRNHiR8Zjl3YhlDmbIgrwiyyYaEmZA b3aCNhUBbRmA2C.u8o4Q5lIHZDDLKOVTW0WPzpSVnBa9yK2UaH1EpR3v2pH1 LkN232oFL7I91jpP9DAe38zOrEJ8KEurP3l9mXisgjDjEQrfain1AChOUfAO gf4Y.Z.XA5vB0ZfDPFkeGZxpCAeqjQmemy16MoNjeOIS.Rj.kXWtLV06YcwA 1PLedGl0EcWK7XnN9Tpuyw29JxoSioChsTb7wbmop6M6tLoJtrd6ocRUDc9P 7.fkN+vgTQ+cxXVH4r4wvpisipDYK3g3MUoVhuDG0VQnWw6fvctFHqER4RXX M6cv8lp4UJBXJ9M5eLpM3nznqAetVlWsHBcaj7Pi+GveAV2gFrEru2vgD3.R na9J1soiEJWM8kvWhKS8e+m9OEIyElSBpk31xTjT+k3KcpPdP+nsLghB26ed Nj6J9xFjTTW60H.IbQlUre.YEkV0HhclUBdCqydFWIsfdO4SlPohNHdcO.u9 7XaOrKOM+j6sDtgQBvLloNCdfOM.U+upymFKUHnVxjioH90XZyTDu.WZy6Gz JaJCxJyw5bPVikDrDox.6vUUMkSRGtPKwVD7qOaRkFJXJahBiNJvv9eSGBpv xjzg.5RDKChJgksSxYxfwioeRgKPpDEqJVQ7YEPcp+U8hb6yhqKatMK55rwL 0daqGKXARmiOFoxOY7YF77RtUFve8NRUqhfKZu0kk.zKW56IAOFIEo8tzX2N YPbcmDUt2U9jV10poaE6CSsXTYuGBpuMiDXKxk5Mf834xmQisix9v7RSj+39 Wakr47W9lqxOeZWU7SYfB36RNVnzIRqNp8cnW7cdLINVHqimrj3i4E4xkR.U LcpoxKN29AI7kQszIstpUylqcSwhQ8SsiUSvtnI7rpISS4uslfyql3cPS+fv eq0jeWjDueRBWXraVGla64PkqJyLZr.7Mfe0xTsMeD+xn4PrrgIV2p6nEyoV MZrhsKovH57ltP5hlvKuzEijPCNcwU33TjtzEwFNlTaydEMQo1D9zKVRfc12 p5xch0NZJDKpChEMaAlAcPQD9rlqPncIYYdsT5R0Sj40li0EJMuEpzk+wwlU EE1wRz6isaoe.Irt6fYzXi6wcLtentCEC915+CvaADnO -----------end_max5_patcher-----------
You’re right that index~ will alias with variable playback speeds, but wave~ would be my last choice to replace it with! As I understand it has the worst interpolation of all the playback objects, because it’s designed as a wavetable rather than for longer sample playback.
Also, using phasor~, trunc~ and poke~ together is likely to create aliasing while recording, because the combination of roundoff error and truncation results in a signal with an unstable delta between increments. It won’t be consistently incrementing by one sample, which for poke~ is basically the same thing that causes aliasing in index~ with playback speeds not equal to 1.
The best alternative would be to still use the count~ poke~ part for recording, but to use phasor~ and play~ for playback, although then there is the need to synchronize them, especially when you DO want normal speed playback. This would be tricky because phasor~ can’t be reset to 0 phase at signal rate…….there is probably a way of doing it though, there’s part of an oscillator hard sync example patch that would help with this if I remember correctly.
Although, the notion of having variable speed playback in a circular buffer overdubbing system might not be suitable in the context of recording rhythmic loops and stacking them on top of each other. It could create some pretty cool sounds though!
In the context of Chewwie’s project, I think variable speed playback would be better realized using separate buffers for each consecutive overdub, sticking to the count~>poke~ recording method, and using phasor~ and play~ for playback. Rate~ could be used to adjust the speed of each loop……..can’t think exactly how to make that patch off the top of my head, but it’s not going to be really complex.
My bad, I just noticed the [+~ 0.5 ] in your patch that sorts out the problem with phasor~ and trunc~. Very useful to know!
Thanks for your comments. I’m actually working on such a loop project…
in the patch I sent, there is a +~ 0.5. If you insert it in your patch, the delta will be 1, as with count~.
About interpolation, wave~ gave me good results so far, without aliasing, but index~ was really unusable. I need to do more tests anyway, on longer buffers.
----------begin_max5_patcher---------- 707.3oc2X9saaBCEF+ZxSgmubKKy+AHvdP1MSUSNfaBSfMJ1QKqUMO6CaG5R mHoNPJEsaffABe767cN9XdbV.bkbOWAAeE7cPPviyBBrCYFH33wAvJ19rRlx dYv6KkhcUv4tS07S4NcIWaOI43n0Lc1lBw5erkmoc+4DZzBzb.NjZ1EgLaI3 EHvcGuG2ei920b2MXdPLMbN.thIVCe95JxsxPt5melfakw8RgVvpr2J7a7s4 LA6zyoJdvdNLo449rxKDsBGaF6oYyLal6IHD7e0Hh1mhlu29lB+zA.ZQT27A eA9frHAGmX4S3qyGUwZAqrSvPuUbgb63hd6NQ1gdykTmugLHtPnSPCSiMOuh qT.LBg5KehbYWHO3S2jgLAIS1llLedu8LjzTyt3gkKgS9OhLwVaB0YSFJXV9 dBF9C4ryUNAcd.jfb.vrMLpcamudgvaUEQUlrle8Z8nMlRsQKrSz1ccpW56s dOZtnTujKA9FOgSNuTy5ewCW+J9znxkxQlhcnzSv3BuDZ7sfKnIHW5cGJ17S ZH4FzgR5DjKer+cs4Jw1T.KZ.LIYB1M6G9hscsE8kLIVvD68xf5hKKmfboIL d.f6YsEL1Mib5fRghmfoPUJsTwppUGt5EN65r24WR7mLyujyIZJ1RqbmP2r1 496dbEaVNL2CYBlTUugoja6eUXWZULdXSY+V.F6CBVVH92uAk8swL9KokRta aVqXaWDB3uuP4bktPvzERwoWD4EWzlh7bt3zlYqJxqkEB8QQ.tqyXmuZx7Yo dUM0zsN.OZRJwSEMdPh5ghHiqjhdQH4LRZTCadYtGUF4i0NYxE0RttnFlFZZ XEGhr8sRbKn0bzPqL3S7DMtATjOZZ43pIebY3w0lg8oDJdbKXE6SMzwcpOeb 3KmdRJ55jDAkZpL39Xhwgs+dnJ0m4DwCodeyAOM6OLYEuEL -----------end_max5_patcher-----------