How can I create a slider to do smooth gains
My math skills are unfortunately very rusty. I have a [gain~] which I want to be able to adjust smoothly from a pedal but I have observed that most of the volume increase happens towards the very top of the range.
I realize that one is to supposed to use some kind of log conversion to compensate for this but I don’t know the right function/coefficients to use.
So if I have a pedal that produces MIDI values from 0 to 127, how can I translate that into the correct values to get perceptually smooth volume changes across the entire range?
Thanks in advance,
Hi, I think that gain~ is the complex object and it’s really easier to implement than you think. Gain uses a dB (log) scaling and the slider is linear so you just have to do the old school Amplitude scaling with it : http://cycling74.com/docs/max6/dynamic/c74_docs.html#mspchapter02
----------begin_max5_patcher---------- 782.3ocyWlsbaBCEF9ZmYx6fFtrC0Uar3dWdN5zIi.TbTBHXXwMKS8ydERfK 0I1QljJmaLVB3ny+mNKhmu7hEdIkOva7.eG7CvhEOqlYgdt9YVLNwBuB1Co4 rF8C5Uva40a87GtWEqM8Vgb8007zVikPvUKg9.BJt+BNZYfOXUvRH3miujrq nrqMm2pMIZbZybsOVwMFx6l7Rlxn6dOQl1EJSt6qgdSLlPtyV5I+8kWzeUcw 2ZcslIjGWVzfdkLHKpViGSV3+ZqZllZWykrjbs3fGTyMh0RVtmOvSHOf1Cdc sims1SKKJ3pUazrs7Gzh1qsDv1TJx.o4hz6a18.4BIOsrS1tmPeAzHXpNHfD owEQGXDeXnsiK2TJakJrociqpE8HY3VIcICTbWjyM0qSLKHbIcEDsJzW8OTD Nftp+evHXPbrO.MckmPTp2z0sQ7jw73kvO3nrCR5qJpxEscYbf54AaX4c7Sm 13Ug8gnJcqoM5SJswth1R9uTq2KgcE6dkapJTcr7cbnIzEqy2Cg5Av4TFaRV 7Q.8zD7SLdb9Y97mxXo1T1iRzwTpAC+9lwTS0C4ithkpyfxRGc6CoK4Pn5KA u412LKWaZQopVmvjqO8MZzYOUfytmUTsUwFanoo4WLc9IC62S2NPQibUFwg. 0W1ZAevwlNb39Tl4wmg9+mLfvma.02kZqMETCz0PHgVmQdjyHMqrNJ5rGLAv Ks.UnXz6MbZdoaDx4lPeSsXQVwn.cJGE45RRjydFW5io47s.JEZQC7wywDOe NMyRS3PWAplbQFu1lfFygYzkfPDpEv3zNUvq+caHrcezp4k0ET2+iy0Rp+F6 gglxt5zwUe3aDASTUFuoUHYshR4zGRklCP+8otUjkwk+izxDM8xUKB3g2X9O 3WPm5W88OsvwbteYEuBctagCswu1GptfWTqbLj6CvhrJ.C8IMxee22ENFx5X L2VCiPrZqj5bhQrZqj39pqH6br2W4hg1lrppM75lASa7I0wDtqrtebnuYrPZ FarrWMeiX7UHpYzVU8ye.zgHQ7M -----------end_max5_patcher-----------
hope this helps.
PS : if you really want to deal with the perceived loudness, you’ll have to deal with the frequency, that would be really more complex I guess : http://en.wikipedia.org/wiki/Equal-loudness_contour
EDIT : I just had alook at your profile and I guess I misunderstood your question sorry, ignore the post above… :)
Hmmm, not sure what’s in my profile that would lead you to misunderstand my question !
The amplitude amount changes more rapidly as one gets to the top of possible values, i.e, much of the gain happens in a very small portion of the slider range.
Therefore, I’d like to arrange things so that the rate of change of the gain slider is reduced the higher is the value of the input control (0..127)
Sounds like you might be happier with a linear response:
----------begin_max5_patcher---------- 714.3ocyW80ihBCD+Y3SQC4d5hmoEPQuOH2KW1roBit0.ERaw0a2r9Y+ZKf5 dpHxxY7EZX5vzeyu4Oc3cWGuE4aAoG5mneibbd20wwJxHvo9cGuL513Tpzpl WbdVFvUdip1SAaUV4qKkJzxbAJE1.oHInTL9pF03kYLdJnr1fbPXdopQJtVZ AUE+h9SeV.wpJj4OiLdxH8R3X7HDYhcwmLFidp9iXIVPjuX8O7IMG5xbthSy .6V+BDITN838jr2r6Q7Gu+vEfT6cTEKm+I.TcjyBLK35GnmLezGttlGi9h7W JiCTAhlUjxTkI.JViPQd5vvfA9SMfNZdWHP7vSfMme3+M9iVlvxQx7RQLLLb VXEYM0B2YQsQYj48gx5g2mAJPr6F7Oxk8Ohtpx3SS7sNn0MIAWvACaNyJaq9 SATYEuko4TsE6SrjCupM9IgRI80cHBAeV2z+lcyvPSyi53XDo03neWhimPAR 1JNM0auEGf.M7VBMd2Mv.3qx.ADaNb3jlmmkAHd8.sqnL9s.V+qB1ld8AsW2 guVLYDxiwUGBMETA0VD8LvoKRsZiGtT2uuaPSZ8w1Zyl2t.KL+QIo8R0ywzT .g0VMR21GQFeVNZ5sxQ9QUsrv1qVH1KgtHGMqWbzvxNkYK.Qq8t0hXYkYGWO e9BGsgaTTypWkipt2eBtMFJpWLjo3RWisfpm0q8hrg7RPojtBNIO6aD8nMCS 8WStUPvgVlj4mm3Bd.RsNegmYlxApsbCgTcKZXq0ZjuR+nSRlZgdr5X8x+4W XrNfQ9m4r5oCqNu5NmnCtPBH0+yhcz0izwL5yQJ8BKIA3GmQmvjlj7jKeUxf BG7cCNlogtJdle+fCtKziN4CQdvvyche5Xz59vNy5.ZBtabSTGPyr6FZB5Rh SOQSUOQZQwFPHqMoEH5aLVmK1OokYVipWsVzS.aXM5G5Zr1Gt+k3+6RW -----------end_max5_patcher-----------
this is an abstraction I use for your situation– generally when I want to change the throw of a physical slider in a midi controller– it remaps a straight line into a parabolic segment
it takes arguments in the same way [scale] does, but the curvature coeff is more useful (in my opinion)
----------begin_max5_patcher---------- 1863.3oc2Zt0bahCE.9YmeEZX5L8RR5JIt22121clcm8GPSmLxfrMsXfEjSx 1N6+8UW.avFLBuXhcamPBBP5b9zQRmyQ5G2LyXd5KzBCvm.eFLa1OtY1LYQh BlUd+Li0jWBhIExWyHHc8ZZBy3N0yXzWXxx+6MjvbBKJ.jSWSxxn4eB7PBHX S9SD1lbJHcA3VzGg.vJRAf.VlSBEkAADFfshBVGk.R2v.OQh2Pu6gDXsuMHm RXzBPAKmDsbECDGkPeH4dTs2Ip.rIqHJjBBSeNAjQxIySiIfmiXq.emlmpZR dqshWEpl4gjnDFMeMMLhW+0pL4SK.Oml+M.KME7tHJ.9Q66.2C+nKBPYAuuh .BQIHcShDC1kEtHMgUD8cpnLDWqKKNYCWKioLIJQkElQXAqhRV9XNMfo5JPX K92.Pthql19he4B4v6KkeSTnD5oy+58lF0ZyDxZYaZ7q4QjXicMKmrUsKTT3 +dyMhK2oYu9h3TdkTUepJi8OYTk3JdLgaR.LlSRVZrUJ6fBY4zBtID2XIMol R6gj5ruTagkW1VW5htF0hMTcS6jCOTxgOAxsdSLKpHlaWl2I9DjaG0JnLtpx qD0SUpvIPBKII7jf.qpEqNrgPim91mpNX0.4HUCOMTCOu10CzqsEut5pib.O xzpeiWG3TX8NpTfWyQq40lnziiFdQUu480l23PfYZ5qHloFDCc0QLcsavd15 a3f+4ECJy.8vfyOsX.45qOFb+4EC3RLf0.CdSAF5x2Yo2lb+LAyoUdOG1p6k li4xLdxqJmKsrZmK9SgykcgkctiyczmSmaaLA9+C8uZUCnZVSn4Q8Rz40jAx PhdqHhk21pEAdTW.wWd0TE1AtcdXa85yi3zmOu3PsPhuiF3v9UEG7flO+VGk KnnhopGb39piiyswQ05JPnF3XRl.Mg9LuwNfFY.QRY9SYxX.Ptb6JtBPZDbl NHxo23XbjDB6iO17qCdk2FcM7PMUboDL7pIJl9DMuHJMo1aOyfigZEOq1mHn 4WSyqk+FUHHphPaKJm9TT026qJj2GcS0C2lABYnpNp0Uwp3VsqYev6MWFmF7 MpjAvpBCoKFRcjlQS189v54LoQhSTuYTR8jtre6R1Dydr8t7lOeAIf14G2Ze 2Lik4QgoIBgnwWJJtp43ioTqDaWWtkuQBIqkOlklFOmjK5NlGSazMyGoP3AO RXTVjRdvvseWz5r7H0jAaKilP30wphf7z33FUk5IO0xSB4VBAzmiBYqj00NZ 0Hep0swpOFtQ46MVd9FFi2Cc2tGevvzFdI24TWc57iryszeX71qMpuZCOsPF Man8yqxrp4qJGObh5ci4vZNO1ljLRv2.EfEU++n3QDHw1HJ58OZn2cLFXvHF 5ta8R9U6ly9c.hgF6ICsOT5vN.mooCnblVR9xB4JHxe5sO3bhVW0BLHq8WY4 fri6eprEOhrUUsFmnNq1L.LxTsLP00NUYutUp5XuxIJw2UE0ov85rMLiowth 9RVN3MKPe3cuYg48uYA982xubbCqSxnxrG.qV8wSEGHxqWiJqS0nBMgfkCUj Dp+xV79JfVkueX03UrSun07Z.sbV9AgcK+maemBxh+9LfWrV30VMOnU+VtnK A71L7MsyEVm4CaLWfAq1+PT64F6fjCYep7DNQ7ryjn0Y7wiJMUlj1pqGDp7A 3z5RGmGlOtogiP4HbmNR4vAbDecvwZopYRvHRMh1AqIFMu3w394+aZvHxe2z iZfQzUAF22XbjfkizqRWoImkaeKPigWBrpw90Mj8raTmyShLe4RGVv9.Gx9R HPOoxoA25N6MPcfRYhU6MTPjyQbnqiPAMtpvgsZeqzLzXj0v4QKNPcUQHDbP DBObBoxY.3298qJvfbjtT4aoIXfmLX9i+55BL3AMlxa3bIJ4JzdwUFRnZur5 mJVmJUZ2XY2thH7sqiMXPJzhm2NtJR2jGTAiRYDzTABoErnjs6Qzm2kSF.pw KtJJLr4dxn1yrvrznDVo7A9hV8uCUr8FhXiuXDaj13FcZ3FymPyd6w9Rr4qU 2ctzHrtZj0o0SfQp8Nw0t5PdVc24RifCQiNg9HjaoNH+kW4o7meyYRgDasDv dLM5BRiU6KtXSm8P1NdNx8a10yxDU+uP6M43zLJSpvVioM4Xovld7O2m+OKw VMfpaQ6gNaVzRdXNlVziFO3SW4xwgmmXHfLJupwCdmWbfGyEOtFFOfzUggW+ Jro1Ky5ooBOQxsulxsE7hRtEmOD83s+kEuQCYo9KH41bHtQd4H2h7youa6WP xsilxcKJ3oK2kEVc7BMJHOQCej2L7vQejvX4Qy2vTwA13rO11Yz6bcv9Nxi5 6LEtLNcNIt7XEssNLtYGEJOArRb1LlW0Ahc+twxiE6wCVridtFgwbXmV6cXG bDc0UhbPZHRd0ca+rKR5.IzzBIrlPxZ5DIGMEIyoSjb0TjvSmH4ooHglNQBp oHMcl2d5Po8j6gIS7a92a9OP3oIOR -----------end_max5_patcher-----------
Terry, this is exactly what I’m looking for except that the behavior is exactly opposite to what I want.
At the bottom, moving source slider a lot only moves the target slider a little.
I want EXACTLY the opposite of that, i.e, at the bottom, moving the source slider a little will move the target slider a lot, and then at the top, moving the source slider a lot will just move the target slider a little as very slight changes in the gain~ are much more noticable at the top end.
Hi, did you try setting the curvature to -1?
Did you try the linear response thing I posted? Was that closer to the curve you’re looking for?
That one didn’t change the gain~ at all. It was the total level that I was trying to change. In the meantime I came up with a simple log function that I’m getting ready to test when I get to my studio but visually it looks close to what I wanted.
----------begin_max5_patcher---------- 524.3oc0V00jaBBE8Y8WAiy9Pa2Tqfwu5a82Qmc5PThKcPHiPll1c19au.Fc +Tkjlwt8ELbujCmygKd8NeufMhCDY.3yfuB77ty2yyFxDv63bufF7gRFVZWV .m7CwluGrpKkhbPYCyD3pMXdcehcXU4sTd82ZIkpN7QwIgQq.v70lGoQlQjd Dbyw+CsxBkF9OBQ8.sUvUbbCwl5KsTLqOCeeCkyHJKufODTrW87nFPjzeYAA hzabW3tUp94NRGCCrJ.biI6899lgUNZKMDoDWSdgujDMuiffVGIFElXrmW2Q ROQCAcQLjyyLpwT9umP2YEV8FutuDPK60iTIfNA0gFSFRZM23Sf.JWcdZZj5 dYIlQ.Qg.XncLIObJgmaEdTmjiRl5JPwIdfm9O7.eVyQaKclzrlCrH1AyI++ HyQxnUj1YENxkaCYS9xuAMjjOHhWWwWHoskIz32yIcJZidpYeF1+w0KJy7H4 k8AzJqGmnAbdjIDeQ5MfNwCesVwJyqPN+lDibMgbXWKfIpeG3JJB7gq1BuF9 9OYBnmq+47kNoc2YxRmrm5afNHVdEvn7m+QGVsYh+T6SJ12V1CU+GF.dPdUD ohxwJpf+nEk9j0bKsphXSGMTfUsSn6DbjCibV5JkRcfQZuG.WLFE6HiVNOB5 .iJVTFk6.ihWTFk4.ixWTFU3.iP+ELRO4d++..mrZuC -----------end_max5_patcher-----------
goodness gracious, dhj did you read the text in the comment box that came with my abstraction? as error_500 says, alter the curvature argument (the 5th arg)– may i suggest about -0.7 is a good feel. It’s got the same types of args as [scale]
It’s true that my patch didn’t change the gain~ slider, but it did try point out that a linear change might be close to what you’re after. If so, why are you using gain~ at all? Why not use the line~ *~ combo? The log/antilog behavior seems silly if what you’re after is a sort of linear response.
Also gain~ goes from -∞ to 0db over the range 0-127. 128 to 157 is adding gain, which you probably don’t want.
Well, it’s partially my lack of understanding of some of the audio stuff, where I have very little experience.
I have built a mixing console with individual channel strips and a system that allows me to create VSTs on the fly and route them without patching.
The output of each VST or VST FX goes into a channel strip that has a gain~ slider to control volume. Then the final master output strip uses a gain~ for the final level. Everything goes to a MOTU 828 mk3
I found as I adjusted those gain sliders from the GUI (or via incoming MIDI expression pedals) that volume changes were very concentrated towards the top of the range, i.e. very slight changes in slider movement had huge impact on volume and so I wanted to compensate for that.
I’m absolutely open to better ways of doing this. At this time, Max has completely replaced Apple MainStage for me and it’s just working brilliantly.
I appreciate your comments and response.
Part of a set of abstractions is a gain that I use always in my own work. It can be downloaded from jvkr.nl or directly using this link: http://jvkr.nl/public_downloads/jx.all.zip
This jx.gain~ has been modeled to be equal to a fader on a mixing desk. Particularly when controlling with midi faders, it gives the feel you describe you’re looking for, in which gain~ is lacking.
@Terry yes I did..and I tried negative ales but it didn’t seem to do what I needed. The single expr with scaling seemed todo the trick though I’m stil interested in what Chris had to say
@jvkr thanks for telling me about your library. As soon as I’m at my Mac, I will take a look.
@jvkr do your abstractions work with Max 6.x?
I just started looking at jx.gain2 (I need stero) and have a few questions. First of all, I don’t really understand what exactly is going on, the purpose of the buffer, peek, line~ and so forth.
What exactly is this doing that could not be done by just appropriately scaling the gain~ slider?
The peek~ is used to store 128 values, the default range of the slider or dial that will be controlling it. The development of this set of abstractions started in a time when it made sense to calculate all values at launch time and store them in a table (or a buffer, in the case of floats), rather then recalculating them each time. Especially as there are two powers in the calculation.
The whole idea is that a slider reads out values for a multiplication factor. A line~ is used to avoid discontinuities in the signal.
Maybe it is possible to find values for inc and scale to get similar behavior but I can’t find documentation on what the calculation looks like and don’t feel like finding it out.
This abstraction solves for me the issue that you mentioned in the initial post. I use in almost all cases this gain. The live.gain~ is kind of fine with me too, especially as it is stereo.
Below patch gives a little more explanation.
----------begin_max5_patcher---------- 1060.3ocyX00bapCD8Y6eEZn8g363PQBLwt2+C2G6KscxHCx1JCHwHIrcZm3 e6Ue.I3av1T+AsuD.IEocO64rqV+ygC7ly2RjdfOC9JXvfeNbv.6PlAFT88. ub71jLrztLuL5ZheJEm4M1M6ZrfgyI6O4WgeudddoJinTOWPbGim2Xf2hLNV 4A9d0ZJvpjUT1xGEjDkaYvYH+fwfvvXyinH6G52a7+HzGqhHdjvvyyr6NrZN 4J9lZiJnZLVYNkosDYyEVHHRBSgUTNq4gOcl87hPG3v0alyur6FpZTZpEE3y e5dTXs+KwqIoOhUJAcdoh71axJTtBlMHYVIgund35wa5pYb1xig16s3RFUIU Om0DF1aA45HqEMBPg9ssf5nVayowXg581hmakuLb3aOr+8kgi6HEKgmmqCJ0 .nhr0FV7vhkklI.RMtCnrhREPfYKIdGlFgfV9S3L6C3jolGnfFgxEblRR+gi +.8OJcY+vdPKgcjWis8Uz4KDQJlg8NCvfQ1n232gEOs0eIlx1YhcQGTpIoZ1 RlQvcbslAPdEjbb+eaLB0UoAb10FiNDgQshp4IRfZEALGKoIfDNaMQH0pc.e AvJ3jl2BtGhd.n3.bdQFUUlRplrdOynLRBujoZ5Ts.kQtjEUYuPvotjX2J9F bZegkB5xUJfyZ.BRgV7KAyKWrfH.lyEH4.xRvFpZE.C1nS5syh6Ikh05+hYf 4DPojjpEt.bYJkCR44ZJbqHb3QP3PWgAnCgCrHbzC2LDNtmTzNH6wSokOlNN L1oiQVN3jySGG1Jx.aAYht5HSY9bhXWGRmc56ODFXwBTrSOFf5JXjySIME45 C0RMtzrdg8bkgKsnPM.hrBrIObiKJzWEN0dutn4Eoxb.Cbp8QT7U7FEsoxfW afQqczm5AQ.mzRyNlquZ0QAhHWt2JI1r2CDscE8fKFjZi8DzSrGx1BAnfu4N Xf+29136ty79cejB+j99C9izCE3ilL5d3n+4gX+QeRCGiNbiPcAbcxOzL3sk lc0uGQ25S7BaRrh5MM5OPOhV0ev41e3jdr8vyp2v+Ls9cnj1KJxvOuCf5PQs 2d6jIvpRg6nOwgWwJbguOhe75+MXCUdzG9Oq237ba0Zs0M1zq1rXCyyMh2+p 8vqGPmhS14cR.CEU0u3UDwZqY598FSnc+VrqtvrftTCtrTWoah2B0pyWQvd7 1Ns9e+leVWvL99nmjWJRpAg5eVKvadQJQpnLalwFKxzfO.95hVQSSIrlw3Tp zjM15.AsFG6p8Xt1Xii5.1SzdF8M2dNI9D1a1yjtXNn9KbA6p8zOvSXWXO8F 5zIsUugMS6h0D7WESd5eW5JSA69QV0AZbOJx6.1btRbWALbQQ0uhq0TLFhtP +Sbg4y3w1OoL2m1czSPVSqWezPyt8xveA9dQXIA -----------end_max5_patcher-----------
Thank you — most illuminating.
I use the following settings with a dial and a gain~ to control it via midi CC:
gain~: Number of Step = 300 (158 by default)
dial : Number of Steps/Range = 100 (128 by default)
Minimum Value = 200 (0 by default)
Are you then scaling midi cc values 0-127 to dial values 200-300?
Yes, for me that’s fine but I guess you could also scale it to a wider range. Just fiddled that long with it till I got the result I expected.