Interpolating extremes of lists

    Jul 13 2013 | 4:29 pm
    So I'm revising all of my mapping stuff for my monome Arc controllers, and I primarily use lists to set the values. It can take a list of 64 numbers (between 0-15).
    The general idea is to have the very end of the list not be binary, but rather fade in/out, to allow for finer visual feedback of parameters.
    I've managed to figure this out when using a block of rolling numbers (see first example), but when using a static image that 'wipes', it glitches when going up. I'm using zl nth's replace function to tell what the index of the highest value is and then replace that, but no matter what I try, it always bangs out an extra 0 in there when I get to the next 'tick'. I've tried zl reg-ing the list going to zl nth, and all sorts of order of operations stuff, and still no joy.
    This is not apparent on a monitor, but on the controller it produces a visible hiccup. You can see it if you print the output.
    So question #1. How can I get rid of that hiccup?
    Question #2. Is there a better way to do this than using zl rot/zl slice, or listfunnel etc... There's been some talk of bringing jitter into the mix on the monome forum, but I wouldn't know where to begin.
    Lastly, I haven't been able to figure out how to interpolate two sides of a rotating image (the 3rd example). Basically having an arbitrary length 'block' of stuff, that the ends of do the interpolation. My plan was to figure out problem two, then do an inversion of it to figure out problem three.
    Here's an example of what I mean:

    • Jul 13 2013 | 10:46 pm
      There's this version from a standard monome app that almost does what I want. This does sine interpolation across the whole length of the list. What I'd want is to just do the extremes of the list (bottom, top, or both).
      inlets = 1; outlets = 3;
      var i; var offset = 0.0; var index = 0.0; var width = 1.0; var point = new Array(2);
      var them = new Array(64);
      var b = 0;
      function bcolor(x) { b = x; }
      function p(x, w) { index = Math.floor(x)+1; offset = (x+1) % index; width = w;
      for(i=0;i point[0] = (64+i+index-Math.floor(w/2))%64+1; //+1 is for multislider point[1] = Math.floor((-Math.cos(((1+i-offset)/width)*Math.PI*2.0) +1)/2*(15.5-b)+b); outlet(0,point);
      them[point[0]-1] = point[1]; }
      outlet(2,them); }
    • Jul 14 2013 | 1:13 am
      This is not exactly there but i wanted to make sure i understand what you want to achieve and wanted to propose a kind of windowing method here. This should work right?
    • Jul 14 2013 | 1:19 am
      fir lowpass for the second problem, just to propose a method again. Of course you can use any filter.
      edit: i don't think that's what you wanted. have to sleep
    • Jul 14 2013 | 1:27 pm
      That first one is awesome. I can't believe I didn't think of using vexpr/scalar!
      The second one, as you mention in your edit, isn't right. Basically it would be to do the interpolating thing the other examples are doing, just on each side of the window thing.
      Here's a stripped down version of the 'working' patch.
    • Jul 19 2013 | 3:34 pm
      Ok, it occurred to me that I can just interpolate between two lists to solve all my problems. Just have two adjacent lists, and interpolate from one rotation value to the next.
      The problem is I don't know how to interpolate a whole list of numbers. I can unpack and interpolate each bit, but that seems hugely inefficient.
      Here's what I mean, and some simple interpolation value math.
    • Jul 19 2013 | 5:34 pm
      Ok, here's the solution.
      Basically adapted the vexpr code from this thread:
      And put together this: