Adsr~ and muting issue
Something I’ve noticed in my poly~ patches is that when I first load them, all voices are on. I have thispoly~ connected to adsr~ in the standard way (including muting info), so it seems that what should happen is this:
all voices muted, envelopes off
but what I’m getting instead is:
all voices on, envelopes off
Using loadmess 0 doesn’t work, because adsr~ already thinks it’s off, so it doesn’t send the mute message again. (adsr~ only sends mute 1 messages once, though it sends mute 0 messages every time there’s an attack)
I can fix this by loadbanging a message box with "1, 0" going into adsr~, but this is a bit of a kluge because it involves turning everything on and then turning everything off, and this problem really shouldn’t require two states. I could loadmess the mute message into this poly~, but it would be nicer if adsr~ could handle this on its own.
----------begin_max5_patcher---------- 514.3oc0VFsaaCBEF9Z6mBFWsI4DAX6Zmocy1yvtapZhZnIrYCVFrZVqZe1m ArWbWccxRak7tv3vAB7e932.2EF.uRsmqgfOB9FHH3tvf.WHaff95AvJ59hR p10MXgpphKMvHeaF9diK9W2IzfaTM+TOzTM0TrSH298FdgwOEwoqQQ.LZi8U VrsjfVi.W1+WDL2Xot5GqvICiy0JoQRq3tl9bifVB9hpjMzrrsRHK4Fm7vGB pZMCQQiFIs3V2HgIqQ1n2GFZKhdgo+mVsZEPp.cyZcq4cf2ecipBT0Z5..vK kOLCXHoDKLxS8HYyrjgrHISEWqoa4OgL3H.ZHnelM+pl6SaH7OI3DPAiwirK wj0ocUxeFnfNGnPlDJ32dnbRDogq6rZTiPIGaUR73vYUP8Eygw3Xm2BiyNNF y+uhh3yyWQx1bx.IaQBDI+lNw8DdTpnLKqN6O3xPG1EJ6h41DJ80aOn2dtT2 HNrk8TFBjOW862DmMWhuLOVheKiV7vLoXR+QJtLLIcnbpLL9evS+JtHQY5lG dVeqVrURKgQi+k64D7y3KxO98MNqCUSmDJIGec0o.XoP92W9xkE13OFfZUaS w.KFNuCbHQXbc2MMbGULpSjG0mcBFiKGa7pDrZU2mF8Z.b4jqlmpjxWbJJaw onzEmhryF4HJJ4EnntJ2G9a.+qy1BC -----------end_max5_patcher-----------
Why not just directly hit thispoly~ with an initialization message, and not rely on adar~ to set the initial state?
Of course that’s doable, but if a poly~ voice of a synth isn’t producing any sound, it would generally also make sense for it to be muted, and since adsr~ is supposed to take care of the mute state automagically, it would make sense that those two things go together.
There’s very few use cases where you want no output but signal processing, and far more where you need output and muting alternately. I’m just saying that it makes much more sense for this to be the default than vice versa, and poly~ is something that people always seem to struggle with, so why add one more loadmess to the equation?
But it’s not another loadmess, is it? Just a different destination. Here’s a version of my StupidSynth example:
----------begin_max5_patcher---------- 1357.3oc0Zs0aiZDF8YmeEHdrx0hu4BW5aQc6CqTuH0UJuTsJBim3PKFr.71 jtZyu8NWv1rI3gAafXTjHbmy4LeWmwe8lY1KydhUXa8SV+k0rYe8lYyjmRbh YUGOydS3SQIgExaydCqnHbMydt5ZkrmJUmeWIyB1e5sgkQOFmt99bVTo50ic nKnysP7+4L2hRDaQNKbr9b0yjsqLgUV97Vl5ArsObo3UxuQ1x+9GIn8eiGxR KSC2Hua6ayiCS1ekzcahS4uKIhQ0t8h3+Sd6.dQ.PPH5wGP80kOAHN42t4Fw l4FJKQYa1vRKeir7KoewJItnTivfbwREolr.0jkZbGAMx86X4qBSCaj8PSrG w+HMQbmdj3+1G+vGs98rRlFl65cf3dHcDGBlNDmOhyRx1pi2HAOma46KYtu1 gbmoCyu6muUCoCbk7jHM1wTsC2SH67sYIO+hUD+ylmcH.TRbJKJaWZY8.PMY H3q72IR6ApbK1sYQw85SSJyVuNQqgNUNZWEgSDsusX9wBMqA16okgWd76SkV yYgF5ATIi.PZZikjDB5bJMb2itg5xP64nGor+kCs2HG4Yhz7NsqIAxsz25l+ VIY9ojEug0hG0exRQTXBu5G92xyhSb9NZMa7o0La.TfAhTiBT2CI39NY2rKc aXz+X8f5OcQL.Y5PfVKCodo4gjrvRgQzo1oQoiNr1Vj9S5hSsP5JqFnGJhBS OWKIxvJG6u4hvuvVcO+Kxg+8gkk4wK4wSJpDkJUYls3J2uOgqB129gO8mhgz eUTKs0mk2nTe6IUNbUQ9K57YUku.d3E9AthNGr.GCbbKhWmJZLo9dmNhGtyC Czg1p77RL5HKmGbkdwH5YlXDt9xKxCoveI57Go0XtJWngwuVFlttQY.Mv4A2 OzlGKyiIqFbQPOVi7mh2rkme7OJhzHbTWS6IBe8UIr9zdwVwsZwfUkRhIsaw HpQd9oKU1exT1TIWYVZsrcuIUkRt9FqMReIc9TC7DJfOGQZ2lkr71yAU0MEN napQiAXISkPKmxB5w3BYG3FHaplr8buXGLfNY7v1Tl8P6tWJSIhyYV8HLvSM QO1GBOW6JUrg1lmZPM0LtFXtbZ2KixT8X7pUrzWMcFioT0ZbGUYLp4ltWB63 MYB6zl1foZkFNpJX61VmAcWs7m3Ao+gWZU.QD4RAf8MtipFKTlNYlHsnmiRX sqKUQg7cuLcwcxnK725K5WFQU0xfZMyvZW6jANLiykMqF1189rXDmZf1UIfm Yxdj+U8TEcIh5oZeskUwDpkAvSaeqSnk05NVRl1ov1uFq0tn0Xz0Gq2FlxRz ttUxntdplOUQhQ9032x0QYIY4p6lmrjPcB7mK1CvdhIGzYAwwymfE6Qc3sf. M9iYnCqp0PvSf3dL8BD.ptAb5ehRemIpZ.EopunZ5DHA8OOAm28QT+5LU4lN HLEclLU9xjqP9q9cGIYi37eO8Kx1kGsOkz91usNhoUrhx3zvx3rzZ2DO0u0Q NerEq8wP1DuZaFux6JLnVQg2LVzIH4zBjDS1xHhIeCTIXbkIjIxDZjwjqIXh NtXxDH4NtV3FISitAdq9b9i6.mIXZbgDXBjBFUHEXx.2HadapGGLppDpMUpa hT.VNylph9..NbzEBULw.4C2wXnXDQgOUO9HuCGcon0jrPhkheDGrwlTSiDS nwESHSvDdbwD1DLQFOL4YxX23FOC6ZpMdGvDDT4QpZlpZcRDG0GJXqncbSRg CFBEjFnzLx2ofjKVAAiTvwsx5WINZprFttvDPGecBccgIvDchLt06SPWxXGX .l3G7sa9e194H3. -----------end_max5_patcher-----------
No, in your patch it really is another, but what I mean is that if adsr~ defaults to being off, then it should output the mute state when the object is initialized, because that is what you would normally expect from adsr~ when it’s not outputting.
This way, in your patch, there’s no need at all for a loadmess to turn muting on, because the default state of the voice (adsr~) is off, consequently the patch is muted. Imagine your synth had 1000 voices; do you really want them all to be consuming CPU while they’re initialized to being off (via their envelopes)? Granted there are a few instances where you might want CPU to be on, but the envelope would also be switched on, so it doesn’t make sense to have the envelope and the mute state out of sync.
It’s a minor point, but it would make things more consistent, and it would make polyphonic patching slightly easier for the newbie.
It’s certainly not another compared to your top patch, but I take your meaning that those were already extra messages that would not be needed if adsr~ worked the way you propose. One issue I can think of is that adsr~ has no idea when things that it may be connected to are actually instantiated. loadbang and loadmess are special cases that fire after a patch is completely loaded.
I’m not saying that it couldn’t be done, but I can’t imagine that it’s worth the effort, given how easy it is to sent a message with the existing rules. Also, many patches use things other than adsr~ to hit thispoly~, and it sounds to me like quite a rabbit hole trying to get them all to behave in the manner you propose.
Yes, I agree that you can’t always know what adsr~ is connected to, but it actually shouldn’t matter in this circumstance. I can’t think of a reason why I would have adsr~’s mute outlet connected to thispoly~ if I didn’t intend it to be muted when the envelope is off, especially since this is how it normally operates.
It’s a little weird that the first thing that I’m doing with my synth is muting everything (even though it’s not making sound), then on. This doesn’t mirror normal operation where when an envelope starts, the voice is unmuted, and when the envelope is finished with the release, the voice is muted.
It’s not a big deal for me, but I teach Max, and my students always have trouble with poly~. It’s nice to say "just hook up adsr~ and thispoly~ for now (until you know more) and it will take care of things." I do address more complicated envelope situations, but it’s nice to have a consistent simple example, and since that’s the point of adsr~’s mute outlet, I think this behavior makes sense, and I really can’t think of a use case where it has a negative effect, since if you’re using it, you already expect muting anyways, and there’s no advantage to having it unmuted once when you load it.
Right, but because Max is more or less a data flow language, the patch network needs to be complete before it can send anything. During patch instantiation, adsr~ could be created before whatever it’s controlling and when it sent its initial mute state, the thing that it is trying to mute might not be created yet. It’s been a long time since I used the Max SDK, but I don’t think that at instantiation time an external knows when the things it’s hooked up to are ready. A different thing to lobby for is to have thispoly~ come up muted, but I don’t think that that is any more likely to happen.
Look at it this way, with the current behavior, your students will get a "high water mark" on DSP usage before they start muting things through the normal use of poly~. Maybe if the message was "pauseDSP" instead of "mute," it wouldn’t feel like you were doing something extra.
I understand this, but the mute message is tied to the completion of the envelope, so it’s not really even an instantiation issue, save for the fact that the object itself instantiates to an in-between state that is otherwise unreachable.
When the dsp turns on, adsr~ should correctly indicate its mute state in a manner that is consistent with its internal state. This works fine within almost any context, poly~ or otherwise, and is consistent with the expected behavior; otherwise, why would you have something hooked up to the mute outlet?
The current behavior is more of a bug than a feature, and the fact that it requires a workaround every time I build a synth indicates that. There doesn’t seem to be any function for the current behavior, and I can’t think of a usage case where it’s helpful. (feel free if you have one, though) When a user is adding a synth to the rack in Max4Live that could chew up say 20% of their CPU, do you really want that to be the default? (especially when there seems to be no advantage to the end user)
Yeah, but if "the mute message is tied to the completion of the envelope" the current behavior is consistent: there hasn’t been an envelope completed, so no message has been sent.
Most things in Max only send things when something happens, either internal state changes or some message is received. The adsr~ mute message is sent when something happens, not continuously to indicate state.
Maybe I’ve been using Max too long, but IMO, there are _lots_ of things that need proper initialization in Max, mute status to thispoly~ is just one of them.
But the state of the envelope is as is if had been completed. Since the outlet is there to simplify the operation of poly~, why not?
You’ve been here longer than me, but I’ve had 13 years myself, and it seems like this is something simple to fix and worth fixing. There’s no downside that I can see, other than minor philosophically.