packages feed

hsc3-db-0.15: scd/gen-db.scd

/* PV_ operates at kr but message is \new.  Demand operates at \dr but message is \new. */
var is_demand = {
    arg o;
    [Dibrown,Diwhite,Dswitch,Dunique].includes(o) || [ListDUGen,DUGen].includes(o.superclass);
};

/* PV_ operates at kr but message is \new. */
var is_PV = {arg o; var nm = o.asString; (nm == "FFT") || (nm.find("PV_") == 0)};

var to_upper = {arg o; o.asString.toUpper.asSymbol};

var find_method_r = {
    arg o, n;
    var m = o.findMethod(n);
    var p = o.superclass;
    if(m.notNil, {m}, {if(p.notNil, {find_method_r.(p,n)}, {nil})});
};

var supports_rate = {arg o, r; find_method_r.(o.class,r) != nil};

var supported_rates = {
    arg o;
    var d = if(is_demand.(o), {[\dr]}, {[]});
    var pv = if(is_PV.(o), {[\kr]}, {[]});
    [\ar,\kr,\dr,\ir].select({arg r; supports_rate.(o,r)}) ++ d ++ pv;
};

var input_names = {
    arg nm, o, r;
    var n = find_method_r.(o.class,r).argNames;
    var x = [
        'this','mul','add',
        'selector', // uop & binop
    ];
    var f = {arg e; x.includes(e)};
    n.reject(f);
};

var input_default = {
    arg o, r ,nm;
    var m = find_method_r.(o.class,r);
    var n = m.argNames;
    var i = n.detectIndex({arg e; e == nm});
    m.prototypeFrame[i];
};

/* Lag etc. and Ramp and Slew optimise constants to constants... */
var number_of_outputs = {
    arg o, r;
    try {var u = o.perform(r); if(u.isArray,{u.size},{if(u.isFloat,{0},{1})})} {arg err; 1};
};

/* these inputs are, in fact, all named numChannels or numChans... */
var nc_input = {arg o; nil};

var ugen_db = {
    arg o;
    var nm = o.name.asString;
    var rt_all = supported_rates.(o);
    var rt_def = if(rt_all.isEmpty, {\ir}, {rt_all[0]});
    var rt_cons = if(is_demand.(o) || is_PV.(o) || rt_all.isEmpty, {\new}, {rt_def});
    var n_a = input_names.(nm,o,rt_cons);
    var n = n_a;
    var nn = n.collect({arg e; [e.asString, input_default.(o,rt_cons,e)]});
    var no = number_of_outputs.(o, rt_cons);
    var h_m = SCDoc.documents.at("Classes/"++nm);
    var h = if(h_m==nil, {"No summary"}, {h_m.summary});
    [nm,rt_all,rt_def,nn,no,h];
};

var ugen_db_haskell = {
    arg o;
    var db = ugen_db.(o);
    var nm = db[0].asCompileString;
    var rr = db[1].collect(to_upper);
    var rr_ = "[" ++ rr.collect({arg r; r.asString}).join(",") ++ "]";
    var dr = to_upper.(db[2]);
    var ii = db[3].collect({
        arg e;
        var nm = e[0].asCompileString;
        var df = if(e[1] == nil, {"0"}, {"(" ++ e[1].asString ++ ")"});
        "I" + nm + df;
    }).join(",");
    var o_n = db[4].asString;
    var h = db[5].asCompileString;
    "(" ++ [nm,rr_,dr,"[" ++ ii ++ "]",o_n,h].join(",") ++ ")";
};

var all_subclasses_of = {
    arg o;
    var u = o.subclasses;
    if(u.size == 0, {[]}, {u ++ u.collect({arg e; all_subclasses_of.(e)}).flatten});
};

// 'BinaryOpUgen' and 'UnaryOpUGen' are required by hsc3-forth
var ignoring = [
    'AbstractIn','AbstractOut',
    'BasicOpUGen','BufInfoUGenBase','DUGen','Filter','ListDUGen',
    'MultiOutUGen','OutputProxy','PureMultiOutUGen','PureUGen',
    'SharedIn','SharedOut',
    'BEQSuite','ChaosGen','ClearBuf','SendPeakRMS','SendReply',
    'FFTTrigger','PackFFT','Unpack1FFT','UnpackFFT',
    'Control','MulAdd',
    'Changed','DynKlang','DynKlank','InBus','LagControl','Splay','SplayAz','Tap', /* derived */
    'SetBuf', /* implicit length input */
    'MaxLocalBufs' /* count input */
];

var uu_a = all_subclasses_of.(UGen).sort({arg a, b; a.name < b.name});

var uu = uu_a.reject({arg u; ignoring.includes(u.name.asSymbol)});

var haskell_preamble = [
    Date.getDate.format("-- AUTOGENERATED: %Y-%m-%d-%Hh%M"),
    "module Sound.SC3.UGen.DB.Data where",
    "import Sound.SC3.UGen.DB.Record",
    "import Sound.SC3.UGen.Rate",
    "sc3_ugenDB :: [SC3_U]",
    "sc3_ugenDB = ["
];

var haskell_postamble = [
    "         ]",
    "-- Local Variables:",
    "-- truncate-lines:t",
    "-- End:"
];

var haskell_write = {
    arg uu;
    haskell_preamble.join("\n").postln;
    uu.do({
        arg e, n;
        if(n == 0, {"    "}, {"    ,"}).post;
        ugen_db_haskell.(e).postln;
    });
    haskell_postamble.join("\n").postln;
};

haskell_write.(uu);
0.exit;