List Processing Help

noiseandrones's icon

Hi there,

I'm currently working on a sampler.

There is an individual sample for each MIDI note, split by frequency.

Instead of using lots of split objects, I thought I would use coll.

The patch takes a frequency input, and the idea is that for every frequency 'query' the patch will scan through the list in coll, and produce a lower and upper boundary for each sample, via split.

So, for instance, if between 32.7 and 34.649 Hz - buf pianosamps1 will be triggered.

If between 34.65 and 36.7, buf pianosamps 2 will be triggered.

I don't seem to be able to make this work and I think it's some minor syntax error.

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

Source Audio's icon

this can not work at all like this, because
you send float through split before uzi start recalling
range values.
here is a bit simpler construct, I am not sure if it will work well,
depends on speed of input and all the rest

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


noiseandrones's icon

Thank you for this. It's a tricky one. This seems to work but for some reason, to respond, it requires two bangs or enter clicks on the floating point box at the top. I'm trying to work it out.

Source Audio's icon

try this, but watch for repeated ouput

zl.change shoud prevent it, but you need to reset it wih zlclear message to pass same input again using some interv, now set to 10 ms.
dealing with foats like this is allways tricky.

are you using microtunning or smething else that forces you to use frequency instead of midi notes ?

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

noiseandrones's icon

This seems to work much better. Yes I am indeed working with microtones - I just thought that coll was a more efficient method than stringing together a bunch of split objects, which was very inefficient!

noiseandrones's icon

Thanks again!

noiseandrones's icon

I would be curious to know if there was a version of my original patch that could have worked. I tried all sorts of things to ensure all the values were being sent together (after removing the original float mistake). Anyway, it's a fun exercise to wake my brain up! :)

MakePatchesNotWar's icon

Tsk tsk Sourceaudio... As a crusader of the Order for the Benefit of Aesthetic Patching it is my duty to object any use of ugly objects such as [del] to control dataflow.

Sorry the message is in jest ofcourse but [del] is just plain ugly. I just can't sugarcoat that...

I still love you and everyone else as well ofcourse (well not everyone, some people are just evil)

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

MakePatchesNotWar's icon

"I would be curious to know if there was a version of my original patch that could have worked. I tried all sorts of things to ensure all the values were being sent together"

Fixed, i think? I've added some objects. The problem was that the trigger before uzi would bang all entries for coll which in turn filled split with all available entries as well. And this all happened before it received the float to compare to split. I think that covered it?


<Edit> ""And this all happened before it received the float to compare to split."

Not true, trying to work out whats really going on

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

MakePatchesNotWar's icon

Ok, so i figured it out... I was confused and for a moment thought that split would function without a specific hot inlet but it doesn't. This explains why only the last entry of coll is output because uzi makes coll go through all values but doesn't trigger split so only the last entry remains. So when you input a new value it only compares itself to the last entry of coll and go through the cycle again.
If you reboot the patch for example split won't output anything on its first input. You can plug in a print object to check.

<Edit> Right, Sourceaudio had it covered all along. I apologize [del] must've blinded me lol
"this can not work at all like this, because you send float through split before uzi start recalling range values."

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

noiseandrones's icon

Thanks for your help everyone.

I seem to have a weird bug - when I upload my full coll list (88 entries), *all* of the patches stop responding when I change the float box at the top. I have no idea why. Is there anything I am missing?

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

noiseandrones's icon

(I have tried inserting the full coll list into all of the solutions presented).

noiseandrones's icon

More specifically, I don't seem to be getting any output from the 'if' object after loading in new coll info. Is this a bug?

MakePatchesNotWar's icon

"More specifically, I don't seem to be getting any output from the 'if' object after loading in new coll info. Is this a bug?"

Yeah, same here no idea why. This works though

<Edit> probably because you filled the coll in the wrong order... lol

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

noiseandrones's icon

