poly~, midinote and voice stealing

Sep 11, 2009 at 1:27pm

poly~, midinote and voice stealing

Hello,

I’m new to the forum – so hello everybody – and new to max/msp… but i’ve spent some intensive time learning it recently.

I’ve come across a problem I can’t get around, concerning the combination of poly~, midinote and voice stealing. Pasted below is an example patch of my situation. In the main patch, there are two examples side by side: a poly using note to trigger events and the same poly but using midinote to trigger events. I’m looking into using midinote because I’d like to add velocity control for each event. But I’d also like to have voice stealing enabled. When using note there is no problem; one can fire many overlapping instances. But with midinote and voice stealing it only fires once and the next (overlapping) trigger steals the first even with the poly set to 6 voices. Is there any way around this? Or another way than midinote for passing velocity info with each trigger?

Any help to understand the problem and to get around it is greatly appreciated.

So here’s my main patch:

– Pasted Max Patch, click to expand. –

And here’s the related poly~ called my_poly.maxpat:

– Pasted Max Patch, click to expand. –

Thanks so much.

Best regards,

antwan

#45428
Sep 11, 2009 at 1:40pm

The problem is that you repeatedly send the same midinote (1). It is like hitting a piano key before releasing it. Although I would agree that something like that should be possible in a virtual environment, at the same time I can imagine that the voice allocation method of poly would have difficulty in determining which note number 1 to turn of.

_
johan

#163781
Sep 11, 2009 at 1:58pm

Hi jvkr,

And thanks for your reply!
Yes I kind of understand the logic… but on the other hand I find the logic to be the same as when using “note”. Also in that case I’m sending many note 1′s in a row.
In addition, with voice stealing off it also works fine with midinote. So my logic would say: with voice stealing on, it would otherwise work exactly as with voice stealing off… except that when it reaches the limit of voices, it steals the oldest voice rather than ignoring the trigger.

antwan

#163782
Sep 12, 2009 at 3:33pm

So…
Although I can’t quite understand why note and midinote must deal with voice stealing in a different manner, I had to move on, so to get my volume information to the correct instance (and later on additional data) I manufactured this little hack around the problem. I thought perhaps it’s of some use to someone, so I’ll post it here.

But more importantly I’d like to hear any comments people might have about my workaround. Are there any pitfalls with my approach that I’m not seeing? Are there any neater way around the problem, that you might have come across?

Thanks,

antwan

Here’s the new main patch:

– Pasted Max Patch, click to expand. –

And here’s the new my_poly.maxpat

– Pasted Max Patch, click to expand. –
#163783
Sep 12, 2009 at 5:11pm

without looking at the programming (mainly because some of these details are obfusciated for the user), let’s just look at the process.

take the following example message:

[midinote 60 120]

when you send a midinote message as such to poly~, poly~ receives a general message “midinote”. then it tells poly~ that there is an ID for this message, which is actually the MIDI pitch itself. the third message is the velocity.

pretty simple.

where it gets tricky is that poly~ can have N number of voices, and any given voice can be playing at the time when you send this note. basically, the ID is used to match the PITCH value with a given VOICE that may be playing. if there is no voice that corresponds to the midi pitch ’60′, then a new voice is created (if it is available), and that new voice now will correspond to the midinote 60. the other thing that should be noted here is that can notify that voice that it could be “marked as busy”. i’ll get to this later, as we don’t have to do this; it’s just an option.

if there is already a voice in use that corresponds to the pitch 60, then that voice will be re-triggered again (just as it would on a regular synth keyboard).

now let’s look at one more message:

[midinote 60 0]

let’s assume in this case that there IS already a voice that’s playing midinote 60. what will happen now is the exact same thing: the voice will be found and the note will be made at the voice. but because the velocity is zero, we know that we can internally shut this voice off. we also know that we can use that zero to effectively trigger the amplitude to zero.

