/*
       This is a documented WhiteCap 'config' file designed to explain them in the hopes that you can make you own.  A "config" file is any file like this for WhiteCap that contains textual commands (that we can edit) that WhiteCap interprets when it runs.  If you make your own configs and they turn out well, please send me them--I'll include what you send in a cool configs folder when i release the next version of WhiteCap.  Check out other config files to see how the various parameters can be used in different ways.  The best way to start learning how things work is to wdit simple things in this file, save the changes, and reload this config within WhiteCap (the 'U' key by default).  When you see how things react to your changes, you will quickly learn how what is what.  You don't haven't have to learn all of the various parameters in a config file, just a handful of will do.
   To make things easier, I put the stuff seen by WhiteCap in boldface type (ie. not the "comments" you're reading now).  There's two ways to make comments (that is, have text ignored by WhiteCap):  
   1)  "//" tells WhiteCap to ignore whatever text follows on that line, 
   2)  Text enclosed within "/*" and "* /" is also ignored (like this big block of text you're reading now)
       In a config file, if you see something is quotes or just a number with an "=" in front of it, it's matched up to the 3 or 4 letter parameter name on its left.   If you see characters contained in quotes, it's called an expression.  Examples of expressions are "3.45", "3 * A2", and "sqrt( B1 ) / (rnd(1) + 1)".  When you see a parameter not in quotes, it means only put a numerical value can be there (ex, 4, -55, 4343--nothing but digits and a leading dash if it's negative).  Be sure you don't forget key things like commas and quotes that signify where data stops and starts.    Parameters are assumed to be 0 or "0" (depending on the type) if they are left out from a config file.  
       Expressions are functions--they represent a single value that depends on a combonation of other numbers, variables, and functions.  "3*b", "3.141", "sqrt(t+7)", and "(s+t+2.7)^dt" are all examples of expressions.  T

***
For a complete list of the available functions, see the "config programming" section of the documentation.
***

*/

/* Big picture: A config is basically a list of function definitions that define pen colors, the camera position, lines in 3D space to draw, and various flags.  */


/* Duration:  This specifies how long a sample stays around until its considered expired.  When a sample has been around longer than this time, it's deleted and disappears.  So as this number increases, the more samples that will around each frame.  A sample is a freq spectrum of the audio for a snapshot in time.  For example, a photograph of a rainbow is a sample of the lightbeam because the spectrum in the photograph shows percisely the contents of the lightbeam at the instant the photo was taken.  WC will keep each sample of the audio signal for the time specified here.*/
Durn="1.3",


/*   Camera position:  This tells WC the position of the camera at the time t (WC needs to know the camera position and orientation to render the frame).  t is the system time (in seconds), and is how you get the camera (or any expression) to do things though time (ex, change position or change viewing orientation) .  CamX, Y, and X are the camera's coordinates in space.  In this example, the camera's position moves around in an erratic elliptical path. */
CamX="60 * sin( .5 * t )",
CamY="20 * cos( .3 * t )",
CamZ="14 + 6 * cos( .3 * t )",

/* Camera Look Point: The point in space the camera looks towards.  In other words, the direction the camera is looking is ( CmLX-CamX, CmLY-CamY, CmLZ-CamZ ).   Here, we just keep the camera looking at a fixed point in space.  */
CmLX="20",
CmLY="0",
CmLZ="0",

/* Camera 'Up' Direction:  The direction of this vector defines the direction from the camera location that is 'up'--that is, it's the y direction in the screen's coordinate system.  In other words, if you were to trace the segment that connects the camera look point, CmL (this is the center of your screen) in the direction of the camera up direction, CUp, then the trace would appear as a verticle line starting from the center of your screen and end somewhere directly above.  Here, the direction (0,0,1) ensures the camera's oriented such that the z-axis is always vertical and points upward.  If the camera up direction ever is the same as the camera direction, then you'll cause an unsightly jump of camera direction (as WhiteCap will be forced to choose an arbitrary 'up' direction).  In other words, as the camera's line of sight approaches the direction of CUp, the up direction becomes unstable/undefined.  "Tunnel Vision" and "Canyon Chase" use CUp to make the camera change orientation in a cool way.   */
CUpX="0",
CUpY="0",
CUpZ="1",

