‹ Pact - Februari sinusdeklinationen ›

atolf lftoa

2011-02-17 01:10 supercollider

Using SuperCollider I reverse-engineered two old MaxMSPJitter externals from Cycling'74. They came as part of the pluggo installer and were compiled in the cfm binary format. This format is since long-defunct and cfm externals can't be loaded into MaxMSPJitter running under Windows or newer Intel macs (afaik). Luckily I could still run the externals and help files under Max4.6 on my old PPC mac.

And as far as I could tell, the source code for these binaries was never released. So I took the trial&error route and managed to figure out how they work internally by using simple input strings like 'aa', 'ab', 'ac', 'ba', 'bb', 'aba', 'abc' etc. Then I just observed the output arrays of floating-point numbers and tried to mimic that in SuperCollider code. It was fairly quick to come up with the algorithms that encode (atolf) and decode (lftoa) shown below.

Also a note on MaxMSPJitter vs SuperCollider: no way I could have solved this using MaxMSPJitter only. Algorithms like these are horrendous to implement with patchcords. See the mess in the screenshots below. Also, MaxMSPJitter's floating-point number boxes, as well as the [print] object, does not show the whole 32bit float values! They round off to 6 digits after the decimal point. Why? So MaxMSPJitter can calculate just fine using 32bit floats as long as you don't try to print or output them in any way.

Anyway, I first wrote RedALF for SuperCollider (it is now in the redSys quark) and from that, I then patched f0.atolf and f0.lftoa (now part of my f0.abs MaxMSPJitter abstractions).

(
~atolf= {|str|
  var res= [1/2**5];
  var tre= [2**12, 2**20, 2**28];
  str.do{|chr, i|
    var j= i.div(3);
    if(i%3==2, {
      res= res++(1/2**5);
    });
    res.put(j, res[j]+(chr.ascii/tre[i%3]));
  };
  res;
};
~lftoa= {|arr|
  var res= "";
  arr.do{|val|
    var a, b, c;
    val= val-(1/2**5)*(2**12);
    a= val.asInteger;
    val= val-a*(2**8);
    b= val.asInteger;
    val= val-b*(2**8);
    c= val.asInteger;
    res= res++a.asAscii++b.asAscii++c.asAscii;
  };
  res;
};
)
a= ~atolf.value("aber")  //--> [0.055025476962328, 0.05908203125]
~lftoa.value(a)  //--> "aber"

‹ Pact - Februari sinusdeklinationen ›