dee68ef70ecc501633769734eea98e098704927c
[Faustine.git] / interpretor / faust-0.9.47mr3 / tools / faust2ck-1.0 / README
1
2 faust2ck - A FAUST wrapper-generator for ChucK Ugens.
3 ========
4
5 FAUST is a functional language for defining DSP structures that can be
6 used for real-time audio computing. It can generate block diagrams
7 and also C++ code which will execute the given routine.
8
9 This is an ideal way to create unit generators (UGens) for ChucK. The
10 ChucK data structures can be a bit weird and the learning curve for
11 hacking on ChucK can be a little steap. Using FAUST, you can
12 concentrate on the DSP algorithm, and allow faust2ck to take care of
13 creating ChucK-compatible C++ code so that you can instantiate your
14 new DSP object in a ChucK program.
15
16 That said, in order to take advantage of faust2ck, you'll need a
17 little C++ knowledge. At least enough to know how to compile ChucK
18 and add a line or two to its source code, which is explained in this
19 document.
20
21 Please see the FAUST websites for more details, online tutorials, and
22 even an online compiler that you can try:
23
24 http://faust.grame.fr/
25 http://sourceforge.net/projects/faudiostream/
26
27 This document describes how to use faust2ck.
28
29
30 Usage
31 =====
32
33 Running faust2ck with no parameters will give you a usage string:
34
35 $ ./faust2ck
36 Usage: faust2ck <filename.dsp.xml>
37
38 You can see that it requires a single input, the name of an XML file.
39 This XML file can be generated with FAUST by giving it the "-xml"
40 parameter:
41
42 $ faust -xml filename.dsp
43
44 faust2ck will then generate a file called "filename.dsp-wrapper.cpp".
45 (Where "filename" is whatever your file is called.)
46
47 This program is yet another input for FAUST. It is a C++ file, but it
48 has some tags in it that tell FAUST where to put the DSP code. So you
49 must run FAUST again, this time telling it to use the wrapper:
50
51 $ faust -a filename.dsp-wrapper.cpp -o filename.cpp filename.dsp
52
53 This gives you a final C++ file containing the algorithm along with
54 routines necessary to plug it in to ChucK.
55
56
57 Adding to ChucK
58 ---------------
59
60 Unfortunately there are a couple of manual steps necessary here.
61 ChucK does not currently support (rightly in my opinion) loadable
62 external modules, like other audio programs such as PureData.
63
64 So, you need to re-compile ChucK. First, we need to tell it about our
65 new C++ file. The first thing to do is create a header file. It only
66 needs to contain one line of code, enough to tell ChucK about a single
67 function declared in the C++ file.
68
69 If your DSP object is called 'mydsp', then your file, mydsp.h, should
70 look like this:
71
72 #ifndef __MYDSP_H__
73 #define __MYDSP_H__
74
75 DLL_QUERY mydsp_query( Chuck_DL_Query * QUERY );
76
77 #endif // __MYDSP_H__
78
79 Put this file in the ChucK source directory. Now you just have to add
80 a few lines to the file, 'chuck_compile.cpp'.
81
82 At the top of chuck_compile.cpp, add an #include statement for our
83 header file:
84
85 #include "mydsp.h"
86
87 Now, find the function "load_internal_modules()", which should be
88 around line 516. Add the necessary code to load your new module,
89 which is done by passing ChucK the "mydsp_query" function, where
90 "mydsp" is the name of your FAUST object.
91
92 EM_log( CK_LOG_SEVERE, "class 'mydsp'..." );
93 if( !load_module( env, mydsp_query, "mydsp", "global" ) ) goto error;
94
95 That's it!
96
97 The last thing to do is to add your C++ file to the makefile so that
98 it gets compiled along with ChucK. Depending on which operating
99 system you are using, load "makefile.alsa" for Linux, or
100 "makefile.win32" for Windows, or "makefile.osx" for OS X, etc.
101
102 There is a big list of filenames in a variable called OBJS. You need
103 to add "mydsp.o" to this list.
104
105 Lastly, you need to add a build target for mydsp.o to the bottom of
106 the file:
107
108 mydsp.o: mydsp.h mydsp.cpp
109 $(CXX) $(FLAGS) mydsp.cpp
110
111 Now, run "make", and if all goes well, ChucK will be built with your
112 object.
113
114 $ make
115
116 Time to create a test program! Make a simple ChucK program that looks
117 something like the following:
118
119 Impulse i => mydsp m => dac;
120 100 => t;
121 1 => i.next;
122 while (t>0) {
123 <<<m.last()>>>;
124 t--;
125 samp => now;
126 }
127
128 This will print the impulse response your object to the console. Good
129 luck! Have fun!
130
131 If you have any questions you can email me at:
132
133 Stephen Sinclair <radarsat1@gmail.com>
134
135
136 License
137 =======
138
139 This code is licensed under the GNU General Public License (GPL) v2 or
140 above. Please see COPYING for details, or visit:
141
142 http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
143
144
145
146 Technical
147 =========
148
149 You wrote a string parsing and XML reading program
150 like this, in 2008, in C ???! Are you mad?
151 --------------------------------------------------
152
153 Yes, a sane person would probably not do such a thing. The FAUST XML
154 output is so simple, however, and generally predictable, that I didn't
155 feel it was necessary to bring in a lot of external dependencies for
156 such a small application. So I ended up basically writing a small,
157 inadequate macro replacement parser, which was actually kind of fun.
158 Of course, if it ever called for more a complex solution I'd probably
159 re-do it in Perl or Python. But this'll do for now, and it means the
160 program is tiny and easy to execute on any computer without installing
161 huge libraries.
162
163 Of course, it does depend on 'sed' to generate the template for
164 inclusion in the final program. I wanted to include it right in the
165 executable instead of having faust2ck load an external file that would
166 always be exactly the same. Unfortunately the C preprocessor doesn't
167 make it easy, so sed is just used to wrap lines of the template file
168 in double-quotes ("") and backslash-escape a few special characters.
169
170 faust2ck is distributed with the template already generated so that it
171 can be compiled without needing to have sed around.
172
173
174 Why generate the C++ wrapper on demand instead of just writing a
175 better wrapper that doesn't need to change?
176 ----------------------------------------------------------------
177
178 If you look at the FAUST wrappers for PureData and Max/MSP, for
179 example, they are just a single file where FAUST replaces a certain
180 line with the DSP code class.
181
182 Unfortunately FAUST doesn't provide much for dynamically generating
183 code from the wrapper, other than a single replacement within the file
184 where it provides the DSP class. Specifically, for parameters
185 (declared in FAUST with "UI" elements like hslider and vslider), it
186 calls a function at run-time to inform the UI code about each
187 parameter. In the case of PureData and Max/MSP, it's possible to
188 instantiate parameters (inlets) at run-time, so this works well. In
189 ChucK however, each parameter needs a getter and setting function,
190 called "cget" and "ctrl", which must be made available statically at
191 compile time. (This isn't strictly true, these functions are "linked
192 in" to the rest of ChucK at run-time, but ChucK doesn't provide the
193 function with enough information to figure out which parameter it's
194 modifying, so each parameter needs its own function.)
195
196 Now, before writing faust2ck, I tried very hard to come up with some
197 kind of combination of preprocessor macros or C++ templates that would
198 do the job of instantiating a cget and ctrl function for each
199 parameter, but I just couldn't figure out a way to do it. If anyone
200 wants to give it a try, it's a nice challenging problem. In any case,
201 I realized I was wasting my time when a quick little program could
202 generate the appropriate wrapper easily enough, hence faust2ck.