/* If you didn't catch all that Camera stuff the first time around, don't sweat it.  If you look a enough configs you can mimic some basic camera movement.  */
 
/*  Tail Position/Shape:  WhiteCap gives you access to several variables and a function: 
   -  t:   the system time index (in seconds)
   -  st:  the system time a (frequency) sample was recorded
   -  s:   a value that goes from 0 to 1
   -  dt:  ( t - st ) / Durn  (a value from 0 to 1 that describes the "age" of a sample)
   -  fft():  The current sample.  fft( <value from 0 to 1> ) returns the magnitude of a given frequency for the current sample.  
   - A0..., B0..., C0..., D0...:  Temporary variables that allow you to avoid repeating calculations.  In other words, WhiteCap allows you to compute commonly used values so that you can avoid having WhiteCap recompute things unnecessarily.  Examples of temporary vars are A0, A1, B0, B15, C2, and D5.

Let's break WhiteCap down:

StartNewConfig() {
   read the config file from disk (or cache)
   calculate A0, A1, A2...  (note how AVars are only evaluated once for a config)
   for each frame {
      t = current system time (in secs)
      newSamp = RecordNewSample();
      newSamp.timeRecorded = t
      erase recorded samples older than Durn seconds
      calculate B0, B1, B2...  (they can depend on t and A)
      calculate then apply BckR,BckG,BckB as the background color
      calculate Cam, CmL, and CUp (the cam pos and orientation, 9 exprs total)
      for samp = step thru list of recorded samples from oldest to newest {
         st = samp.timeRecorded
         dt = ( t - st ) / Durn
         SetPenWidth( LWdt )
         calculate C0, C1, C2... (they can depend on st, dt, t, fft(), and B)
         for s = 0 to 1 step 1/Stps {
            calculate D0, D1, D2... (they can depend on anything the C's doas and C)
            screen_pt = GetScreenCoordFor( X, Y, Z, Cam, CmL, CUp )
            if ( st == t ) 
               SetPenColor( LvlR, LvlG, LvlB )
            else
               SetPenColor( R, G, B )
            if ( ConL == 0 AND ConB == 0 )
               DrawDot( screen_pt )
            else
               DrawLineTo( screen_pt )
         }
      }
   }
}



			Using temporary variables is useful when you want to compute something once and use it multiple times (to avoid redundant computation).  There are 4 groups of temporary variables available for use in WhiteCap: A, B, C and D.    The A variables are evaluated once, when the config is loaded, the B variables are evaluated at the start if each frame, the C variables are evaluated each sample (for each frame), and the D variables are evaluated for each change in 's' (for each sample for each frame).  The A variables are usually used as global config values when the config loads.  For example, you could set A0, A1, A2 to be random values that get used together to form an RGB color that's used for the config, so that each time the config loads it's would be a different color.  The B variables are useful for computing things that depend on 't', such as the B0 parameter in Cosine Classic.  The C variables are useful for computing things that depend on 'dt', that is, values that stay constant over s.  For example, in this config we precompute a cosine in C0 because the cosine doesn't change with any change to s.  D variables are useful for computing a value that's used multiple times and is dependent on s.  The D variables are useful for computing values shared by the 6 expressions: X, Y, Z, R, G, B.  For example, if the RGB all depend on some big function of s, it makes sense to do all the shared computation in D0 and just use D0 in R, G, and B.  Finally, if you declare B7, then make sure B0 thru B6 exist too (ie, don't leave gaps in temp var numbering). 
   Back to the WhiteCap main loop...  Note how using the fft() function in an A or B variable wouldn't make any sense because they are values that constant for all the samples.  There is one exception--if you use the fft() fcn inside a B var, it accesses the most recent sample (ie, dt == 0).   This allows you set values (ie. B vars) that are universal for the entire frame.  This is how could, say, make the background color beat with the music or make the camera jiggle with the bass beat. */

