Clang wrap LLVM jit compiler in a UGen, and create source for it via Clang 


Clang.ar(input, mul, add)


Clang is a compiler for the C language which makes a special 'intermediate representation' which is understood by the LLVM jit compiler. This means that you can live code dsp functions in C, and hot swap the dsp function used by the Clang UGen. The ClangLiveCode class provides Document based support for this in SuperCollider. 


There can be multiple Clang UGens, each running some dsp function. The LLVM compiler is shared between instances (it is created globally in the plug-in) but each UGen will have its own independent dsp. 


Extensions

1) Can't get clang reporting of code compilation errors to print to SC post window at present

2) Should be able to create code files for standalone UGens once have a favourite working dsp function. Need to write wrapper for the C code dsp function, taking arbitrary UGen string name. 

3) Adding additional inputs, especially control rate. Presently just takes a single audio input. 


bugs: 

occasionall crashes as llvm gets confused about function declarations, e.g., if using lots of sin, cos etc

occasional crashes on freeing synths with out of memory error. Not sure why

may need to name each separate clang instance's dsp function individually. global llvm jit compiler danger at present. 

 



(

~clangsynth1= {

~clang = Clang.ar(SoundIn.ar);

Pan2.ar(SinOsc.ar*~clang,-0.3);

}.play

)


//set up a Document to live code the associated C function. Note that we need to know both the Synth Node and the index of the Clang UGen within the Synth

ClangLiveCode(~clangsynth1,~clang.synthIndex)



//Another:

(

~clangsynth2= {

~clang2 = Clang.ar(WhiteNoise.ar);

Pan2.ar(SinOsc.ar*~clang2,0.3);

}.play

)


ClangLiveCode(~clangsynth2,~clang2.synthIndex)






//TESTS//////////////////////////////////////////


//testing u_cmd explicitly

s.sendMsg("/u_cmd",b.nodeID,~clang.synthIndex,"newir","");


//Getting UGen indices via a SynthDef

a= SynthDef(\test,{ClangUGen.ar(SinOsc.ar*Saw.ar); Mix(SinOsc.ar([330,440]))})

c= List[]; 

a.children.do{|val,i| if(val.class==ClangUGen,{c.add(i)})}