Audacity  2.2.2
Functions | Variables
Envelope.cpp File Reference
#include "Envelope.h"
#include "Experimental.h"
#include "ViewInfo.h"
#include <math.h>
#include <wx/dc.h>
#include <wx/brush.h>
#include <wx/event.h>
#include <wx/pen.h>
#include <wx/textfile.h>
#include <wx/log.h>
#include "AColor.h"
#include "DirManager.h"
#include "TrackArtist.h"
#include "TrackPanelDrawingContext.h"
#include "tracks/ui/EnvelopeHandle.h"

Go to the source code of this file.

Functions

static void DrawPoint (wxDC &dc, const wxRect &r, int x, int y, bool top)
 TODO: This should probably move to track artist. More...
 
static double InterpolatePoints (double y1, double y2, double factor, bool logarithmic)
 
static double IntegrateInterpolated (double y1, double y2, double time, bool logarithmic)
 
static double IntegrateInverseInterpolated (double y1, double y2, double time, bool logarithmic)
 
static double SolveIntegrateInverseInterpolated (double y1, double y2, double time, double area, bool logarithmic)
 
static void checkResult (int n, double a, double b)
 

Variables

static const double VALUE_TOLERANCE = 0.001
 

Function Documentation

static void checkResult ( int  n,
double  a,
double  b 
)
static

Definition at line 1734 of file Envelope.cpp.

Referenced by Envelope::testMe().

1735 {
1736  if( (a-b > 0 ? a-b : b-a) > 0.0000001 )
1737  {
1738  wxPrintf( "Envelope: Result #%d is: %f, should be %f\n", n, a, b );
1739  //exit( -1 );
1740  }
1741 }
static void DrawPoint ( wxDC &  dc,
const wxRect &  r,
int  x,
int  y,
bool  top 
)
static

TODO: This should probably move to track artist.

Definition at line 309 of file Envelope.cpp.

Referenced by Envelope::DrawPoints().

310 {
311  if (y >= 0 && y <= r.height) {
312  wxRect circle(r.x + x, r.y + (top ? y - 1: y - 2), 4, 4);
313  dc.DrawEllipse(circle);
314  }
315 }
static double IntegrateInterpolated ( double  y1,
double  y2,
double  time,
bool  logarithmic 
)
static

Definition at line 1434 of file Envelope.cpp.

Referenced by Envelope::Integral().

1435 {
1436  // Calculates: integral(interpolate(y1, y2, x), x = 0 .. time)
1437  // Integrating logarithmic interpolated segments is surprisingly simple. You can check this formula here:
1438  // http://www.wolframalpha.com/input/?i=integrate+10%5E%28log10%28y1%29*%28T-x%29%2FT%2Blog10%28y2%29*x%2FT%29+from+0+to+T
1439  // Again, the base you use for interpolation is irrelevant, the formula below should always use the natural
1440  // logarithm (i.e. 'log' in C/C++). If the denominator is too small, it's better to use linear interpolation
1441  // because the rounding errors would otherwise get too large. The threshold value is 1.0e-5 because at that
1442  // point the rounding errors become larger than the difference between linear and logarithmic (I tested this in Octave).
1443  if(logarithmic)
1444  {
1445  double l = log(y1 / y2);
1446  if(fabs(l) < 1.0e-5) // fall back to linear interpolation
1447  return (y1 + y2) * 0.5 * time;
1448  return (y1 - y2) / l * time;
1449  }
1450  else
1451  {
1452  return (y1 + y2) * 0.5 * time;
1453  }
1454 }
static double IntegrateInverseInterpolated ( double  y1,
double  y2,
double  time,
bool  logarithmic 
)
static

Definition at line 1455 of file Envelope.cpp.

Referenced by Envelope::IntegralOfInverse(), and Envelope::SolveIntegralOfInverse().

1456 {
1457  // Calculates: integral(1 / interpolate(y1, y2, x), x = 0 .. time)
1458  // This one is a bit harder. Linear:
1459  // http://www.wolframalpha.com/input/?i=integrate+1%2F%28y1*%28T-x%29%2FT%2By2*x%2FT%29+from+0+to+T
1460  // Logarithmic:
1461  // http://www.wolframalpha.com/input/?i=integrate+1%2F%2810%5E%28log10%28y1%29*%28T-x%29%2FT%2Blog10%28y2%29*x%2FT%29%29+from+0+to+T
1462  // Here both cases need a special case for y1 == y2. The threshold is 1.0e5 again, this is still the
1463  // best value in both cases.
1464  double l = log(y1 / y2);
1465  if(fabs(l) < 1.0e-5) // fall back to average
1466  return 2.0 / (y1 + y2) * time;
1467  if(logarithmic)
1468  return (y1 - y2) / (l * y1 * y2) * time;
1469  else
1470  return l / (y1 - y2) * time;
1471 }
static double InterpolatePoints ( double  y1,
double  y2,
double  factor,
bool  logarithmic 
)
static

Definition at line 1426 of file Envelope.cpp.

Referenced by Envelope::Integral(), Envelope::IntegralOfInverse(), and Envelope::SolveIntegralOfInverse().

1427 {
1428  if(logarithmic)
1429  // you can use any base you want, it doesn't change the result
1430  return exp(log(y1) * (1.0 - factor) + log(y2) * factor);
1431  else
1432  return y1 * (1.0 - factor) + y2 * factor;
1433 }
static double SolveIntegrateInverseInterpolated ( double  y1,
double  y2,
double  time,
double  area,
bool  logarithmic 
)
static

Definition at line 1472 of file Envelope.cpp.

References min().

Referenced by Envelope::SolveIntegralOfInverse().

1473 {
1474  // Calculates: solve (integral(1 / interpolate(y1, y2, x), x = 0 .. res) = area) for res
1475  // Don't try to derive these formulas by hand :). The threshold is 1.0e5 again.
1476  double a = area / time, res;
1477  if(logarithmic)
1478  {
1479  double l = log(y1 / y2);
1480  if(fabs(l) < 1.0e-5) // fall back to average
1481  res = a * (y1 + y2) * 0.5;
1482  else if(1.0 + a * y1 * l <= 0.0)
1483  res = 1.0;
1484  else
1485  res = log1p(a * y1 * l) / l;
1486  }
1487  else
1488  {
1489  if(fabs(y2 - y1) < 1.0e-5) // fall back to average
1490  res = a * (y1 + y2) * 0.5;
1491  else
1492  res = y1 * expm1(a * (y2 - y1)) / (y2 - y1);
1493  }
1494  return std::max(0.0, std::min(1.0, res)) * time;
1495 }
int min(int a, int b)

Variable Documentation

const double VALUE_TOLERANCE = 0.001
static

Definition at line 46 of file Envelope.cpp.

Referenced by Envelope::RemoveUnneededPoints().