Best practice recommendation - controlling volume of dac~ with a slider
What's the recommended way to connect a slider (say) to a dac~ to control volume such that you get reasonable behavior throughout the range of the slider. I recognize that logarithmic behavior is required but I don't know what are the right multipliers etc.
Would appreciate an example.
Thanks,
D
live.gain~ if you want metering, otherwise dbtoa -> pack f 50 -> line~ -> and *~.
Alternatively, you can do:
dbtoa
|
message 0 0 $1 50
|
matrix~ 1 1 0.
The important thing is that you need to do interpolation (line~) so that when you change the gain you're not creating zipper noise. (matrix~ can do it internally; the last value in the list (50) is interpolation time)
Thank you --- I was getting that zipping noise and wondering how to fix it.
Didn't know about live.gain~ I was actually using sliders and separate meter object. I'll play with that.
I assume the live.gain does the interpolation?
I appreciate the help.
tip: when you're using multiple (ez)dac~'s with the same output channels you can use adoutput~ in combination with meter~ to see your total output level.
Yeah, that part I was doing for a long time and it's quite critical because, although I'm currently using about 12 outputs, I am often combining related sounds through the same stereo pairs.
It's just the overall volume response with which I have not been happy.
I wonder if someone would be willing to post an actual Max patcher with an example of how to implement the internals of live.gain~ so that I could use a separate slider (or other control data feed that I can scale between 0. and 1.)?
The live.gain~ works beautifully but (I'm sorry) it's not a "pretty" looking interface so I'd like to just have the implementation and I'll use my own sliders/dials/external MIDI events to control its volume.
Thanks,
D
Thank you --- I just want to make sure I understand
1) The live.slider seems to be producing values between -70 and 0. Should it be going to +6 like live.gain~? More importantly, do the values change linearly so that I could use a different slider (and just use [scale], say to map from MIDI values to this -70..0)?
2) The dbtoa seems to be the real key here. Is it the case that all I really need to do is feed (scaled) values between -70 and +6 (or 0) to get the appropriate logarithmic behavior?
3) I assume that [line~] object is what eliminates the zipping, a nice bonus to my original question :-)
Thanks again,
D
1) You can set it to whatever you like with the inspector. Since you said 0.....1, I figured I'd go with -70 to 0, since that seems to correspond better. What I'd probably do in practice is to use select to look for -70. and replace that with -127. so that it fades all the way out.
2) Yup. Decibel is logarithmic (pow 10)
3) Again. Pack is the key here so that you always are providing an interpolation time. (I don't know the last time I used the right inlet of line~....)
Peter, thank you SO much for this guidance. I inserted your code into the mixer and effects send portions of my code base and the results are orders (logarithmically speaking of course!) of magnitude better.
Glad to help. For some extra fun: you can wrap your sends within poly~ so that you're not using them when you don't need to. (and dynamically change their target as needed!)
That's something on my list to explore --- I don't quite understand how poly~ actually works or can help me.
Right now, I have a mixer console that has 3 inputs for external keyboards and then 6 more inputs to which one can associate VSTs as desired. The mixer console is always visible and it loads a subpatch (inside a bpatcher) with a specific set of assignments and routings on a per-song basis. The VSTs are managed through a whole separate patcher (with lots of abstractions). There's a writeup of this here (http://deskew.com/blog/?p=54)
I'm definitely interested in improving this system as it has already proved its roadworthiness at live gigs (even before I did the new change described in this thread) and so I'm sticking with it for the long term.
To chip in a little more complicated: zippering is easiest fixed with LINE~ and setting >100msec for transitions, but that results in slow response. For faster response, the changes in gain have to be at zero crossings of the input signal, which is, as of this year, relatively easy to add in GEN~.
I have not even looked at GEN yet ---- most of my usage for Max has been in MIDI routing/layering/splits/transformations and the audio side has been little more than abstracting the VST~ into something more usable along with the mixer stuff as discussed in this thread.
Would love to know how GEN can help.
You can definitely use a ramp time of < 100 msec; it may be more effective if you don't use a linear fade (use curve~ instead), though, since you want it to be more exponential in character. A Hann or Hamming window lookup would be even more ideal for fade outs as those curves are engineered to minimize spectral distortion.
You check out another recent thread (below); there's a demo I posted about how to automatically fade the volume out when the playback rate slows below a certain speed.
I tend to view de-popping as a question of the velocity of the wave more so than the position. For example: your speakers will stop making sound if you jump from 1 to 0 (and stay there) just the same as if you jump from -0.5 to 0.5 (and stay there), the main difference being that in the latter you'll be tearing up your speakers with the DC offset... A fadeout reduces the effective velocity of the wave and prevents DC offset. I'm skeptical that just doing zero crossings will work, but YMMV, and this is sometimes just a matter of taste.
Having had my coffee now...perhaps it's better to say that I'm skeptical that _any_ zero crossing will work fine. There are plenty that will, especially where the wave is already decreasing, but just changing the gain at an arbitrary zero crossing may not be sufficient. Using gen~, you could cook up something like this (not tested!):
1. Request a fade-out
2. Track the average absolute amplitude of the last n (3?) zero crossings.
3. If they are all decreasing in volume, allow the gain to go to 0 at the last zero crossing. Otherwise, do an exponential fade.
Not sure how well it would work, but it might be interesting.
Peter : cros posting betweens topics : I like it. It's really nice to see some other uses of some parts of a patch. Going to try [curve~] in the TapeStart patch.