Well, funny story - I was halfway through entering the values manually and decided I'd use uzi and unpack to fill it instead. Perhaps this is where it all went horribly wrong? Bizarre.

noiseandrones's icon

Thanks again, by the way :)

noiseandrones's icon

With respect to filling a coll - I know that lots of people would do so using uzi directly, right? I mean, surely people aren't sitting there manually filling tables out? Is there a better way of doing it? For instance, creating a list and then using zl.iter + uzi or something?

MakePatchesNotWar's icon

"This works though"

Spoke too soon! I'll look into it later!

noiseandrones's icon

I think I may have made a stupid mistake in the coll, actually. I'll fix it and report back :)

Roman Thilenius's icon

i still dont see how coll could help with the recognisation of an incoming float range.

at one point you just have to make e.g. 127 connections out of 1.

if under overdrive condition 127 split objects are too expensive, you might try to find externals which can split more than 2 ranges at once "inside".

for example (and now the unavoidable follows...) you could use expr to turn up to 8 float ranges into ints/different connections (where split would only give you 1)

[expr (($f1>=32.7)&&($f1<34.65))*1 + (($f1>=34.65)&&($f1<36.7))*2 + ..... + (($f1<32.7)&&($f1>=36.7))*$f1]

and if required [select 1 2 3 4 5 6 7 8]

and the last outlet is "if it is outside these ranges" just as with split, where you can add additional expr here for the next 8 ranges.

and as always, if the scale is repetive across octaves, you can of course convert the hertz into notenumbers and then split these linear frequency values into octave and offset first, then all arguments are the same for each octave splitting.

[110.multisplit 32.7 34.65 36.7 ...], [110.multisplit 32.7 34.65 36.7 ...], [110.multisplit 32.7 34.65 36.7 ...]

noiseandrones's icon

Hi Roman,

It was really an 'elegance' thing more than anything - I did build something of this with multiple split objects but I thought it was very unwieldy, and thought that coll would be more efficient (not to mention less labour-intensive).

MakePatchesNotWar's icon

This... works? I reversed the order of coll because it made a mess of triggering before so it was outputting double values (and indeed used uzi to reverse the coll :) i also left out the integer because you can just use the index from coll itself for that.

I must say that i'm not a fan of the uzi/coll solution either but i can't think of a good alternative

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

Source Audio's icon

In patches like this, one should take into account what is the input and what is the output.
mouse driven gui object is different thing than note input from keyboard or sequencer, or uzi, whatever.
delay to reset zl.change is there to allow output of same float input
if it came in so, but to avoid false retrigger.
can you play same note in shorter interval than 10 ms ?
remove it and you are in shit, as seen in max console.

but - one does not really need to make a list of float and detected range.
float input can travel alone, and sample selection can serve as gate or anything else, again taking care of proper timing.

zl.change can prevent resending of same sample selection, in case it makes sense.


if coll or anything else is better to split 88 float ranges ?
don't know.
P.S. if there is no need to limit coll output to 88 or any other number of lines, then one can replace uzi with dump message to coll.

noiseandrones's icon

Thanks again for your help.

I have a quick (I hope) additional question.

This is the patch in context.

At the top right is a list of microtonal frequencies which plugs into the algorithm discussed yesterday - this selects the appropriate sample for each frequency.

At the same time, I need to send a transposition value for each sample to an instance of poly~ grainflowmodule. This transposition is accomplished via the expression subpatch.

The subpatch needs to receive the 'desired' frequency (from the list at the top right), and the equally tempered frequency (taken from the first term of each coll entry). I used a second, identical coll to do this, using what I believe to be the current coll index from the main coll - so index 27 yields 146.83 Hz, for instance.

I seem to have a problem where expression is only outputting six instances of the same value, rather than multiple values. I haven't yet figured out what is going wrong.

I also thought that using poly to control voice management to the poly~ was a good idea, but perhaps I should use target?

So, in short - the poly~ grainflow needs to receive an instance instruction, the sample (buf pianosamps), and the appropriate transposition value.

