1
#ifndef __FWEELIN_CONFIG_H
2
#define __FWEELIN_CONFIG_H
6
#include <libxml/xmlmemory.h>
7
#include <libxml/parser.h>
8
#include <libxml/tree.h>
10
#define MAX_PULSES 10 // Maximum number of time pulses
11
#define LAST_REC_COUNT 8 // Keep track of the last n indexes we recorded to
13
// Divisions are added in browsers wherever files are greater than
14
// FWEELIN_FILE_BROWSER_DIVISION_TIME seconds apart
15
#define FWEELIN_FILE_BROWSER_DIVISION_TIME 3600
17
#define FWEELIN_CONFIG_FILE ".fweelin.rc"
18
#define FWEELIN_CONFIG_HELP_TOKEN "HELP:"
20
#define FWEELIN_OUTPUT_STREAM_NAME "live"
21
#define FWEELIN_OUTPUT_TIMING_EXT ".wav.usx"
22
#define FWEELIN_OUTPUT_LOOP_NAME "loop"
23
#define FWEELIN_OUTPUT_SCENE_NAME "scene"
24
#define FWEELIN_OUTPUT_AUDIO_EXT ".ogg"
25
#define FWEELIN_OUTPUT_DATA_EXT ".xml"
27
// Console sequence for error color
28
#define FWEELIN_ERROR_COLOR_ON "\033[31;1m"
29
#define FWEELIN_ERROR_COLOR_OFF "\033[0m"
31
#include "fweelin_datatypes.h"
32
#include "fweelin_audioio.h"
33
#include "fweelin_event.h"
34
#include "fweelin_videoio.h" // TTF_Font decl
41
// ****************** CONFIG CLASSES
50
// Config tokens can reference user variables (UserVariable)
51
// or input EventParameters (EventParameter)
55
CfgToken() : cvt(T_CFG_None), var(0) {};
59
// Dump CfgToken to stdout
62
// Evaluate the current value of this token to dst
63
// Using event ev as a reference for event parameter
64
// If overwritetype is nonzero, sets dst to be of the appropriate data type
65
// Otherwise, converts to existing type of dst
66
void Evaluate(UserVariable *dst, Event *ev, char overwritetype);
68
// Reference a user defined variable
70
// Reference an event parameter
71
EventParameter evparam;
72
// Or reference a static value
76
// Simple algebra is possible in config file
77
// it allows, for example, a midi fader level to be divided into an appropriate
79
// This is one math operation as part of an expression
80
class CfgMathOperation {
82
CfgMathOperation() : next(0) {};
84
// Symbols for different math operators (div, mul, add, sub, etc..)
85
const static char operators[];
86
// Number of different math operators
87
const static int numops;
89
char otype; // One of the above operator types
92
CfgMathOperation *next;
95
// A complete expression of config tokens modified by math operations
96
class ParsedExpression {
98
ParsedExpression() : ops(0) {};
101
CfgMathOperation *cur = ops;
103
CfgMathOperation *tmp = cur->next;
109
// Evaluate this expression
110
UserVariable Evaluate(Event *input);
112
// Returns nonzero if this expression contains only static tokens
113
// and no user variables and no input parameters
116
// Dump expression to stdout
119
CfgToken start; // Starting token of expression
120
CfgMathOperation *ops; // Optional sequence of math ops to perform on 'val'
123
// DynamicToken is an expression and a config token,
124
// used in a few places:
126
// 1) To evaluate an expression and assign the result to an output event
127
// parameter (wrapped in CfgToken)
128
// 2) To evaluate an expression and compare the result to an input event
129
// parameter (wrapped in CfgToken)
130
// 2) To evaluate an expression and compare the result to a user variable
131
// (wrapped in CfgToken)
134
DynamicToken() : exp(0), next(0) {};
140
CfgToken token; // Variable/parameter to compare or assign to
141
ParsedExpression *exp; // Expression to evaluate
145
// Binding between a freewheeling event and some input action
146
// controls basic user interface
149
EventBinding(char all = 0) :
150
boundproto(0), heldprereq(0), all(all), echo(0),
151
tokenconds(0), paramsets(0), continued(0), next(0) {};
152
virtual ~EventBinding();
154
Event *boundproto; // Prototype instance of the output event
156
// We can specify that for the event to be triggered, a set of
157
// keyboard keys must be held down.
158
SDLKeyList *heldprereq; // These keys must be held
159
char all; // Nonzero if all keys must be held, zero if any one is enough
161
// Nonzero if input events should be rebroadcast even
162
// if they are consumed in this binding
167
// List of dynamic token conditions
168
// (for example, MIDI channel on input must match given expression)
169
DynamicToken *tokenconds;
171
// ** Parameter mappings
173
// List of dynamic parameter assignments for output events
174
// (for example, when triggering from MIDI keyboard: loop # = notenum + 12)
175
DynamicToken *paramsets;
177
// Continued is nonzero if the next binding should always be triggered
178
// when this binding is triggered- so the next binding is a
179
// continuation of this binding
185
class InputMatrix : public EventProducer, public EventListener {
188
InputMatrix(Fweelin *app);
189
virtual ~InputMatrix();
191
// Sets the given variable to the given value- string is interpreted
192
// based on variable type
193
void SetVariable (UserVariable *var, char *value);
195
// Called during configuration to create user defined variables
196
void CreateVariable (xmlNode *declare);
198
// Called during configuration to bind input controllers to events
199
void CreateBinding (xmlNode *binding);
201
// Are the conditions in the EventBinding bind matched by the
202
// given input event and user variables?
203
char CheckConditions(Event *input, EventBinding *bind);
205
// Receive input events
206
void ReceiveEvent(Event *ev, EventProducer *from);
208
// Start function, called shortly before Fweelin begins running
211
// *********** User defined variables
217
// Parses a given expression string, extracting tokens
218
// for example: 'VAR_curnote+12' references variable VAR_curnote and
219
// creates 1 math operation +12
220
// The expression may also reference parameters in event 'ref'
221
// and these references will be extracted
222
ParsedExpression *ParseExpression(char *str, Event *ref,
223
char enable_keynames = 0);
227
// Removes leading and trailing spaces from string str
228
// Modifies the end of string str and returns a pointer to the new
229
// beginning after spaces
230
char *RemoveSpaces (char *str);
232
// Adds one key to the given list based on the keysym name
233
// Returns the new first pointer
234
SDLKeyList *AddOneKey (SDLKeyList *first, char *str);
236
// Extracts named keys from the given string and returns a list
237
// of the keysyms (named keys are separated by ,)
238
SDLKeyList *ExtractKeys (char *str);
240
// Parses the given token (no math ops!) into dst
241
// Correctly identifies when variables or event parameters are referenced
242
void ParseToken(char *str, CfgToken *dst, Event *ref,
243
char enable_keynames = 0);
245
// Stores in ptr the value val given that ptr is of type dtype
246
void StoreParameter(char *ptr, CoreDataType dtype, UserVariable *val);
248
// Using the eventbinding's parametersets as a template, dynamically
249
// sets parameters in the output event
250
void SetDynamicParameters(Event *input, Event *output, EventBinding *bind);
252
// Scans in the given binding for settings for output event parameters
253
// and sets us up to handle those
254
void CreateParameterSets (EventBinding *bind, xmlNode *binding,
255
Event *input, int contnum);
257
// Scans in the given binding for conditions on input event parameters
258
// or user variables, and sets us up to handle those
259
// Returns the hash index for this binding, based on an indexed parameter,
260
// or 0 if this binding is not indexed
261
int CreateConditions (EventBinding *bind, xmlNode *binding,
262
Event *input, int paramidx);
264
// Traverses through the list of event bindings beginning at 'start'
265
// looking for a binding that matches current user variables and input
267
EventBinding *MatchBinding(Event *ev, EventBinding *start);
269
// *********** Event Bindings
271
// Bindings that trigger on input events- for each input event type,
272
// a hashtable of bindings along an indexed parameter
273
EventBinding ***input_bind;
276
class FloLayoutElementGeometry {
278
FloLayoutElementGeometry() : next(0) {};
280
// Draw this element to the given screen-
281
// implementation given in videoio.cc
282
virtual void Draw(SDL_Surface *screen, SDL_Color clr) = 0;
285
FloLayoutElementGeometry *next;
288
class FloLayoutBox : public FloLayoutElementGeometry {
291
// Draw this element to the given screen-
292
// implementation given in videoio.cc
293
virtual void Draw(SDL_Surface *screen, SDL_Color clr);
295
// Outlines along borders?
296
char lineleft, linetop, lineright, linebottom;
297
// Coordinates of box
298
int left, top, right, bottom;
301
class FloLayoutElement {
303
FloLayoutElement() : id(0), name(0), nxpos(0), nypos(0), bx(0.0), by(0.0),
304
loopmap(0), loopx(0), loopy(0), loopsize(0), geo(0), next(0) {};
305
~FloLayoutElement() {
309
FloLayoutElementGeometry *cur = geo;
311
FloLayoutElementGeometry *tmp = cur->next;
317
int id; // Id of element
318
char *name; // Name of element
319
int nxpos, nypos; // Location to print name label
320
float bx, by; // Base position for element
322
// Generated map that will take a flat scope and project it onto the right
323
// size circle-- see videoio
324
CircularMap *loopmap;
326
int loopx, loopy, // Position of loop graphic for the element
327
loopsize; // Size of loop graphic (diameter)
329
// Geo describes how to draw this interface element
330
FloLayoutElementGeometry *geo;
333
FloLayoutElement *next;
336
// The user can define the onscreen layout for loops-- see config file!
339
FloLayout() : id(0), xpos(0), ypos(0), loopids(0,0),
340
name(0), nxpos(0), nypos(0), elems(0), show(1), showlabel(1),
341
showelabel(1), next(0) {};
346
FloLayoutElement *cur = elems;
348
FloLayoutElement *tmp = cur->next;
354
int id, // User refers to a layout by ID
355
xpos, ypos; // Base location on screen for this layout
356
Range loopids; // Range of loopids that map to interface elements
357
char *name; // ex PC Keyboard, MIDI Footpedal
358
int nxpos, nypos; // Location to print name label
360
FloLayoutElement *elems; // Elements that make up this layout
362
char show, // Layout shown onscreen?
363
showlabel, // Name of layout shown onscreen?
364
showelabel; // Element names in layout shown onscreen?
370
// List of strings- optional two strings per listitem
371
// Second string is assumed to be substring of first string
372
// Only first string is deleted at destructor
373
class FloStringList {
375
FloStringList(char *str, char *str2 = 0) : str(str), str2(str2),
386
// List of fonts used in video- video handles the loading and unloading,
387
// but config sets up these structures to know which fonts and sizes to load
390
FloFont() : name(0), filename(0), font(0), size(0), next(0) {};
398
char *name, *filename;
404
enum FloDisplayType {
409
// List of variable displays used in video
410
// There are different types of displays, this is a base class
413
FloDisplay() : id(-1), exp(0), font(0), title(0), xpos(0), ypos(0), show(1),
415
virtual ~FloDisplay() {
422
// Draw this display to the given screen-
423
// implementation given in videoio.cc
424
virtual void Draw(SDL_Surface *screen) = 0;
426
virtual FloDisplayType GetFloDisplayType() { return FD_Unknown; };
428
int id; // Way to refer to this display from events
430
ParsedExpression *exp; // Expression which evaluates to a value to display
431
FloFont *font; // Font for text
432
char *title; // Title to be displayed
433
int xpos, ypos; // Onscreen location for display
434
char show; // Show (nonzero) or hide (zero) display
439
// Text display shows the value of expression 'exp' as onscreen text
440
class FloDisplayText : public FloDisplay
444
virtual void Draw(SDL_Surface *screen);
447
// Switch display shows the title in different color depending on the value of
449
class FloDisplaySwitch : public FloDisplay
453
virtual void Draw(SDL_Surface *screen);
456
// Circle switch display shows a circle which changes color and optionally
457
// flashes depending on the value of expression 'exp'
458
class FloDisplayCircleSwitch : public FloDisplay
461
FloDisplayCircleSwitch() : rad1(0), rad0(0), flash(0), prevnonz(0),
464
virtual void Draw(SDL_Surface *screen);
466
int rad1, rad0; // Radii of circle when switch is on or off
469
char flash, // Flash or solid colors?
470
prevnonz; // Previous character value of expression (for nonzero test)
471
double nonztime; // System time at which the expression last became nonzero
474
enum CfgOrientation {
479
// Bar display shows the value of expression 'exp' as a bar
480
class FloDisplayBar : public FloDisplay
483
FloDisplayBar() : orient(O_Vertical), barscale(1.0), thickness(10) {};
485
virtual void Draw(SDL_Surface *screen);
487
CfgOrientation orient; // Orientation of bar
488
float barscale; // Scaling factor for size of bar
489
int thickness; // Thickness of bar
492
// Bar-switch display shows the value of expression 'exp' as a bar and changes the color of the bar
493
// depending on the value of expression 'switchexp'
494
class FloDisplayBarSwitch : public FloDisplayBar
497
FloDisplayBarSwitch() : switchexp(0), color(1), calibrate(0),
499
virtual ~FloDisplayBarSwitch() {
504
virtual void Draw(SDL_Surface *screen);
506
ParsedExpression *switchexp; // Expression which evaluates to a value. Nonzero values cause the bar
507
// to appear bright, zero values cause a dim, faded bar
509
int color; // Color of bar-switch (index of hardcoded color)
510
char calibrate; // Nonzero shows calibration value on barswitch
511
float cval; // Calibration value
515
#include "fweelin_fluidsynth.h"
519
class FluidSynthParam {
521
FluidSynthParam(char *name) : next(0) {
522
this->name = new char[strlen(name)+1];
523
strcpy(this->name,name);
525
virtual ~FluidSynthParam() { delete[] name; };
527
// Send this parameter into the given settings
528
virtual void Send(fluid_settings_t *settings) = 0;
531
FluidSynthParam *next;
534
class FluidSynthParam_Num : public FluidSynthParam {
537
FluidSynthParam_Num(char *name, double val) :
538
FluidSynthParam(name), val(val) {};
540
virtual void Send(fluid_settings_t *settings);
545
class FluidSynthParam_Int : public FluidSynthParam {
548
FluidSynthParam_Int(char *name, int val) :
549
FluidSynthParam(name), val(val) {};
551
virtual void Send(fluid_settings_t *settings);
556
class FluidSynthParam_Str : public FluidSynthParam {
559
FluidSynthParam_Str(char *name, char *val) :
560
FluidSynthParam(name) {
561
this->val = new char[strlen(val)+1];
562
strcpy(this->val,val);
564
virtual ~FluidSynthParam_Str() { delete[] val; };
566
virtual void Send(fluid_settings_t *settings);
571
class FluidSynthSoundFont {
573
FluidSynthSoundFont(char *name) : next(0) {
574
if (strchr(name,'/') != 0) {
576
this->name = new char[strlen(name)+1];
577
strcpy(this->name,name);
579
// Path not specified, use default
580
this->name = new char[strlen(FWEELIN_DATADIR)+1+strlen(name)+1];
581
sprintf(this->name,"%s/%s",FWEELIN_DATADIR,name);
584
~FluidSynthSoundFont() { delete[] name; };
587
FluidSynthSoundFont *next;
591
// Fweelin configuration
594
FloConfig(Fweelin *app);
597
// Parse configuration file, setup config
600
// Start function, called shortly before Fweelin begins running
601
void Start() { im.Start(); };
603
// Configure bindings between events and their triggers
604
void ConfigureEventBindings(xmlDocPtr doc, xmlNode *events);
606
void ConfigureElement(xmlDocPtr doc, xmlNode *elemn,
607
FloLayoutElement *elem, float xscale, float yscale);
608
void ConfigureLayout(xmlDocPtr doc, xmlNode *layn,
609
FloLayout *lay, float xscale, float yscale);
610
void ConfigureVideo(xmlDocPtr doc, xmlNode *vid);
611
void ConfigureGeneral(xmlDocPtr doc, xmlNode *gen);
613
// Is node 'n' a comment with help information? If so, add to our
614
// internal help list
615
void CheckForHelp(xmlNode *n);
617
// Creates an empty variable based on the given name. The config file
618
// can then refer to the variable
619
UserVariable *AddEmptyVariable(char *name);
621
// Makes the given variable into a system variable by linking it to
623
void LinkSystemVariable(char *name, CoreDataType type, char *ptr);
625
// Input matrix- stores and handles all bindings between inputs and events
626
inline InputMatrix *GetInputMatrix() { return &im; };
629
// Extracts a comma separated array of floats from the given string-
630
// returns size of array in 'size'
631
float *ExtractArray(char *n, int *size);
634
inline char *GetLibraryPath() {
635
if (librarypath != 0)
638
printf("CORE: ERROR: Library path not set in configuration!\n");
644
// Number of MIDI out ports
645
inline int GetNumMIDIOuts() { return midiouts; };
648
// Is input/output #n stereo?
649
inline char IsStereoInput(int n) { return ms_inputs[n]; };
650
inline char IsStereoOutput(int n) { return IsStereoMaster(); };
651
char *ms_inputs; // Zero or nonzero for each input- is this input stereo?
653
// Is FreeWheeling running in stereo or completely in mono?
654
char IsStereoMaster();
656
// Number of external audio inputs into FreeWheeling (specified in config file)
657
// AudioIO may add its own inputs internal to FreeWheeling
658
// (for example, softsynth)
659
inline int GetExtAudioIns() { return extaudioins; };
662
// Maximum play volume
663
inline float GetMaxPlayVol() { return maxplayvol; };
666
// Maximum limiter gain
667
inline float GetMaxLimiterGain() { return maxlimitergain; };
668
float maxlimitergain;
670
// Limiter threshhold
671
inline float GetLimiterThreshhold() { return limiterthreshhold; };
672
float limiterthreshhold;
674
// Limiter release rate
675
inline float GetLimiterReleaseRate() { return limiterreleaserate; };
676
float limiterreleaserate;
678
// Number of triggers (loop ids)
679
inline int GetNumTriggers() { return num_triggers; };
683
inline int *GetVSize() { return vsize; };
684
inline float XCvtf(float x) { return (x*vsize[0]); };
685
inline float YCvtf(float y) { return (y*vsize[1]); };
686
inline int XCvt(float x) { return (int) (x*vsize[0]); };
687
inline int YCvt(float y) { return (int) (y*vsize[1]); };
690
// # of samples in visual oscilloscope buffer
691
nframes_t scope_sample_len;
692
inline nframes_t GetScopeSampleLen() { return scope_sample_len; };
694
// Macro to check whether debug info is on
695
#define CRITTERS (app->getCFG()->IsDebugInfo())
696
// Return nonzero if debug info to be shown
697
char IsDebugInfo() { return showdebug; };
698
// Show debugging info?
702
FloLayout *GetLayouts() { return layouts; };
706
// Returns the named font from our list of fonts
707
FloFont *GetFont (char *name) {
708
FloFont *cur = fonts;
709
while (cur != 0 && strcmp(cur->name,name))
713
FloFont *GetFonts() { return fonts; };
716
// Graphical displays
717
inline FloDisplay *GetDisplays() { return displays; };
718
inline FloDisplay *GetDisplayById(int id) {
719
FloDisplay *cur = displays;
727
FloDisplay *displays;
730
int GetNumHelpLines() {
731
FloStringList *cur = help;
740
char *GetHelpLine(int idx, int col) {
741
FloStringList *cur = help;
743
while (cur != 0 && cnt != idx) {
751
return (col == 0 ? cur->str : cur->str2);
758
int GetFluidInterpolation() { return fsinterp; };
760
int GetFluidChannel() { return fschannel; };
762
char GetFluidStereo() { return fsstereo; };
763
FluidSynthParam *fsparam;
764
FluidSynthParam *GetFluidParam() { return fsparam; };
765
void AddFluidParam(FluidSynthParam *nw) {
769
FluidSynthParam *cur = fsparam;
770
while (cur->next != 0)
775
FluidSynthSoundFont *fsfont;
776
void AddFluidFont(FluidSynthSoundFont *nw) {
780
FluidSynthSoundFont *cur = fsfont;
781
while (cur->next != 0)
786
FluidSynthSoundFont *GetFluidFont() { return fsfont; };
789
// Pitch transpose on outgoing MIDI events
790
signed int transpose;
792
// Chunksize for peaks & avgs display of loops
793
// (bigger # means shorter displays)
794
nframes_t loop_peaksavgs_chunksize;
797
#define FS_REPORT_BLOCKMANAGER 1
799
// Seconds of fixed audio history
800
const static float AUDIO_MEMORY_LEN;
801
// # of audio blocks to preallocate
802
const static int NUM_PREALLOCATED_AUDIO_BLOCKS;