I’ve been working on this for a while. I want to create a patch that allows independent control of each grains frequency, duration and delay. Each grain. I don’t want a cloud, I want a stream of grains where each grains 3 parameters have been chosen based on what they are set to currently.
Also, I’m not talking about granulating an audio file in some random pulling of grains from it. I want to use an audio file but only as a single grain. Kind of like using a whole carrot instead of cutting it up into sections.
I’ve made a scheduler-based version but I’m not sure if doing this at audio-rate is possible. Can someone please tell me if they have experience with this? Please don’t recommend a package unless you know for sure that what I’ve just mentioned is possible.
I’ve tried all of the following in addition to my own:
• granular toolkit
• Max examples
• FTM Gabor
• and others
Would you be able to post a patch/part of a patch to demo what you’re having trouble doing at audio rate? I’m not sure I understand exactly what you’re trying to do. Do you want the grains to overlap pseudo-synchronously, but each with a different/variable length, and keeping the "phase relationship" constant all the time? That doesn’t sound too difficult to do at audio rate.
Is there a problem with your scheduler based version? Or do you just believe it should be done in audio rate?
I would do it with a poly~ and trigger the grains with scheduler events. 1ms is short in comparison to the usual length of a grain…
this is from an archive of stuff i have of other people’s patches… posted long ago and i can’t find the original thread now(hope the author doesn’t mind me posting it here). it does the granular-streaming thang pretty well and all within signal realm, but i’m unclear on whether you want more control over the stream of grains(even as the grains keep an ordered phase-relationship, as in a ‘granular train’, maybe you want to still control more parameters on each grain as the train plays back?) and also what do you mean by using a single file for a grain? does that mean the entire granular synthesis would come from playback of short-duration files? that seems more a matter of sequencing audio files than of granular synthesis(because, in that case, it would be more efficient to take care of the windowing ahead of time right there within each file)…
anyways… this might not be what you’re looking for since i’m unclear on that, but in case it helps…
Here’s the patch. You’ll have to replace it with a 512 sample waveform. You can download the one below if you like.
@Stefan: The problem is the timing. It’s not as tight as I would like. Also, I haven’t yet been able to figure out a way to use windowing (gaussian, etc) as a stored waveform using phasor~ or wave~ that I can play through to window the grains while also being click free.
@Noob4Life: Thanks for the patch! I’ll have a look. Yes, the entire stream would come either from a 512 sample waveform such a sine wav or other sample. Where I could then vary the distance between each subsequent grain. It’s described more below what I’m trying to do.
My goal is to have a single numerical control over each grains frequency, the delay between each grain and the duration (in ms.) of each grain. And do all of this at audio-rate if possible. Trying to do this in the past, I’ve run into issues with having to find zero crossings and such.
----------begin_max5_patcher---------- 2888.3oc6cs0iihiE94p9UDEMOL6nZRiuBLusRizt+GFspDIgjhcIPVfTU2S qo+suXafXtXvbsopsaoNIX.y47ct5iMt95iOrce3mci2t4217Gad3gu93COv ah0vCYG+v1KNe9fuSL+x1dH7xE2fjsOINWh6mS3sGF7ovSmxaN31kvaI9tI7 axHqUuihKc++9Ww4W4ovfj.mKt7y72i7b7yOy0H23zmjShWXvyQtGRDjIBat y3oMDD6SirO17ut+f8Bxet.omQr2exeF.3tbx4pSxgW7BNK04.K.qGsHrOQV rOg7tmcG+0iOx93IMQp82RRBCZFQxoLQSIe4pq34ucuSv4sEbiDfg11FG1Dq .43D.XmyEifWTI0ibu56bvcyaNu5dJL5R9E36E3dH7V.+pf5pT.FrRA.xkaT xrnTXPuqTPgbUC7DCjGc8c9h9VOztQpQxzHj8jYInjouEsSedlL67LTvsY7L YV34SQt+2dvz34mog1SFSysNSZl6vpb4keSa15Ev+pbCM4LDC6s2PtILfGz. Xv8PfkcQHdlOezIwIOZXAOJdL6cijdFosc+ZoOk4ilvH5yNdAei8CeuXFW.P X1yjGzJ+BMYmOI77Ye26LNP5BrYMexOL8Am8KG1k.QxcC1n4qp7CCCTzWERY lHdPx67NsI4MTk7N+4qNVGFr.t2r1gR+GlIaDAGIiKD4bgEFKfaODGK.nUNV vrJlcug7PcSCLjaf2qL.U4yi4ynm97xjqR53iLMvLWa8RrF6cNfIdZgyHMxY vVjRXjfOD41JDY.qAxUWbiicN6VKTcbR30dJ7Zl+5aPb3.F2BGPPB.AIByM8 3gSTxadAGCeaRfEzrCK1XITwDOJTIv8sTptdNrNG9l1oyAslcVNyz.IFJDxb T16J34qaNG4Dby2Ipm5AY9BZRa.Z1SngLTnAPn2GqHrTRfr6QjlmT1eaO446 9paTb5PNky.b68dFS.BzlO3PJk6PhXYcuuSQ5y9gG9OtGkTMRygz8T+5kvqt A2uCC4g6VZLuhqzKPd7xUexN27SdtY3q74OkNDek2bihpG1dNx6XX.iHJcmr lyebotsHBAhLcyuh.mqMbyIgg96chd0K1auuaIYQpdrSf2EmD2DOA8.MJtOu KWi7D0hnnM2.mz93k3CQg99k5JwYdsgybz8UuCtu4cL4EdecGsJUFM4QNHag Up8JVZb85bvSoEkF0LpVMULk6UEkOAVLfnFzjpY4YH2gMXlI0YPR9mk5t7AG yHx+QTZREaXCK9Vvgur4m+m+4t+117Kk6uR7imFHxVxGF+zu5DUnzdiBSUTL LJCSEd5X0w5apEKv1DK2S7ocAjb2q1fRUngV7ApT.YykMHwvDwfxgHlHX+Tp zj6zQI3gkNywvKoZAbx2nD4qdTB4+uN3tOL5nazgP+vnFcSBpnMJGERlbEEw TpWP7+8Ti+pZmdML0iS46FlF4w9oF+EnM6MPGhSpvTST6F.xPD8nRO5b7Hmj hqAIruMwXpEf8K.j2DXGxBZaxIRncFyxZ1FfsrwrlInhlg6nDahIuYSyhlSG 9AAXP4Mae+pw6nVFVD.ms4sP1QrXWI+Bo7lnBBvh0jEo3dSymgSq7mDRpYSN EvoKLkRM4MmF5rneQzrln.SCHmWgfhNvdGjPP.N+ldC4cf8Na9+xwpI0Dotm IoLr3ED9Y+vhgfLoQEPCzoCdvNcP44awStwxnZxWMk.VYvSYhXURFyTL0PPp 3KrXHQvJFDMmPV8jxzs2zNwLMRNSmDz5LIMMSTqkj0zKgsNRZqiD25L4MUIv 0dRbsmHW6Iy0bBcUzEqYjW67cYrWYhzDF7DipWgRK9NFocWoZzskeqI90gG. k0ofvGPJEb+yxYdTx0ZY2qiUBTpnjcmPWeJR4c4YjW7AGgJdZnL0hB3HEEUU D1etTtFVzrPXM7qJ4Zvu8WXJhk6ASizgd9Ti+podnCcgTR26RJ5WyRS4rWmM UMXoASrTZJcXqJOWsC0NsY0GEQnGhBBbz1pzLe8lpFkvGbI.dsHAxrAVVIP0 BRL4AiH8JTiRzos5LTqVCa+H.bzwBbhUDzGRfSDdtMzybrnmk4+GidViV2SD We0AeBrnc7yPMtX2qj0T5LChfSDtTd3YrJY0wnY3zD65ZGzhCuEcHWeIKOkM 0IyitwIdAECr8OJhn1v09h2wi0GynfYKRHUToncHpgoEudRTKHhfZNWzKdkp 0kIdGgMwe37UtWkCDyRn3prwCN95PQPxLhfUPhElyn8fyPiiyfVbYrXsAmIv YGrvbLd433Ely5ict86JNyrm1ef2MbFrmZiify.oQtX1bhkdhMs3fElkA8fk giSMEPo4QLdJm++ND9vZ433V4LoSlxl2qoeryqtGeN8omlqyyNIIQd6ukHxF ooZ72YIs6nT1ZVwacpt9Y+v8N9YyIQQessJwnjJk62GqiZy8LH4E3kLvotlW ajJqXu1JORelBIiAOERhUiY9p2FLeyfT1DjyLv44JJVJUFfgMCR51a+XFj9w LHMhZhN5oNppw9TO6Qiudnl1BG.YyA6Zphzw5M+cFK2LBMX3UjBG0bMAuX7b qciVKZ2hk8IBslfe+PmihbBV2S4x3sAHRu2GzkcVGGYIHIisDjY5e114AnaH L86vRyRGKtjk14jgKKVoY6SwnnuqJYSe3Lv33LhMeb87ngVV4+9iaUM93VvT gjL6s+PHJ4GrhKjJ4G0q4CU8ZJ+l0UYE.J1JMF3p8UYYZHK9qWP1adlXJdEu RS2eo6lHfrzdqxjtxnoaG3xvGalUlmFeQaWNEnMGBOcx084C2t9LIUZ43cZp 0oLWbcJQNXnLHlPlEkpVpl59aoXZz2Xu2idACrnppW5npVgE8AaAiDawhxpZ ZOOuMPUW6sSDvob81pZwYLTHc3qu1ws1ZaSVJslZIc9NeIbKAvbSGh4h6cJ1 MQ7Rds4m.Ss+Hfwx+Nzk6lWriAgWZGRwt9a.o4F1YVCXclmmpeqFoAKt6o73 ph2qM6kOtpz1.wzowB+NDBUN+DQ1YKoF6u7sABhU1z.pAknk23GPjRGA8ALj I.+AMlYiuSRDo2eVLbVjlsXXv16D6LyxQYgLzw.hFMlZy+xzbowzTk74xcC8 6FXRmyb2FyFPQ80MdoI1Dtcf6jDYL9pYqjXFwHzPwHHcHa2F+9sHdsF27yWh e2fQ3ghQXHsWXzuylJ+UJF01RxBRFLBY1OsH9VA1mXYFu4W2.9jwThN0luO0 y0WIlevUtKKcNrUOrg369UaRopq2RZh4uueFUaB9tiGMMEBRnR8oAp1RUV24 Mn44Ln1hnmOCIHwZOPrH5QkWCusJd6M6fzjcfzgwOyDcCIZR2.v5htwZR2L4 BZ8P15plXutPantZI3UEcqqRh4php00yn0phpIyKUm4BW7FJHl9aT42Pgo0e NycGb9BOQRSiyJaeJFIFsddPJxrwT0dielXqXK.iCfh+9E.n3hilKgjt12f0 UP2FHGEzMYcQ2Zmr.ZXzclNCRLS6P38ilKNpOLDXHYgJ7TQDUhCiKNZlXHac YHi0klkgtoOupHaz7R0HyLWnhpxSsKNZtxyS2.DqKkGXOFKvPhUaHVsc1h+b 4j8FYaOeFw8hgzwqz.17A5.DRS8xJe63eFQB55CHvleO.B6d.DvADmhJyTX. YGfRoD5Lqmqa32UV5a.ccSNkQqxZLe8s10Za8q5r2m2xddtFaK5cssq29ZXc qRJp1ZWUfBY62+b3rbkHEa++UEiY+Q.n8f1pBXWZL30kZMKwp8Wj.sIIrNzj 0xRSn0GMUQrnvEHYYwIxJT1oMMAVNZxTW6N7xQS15RSKGNgMzklfKGMAzklP CjlRO3ud7+soUyrO -----------end_max5_patcher-----------
Here’s a quick throw-together of an audio-rate version of your patch, which I’m fairly sure does exactly what you need. It won’t sound quite the same with the same settings (you’ll need to tweak the dur and delay times), I think just because of the schedular-windowing in yours not being as accurate. You’ll need the [shot~ ] external by Andrew Benson. It just provides an easy way of generating a 0-1 ramp of variable duration from a click pulse. That’s a bit of a pain to do natively in msp :) You should d/l the rest of his objects from the share pages, they’re very useful for this sort of patch. http://www.cycling74.com/share.html
Thanks so much for posting this Tim! It’s exactly what I was trying to build. One thing I noticed though was that when I scale the delay down to 0, the sounds cuts out. Do you know why this is? I don’t completely understand how the patch works yet.
Off the top of my head (I’ve not got max available atm), it doesn’t make sense to give [train~ ] a pulse interval of 0, because that would translate to an infinitely high frequency. If you start off at 0 you should see the patch kick back into life somewhere below a pulse interval of 1ms.
I *think* that the smallest pulse interval that will allow output from [train~ ] is determined by sample rate/2 (then convert hz to ms to limit the lower bound of the delay parameter), so running the patch at a higher sample rate will allow you to get closer to 0. The best way to do it in this scenario would probably be to use your grain_pulse subpatch in an up-sampled [poly~ ], if you need to get really close to a delay of 0 :)
this ‘thing’ is awesome. thanks, Tim!
@Tim: after doing looking again at the patch with some scopes and number~ boxes, I may be wrong, but the change~ object doesn’t appear to doing anything. When I took it and the clip object out, things didn’t seem to change much in the signal. Thoughts?
You’re right Wade. I was using change~ and clip~ in the patch before I remembered shot~. Shot~ creates a ramp on any 0 to non-0 transition so yeah, it can be driven directly from train~. Nice catch, the simpler the better!
I can’t find "shot~" in max/msp. It is an external ? Where can I find it ?
As stated before…
"You’ll need the [shot~ ] external by Andrew Benson. It just provides an easy way of generating a 0-1 ramp of variable duration from a click pulse. That’s a bit of a pain to do natively in msp :) You should d/l the rest of his objects from the share pages, they’re very useful for this sort of patch. http://www.cycling74.com/share.html"
Unfortunately, there seems to be no windows version of Andrew’s externals…
@Cheng – Here is an *almost* working shot-less version of the patch I posted before. You have to keep duration less than delay or it doesn’t work correctly………..like I said……..replicating AB’s externals natively is a bit of a pain :)
Tbh, it might be easier to just use Nathan Wolek’s grain.pulse~ external, because it does exactly what my patch does already. You just have to bear in mind that the pitch_mult parameter is your control over the read speed of the grain. It may not let you expand the concept of that kind of grain generator in the same ways, but if you simply want a stream of grains of x duration, x ms apart at x pitch, then it’s easier and more efficient to use the external.
Here you go anyway if you’re interested:
----------begin_max5_patcher---------- 1691.3oc4assbihCD8YmuBVdamxSVcgadp86XeI0TojMx1ZFrvKfSxLSM9ae AIvF4vEgCfw0lGvAI.c5i5tUqlle8vLykguQiMM9hwSFyl8qGlMSzTVCyxOe l4NxaqBHwhKyLdU3d5Qy4xt1SRVskw27bDcUh7wf7.OBla.8rE+fAm9w3q42 EyW7nBW9sOCscKdV7C6X7.ZhXbPmaL7PRQqfrF+8COjcXtl.lSeMcfJFjD5a BbZt2X6NweE8rNjmDy9IMqWHJEzxlkidxO1SkhmYLaCmDXdRXpfBftRY2Q9C vJ6GDrNFvoLD3jchQx7enQ9DNoCrCrLhnQ4bRNoj9zYAzWnQwrPdoqdlYIbC wNYP0B6IPrbtCaaeF4or8lfvUemJD.PQi9z0c7wjpEwOeKhqP4f5Ux36inwT dBIIG9kGZxgfjmqd9Ss+0jUzZu4ZX9YlahX9g7LXnbuYMWLfOYHlpUjPQ+bx 9Jt0jvvfkjnWXwrkATkYiTkYBmsijPSXR7f.mtO1t8QLdhxyhxIoOiswqhBC BTdTxddohd7ouvVQek4mrU7rNyVJ9CJo8nXlozdSlaplbIQDF+nALc7rKeA0 Ly0j02bCykD9lSVg0ZIJ89fDyNdKtzN7c1h.mKAVcZEuylDq1QI6RTQGBOWx +Yd+Su+0wOHo1FYZIXwEhiXzi1swkvqlKQ0xkvwgK+iAmLgfNwl1n6Wx7SiD WlalaiakLuu0LSkW.XnoTKvY0SYbLMxnf6WFMkQFGOmxiX21HSKuqlLg+OfL yUM0lMcueYyMogAN7NOELX9t1fVsZp6c+ZpmFK9FQ.nFvwYIIjsfV8bZkUWL .AdNRr5mGo02QH4FIac8cm6302iIaGb5TxivERcyVs3ctii8b+VRbXzwwxdG 5H3TWbqbJdhyohwyrIlYcPHIQyPexWjwt3XsaZzFWqbCpWtK0ypvc6nxTjXZ NA4i7nWzmPrlnDhb3L0I3Br9Rq8UDLFnCR64zyEv30koKgfj0e0zPb3gnUEy 5mRajgpT4SiSX7Soq7oytRSi+n7Etk46qldPobDDFojaTDFhcwo2sP84BNbG yeeHimjKPvEYKQBsEoU.tv5zYFeUKMftR.YwXqk7msOwKtvAQ9sDDP9qf37I Cj3WgTUi3C0b5+B44VOsIxk2Xn2VddyQ71CFvosr8Y2AwuipsP0WoQKR9seF 14FXYNzFlUMw0j7OcLMyx2q9tT.SGWJ5ZSUg.1ylT1hk8xeUrvSmbyWBDM9t Rgng1WZV9KzS78lT1YN55fnBA7lhartQbNs7O3f5Btg2g7MZRw25u0DauQI. fgx+it1wULQdSmer0UwxxahAbKcAt6jB31ZG0eVxH5Mfm2XpDHKRqXxKT+mS GG5pjmIIIQrkGRjIjPonsznplpsvkZqznZtpmBBWRBxqkrSWkoVkUkRiOblI 5Xo6UjLmKqcuuSo6M7ODIlwL9aCeZ.4GOp725vHCd3qmN23K+YKE5WC0wmL2 tXfcy0wGpy0wGr2pxw5nJA0zcIGixqdS4KtF2jfaY2WxcAdJUpekvj2BAL7f pkI3UPVqCBSG4tV3mx76dYkmUYIv5.JwdNMV9mVNWM6k1DaWpbTtB9trzyZg Ry2WvGmRqU+6PT209PJZeXXi7GZbz9f.njq.Sd0uB2VR5S9Fnqk9rtgpeKb5 KJslh71Od+wtq9IsZkEYBpQW9cl6.CdYsmUgCCPIsm6QyUCUpz8BzYdAWcAs 2e7xmNZfFNZQRHVsPKn9pN+6Q0E4qGe3XFombGXyLCb5wLKOrdMM5nwlrhV2 HKF3vzvNejvVObNtcJ8pggNKZjyPd8z5dn9iydMcOMGMdkw8Cec39rZPfbZp QkJOvzyITgNkjgL1R37gVYBm+JPaz0j6hantzlrOJDyVTKlmU.FIZHuHa6yh sWMezYtvN3SA0iQCuNh9uWw1Pke.URsebi6lvw4FtGz5BBir5JBBKW8Muxoa zTGunmV9.zmwaLXqoV78z8tuYDENwa5sjpb4AwBpCG4HWbvysQElaY.pC8t+ bJ4rvsQ29H2anae5OK6WntcgAKUp+V10EJzUZhKdXp0AlD4WlR4b7WQNvUd4 J0lGYkDf+9bHWc9ieGepKprrzBTNiKnbzFTvQCT5M+4AFUl5hgqZLg85FQA8 D0+Pdh07j4yEYWa1VzErtPc.6hQk.0GSimlF1SCLcAvGbL4pqh13gIjNXRju fQDTP8XJ2QFTHsnpwFUPsPE5CfpzS98C+G3Txb1. -----------end_max5_patcher-----------
I haven’t looked at the patch, but if you don’t need uninteruptable output from the shot~ object, I think rampsmooth~ works just as well.
haha, rampsmooth~ would have been a much easier way of doing it I think! One day I’ll learn not to do things the hard way :)
Although with rampsmooth~ you’re limited, because you can’t control the grain duration at audio rate.