Sound picker & player w/ poly~

kp*'s icon

I have this patch that loads a folder of sounds and then groups them into 6 groups. It then picks a group and then picks a sample from that group. This works great if i just plug it into sfplay~.

My problem is that i know in some cases i will be triggering another sample before the current one ends. Enter poly~

But now this sucker doesn't work. Clearly it is a problem inside of my poly patcher, but i have tried lots of things and cannot get it to work. Furthermore, i am worried that it wont work in all cases. So do we have what obama would call a teachable moment? What is being fed into poly~ how should that be parsed so that sfplay and mute get all the info they need... what is it that i am not getting here? Perhaps I just need another pair of eyes but frustration is setting in as i know i am one or two boxes or one misunderstanding away from a clear and functioning patch.

I have simplified this patch for the sake of the this query.

I am sure it is the input to poly... but i dont see it.

cheers,
kevin

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

Eli's icon

You're on the right track- continue to look at the [poly~] help file, and take a look at the "target" message. You could use the "target" message (send "open 1.aif" to the [sfplay~] in instance 1 of the poly, then "open 2.aif" to instance 2, etc.) in order to load 16 different audio files into the 16 instances of the [poly~] in your patch.
Think of each [poly~] instance as a handbell- while it's still "ringing" (playing your sound file) you need to have access to other handbells (other sound files) in order to ring multiple bells (have multiple sound files overlapping, polyphony).

Eli

kp*'s icon

okay... got that working, but it turns out to be less than ideal since it is sending an open message to sfplay~ and then triggering the sample is throwing off my timing.

So i have a crapload of files. All these files are edited and organized into folders. I want to be able to point max to the folder & have it load a buffer for each sample in the directory. Since then we wont be dynamically opening and reading off the disk, the patch should play back really speedy, since it just holds the samples in memory.....

Problem is i have tons and tons of short, perfectly manicured little samples. So doing and read message and named buffer~ for each one of those is gonna be a mother of a task. It would be hundreds of copying and editing the same messages over and over.

Read foo1.aif --> buffer~ foo1
Read foo2.aif --> buffer~ foo2

Plus.... if i then change the contents of that folder by adding/deleting/editing any of those samples I have to go through each buffer and tweak.

How would you autoload a whole folder of files by file type (actually i already know how to do that part with an umenu and prefix) and then pack that into a list that, get the length of that list and stuff each .aif file into a buffer?

In Python that is trivial. It is three lines of code (four if you include the import statement):

So if i have a dir of fluttery sounds, i can have a bunch of sounds in there:
01.aif
02.aif
03.aif ..... etc.

but i can slurp them all down with something like this:

flutter = '/Users/kevin/snd/01/flutter'
pth1 = flutter
samps = [os.path.join(pth1, f) for f in os.listdir(pth1) if f.endswith('.aif')]

boom.. now i can just grab the samp i want by indexing my list.

What is the max idiom for this? I get how to point it to a directory and recognize what files I want, but then how do i get it to pack those into a list and dynamically make and name a buffer for each sample.

Luke Hall's icon

Again you can use [poly~] for this. Check out the example patches below which I sometimes use for preloading samples ready for use. All you need to do is work out how many samples you want to load, then send that as an argument to the "voices" message to [poly~] so it will create that many buffers. Then send "target , replace " for each filename. Then you can access them by the order you loaded the files, for example the first sound will be in [buffer~ buffer1] etc...

lh

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

kp*'s icon

Thanks... I was working on something kind of kludgy using umenu prefix and getting the dump out of the umenu and shoving that into to route and counter... something embarrassing like:

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

I'll study your solution as well. I like little bits of code i can put some prints on/ read the help and comment up.

You could see i was sniffing in some of the right directions.

kinda
sorta

Thanks,

-kp--

Luke Hall's icon

It looks like you had the right idea. Try to work your way through the patch I posted, check out the helpfiles and reference pages for any objects/messages you aren't sure with and put in some [print]s to see what is going on. If you're unsure of anything just let me know and I'll comment it step by step to help you understand. Enjoy!

