
Hi Stephen,
From: Stephen Tetley
Hi John
For the user level stuff, I don't think CSound really has "functions" - either for the score or orchestra. The score I think is just a list of /notes/ with many, many parameters and the orchestra is a graph description saying how the UGens are connected.
This is good news - I believe Pan, Feldspar, Lava etc. generate
functions or procedures in the output code which means they have to involve the complicated techniques for embedding lambdas and functions in the EDSL. If they didn't, there would be massive code blow up. However because CSound is more or less "straight line" code - i.e. lines are interpreted sequentially, there are no procedures or functions to define and call - generating it should be much simpler.
Yes, exactly. I'm not interested in anything nearly as sophisticated, so those aren't great examples for me.
Andy Gill's Dot package on Hackage has a crafty, but simple technique to allow you to reference graph nodes and link them within a monad and output as "foreign" code - here dot files. Something similar might be satisfactory for orchestra files.
The orchestra graph is basically the issue I'm looking at (ignoring the score for now). My first implementation used an Orch monad very similar to the one used in Andy Gill's dotgen. It worked and the implementation was very straightforward, however I wanted to see if it was possible to create a non-monadic interface. That is, change my classes from class GenM repr a where sigGenM :: a -> repr (ASig repr) to class Gen repr a where sigGen :: repr a -> repr (ASig repr) This is in tagless-final style (which really is slick BTW); that's why everything is represented through type classes. The second version is really the one I want to use, although it was more work to implement. For the Csound interpreter, I needed a naming mechanism like TH's Q monad, along with some other machinery. So here's a very simple expression: t1 = let v = sigGen (cnst 1) in outs v v which is what led to my question. I'm binding the sigGen to 'v' to introduce sharing at the meta-level. Would it be better to introduce support for this in the dsl? Anyway, here are a few simple test expressions to provide the flavor of what I'm doing: -- additive synthesis, 20 partials of constant amplitude t6 = let so = sum . zipWith (oscil (cnst 1000)) [ cnst (110*f) | f <- [4..]] (replicate 20 1) in outs so so -- stacked frequency modulation using 4 oscillators t8 = let stack = foldr ($) (csig 40) (replicate 4 \fq -> oscil (cnst 1000) fq 1) in outs stack stack The edsl provides the functions "oscil", "cnst", "csig", and "outs", but most of the magic happens in the csound interpreter. Cheers, John