‹ Pact - Februarisinusdeklinationen ›

atolf lftoa

2011-02-17 01:10:25 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"

f0atolf screenshot f0ltfoa screenshot

‹ Pact - Februarisinusdeklinationen ›