lh

kp*'s icon

Thanks. I am going to work through that soup to nuts and I'll be back with any questions i might have. But... after a long day of maxing i am maxed out... It's 4 am here, so i'll have more learning to do tomorrow.

kp*'s icon

okay... I think i see how most of this works.

You bang open a dialog box which then adds the path for your soundfile directory to the umenu. You used the same route populate biz i used but instead of counter you used uzi and got a flurry of bangs, one for each element in our umenu, and then you configure the poly by appending target, etc.

In the actual poly is where i get a real murky.

Are we using poly here to switch buffers.. or did we just use poly to dynamically create a buffer for each sound file? Also unclear to me is how this can all be plugged into groove and if groove should be in or out of the poly. I would have expected groove~ to be the Ugen in poly~ unless i misunderstand what is happening here.

If poly is used here to make a bunch of buffers... how then do we call those buffers with groove~ since groove is set with set but we need to say set buffer0 and set buffer25 (that's what the sprintf%d thing does right?)... but using prepend and tosymbol still yields set buffer 1, set buffer 2, with the space, which is not going to be okay with groove... I am guessing that all this is just wrong that what we have to do is set groove~ outised the poly~ and poly is swapping the buffer contents? if this is so, is this not the same as sending open to sfplay~ in that there will be a delay as the buffer loads?

somewhat confused now.

-k

justin's icon

you may be better off using the sflist~ object to allocate each file to a certain cue (outside of poly). then using sfplay~ within poly to trigger the correct cue. FYI, sflist enables u to preload cues for sfplay... but YMMV

BTW, "sprintf buffer%ld" is the only way to get buffer0 (without a space!) -- sprintf is a very useful object for formatting strings!

hth,

j

kp*'s icon

Yes.. The joys of sprintf so handy, as it is in C and Python... That actually works if i just use sprintf instead of prepend.... so this sucka *nearly* works~

kp*'s icon

Additionally, if one were to put a groove inside a poly~ how do you send the mute 1, 0 & mute 0, 1 messages to thispoly~ to free the voice? sfplay has the bangwhendone biz on the last outlet so you just bang a mute on the way in and bang a mute off the last outlet of sfplay to free the voice, but groove~ doesn't have a band when done. I know there you can just send that last outlet to mute and when the amplitude goes down to 0 it will free like in the littlesynth example, but what if you have silences in your buffers? won't that trip up your poly~ and free the voice too soon?

-kp

kp*'s icon
Max Patch
Copy patch and select New From Clipboard in Max.

kp*'s icon

Grrr.... I am still really stuck. Closer, but really stuck.

I am still not quite sure how to parse and route those messages into my poly~ so that buffer~, poly~, & groove~ are all getting what they need on the initial loadup and then on play at the right time. I feel like i am getting close. I got some good advice that i only part ways understood.... But wow is this a crazy hard task my head is spinning.

Pardon the insane amount of commenting. I am trying to keep this all straight in my head.

ANY HELP/TIPS/SPOON FEEDING ... would be really appreciated. I feel like i been stuck in the mud for a while now and would really really really like to get this working so i can get on to other parts of my projects. This takes like a dozen lines to do in cmix, but i really want to be able to do this in real time with the innnnnnerfaces that max provides, i also want good timing since i am doing some rhythmic stuff so that is why i am stubborn about using groove and buffer even though i had this working using sfplay.

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

Luke Hall's icon

I haven't looked at your recent attempts because I'm in a bit of a rush but I will do later. I use this patch only to load sound files into the [buffer~]s. Then I use [groove~] elsewhere in my patch to refer to one of these buffers using the index number. It wouldn't be too difficult to name the buffer after the sound file if that makes it easier for you.

lh

kp*'s icon

thereishopeforus@hotmail.com wrote on Fri, 14 August 2009 19:23I haven't looked at your recent attempts because I'm in a bit of a rush but I will do later. I use this patch only to load sound files into the [buffer~]s. Then I use [groove~] elsewhere in my patch to refer to one of these buffers using the index number. It wouldn't be too difficult to name the buffer after the sound file if that makes it easier for you.

lh

Actually that idea was one of the few notions that i did grok, but i am still fuzzy on the details of integrating this now with selection and playback. If you look (please don't haha) at the history of my mad attempts you see how confused I am about how to integrate groove~ i tried it outside the poly, in it's own poly and now trying to put it in the poly with buffer (which is where i had it to begin with) .... not quite sure how to handle note $1

Googling around the forum shows that this is a common source of confusion that comes up again and again and again. If you search for poly groove and buffer you get lots of folks trying to grasp how they all play together to create, essentially, a polyphonic sampler. They want to play trigger a sample somehow, have it play all the way to the end and be able to trigger other samples while they other are still ringing away. I've searched dozens of times hoping that there would be a working idiom, or an example that i could crib, scaffold and comment up.

kp*'s icon

One small benefit of posting my broken code here is that while still banging my head against the wall and getting nowhere fast I somehow screwed up my patch so bad that Max now says:

Error parsing patcher file .... etc.

and won't open my patch at all now. Max is revolting against its owner like the characters in a Flann O'Brian novel.

However, It just occurred to me that I posted my embarrassing patch here and just copied it from above to get most of it back (more or less trading today's headaches and broken bits for yesterdays).

kp*'s icon

While I wait and pray for some help on my buffer~ groove~ poly~ query... I been going back to first principles, reading help patchers and toots and mucking around... Here is a pea shooter hard wired simple sample player

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

kp*'s icon

Here is one that uses groove~ instead of play~ ... again no poly and no autoloader code... just doing this b/c i am so painfully stuck on that patch that i just though i would muck around one piece at a time.

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

.... so i got groove~ working. The autoloader thing works thanks to the help i have already received. (thank you thank you!). I also got poly working in the original sfplay~.... I just need to see if i can get them all working together now. I know it is just a matter of figuring where groove & buffer go, and then passing, routing and parsing the info correctly to and from poly~

kp*'s icon

SO now the trick would be to take the handwired bullshit and stuff into the a poly~ and get that working. Groove doesn't have a bang when done to free the voice so you have to jigger that (which i have in here)... and you need to take your list and prepend note before you send it in to poly~ I did that.

It doesn't work. So here is one area where i am confused. I feel like i am one box or one message away from getting groove and poly to work... if i get that i am half way there. Then i just have to integrate the autoloadeder code.

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

kp*'s icon

Still doesn't quite work.. I found one problem. I was using delta and edge to detect when a sample was playing to send the mute messages, but had my mute 0 and mute 1 flip flopped.

Additionally one area i don't quite get since the toots all use midi to trigger a sample is, when no midi is involved, what meaning does note or midinote have if you are just algorhytmically triggering samples sans midi or faux midi input. I suspect one problem with my patch, is that following greg's advice on another thread, i am packing everything into a list and using one input to the poly... but the first thing in my list is a 0.0 start time which triggers the sample. If i prepend the note message i get a list that starts note 0.0 .... which prolly is not cool.

Anyway here is where i am at.

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

kp*'s icon

getting so close with this.... I couldn't get note to work, nor understand why or how to use note or midinote .... i've worked out a strategy just assigning target by hand using a counter.

Now i am sending counter --> target $1 & my params list to poly.. not yet working but close.

cycling '74 should really redo these poly toots. Tons of stuff is not covered at all. Max is famous for it's great docs, but the docs and toots on poly are somewhat terse...

back to work... since no one is helping me i just might get this on my own.... tho a little help would be awesome as i am soooo tantalizingly close

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

kp*'s icon

Okay.. groove finally works with poly, now using target. I only had 2 problems above: my dac was disconnected and i didn't know it & I forgot that once you use target you need to skip that whole edge mute unmute bullshit... ugh.. so much not explicit in those toots.

This works, but what is left is to un-hardwire the buffer so that i can pick and play different samps

Figure out how to get the autoloader thing integrated....

but really.. it took way too long to get poly to work with groove and buffer partially cause i am fucking stupid.. but only partially....

tomorrow's another day

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

kp*'s icon

I got this a step further.... getting groove to work with different buffers.... The params to groove are just hard wired for now ... I also just added 6 sounds from the /Applications/Max5/examples/sounds/ directory so that any one with max can test this out without having to load samples...

So the only thing left is to integrate the sound file folder autoloader code... which is actually a bit confusing 2 me.

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

kp*'s icon

okay ... got some problems to work out here... I am hoping that mr.thereishopeforus will chime in. paging mr.thereishopeforus!

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

Luke Hall's icon

What exactly are the problems and what are you trying to achieve? It doesn't look like a simple sample player due to the looping features you have included. What exactly are you going to use it for?

lh

kp*'s icon

Here is what i am trying to do

Load a crapload of short(ish) files into buffers. Mostly small files that I have recorded and perfectly and lovingly manicured.
I am using buffers instead of sfplay~ (which is what i started with) because that prooved to be too slow is throwing off my timing.

Since i have a ton of small edited files, i don't want to have to load the buffers by hand and i don't want to have to type them in by hand.
Hence the help on the autoloader patch you helped me with.

So i want to be able to organize all my little sounds into directories and eventually point my patch to that directory and have the patch down all the aif files it finds into buffers. Then i want to algorhythmically pick and play my sounds. Some sounds at regular speed/pitch some shifted, some reverse, not likely any looping. Just algo pick and play. I have my dirs all ordered according to morphology (etc.) and i want to (over time) grab some from here, mix in some from there ... etc. Right now it is all just random to get the playback engine working polyphonically.

kp*'s icon

So if you see message #179385 you can see i got this far piece by piece and in message #179385 i got groove~ buffer~ and poly~ to work with a limited number of hardwired samples so that no matter how fast i pick sounds nothing gets cut off and everything more or less works even if it is kind of all hard wired in there in a silly way. Now what i am trying to do is get it so that i can play play from a whole directory of sounds without (my original query) having to type in a whole bunch of buffers by hand. That is what you patch allows, but i can't get that working with what i have got as i am unsure how the pieces fit together. In my last example i attempted to put the groove in the poly with the buffer. While that makes sound, it doesn't seem to be triggering the right thing and poly is not letting sounds ring, it is cutting them off.

In short I want to say load up these hundreds of tiny little files... for the first few minutes i will algorhytmically pick from a certain group of samples... then i might mix in a few of the next group.. then move on to group three for some amount of time, etc... The reason for buffer is that calling sfplay to load then play a sound was putting my timing off and i also have some temporal/cannonic/ thingy happening rhytmically with multiple transports. That all works so i took it out and dumbed my patch down just to get poly to work.

I am dumb.. but i am pretty darn proud that i figured out to use target instead of note and to use a counter to set the target and get all that prepended before and parsed after with just one inlet.... I just can't figure out how the pieces fit together with poly.

sorry if that is not clear.

cheers~

Nathan Bowen's icon
Nathan Bowen's icon

Sorry to pick up an old thread here, but I've found this to be really similar to something I'm doing, and quite helpful. BUT, I have an issue, specifically with combining poly~ and umenu. I've been looking closely at Luke Hall's code posted above (reposted here, but with my additional code in red; I've attached the same as patches).

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

Luke: Isn't there an issue with poly~ creating instances starting at 1 and the umenu starting at 0? The reason I ask is that I added a folder of .aif files, started playing through them, but can't get the first umenu item (0) to play. In poly~ isn't the 0 message usually reserved for sending something to all instances? I don't think there's an instance 0 permitting a buffer0 name.

2348.lh.autobuf.maxpat
Max Patch