1# SmartKeyboard Mobile App Generator Documentation
2
3`faust2smartkeyb` is a tool to generate ready-to-use musical Android and iOS applications using the [Faust programming language](http://faust.grame.fr). Unlike [`faust2android`](https://ccrma.stanford.edu/~rmichon/faust2android/) and `faust2ios`, `faust2smartkeyb` ignores the standard user interface (UI) declared in the Faust code (e.g., `hslider`, `button`, etc.), and replaces it by a `SmartKeyboard` UI.
4
5The `SmartKeyboard` UI allows to implement a wide range of controllers (basic keyboards, isomorphic keyboards, pads, X/Y controllers, etc.) on a touch-screen and can be configured directly in the Faust code using the `SmartKeyboard` metadata.
6
7This documentation demonstrates how to use `faust2smartkeyb` and provides [a series of links to tutorials on how to turn mobile devices into musical instruments](#additional-resources).
8
9`faust2smartkeyb` is part of the [Faust distribution](https://github.com/grame-cncm/faust) and will be automatically installed on your system with the latest version of Faust.
10
11WARNING: this tool is still being beta tested and there are probably a few bugs. If you find a bug, please report it to rmichon_at_ccrma_dot_stanford_dot_edu.
12
13## Compatibility
14
15Apps generated with `faust2smartkeyb` should work on any iOS device running a "reasonably recent" version of iOS (less than 4 years old). Things are a bit more restrictive on Android and target devices must run at least on *Jelly Bean* (version 4.1). However, for optimal performances (especially regarding latency), we recommend you to be at least on *KitKat* (5.0). Interested readers might want to read [this page on Android audio latency](https://source.android.com/devices/audio/latency_measurements.html) to learn more about this topic.
16
17## Setting Up Your System
18
19This section shows how to configure your system to use the various features of `faust2smartkeyb`.
20
21### iOS
22
23Aaaaah iOS... This OS has been (and still is, even though Android is catching up fast) by far the best one to make musical apps involving real-time audio DSP. However, Apple likes to make the life of developers hard, and in order to develop apps for this platform, you used to need to have an Apple developer account ($100/year, yes). Things changed since then, and it is now possible to develop iOS apps and upload them on your device for free! However, the number of apps you can install using this technique is very limited (5, if I remember correctly). Oh, and needless to say that YOU WILL NEED A MAC to generate iOS apps with `faust2smartkeyb`.
24
25In any case, to use `faust2smartkeyb` (as well as `faust2ios`) or to do any kind of iOS development in general, you will either need a "pro" Apple developer account or a free one. This documentation doesn't show how to take care of that. For more information about this, visit the [Apple website](https://developer.apple.com/). Good luck!
26
27Once you took care of this, make sure that Xcode is properly installed on your system (using the Apple Store, not some weird technique) and that it is UP-TO-DATE. A little bit more Apple c[...]p: if the iOS device you're using is running the latest version of iOS, then you will need to have the latest version of the iOS SDK installed on your system. Unfortunately, the only way to do that is to also have the latest version Xcode which will require the latest version of OSX! Once again, good luck!
28
29After all these steps, you should be ready to go.
30
31### Android
32
33Android apps can be developed on all major platforms (Windows, OSX and Linux). Unlike Apple (see previous section), Google provides a lot more flexibility to app developers and it is not required to sign up for any developer account in order to install apps on your device. On the other hand, the installation of the Android development tool chain is a little bit more complex than on iOS. It should be quite similar on Linux and OSX and we describe it below. We don't provide information for Windows since `faust2smartkeyb` will probably not work at all on this platform (sorry).
34
35First, install [Android studio](https://developer.android.com/studio/index.html). When you run it for the first time, we advise you to choose the option where you don't import previous settings (unless you know what you're doing, of course). Then, during the configuration process, choose a "Standard" setup. The sdk installation path should be prompted to you after that. Take note of it as we'll need it later (should be `~/Library/Android/sdk` on OSX). Once Android studio finished setting up, click on "Configure" and then "SDK Manager" (you might have to go in "Tools/Android/SDK Manager" on Linux). In the `SDK Tools` tab, install the [NDK (Native Development Kit)](https://developer.android.com/ndk/index.html) which is necessary to compile apps generated by `faust2smartkeyb` (`faust2smartkeyb` uses `faust2api` internally, if you want to get more details about why you need to do all that, have a look at the [`faust2api` documentation](https://ccrma.stanford.edu/~rmichon/faust2api/)).
36
37In order to be able to compile Android apps in your terminal, you must configure the `ANDROID_HOME` and `ANDROID_NDK_HOME` environment variables so that they point to where the `sdk` and the `ndk` are installed. To do this, add the following line to `~/.bashrc` on Linux or `~/.bash_profile` on OSX (if this file doesn't exist, create it):
38
39```
40export ANDROID_HOME=/home/r/Android/Sdk
41export ANDROID_NDK_HOME=$ANDROID_HOME/ndk-bundle
42```
43
44where paths should be replaced with the ones on your system, of course.
45
46Finally, if you want to be able to install the generated Android apps directly from `faust2smartkeyb`, you will have to install `adb` on your system using your package manager.
47
48That's it! You're now ready to forge Android apps with `faust2smartkeyb`!
49
50<!--
51Say something about the first time you run it and gradle doing its shit
52-->
53
54## Quick Tour: From a Simple Faust Code to a Working App
55
56`faust2smartkeyb` uses `faust2api` internally. Thus, Faust codes provided to `faust2smartkeyb` must respect the same standards as for `faust2api` (check the [`faust2api` documentation](https://ccrma.stanford.edu/~rmichon/faust2api/) for more information about this).
57
58The following code is similar to the one presented in the [`faust2api` documentation](https://ccrma.stanford.edu/~rmichon/faust2api/) in the [MIDI Enabled Polyphonic Object](https://ccrma.stanford.edu/~rmichon/faust2api/#midi-enabled-polyphonic-object):
59
60```
61import("stdfaust.lib");
62freq = nentry("freq",200,40,2000,0.01);
63gain = nentry("gain",1,0,1,0.01);
64gate = button("gate");
65cutoff = 1000;
66envelope = gate*gate : si.smoo;
67process = os.sawtooth(freq)*envelope : fi.lowpass(3,cutoff) : *(0.25) <: _,_;
68```
69
70It implements a simple synthesizer based on a filtered sawtooth wave and it is polyphony-compatible thanks to its `freq`, `gain`, and `gate` parameters. Note, that the gain of the synth is scaled. This is done to prevent clicking if several polyphony voices are played at the same time. When using an effect with a synth, it's better practice to carry out this type of gain scaling in the effect section to save up computation (see [`effect`](#effect)).
71
72If this code is provided as such to `faust2smartkeyb`, its UI declaration will be ignored and replaced by the default `SmartKeyboard` interface. This interface can be configured at the beginning of the Faust code using the `SmartKeyboard` metadata:
73
74```
75declare interface "SmartKeyboard{
76	// configuration keys
77}";
78```
79
80and by placing a set of [key/value pairs](#smartkeyboard-configuration-keys) between the two curly brackets. For example,
81
82```
83declare interface "SmartKeyboard{
84	'Number of Keyboards':'2',
85	'Keyboard 0 - Number of Keys':'13',
86	'Keyboard 1 - Number of Keys':'13',
87	'Keyboard 0 - Lowest Key':'72',
88	'Keyboard 1 - Lowest Key':'60'
89}";
90```
91
92will create an interface with 2 keyboards of 13 keys each. The lowest note of the top keyboard will be MIDI note 72 (C4), and the lowest note of the other keyboard will be 60 (C3).
93
94A `SmartKeyboard` interface can stream a set of [standard Faust parameters](#smartkeyboard-standard-parameters) to control the given Faust DSP. For example, the cutoff frequency of the lowpass filter of the previous Faust code can be controlled with the Y position of the finger on the key simply by adding `'Keyboard 0 - Send Y':'1','Keyboard 1 - Send Y':'1'` to the interface declaration and by using the associated standard [`y`](#y) parameter:
95
96```
97fingerY = nentry("y",0.5,0,1,0.01) : si.smoo; // y is always normalized between 0 and 1
98cutoff = fingerY*1960+40; // mapping
99```
100
101The two following sections give an overview of the different [configuration keys](#smartkeyboard-configuration-keys) and [standard parameters](#smartkeyboard-standard-parameters) that can be used with `SmartKeyboard` interfaces. Also, the [Additional Resources](#additional-resources) section provides links to tutorials on how to design various kinds of instruments using this system. We recommend you to check these resources since complex mappings (that are not presented here) can be created by combining different interface configurations with specific uses of standard parameters. Example codes can be found in the `/examples/smartKeyboard` folder of the Faust distribution. Finally, the [Compilation](#compilation) section demonstrates how to compile Faust codes such as the one presented above using `faust2smartkeyb`.
102
103## SmartKeyboard Configuration Keys
104
105This section presents the different configurations keys of `SmartKeyboard` and their function. For practical use cases, check the [Additional Resources](#additional-resources) section.
106
107### `Inter-Keyboard Slide`
108
109When 1, fingers can slide between keyboards.
110
111Default value: 1
112
113---
114
115### `Keyboard M - Key N - Label`
116
117Allows to set the text inside a key on a specific keyboard. The corresponding value should be a string.
118
119Default value: null
120
121This is a keyboard and key specific parameter where `M` is the keyboard number and `N` the key number.
122
123---
124
125### `Keyboard N - Lowest Key`
126
127Defines the MIDI note number of the lowest key on a specific keyboard.
128
129Default value: 48
130
131This is a keyboard-specific parameter. For example, if `Number of Keyboards = 2`, then there are 2 keyboards in the interface that can be configured independently with the `Keyboard 0 - Lowest Key` and the `Keyboard 1 - Lowest Key` keys.
132
133---
134
135### `Keyboard N - Number of Keys`
136
137Defines the number of keys of a specific keyboard in the interface.
138
139Default value: 13
140
141This is a keyboard-specific parameter. For example, if `Number of Keyboards = 2`, then there are 2 keyboards in the interface that can be configured independently with the `Keyboard 0 - Number of Keys` and the `Keyboard 1 - Number of Keys` keys.
142
143---
144
145### `Keyboard N - Orientation`
146
147Defines the orientation of a specific keyboard: left to right when 0 and right to left when 1.
148
149Default value: 0
150
151This is a keyboard-specific parameter. For example, if `Number of Keyboards = 2`, then there are 2 keyboards in the interface that can be configured independently with the `Keyboard 0 - Orientation` and the `Keyboard 1 - Orientation` keys.
152
153---
154
155### `Keyboard N - Piano Keyboard`
156
157When 1, note names are displayed and black and white keys are differentiated (if 0, all keys are white).
158
159Default value: 1
160
161This is a keyboard-specific parameter. For example, if `Number of Keyboards = 2`, then there are 2 keyboards in the interface that can be configured independently with the `Keyboard 0 - Piano Keyboard` and the `Keyboard 1 - Piano Keyboard` keys.
162
163---
164
165### `Keyboard N - Root Position`
166
167Position of the root (as a key number starting from 0) on a specific keyboard. This parameter is very useful when dealing with [specific scales](#keyboard-n---scale).
168
169Default value: 0
170
171This is a keyboard-specific parameter. For example, if `Number of Keyboards = 2`, then there are 2 keyboards in the interface that can be configured independently with the `Keyboard 0 - Root Position` and the `Keyboard 1 - Root Position` keys.
172
173---
174
175### `Keyboard N - Scale`
176
177Defines the scale of a specific keyboard.
178
179Default value: 0
180
181With:
182
183* `Keyboard N - Scale = 0`: Chromatic scale, note names are displayed
184* `Keyboard N - Scale = 1`: Chromatic scale, note names are not displayed
185* `Keyboard N - Scale = 2`: Major scale, note names are not displayed
186* `Keyboard N - Scale = 3`: Harmonic minor scale, note names are not displayed
187
188Custom scales can be created by specifying an array of intervals. For example, the chromatic scale can be defined as `Keyboard N - Scale = {1,1,1,1,1,1,1,1,1,1,1,1}` where the `1`s are the intervals in semitones between each note. The only rule is that the sum of the intervals specified in the array must always be equal to 12. For example, the major scale can be declared as `Keyboard N - Scale = {2,2,1,2,2,2,1}`.
189
190This is a keyboard-specific parameter. For example, if `Number of Keyboards = 2`, then there are 2 keyboards in the interface that can be configured independently with the `Keyboard 0 - Scale` and the `Keyboard 1 - Scale` keys.
191
192---
193
194### `Keyboard N - Send Freq`
195
196When 1, the [`freq`](#freq) and [`bend`](#bend) parameters are computed and sent to the Faust DSP object.
197
198Default value: 1
199
200This is a keyboard-specific parameter. For example, if `Number of Keyboards = 2`, then there are 2 keyboards in the interface that can be configured independently with the `Keyboard 0 - Send Freq` and the `Keyboard 1 - Send Freq` keys.
201
202---
203
204### `Keyboard N - Send Key X`
205
206When 1, send the normalized X position of the finger in the current key (associated with the [`kbMkNx`](#kbmknx) standard parameter where `M` is the current keyboard and `N` is the current key).
207
208Default value: 0
209
210This is a keyboard-specific parameter. For example, if `Number of Keyboards = 2`, then there are 2 keyboards in the interface that can be configured independently with the `Keyboard 0 - Send Key X` and the `Keyboard 1 - Send Key X` keys.
211
212---
213
214### `Keyboard N - Send Key Y`
215
216When 1, send the normalized Y position of the finger in the current key (associated with the [`kbMkNy`](#kbmkny) standard parameter where `M` is the current keyboard and `N` is the current key).
217
218Default value: 0
219
220This is a keyboard-specific parameter. For example, if `Number of Keyboards = 2`, then there are 2 keyboards in the interface that can be configured independently with the `Keyboard 0 - Send Key Y` and the `Keyboard 1 - Send Key Y` keys.
221
222---
223
224### `Keyboard N - Send Key Status`
225
226When 1, send the status of the current key (associated with the [`kbMkNstatus`](#kbmknstatus)).
227
228Default value: 0
229
230This is a keyboard-specific parameter. For example, if `Number of Keyboards = 2`, then there are 2 keyboards in the interface that can be configured independently with the `Keyboard 0 - Send Key Status` and the `Keyboard 1 - Send Key Status` keys.
231
232---
233
234### `Keyboard N - Send Numbered X`
235
236When 1, send the normalized X position of the finger in the current key for a specific finger (associated with the [`xN`](#xn) standard parameter).
237
238Default value: 0
239
240This is a keyboard-specific parameter. For example, if `Number of Keyboards = 2`, then there are 2 keyboards in the interface that can be configured independently with the `Keyboard 0 - Send Numbered X` and the `Keyboard 1 - Send Numbered X` keys.
241
242---
243
244### `Keyboard N - Send Numbered Y`
245
246When 1, send the normalized Y position of the finger in the current key for a specific finger (associated with the [`yN`](#yn) standard parameter).
247
248Default value: 0
249
250This is a keyboard-specific parameter. For example, if `Number of Keyboards = 2`, then there are 2 keyboards in the interface that can be configured independently with the `Keyboard 0 - Send Numbered Y` and the `Keyboard 1 - Send Numbered Y` keys.
251
252---
253
254### `Keyboard N - Send X`
255
256When 1, send the normalized x position of the finger in the current key (associated with the [`x`](#x) standard parameter).
257
258Default value: 0
259
260This is a keyboard-specific parameter. For example, if `Number of Keyboards = 2`, then there are 2 keyboards in the interface that can be configured independently with the `Keyboard 0 - Send X` and the `Keyboard 1 - Send X` keys.
261
262---
263
264### `Keyboard N - Send Y`
265
266When 1, send the normalized y position of the finger in the current key (associated with the [`y`](#y) standard parameter).
267
268Default value: 0
269
270This is a keyboard-specific parameter. For example, if `Number of Keyboards = 2`, then there are 2 keyboards in the interface that can be configured independently with the `Keyboard 0 - Send Y` and the `Keyboard 1 - Send Y` keys.
271
272---
273
274### `Keyboard N - Show Labels`
275
276When 1, shows note names on a specific keyboard. This parameter is overridden if [`Keyboard N - Piano Keyboard`](#keyboard-n---piano-keyboard) is defined.
277
278Default value: 1
279
280This is a keyboard-specific parameter. For example, if `Number of Keyboards = 2`, then there are 2 keyboards in the interface that can be configured independently with the `Keyboard 0 - Show Labels` and the `Keyboard 1 - Show Labels` keys.
281
282---
283
284### `Keyboard N - Static Mode`
285
286When 1, keys don't change color when touched.
287
288Default value: 0
289
290This is a keyboard-specific parameter. For example, if `Number of Keyboards = 2`, then there are 2 keyboards in the interface that can be configured independently with the `Keyboard 0 - Static Mode` and the `Keyboard 1 - Static Mode` keys.
291
292---
293
294### `Number of Keyboards`
295
296Defines the number of keyboards in the interface.
297
298Default value: 1
299
300---
301
302### `Max Fingers`
303
304Defines the maximum number of fingers allowed on the touch-screen. This parameter is independent from the number of polyphony voices of the DSP object.
305
306Default value: 10.
307
308---
309
310### `Max Keyboard Polyphony`
311
312Defines the number of polyphony voices of each keyboard (and more, see below).
313
314Default value: 16
315
316This parameter has some special cases:
317
318* `Max Keyboard Polyphony = 1`: in that case, keyboards are monophonic. Monophonic mode can be configured using the [`Mono Mode`](#mono-mode) key.
319* `Max Keyboard Polyphony = 0`: the first voice of the DSP object is activated. This is very convenient to create an app generating a continuous sound or based on a physical model of a musical instrument. The voice allocation system is deactivated in that case (although the `freq` and `bend` parameters can still be sent using the [`Keyboard N - Send Freq`](#keyboard-n---send-freq) option).
320
321---
322
323### `Mono Mode`
324
325Configures the way monophonic keyboards work. Keyboards are made monophonic by setting [`Max Keyboard Polyphony`](#max-keyboard-polyphony) to 1.
326
327Default value: 1
328
329With:
330
331* `Mono Mode = 0`: the finger currently on the keyboard keeps priority: all other fingers are ignored.
332* `Mono Mode = 1`: priority goes to any new finger on the keyboard. When the finger holding the note leaves the keyboard, the note is transferred to the closest finger on the same keyboard. This mode is probably the most natural one to implement a guitar interface, for example.
333* `Mono Mode = 2`: priority goes to any new finger on the keyboard. When the finger holding the note leaves the keyboard, the note is terminated.
334* `Mono Mode = 3`: same as `Mono Mode = 1`, but priority is given to new fingers only if they are at higher pitch than the current note.
335* `Mono Mode = 4`: same as `Mono Mode = 1`, but priority is given to new fingers only if they are at lower pitch than the current note.
336
337---
338
339### `Rounding Cycles`
340
341The number of cycles before rounding is activated.
342
343Default value: 5
344
345---
346
347### `Rounding Mode`
348
349Configures the way the [`bend`](#bend) parameter associated with the current finger is quantized.
350
351Default value: 0
352
353With:
354
355* `Rounding Mode = 0`: keys are rounded to the nearest integer: [`bend`](#bend) is always equal to zero.
356* `Rounding Mode = 1`: [`bend`](#bend) is continuous (new notes might sound out of tune).
357* `Rounding Mode = 2`: keys are rounded to the nearest integer when the finger is not moving or when a new note is started but become continuous when fast movement are happening. The behavior of this system can be fine-tuned using the [`Rounding Update Speed`](#rounding-update-speed), [`Rounding Smooth`](#rounding-smooth), [`Rounding Threshold`](#rounding-threshold) and [`Rounding Cycles`](#rounding-cycles) parameters.
358
359---
360
361### `Rounding Smooth`
362
363The pole of the integrators used for smoothing movements during rounding.
364
365Default value: 0.9
366
367---
368
369### `Rounding Threshold`
370
371Rounding is deactivated when the output of the smoothers (see [`Rounding Threshold`](#rounding-threshold)) goes above this value.
372
373Default value: 3
374
375---
376
377### `Rounding Update Speed`
378
379Speed in seconds at which the rounding loop is updated.
380
381Default value: 0.06
382
383---
384
385### `Send Current Key`
386
387When 1, send the number of the current key in the current keyboard (associated with the [`key`](#key) standard parameter).
388
389Default value: 1
390
391---
392
393### `Send Current Keyboard`
394
395When 1, send the number of the current keyboard (associated with the [`keyboard`](#keyboard) standard parameter).
396
397Default value: 1
398
399---
400
401### `Send Fingers Count`
402
403Send the number of fingers present on each keyboard using the [`kbNfingers` standard parameter](#kbnfingers) where `N` is the keyboard number.
404
405Default value: 0
406
407---
408
409### `Send Sensors`
410
411When 1, sends the raw sensor (accelerometer and gyroscope) values to the DSP
412object. If the `acc` metedata is declared with one of the parameters, sensors
413data will be used to control this parameter through a specified mapping.
414
415Default value: 1
416
417---
418
419## SmartKeyboard Standard Parameters
420
421This section presents the different standard Faust parameters that can be used with `SmartKeyboard` interfaces. For practical use cases, check the [Additional Resources](#additional-resources) section. Also, example codes can be found in the `/examples/smartKeyboard` folder of [the Faust distribution](https://github.com/grame-cncm/faust).
422
423### `freq`
424
425The reference frequency in Hz of the current event. This value is provided at the same time than [`gate`](#gate) and only once. To implement continuous pitch control such as slides, vibrato, etc. use the [`bend`](#bend) parameter.
426
427---
428
429### `bend`
430
431A coefficient to multiply to `freq` to bend it (`bend = 1` corresponds to no bend so `continuousFreq = freq*bend`). This parameter can be used to implement vibrato, slides, etc. It heavily relies on [`Rounding Mode`](#rounding-mode).
432
433---
434
435### `gate`
436
437The trigger signal sent when a finger touches the screen (1) or when it stops touching it (0). If `Rounding Mode = 0`, then "0" and "1" are sent everytime a finger slides to a new key (a new voice is allocated everytime).
438
439---
440
441### `key`
442
443The key ID in the current keyboard.
444
445---
446
447### `keyboard`
448
449The ID of the current keyboard.
450
451---
452
453### `kbNfingers`
454
455The number of fingers present on a specific keyboard `N`.
456
457---
458
459### `kbMkNstatus`
460
461Status of the current key `N` in keyboard `M` with:
462
463* `status==0`: finger up on the key
464* `status==1`: finger down on the key
465* `status==2`: finger is moving inside the key
466* `status==3`: finger moved to another key
467* `status==4`: finger moved from one key to the current key
468
469---
470
471### `kbMkNx`
472
473The normalized (0-1) X position of the finger in a specific key where `M` is the current keyboard and `N` is the current key.
474
475---
476
477### `kbMkNy`
478
479The normalized (0-1) Y position of the finger in a specific key where `M` is the current keyboard and `N` is the current key.
480
481---
482
483### `x`
484
485The normalized (0-1) X position of the finger in the current key.
486
487---
488
489### `y`
490
491The normalized (0-1) Y position of the finger in the current key.
492
493---
494
495### `xN`
496
497The normalized (0-1) X position of the finger in the current key for a specific finger where `N` is the finger ID in order of appearance on the screen starting from 0 (e.g., `x0` for the X position of the first active finger to touch the screen, `x1` for the X position of the second active finger to touch the screen, etc.).
498
499---
500
501### `yN`
502
503The normalized (0-1) Y position of the finger in the current key for a specific finger where `N` is the finger ID in order of appearance on the screen starting from 0 (e.g., `y0` for the Y position of the first active finger to touch the screen, `y1` for the Y position of the second active finger to touch the screen, etc.).
504
505---
506
507## Compilation
508
509### Overview
510
511We assume that you followed the steps described in the [Setting-Up Your System](#setting-up-your-system) section before reading this. Only 2 arguments are required to use `faust2smartkeyb`: the target platform (iOS or Android) and a Faust code:
512
513```
514faust2smartkeyb -ios mySynth.dsp
515```
516
517will compile `mySynth.dsp` into an iOS app (`mySynth.app`) with a `SmartKeyboard` interface and
518
519```
520faust2smartkeyb -android mySynth.dsp
521```
522
523will do the same for Android (`mySynth.apk`).
524
525While this should be very smooth on Android if your followed the steps in [Setting-Up Your System](#setting-up-your-system), this will probably not work on iOS. Why? Because the bundle identifier associated with the template app used to compile a `SmartKeyboard` app for iOS is not yours. So unless you change it directly in the source code of the Faust distribution (`/architecture/smartKeyboard/iOS/Faust.xcodeproj`) and re-install Faust, it will not work (yes, we know, we know... :( ).
526
527However, in practice, you'll rarely want to compile directly your Faust code into an app package. Instead, you might prefer to create an Android Studio on an Xcode project associated to your Faust code and update it when necessary. This is a much better solution because compiling an app from scratch every time (especially on Android) takes a lot of time (>1 minute in most cases). To do this, you can use the [`-source`](#source) option in combination with [`-reuse`](#reuse):
528
529```
530faust2smartkeyb -android -source -reuse mySynth.dsp
531```
532
533In that case, `faust2smartkeyb` will not compile `mySynth.dsp` to an app but will create a folder called `faustsmartkeyb.mySynth` in the current folder containing an Android Studio project. Every time the previous command will be run, the portion of the app source code corresponding to `mySynth.dsp` will be updated (if we only used `-source` without `-reuse` then `faustsmartkeyb.mySynth` would be erased and re-created). The same steps can be followed when using `-ios`.
534
535The app can be easily installed on your device from Xcode or Android Studio. On iOS, bundle identifier issues can be fixed directly in the Xcode project contained in `faustsmartkeyb.mySynth` which is more convenient than doing it in the Faust source code.
536
537The end of this section gives an overview of the different options that can be used with `faust2smartkeyb`.
538
539### `-android`
540
541Asks `faust2smartkeyb` to generate an Android application.
542
543---
544
545### `-debug`
546
547Debug mode: prints all the details.
548
549---
550
551### `-effect`
552
553Allows to specify an effect Faust file to be connect to the provided synth file. For example:
554
555```
556faust2smartkeyb -android -effect effect.dsp synth.dsp
557```
558
559Will compile an app where `synth.dsp` is the Faust code containing the source for the polyphonic synthesizer and `effect.dsp` the effect chain that will be connected to the output of the polyphonic synth. Indeed, in most cases, it is not necessary to have a different effect chain for each voice.
560
561---
562
563### `-help`
564
565Prints the documentation of `faust2smartkeyb`.
566
567---
568
569### `-install`
570
571Installs the generated app on any device connected to the computer. This option is only available on Android and requires `adb` to be installed on your system.
572
573---
574
575### `-ios`
576
577Asks `faust2smartkeyb` to generate an iOS application.
578
579---
580
581### `-nvoices`
582
583Allows to specify the maximum number of voices of polyphony of the generated synth. This option is only used as a safeguard since only active voices are allocated and computed.
584
585---
586
587### `-reuse`
588
589Asks `faust2smartkeyb` to reuse the same project and to only update its portion corresponding to the provided Faust code. This option will not prevent compilation from happening. Instead, use [`-source`](#source) for that.
590
591---
592
593### `-source`
594
595Asks `faust2smartkeyb` to only generate the source of the app and to not compile it. The source of the app will be placed in a folder called `faustsmartkeyb.faustFileName`.
596
597---
598
599## Additional Resources
600
601* [What Is Faust?](https://ccrma.stanford.edu/~rmichon/faustTutorials/#what-is-faust)
602* [Faust Hero in 2 Hours](https://ccrma.stanford.edu/~rmichon/faustTutorials/#faust-hero-in-2-hours)
603* [Making Faust-Based Smartphone Musical Instruments (`faust2smartkeyb` Tutorials)](https://ccrma.stanford.edu/~rmichon/faustTutorials/#making-faust-based-smartphone-musical-instruments)
604
605## Version/License
606
607Version 0.0.
608
609See `LICENCE.md` in the `SmartKeyboard` source code (`faust/architecture/smartKeyboard`).
610