/* Until you get a feel for how to use temp variables, don't bother using them--just put everything in terms of t, st, dt, and s in the RGB and XYZ expressions.  The only consequence will be that your config will run slow.   Send in your config and it'll be optimized.  */

/* This is an oscillator than goes from -1.2 to .6, the 'wing' angle (in radians).  Try taking changing the coefficient of dt or t to zero and observe the effects.  */
C0="-1.2 + 1.8 * ( .5 * sin( t * 1.5 - 1.5 * dt ) + .5 )",
C1="cos( c0 )",		// We use this twice in Y and Z

/* We need the following value twice, and it depends on s, so we can't make it any faster than a D var.  Note how we access the sound level/magnitude. */
D0="13 * fft( s )",

/* If you want to check out XYZ expressions less complicated than this, check out "My Malia".  In "My Malia", the XYZ exprs look like:
X="dt * 40",
Y="60 * ( 2 * s - 1)",
Z="20 * fft( s )",
Watch "My Malia" until you see how the above XYZ expressions cause what you're seeing.  Below, we use some fancy math to get the effect of bird-like flapping motion.  Don't worry about figuring out what the math is doing, just understand that these fcns define a V-shape that widens and narrows periodically thru time.  */
X="dt * 40",
Y="165 * ( s - .5 ) * C1 - sin( sgn( s - .5 ) * C0 ) * D0",
Z="165 * abs( s - .5 ) * sin( C0 ) + C1 * D0",


/* Tail Color:  This express the RGB for each point on the tail.  The rules for the RGB expressions are the same as the XYZ expressions, and you're free to use temporary variables.  Once WhiteCap calculates the coordinate of a point using the above XYZ expressions, it uses the these 3 expressions to know what color to draw in.  A value of 1.0 signifies 100% of a the primary color, 0.0 represents a complete absence of that color.   Check out the pseudocode for WhiteCap above to see when these three expressions are evaluated.  Again, check out the config "My Malia" to see a less complicated RGB triple. */
R="( 1 - .7 * dt ) * ( .5 * cos( 18 * dt ) + .5 )",
G="0",
B=".3",
/*    Note that I didn't bother to put the expr for R in a C variable.  This is because when whitecap goes to evaluate an expression for each change in s, it won't bother to revaluate an expression if it doesn't have an s or D variable in it.   It's always critical that you always move whatever you can into C expressions--that's what's gonna make the key speed difference for your config.  */


/* "Level" Color	(the color of the "present" sample, in other words, the sample where st == t, dt = 0).  This is the color painted on the front end of the tail.  If these params are missing, the RGB of the front of the wave is determined by above RGB expressions.  These are expressions, so you're free to use t, s, and fft().  */
LvlR=".4",
LvlG=".4",
LvlB="1",

/* Background Color -- same param types as the Level color: Expressions that return a value from 0 to 1.  You are free to access t, s, and fft()  */
BckR="0",
BckG="0",
BckB="0",


/* Connecting Lines: A 1 here tells WhiteCap to connect adjacent samples together with lines, 0 means you don't want those lines.   Try changing this to 0 and see what happens.  */
ConL=1,

/* Set ConB to 1 if you want the points of the sample ("bins") to be connected.  Set ConB to 0 if you don't want those lines.  "Vortex" has the effect of 'particles' by setting ConL and ConB both equal to 0.   If ConB is set to 2, WhiteCap draws as if it was set to 1 and draws a line from bin 0 to bin N. */
ConB=1,

/* Line Width: This is an expression of the pen width, in pixels, evaluated for each sample.  You're free to access t, dt, st, and fft() here.  */
LWdt="1",

