[linux-audio-dev] [semi-OT] EEL 0.1.0

David Olofson david at olofson.net
Tue Jan 11 04:45:05 UTC 2005


On Tuesday 11 January 2005 04.22, Dave Robillard wrote:
[...]
> Yes, the basic sound production in ChucK is based on ugen networks,
> but the cool thing about the language is it's handling of time. 
> Time is essentially a variable, so you can do a bunch of
> operations, then increment time (ie "now += 1 second") and do some
> more operations.  It's really great for algorithmic composition and
> things like that.

Yeah, that's the part I'm particularly interested in.


> It's main attraction to me however is the ability to
> insert/delete/modify chunks of code on the fly, while everything
> runs. That would be ideal in a modular synth - those "chunks of
> code" are just modules.  The only problem is a chunk of ChucK code
> doesn't really have a way to specify inputs and outputs that I know
> of, so the language and/or vm would have to be modified a bit to
> allow coding of modules with arbitrary inputs and outputs.

Event ports or something? I'll probably integrate something like 
Audiality's event system (very similar to what was discussed for XAP) 
into the VM, with optimized types and VM instructions. There will be 
appropriate language constructs to go with that, of course, probably 
integrated with microthreads and "virtual time" timers. (Dealing with 
ticks, video frames, audio frames or whatever you want in your 
application, as opposed to real time, which is mostly irrelevant 
inside a graph with buffered I/O.)


> > > I need the guarantee that the audio thread of the language/VM
> > > is 100% realtime safe (ala the jack guidelines).
> >
> > That's a primary design goal for EEL (which is the main
> > difference from scripting languages in general) - but raw speed
> > is another matter. Of course, I'll try to make EEL as fast as
> > realistically possible, but as long as it isn't compiling into
> > native code, instructions will be expensive, and doing DSP by
> > actually operating on a single value per instruction (as opposed
> > to SIMD) is going to be very slow, compared to native code.
>
> Fast as realistically possible is fast enough for me. :)  If
> performance of a patch with code in it needs improving, one can
> always go write the LADSPA plugin. At least having a scripting 
> language available means you don't /have/ to write a LADSPA plugin
> to get something done.

Yeah. Well, to get an idea of what to expect, here's an example:

---------------------------------------------------------------
IM = 139968;
IA = 3877;
IC = 29573;
LAST = 42;

function gen_random(max)
{
 LAST = (LAST * IA + IC) % IM;
 return (max * LAST) / IM;
}

export procedure test[n]
{
 if specified n
  N = (integer) n;
 else
  N = 1;
 t = getms;
 print "  Trying ", N, "...\n";
 while N > 1
 {
  gen_random 100;
  N = N - 1;
 }
 print "      Time: ", (getms - t), " ms\n";
}

export function main<args>
{
 print "Random Number Generator benchmark:\n";
 if specified args[1]
  test args[1];
 else
 {
  test 1000;
  tv = gen_random 100;
  print "1000'nd value: ", tv, "\n";
  if (integer)(tv * 1000) != 8163
   throw "1000'nd value should be ca 8.163!";
 }
 print "Random Number Generator benchmark done.\n";
 return 0;
}
---------------------------------------------------------------

(Hmm... I have 'for' loops now. I should update this example a 
little! :-D )

'eel random.eel 10000000' (generates 1,000,000 pseudo random numbers) 
runs in about 4.1 seconds on my 933 MHz PIII. There are 24 VM 
instructions executed per number generated, so that's almost 6 MIPS.

Note that the code is really rather inefficient - or rather the VM, 
which does not (yet) provide operator instructions that work directly 
on static variables. The calling loop also generates rather ugly VM 
code. This should definitely not take 24 instructions in a virtual 
machine!

Here's gen_random() compiled:
|   |   |   .---------------------------------------
|   |   |   | function (1)gen_random(1)
|   |   |   | uvlevel: 2
|   |   |   |---------------------------------------
|   |   |   |     max              an argument, args[0]
|   |   |   |---------------------------------------
|   |   |   |     0: GETVAR  SV[3], R[1]
|   |   |   |     4: GETVAR  SV[1], R[2]
|   |   |   |     8: BINOP   R[1] MUL R[2], R[1]
|   |   |   |    13: GETVAR  SV[2], R[2]
|   |   |   |    17: BINOP   R[1] ADD R[2], R[1]
|   |   |   |    22: GETVAR  SV[0], R[2]
|   |   |   |    26: BINOP   R[1] MOD R[2], R[1]
|   |   |   |    31: SETVAR  R[1], SV[3]
|   |   |   |    35: INDGETI R[0][0], R[1]
|   |   |   |    39: GETVAR  SV[3], R[2]
|   |   |   |    43: BINOP   R[1] MUL R[2], R[1]
|   |   |   |    48: GETVAR  SV[0], R[2]
|   |   |   |    52: BINOP   R[1] DIV R[2], R[1]
|   |   |   |    57: RETURNR R[1]
|   |   |   |    59: RETURN
|   |   |   '---------------------------------------

Note all those GETVAR instructions! Not that the *work* they do 
matters much - but remember; this is a VM, and instruction decoding 
hurts like h*ll...

(Oh, and there's a dead RETURN too, but that's just because I don't 
trust the dead code eliminator right now. The "compiler event" system 
needs some minor changes, because it can't handle certain constructs 
as it is.)


> The fact that a primary design goal is RT safeness is very
> appealing, I'll take a good look at EEL as it stands..

That's the main reason why I started hacking EEL. I really need 
something that has "hard RT" as an official requirement; not just 
soft RT as a desirable feature, as is the case with most engines that 
are used for game scripting and the like.


> > Another problem (for me at least) is that the few alternatives
> > that looked interesting are either non-Free, or licensed in a way
> > that prevents using them in proprietary projects - which is
> > exactly what I need to do. (All my personal projects are
> > Free/Open Source, though.)
>
> I prefer the GPL myself, but as long as EEL is free software (I
> assume BSD?) it's okay with me.

It's LGPL, because the GPL would prevent the use of EEL in non-Free 
applications, which is not what I intend.

I'm considering dual-licensing with MIT/X11 as well, since the LGPL 
seems to make a lot of developers from the non-Free world nervous... 
(Game developers in particular, which I suspect might be rather 
interested in EEL.) It may be useful to customize the VM and/or 
compiler for some applications, and that's where the LGPL actually 
does cause problems. I'd rather have people (ab)using my code and 
*maybe* contributing something, than scare them away and not even 
hear a complaint about the license.


//David Olofson - Programmer, Composer, Open Source Advocate

.- Audiality -----------------------------------------------.
|  Free/Open Source audio engine for games and multimedia.  |
| MIDI, modular synthesis, real time effects, scripting,... |
`-----------------------------------> http://audiality.org -'
   --- http://olofson.net --- http://www.reologica.se ---



More information about the Linux-audio-dev mailing list