multiple CC crossfader

    Jun 03 2014 | 7:20 pm
    Dear readers of this topic. Today I've been struggling with the seemingly simple task of creating a multiple CC crossfader. Its function is to divide an incoming MIDI CC into 4 different outputs, crossfading between them. The attached result works but the numbers are not returning properly to their zero states. Now, I know that there might be other ways of doing this but I can't figure out which. Any tips would be really appreciated.

    • Jun 04 2014 | 9:03 am
      I solved this problem - sort of. The problem with the previous patch was that the split object could not handle the speed of the incoming number stream. This is now vastly improved by using equations instead, but still not 100% to my liking... So far, I had no reactions to my topic and I'm still hoping someone can help me with a better solution. Jan-Bas
    • Jun 05 2014 | 12:26 am
      Something like this might work with a few adjustments...
    • Jun 05 2014 | 4:36 pm
      Thank you very much, Pedro. I tried to refine your patch and in the mean time I kept on working my own version. It seems that the sliders caused timing problems. In the end the attached version (V3) is the most reliable until now. However, when you increase and decrease the values in the top number box very fast, there is still erratic behaviour. I think the switch object is the culprit now and I tried to replace it with an expression (if $i1 == 1 then $i2 out1 else $i3 out1) but to no avail - as could have been expected. I'm still hoping to find the perfect solution ;-) Jan-Bas
      p.s. Sorry for not posting the previous two versions in the appropriate format.
    • Jun 06 2014 | 1:29 am
      it is more or less impossible that [split] has a problem with the amount of data coming in.
    • Jun 06 2014 | 7:30 am
      Thank you, Roman. I still believe there is something wrong with [split]. Have a look at the attached example.
    • Jun 06 2014 | 7:52 am
      Roman is, as always, right. ;-) The problem isn't related to [split]. It's the number box. When you scroll up and down fast, the number box doesn't output every integer number, it outputs at a certain time interval and, therefore, jumps from value to value (e.g, from 17 to 33). You can "force" every value if you use the [line] with a small output interval to make sure every integer value is fed into split.
    • Jun 06 2014 | 7:58 am
      Or, something like this, forcing that when the value is above 32, the first output is 32...
    • Jun 06 2014 | 12:05 pm
      Thanks Pedro, both your approaches solve the issue. I find the 2nd solution the fastest. It will be interesting to see how sliders will behave in that environment. After all, I do want to have some kind of visual feedback. At first I thought that it was an interrupt issue but then I thought: 'No, that can't be - not with Max.' So I looked elsewhere. It remains strange that such a fundamental Max object like [number] behaves in this way... JB
    • Jun 07 2014 | 12:19 am
      i just looked at the patch.
      the explanation is simple, and you are aready half way there (with your assumption about split).
      the problem is that the MOUSE is simply not fast enough to produce all possible numbers from 0-127 at the slider output.
      this is a general problem for GUI objects or physical controllers and can be solved by allowing the mouse to produce more data then needed.
      the mistake you made here is that e.g. [split 0 32] will not properly set the first slider to "0" when the incoming CC sends "127", because "127" of course wont pass the split object. solution: you must generate the "reset" values elsewhere, before the split(ters). OR, you could use [clip] instead of split, but this will make the patch handel tons of data nowhere needed.
      however ... i would do it with expr anyway. sorry crowd. :D
      [split] can be replaced by [expr min(max($i1\,$i2)\,$i3)]
      [map] can be replaced by [((($i1-$i2)/($i3-$i2))*($i5-$i4))+$i4]
      the reversed part 127-1 can be made by using map as above with reversed inputs for the min out and max out values, [((($i1-$i2)/($i3-$i2))*($i4-$i5))+$i5], the input range of n to m then must be changed accordingly.
      the whole thing is getting much easier when you use float, a simple /127. at the beginning and you are ready to rock.
      [i´ve deleted the code, will do it in maxmsp later]
      this has not been tested yet, as i dont have maxmsp here.
      oh, and btw, you are not very consequent: at the low end the first slider starts from 0, at the high end it remains up. ;)
    • Jun 07 2014 | 6:07 am
      Thanks Roman. The patch is intended to replace my previous routine for controlling Midi volume CC's (a.o.) with the Leap Motion. After I made this:, I wanted more sophisticated control over the division of each axis into (4) separate zones for different sounds from distinct channels, crossfading between them. Since I trigger sounds via note-ons and -offs from Max to external sound sources, any crossfaded state of the channel volumes can remain at any time. Consequently, there should always be at least one fader open. (for more general purposes of the use of the patch this is, of course, a side thought). Thanks for pointing out my mistakes. I'm curious to know why you would choose for the use of expressions. JB
    • Jun 07 2014 | 2:00 pm
      ok, just wanted to make sure thats intended with the left slider. will boot into OS9 now and fire up some expr. no wait, first i need some coffee.
    • Jun 07 2014 | 7:15 pm
      it is wise to stay within integer numbers wwhen fold and wrap are involved in some way, because fold and wrap works differently for int and float. so that means that you should better not try to reach the output range of 0-127 ... because you will end up with a nonlinear controller range. it is better to calculate everything in int, not round anything, and limit the controller to a range of - in this case - 0-124. as you can see, the center is now doubled (value 32 AND 33 will produce the highest value for CC#1) – there is no other option if you want a linear controller as ouput.
      normally the [change] should be between the min(max()) and the folding to save some CPU, but i thought its more fun to write everything in one expression. :)
      input to CC#1:expr ((((min(max(($f1+1)\,1)\,64))32)*(65-(min(max(($f1+1)\,1)\,64))))*4)-4
      input to CC#2:expr (((((min(max(($f1+1)\,33)\,96))-32)32)*(65-((min(max(($f1+1)\,33)\,96))-32)))*4)-4
      input to CC#3:expr (((((min(max(($f1+1)\,65)\,128))-64)32)*(65-((min(max(($f1+1)\,65)\,128))-64)))*4)-4
      input to CC#4:expr (((min(max(($f1+1)\,97)\,128))-96)*4)-4
    • Jun 07 2014 | 7:19 pm
      another subject of debate would be if one should apply interpolation at the input or at the 4 outputs.
      however, you might want to use some clever interpolation for this, because a quarter of 7 bit resolution is not that much when the aim of the produced CCs is something like gain or frequency...
    • Jun 08 2014 | 10:04 am
      That is phenomenal, Roman. You've got all the issues dealt with in one go. Thank you very much.
      Of course, you are right about the serious degree of data decrement at the outputs... I will see what I can do re:interpolation (although it will probably not in the form of your beautiful expressions!). Jan-Bas
    • Jun 08 2014 | 5:46 pm
      that does not help you much here, but for audio it is easier:
      slider (float) | [line 50.] | [110.xfade-4~] (add single outputs, rename it, install in search path)
      signal-only & optimised for speed
    • Jun 24 2014 | 8:59 pm
      And, this version for OSC (with values -1. to 1.) works for me, too.