Extending Snd with Eval-C and Snd-Rt
Total Page:16
File Type:pdf, Size:1020Kb
Extending Snd with Eval-C and Snd-Rt Kjetil Matheussen Norwegian network for Technology, Acoustic and Music. (NOTAM). Nedre Gate 5, 0551 OSLO, Norway, [email protected] Abstract Language features This paper presents two domain specific program- Guile Snd-Rt Eval-C ming environments made for extending Snd: Eval- C and Snd-Rt. Eval-C and Snd-Rt add another Interpreted x set of pragmatic and practical solutions for work- Compiled x x ing with music programming in Snd, from very low Closures x level to very high level, and both in realtime and Nested functions x x non-realtime. Functions as arguments x x x The software synthesizer program “San-Dysth” is Lisp lowlevel macros x x x also presented, since its programmed using Snd-Rt. Dynamic typing x And finally, Snd/Pd is presented, which makes Snd’s Static typing x x and Snd-Rt’s features available as a Pure Data (Pd) Type inference x external. Heap allocation x x Stack allocation x x Garbage collection x Keywords Runtime error checking x x1 Music programming, Snd, Programming languages, Can segfault x Lisp, Pure Data Speed 1 9 10 Hard realtime 0 10 5 Software overview Soft realtime 5 10 9 C library access 8 8 10 Name Description Vector read access 10 10 5 Vector write access 10 0 5 Snd A sound editor written by Bill List read access 10 10 5 Schottstaedt. List write access 10 0 5 Vct read access 10 10 5 Snd-ls A distribution of Snd. Vct write access 10 10 5 CLM A music synthesis and signal Signal bus access 0 10 2 processing package (Common CLM access 10 8 4 Lisp Music) written by Bill Schottstaedth. 1 Snd, Eval-C and Snd-Rt Snd-Rt A realtime music program- Eval-C and Snd-Rt are two domain specific ming environment running in- programming environments made for extending side Snd. Snd. Eval-C and Snd-Rt are implemented as Eval-C The programming language lisp low level macros running inside the Guile large parts of Snd-Rt is writ- Scheme implementation, and Guile again runs ten in. inside the Snd soundeditor. This means that San-Dysth A softsynth written in Snd- the three languages, Scheme, Snd-Rt and Eval- Rt. C, can be written and evaluated in the same source to provide an integrated and interactive Snd/Pd Snd running as a Pd external. environment. By combining Guile, Snd-Rt and Guile An R5RS Scheme interpreter. Eval-C, programmers get three levels of versatil- A community effort based on ity and execution speed which can all be used in the SCM Scheme implementa- 1Can be turned off, with the consequence of making tion by Aubrey Jaffer. Snd-Rt segfaultable and somewhat faster. the same source files. Snd/Pd, presented later, is programmed using all three languages. 2 Snd Figure 2: Snd-ls V0.9.8.3 Snd-ls has enabled various features which are Figure 1: Snd 9.4, vanilla not by default enabled in vanilla Snd. Snd-ls is also configured to run Snd-Rt and Eval-C code. Snd is an extendable sound editor made by Bill Schottstaedt. Here is a quote from the Snd 3 Eval-C manual: Eval-C is a language based on C, but using S-expressions as its syntax format. Using S- Snd is a highly customizable, extensi- expressions makes it possible to mix Scheme and ble program. I’ve tried to bring out Eval-C in the same source files and easily add to the extension language nearly ev- advanced syntactic features to the C language ery portion of Snd, both the signal- such as object oriented programming and eval- processing functions and much of the uation on the fly to support interactive develop- user interface. You can, for example, ment of programs. Evaluating and re-evaluating add your own menu choices, editing code on the fly makes it very convenient to add operations, or graphing alternatives. low-level features to Snd and Snd-Rt since its Nearly everything in Snd can be set not necessary to recompile and restart Snd while in an initialization file, loaded at any developing. time from a text file of program code, or specified in a saved state file. It can 3.1 Some features provided by Eval-C also be set via inter-process commu- • Integration of C-code from within Lisp. nication or from stdin from any other Scheme and C-code is mixed in the same program (CLM and Emacs in particu- source, and the two languages can interact lar), embedded in a keyboard macro, directly. or typed in the listener. • Direct access to C libraries Virtually everything in Snd can be cus- • Lisp-macros. tomized via extension languages. Currently, Snd supports the following implementations • Generate, compile, link, run and redefine as being extension language: Guile (Scheme), C-code on the fly in Emacs or other Lisp Gauche (Scheme), Ruby (Ruby) and FTH programming environments (Forth). • Same efficiency as C Snd also provides features such as interac- tion with Common Music (CM) and bindings • Same low-level features as C for CLM, Gtk, Motif, Xlib, OpenGL, etc. Snd • Extra macros to support features such as runs in Linux, Freebsd, MacOSx, Solaris, Win- arrays, shared structures, classes, and au- dows and probably many other Unix dialects. tomatic wrapping of C library functions. 2.1 Snd-ls 3.2 Hello world! Snd-ls2 is a distribution of Snd. 2Snd-ls stands for Snd-Non Lisper. I accidentally (eval-c "" wrote ls instead of nl in the beginning of the develop- (run-now ment (printf (string "Hello world!\\n")))) First argument to eval-c contains extra op- By evaluating the above code, a structure tions sent to the C compiler. called struct name will be available from guile. The rest of the arguments are Eval-C code. It can be used like this: Strings containing pure C-code can be used (define test (<struct name> :one 1 anywhere in Eval-C code, which is very handy :twos ’(2) when writing macros and providing C features. :three "three")) For example, the above example can also be (-> test one) => 1 written like this: (-> test one 90) (eval-c "" (-> test one) => 90 (run-now "printf(\"Hello World!\\n\")")) (-> test twos) => (2.0) To make an actual null-terminated string for (-> test twos ’(4 5 6)) C, the string special form must be used instead, (-> test twos) => (4.0 5.0 6.0) as in the first version. 3.3 The Fibonacci function (-> test three) => "three" The simplest Fibonacci function: (-> test three "four") > > (define-c <int> (fib ((<int> n)) (- test three) = "four" < (if ( n 2) (-> test scm) => #f (return n) (return (-> test scm (lambda (x) x)) (+ (fib (− n 1)) (-> test scm) => #<procedure #f ((x) x)> (fib (− n 2))))))) (fib 30) (-> test get-size) => 16 => 832040 (-> test get-c-object) define-c is a macro transforming its argu- => ("A POINTER" 147502592) ments into a call to eval-c. The function fib > above is transformed into: (- test destructor) ;;free it Modifiers and accessors are available for all (eval-c "" 4 slots. Known slot-types are SCM , char, int, (public float, double and char ∗, and arrays of those. C (<int> fib modifiers such as unsigned are treated appropri- (lambda ((<int> n)) ately. There are also functions to add new types (if (< n 2) which can be mapped to the known types. Slots (return n) with unknown types keep their names, but are (return (+ (fib (− n 1)) treated as pointers by Eval-C. (fib (− n 2))))))))) Ec-structs are extremely convenient when When evaluating the above block of code, the communicating with C programs since they con- eval-c macro uses gcc or icc to compile and link tain actual C structures. the code. The C object must unfortunately be freed manually5. This was in the example done by 3.4 Structures evaluating (-> test destructor). The macro define-ec-struct creates structures 4 3 SCM is the Guile datatype, which can hold any type which are shared between Eval-C, C and Guile : of Scheme object. However, care must in some situations be taken using SCM types in ec-structres, since Guile’s (define-ec-struct <struct name> garbage collector doesn’t scan ec-structure objects. The <int> one objects are also kept in the Scheme object though (ie. <float-∗> twos the variable test in the example), so usually this should not be a problem. <char-∗> three 5 < > Either using a general garbage collector for C, such SCM scm) as the one made by Hans Boehm, or use a Guile SMOB around the structures, would solve this problem. How- 3And hopefully Snd-Rt sometime into to future as ever, freeing ec-structures manually hasn’t been a big well issue yet. 4 Snd-Rt • <realtime> objects are started and Snd-Rt, or the RT extension for Snd, consists of stopped in realtime without sound two parts: glitches. The RT Engine - An engine for doing real- • Buses can be rerouted in realtime without time signal processing. sound glitches. The RT Compiler - A compiler for a Scheme- • Frame-accurate timing and scheduling like programming language to generate • Protection mechanism to avoid locking up realtime-safe code understood by the RT the computer if using too much CPU. Engine. • Controlled entirely from Scheme using The entire realtime engine and large parts of Guile, and, to a certain degree, from inside the compiler for Snd-Rt is written in Eval-C. the realtime objects themselves Nothing in the realtime engine or the RT lan- guage is written directly in C.