where voice stealing comes in is when you want to only use let’s say, 8 voices.
at some point you might play more notes than you have voices, so if you have the busy state set, when a new 9th note is played you can tell the *oldest* playing voice to kill itself and allow the new note to come in on that voice.
* look at the last bit, where we play a note at zero velocity… this is where the busy state could come in handy. (for info about busy state check out thispoly~)

does this clarify things?
jml

#163784
Sep 12, 2009 at 5:34pm

So if I understand correctly, your ultimate goal is to have multiple instances of the same sample playing simultaneously, at the same pitch/speed but at different velocities?

In your patch, the midi pitch that you send to poly~ does not change the pitch of the sample, so you could just use a counter object to cycle through 6 different “pitches” so that poly~ will send the notes to separate voices, causing them to overlap.

#163785
Sep 12, 2009 at 7:41pm

try using the poly object with the target message(not the poly~ object)

#163786
Sep 12, 2009 at 10:26pm

Why not just use the target message with poly~? This way you can set up your own voice management. I dont know why it would be necessary to use poly (no tilde) instead.

#163787
Sep 12, 2009 at 10:36pm
Matthew Aidekman wrote on Sat, 12 September 2009 21:41
try using the poly object with the target message(not the poly~ object)

exactly.

the only reason not to use “target” is when actually want a
“not voice stealing” mode in your generator.

that would be difficult because the poly would have to tell the
outside world about its busy voices in that case.
Smile

#163788
Sep 13, 2009 at 6:44am
Quote:
Yes I kind of understand the logic… but on the other hand I find the logic to be the same as when using “note”.

The note messages doesn’t need to keep a record of which notes have been sent where, because these notes are not turned off.

The fact that it works with midinote without stealing might be because another routine is used to distribute the notes (no check needs to be performed). This is something that the programmer(s) of the object can only tell. Apparently it does stealing in a different way from poly.

I remember having programmed once my own voice allocation method because I wanted to have control over the order in which identical notes are stolen. The poly object steals in the order in which they are assigned, I wanted inverse order. Also I wanted to be able to transpose with keys pressed.

_
johan

#163789
Sep 13, 2009 at 9:25am

Hi everyone,

Thanks for the wide range of replies. It also made me realize I might have not been clear enough about all that I’m battling with. Not to myself and not to all of you. The problem was two-fold:
a) to find the most suitable voice allocation automation
b) to find a way to send multiple parameters (f.ex. volume, pitch, pan, start pos, end pos) unique to each fired “note” – a way that works together with the chosen voice allocation method

I found, by means of a lucky trial, a solution to both my problems.

So, I needed to have voice allocation based on the busy state. This was mainly due to two things:
- First of all, in my poly-patch I am specifically dealing with voice stealing by identifying that it is in fact a steal incoming, then applying a little volume duck before triggering the new voice. Never actually freeing the busy state in that case until the sample reaches the end without a steal.
- Also, as soon as I decide to add for example pitch shifting of the sample it affects the length of the playback. Hence some instances it might be able to free sooner, some later. And only poly~ knows when it’s done with it.

Since “note” worked for me as an allocation method, with voice stealing on or not, I worked from there and just now noticed something I hadn’t come across: that the note-message can in fact have as many supplementary arguments I want and they all get passed to the chosen instance/voice.
So sending something like “note 1 0.8 0.6″ works fine!
“note” takes care of the voice allocation; chooses the first free voice or the oldest busy voice and “1 0.8 0.6″ is passed into the chosen poly~ instance. This I didn’t know before I gave it a shot.

Thanks for all the help, people!
And perhaps this is new information also to some other poor soul out there.

antwan

#163790
Sep 13, 2009 at 6:55pm
antwan wrote on Sun, 13 September 2009 05:25
just now noticed something I hadn’t come across: that the note-message can in fact have as many supplementary arguments I want and they all get passed to the chosen instance/voice.
So sending something like “note 1 0.8 0.6″ works fine!
“note” takes care of the voice allocation; chooses the first free voice or the oldest busy voice and “1 0.8 0.6″ is passed into the chosen poly~ instance. This I didn’t know before I gave it a shot.

For the record, midinote also does this.

#163791

You must be logged in to reply to this topic.