Can anyone help? I'm too close to it to be able to debug this properly, and I'm sure it's something simple.

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

Source Audio's icon

I will take time to properly read your patch later,
but first look allready shows a problem:

look at the output from your comprison (red message)


Sébastien Gay's icon

Back to the first discussion, why not using poly to solve the parallel/sequential data flows issue ?
For instance:

MAIN patch :

and POLY:

MAIN.zip
application/zip 2.57 KB

noiseandrones's icon

That would *never* have occurred to me!

Source Audio's icon

I'd say this last pach you posted is making no sense to me.
"At the top right is a list of microtonal frequencies which plugs into the algorithm discussed yesterday - this selects the appropriate sample for each frequency."
no it does not. that has been discussed and solved in previous patches, no matter if for single input or a list.

here is a patch that runs input list through range selector,
and makes 3 lists -
1- transpose factor list (if I undersand it correctly)
2- "desired" frequencies list
3- sample select list
-----
you pick what you need from that to feed next stages

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





noiseandrones's icon

Thank you so much for this - I'm grateful for the assistance!

noiseandrones's icon

Sorry to bother everyone again.

I have a quick question about the final logic in this patch.

I need to send the poly~ object three messages - the transposition value, a buffer number, and a target index (this is organised such that the poly~ will always populate sequentially, from voice 1, to voice 16).

For some reason, I am getting lots of duplicated values (outputs to the three message boxes, bottom left). Where am I going wrong? I think on a good day I'd be able to crack this quickly, but perhaps I need more coffee!

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

noiseandrones's icon

Thanks again, in advance.

noiseandrones's icon

I think this is kind of working, but not 100% sure it's the best way.

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

noiseandrones's icon

It's alive!

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

Source Audio's icon

3 messages to poly object - I am sure can be done in easier way.
But - for me the question is what is expected input ?
let me detail my question - you have 88 freq ranges,
and have to assign 16 poly voices, depending on what ?
Your input is unknown variable, it could have several freqs
in same range, which would use several voices for same quantized
frequency and sample selection, right ?

if you decie that 1 quantized frequency occupies 1 poly voice,
then you need to bundle it with sample selection.
If you think in midi terms, it is like 88 midi notes
and 16 voice polyphony, with voice stealing turned on.

so you could use sample selection as target,
or even as note, supplying transpose value.
see here, no double - no trouble...


put this into poly instance:

you need to take care about timing -
selecting buffer and transposing it, trigger playback etc.

------
when you post a patch containing poly~, poly voice subpatch can not be embedded into main patch, no one can see what is inside.




noiseandrones's icon

Hi Source Audio,

It's as you describe - one poly instance per pitch.

The idea (for now) is I send a list of frequencies - the closest equally tempered sample is selected for each one, and they are retuned.

I think, once again, you've arrived at a more elegant solution than me. It's been a while since I did anything involved with poly~.

The other thing that I've not yet done within the poly~ grainflow, but will need to do, is to fade out the output of unused each instance when a new list is received. In fact, the most 'ideal' thing might be to find a way of crossfading between each list, but I think that would require two playback engines per poly~ instance, and this patch is already extremely DSP hungry, so I haven't quite figured out how to do that in a way that won't crash my computer in a live context.

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

noiseandrones's icon

(I've attached the grainflow subpatch in the previous post).

Source Audio's icon

I looked into that patch you uploaded last.
Sorry, but I don't use that overcomplicated Ircam stuff,
simply have no nerves for it.

No wonder it uses too many cpu cycles.

if your input list is not exceeding 1/2 of 16 voices,
then use fade in/out on each list.
no need for duplicate poly~




noiseandrones's icon

'If your input list is not exceeding 1/2 of 16 voices, then use fade in/out on each list. no need for duplicate poly~' Unfortunately, it regularly will! I like Grainflow a lot because it manages to sound fairly natural for creating sustains, but that does come at a price. Thanks for your help again.