/* Gaussian Blur:  Blrs represents how steps of blurs you want in the tail.  For example, if Blrs=3 then after WhiteCap will blur the last 1/3 of the tail, then the last 2/3 of the tail, then the entire tail.   BlrB is the blur "box" size.  It's how much things are blurred. BlrB set to less than 2 doesn't blur at all.   You tell WhiteCap you don't want any blurring of any kind by setting Blrs to 0.  */
Blrs=0,BlrB=3,

/* The height and width window this config fit into.  WhiteCap uses these two params to shrink or expand your config based on the current window size.  WhiteCap will always shrink your config, based on these values, such that *both* dimensions will fit in the window.  For example, with the below values, and with a current window size of 100 wide and 400 tall, WhiteCap will shrink your config by 1/5 at all times.  */
widt=500,heig=450,

/* Scale: Directly scales the screen x and y coordinates.  This param basically provides an easy way to shrink/expand your config painlessly.  Note: doubling widh and heig will have exactly the same effect as halving Scal.  */
Scal="500",

/*  Number of bins per sample: This is how many steps WC will chop the interval [0,1] into when it steps 's' from 0 to 1.  In G-Force and WhiteCap, when you see 's' in an expression, it really means, "all the values from 0 to 1 separated by small intervals."  The 'Stps' parameter tells G-Force and WhiteCap how many steps to take from 0 to 1, so the larger 'Stps' is, the smaller the interval between each step of s.  Normally, you'll want to step s the same number of times as the of pieces of data you have because you want each step of s to correspond to one piece of data--taking more of less steps wouldn't make any sense.   Therefore, you'll normally want the number of s-steps to be equal to the resolution of the fft() function.  The fft() function takes a number from 0 to 1 and uses that number to return one of the sub-samples within in fft():  fft(0) returns the first freq bin, fft(1) returns the last freq bin, etc. Note that fft() is only made up of a finite number of bins (ex, fft(.4) and fft(.40001) refer to the same data value).  You control how many bins compose a sample via the 'FNum' in your preferences file and you can access that value using NUM_FFT_BINS.  When the 'Stps' parameter is either 0 or omitted from a config file, WhiteCap assumes:  Stps="NUM_FFT_BINS".  Unless you have a specific reason to have a certain number of s steps, you'll want to let WhiteCap to step s the number of times there are bins in fft().   You're free to put whatever expression you like here, but note that you don't have access to any A-Vars here.  Finally, the 'Stps' expression is evaluated only once when a WaveShape loads and its value after is stored in NUM_S_STEPS.  */
Stps=-1,

/* Scale with size:  When this is 1, WhiteCap will scale your config so that it will fit nicely inside the current window.  If this param is 0, WhiteCap will not scale your config in the way described in the descripion for widh and heig if it means your config will be made larger.  Usually this is set to 1, but in Flame, for example, where blurring is used, WhiteCap would slow to a crawl if scaled Flame up to a particularly large window. */
ScSz=1,

/* Perspective Scale: How much points obscure to the fringes based on their distance from the camera.  WhiteCap uses the following formula to express screen coords:
scrn_x = Scal * scrn_x / ( scrn_z + Pers )  
The bigger you make this value, the more 'dimensionless' things will look.  For example, the camera that records from the backside of the pitcher in a major league baseball game has a high Pers value because the camera is very far away (and has a high Scal from a telescopic lens).  The result is that the pitcher looks the same size as the batter.  On the other hand, if the camera was on 2nd base or you were standing at the foot of a skyscraper, the Pers is low because your eyes are near the object, causing high perspective-distortion for nearby features.   So increasing Scal increases the power of your telescopic lens (making your object bigger), and increasing Pers walks you further away (making your object smaller and reducing distortion due to perspective).   So to change the distortion due to perspective but keep your object the same size, you must change both Scal and Pers.  */
Pers="150",

/* This should always equal to the lowest version of WhiteCap the config is compatible with (times 10).  WhiteCap makes sure the config it's about to show matches it's current version.  If it doesn't match, WhiteCap will just display the built-in 'factory' config (it's green with a red level line).  */
Vers=40