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;