Audacity 3.2.0
Functions | Variables
Envelope.cpp File Reference
#include "Envelope.h"
#include <float.h>
#include <math.h>
#include <wx/wxcrtvararg.h>
#include <wx/brush.h>
#include <wx/pen.h>
#include <wx/textfile.h>
#include <wx/log.h>
#include <wx/utils.h>
Include dependency graph for Envelope.cpp:

Go to the source code of this file.

Functions

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

◆ checkResult()

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

Definition at line 1415 of file Envelope.cpp.

1416{
1417 if( (a-b > 0 ? a-b : b-a) > 0.0000001 )
1418 {
1419 wxPrintf( "Envelope: Result #%d is: %f, should be %f\n", n, a, b );
1420 //exit( -1 );
1421 }
1422}

Referenced by Envelope::testMe().

Here is the caller graph for this function:

◆ IntegrateInterpolated()

static double IntegrateInterpolated ( double  y1,
double  y2,
double  time,
bool  logarithmic 
)
static

Definition at line 1115 of file Envelope.cpp.

1116{
1117 // Calculates: integral(interpolate(y1, y2, x), x = 0 .. time)
1118 // Integrating logarithmic interpolated segments is surprisingly simple. You can check this formula here:
1119 // 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
1120 // Again, the base you use for interpolation is irrelevant, the formula below should always use the natural
1121 // logarithm (i.e. 'log' in C/C++). If the denominator is too small, it's better to use linear interpolation
1122 // because the rounding errors would otherwise get too large. The threshold value is 1.0e-5 because at that
1123 // point the rounding errors become larger than the difference between linear and logarithmic (I tested this in Octave).
1124 if(logarithmic)
1125 {
1126 double l = log(y1 / y2);
1127 if(fabs(l) < 1.0e-5) // fall back to linear interpolation
1128 return (y1 + y2) * 0.5 * time;
1129 return (y1 - y2) / l * time;
1130 }
1131 else
1132 {
1133 return (y1 + y2) * 0.5 * time;
1134 }
1135}

Referenced by Envelope::Integral().

Here is the caller graph for this function:

◆ IntegrateInverseInterpolated()

static double IntegrateInverseInterpolated ( double  y1,
double  y2,
double  time,
bool  logarithmic 
)
static

Definition at line 1136 of file Envelope.cpp.

1137{
1138 // Calculates: integral(1 / interpolate(y1, y2, x), x = 0 .. time)
1139 // This one is a bit harder. Linear:
1140 // http://www.wolframalpha.com/input/?i=integrate+1%2F%28y1*%28T-x%29%2FT%2By2*x%2FT%29+from+0+to+T
1141 // Logarithmic:
1142 // 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
1143 // Here both cases need a special case for y1 == y2. The threshold is 1.0e5 again, this is still the
1144 // best value in both cases.
1145 double l = log(y1 / y2);
1146 if(fabs(l) < 1.0e-5) // fall back to average
1147 return 2.0 / (y1 + y2) * time;
1148 if(logarithmic)
1149 return (y1 - y2) / (l * y1 * y2) * time;
1150 else
1151 return l / (y1 - y2) * time;
1152}

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

Here is the caller graph for this function:

◆ InterpolatePoints()

static double InterpolatePoints ( double  y1,
double  y2,
double  factor,
bool  logarithmic 
)
static

Definition at line 1107 of file Envelope.cpp.

1108{
1109 if(logarithmic)
1110 // you can use any base you want, it doesn't change the result
1111 return exp(log(y1) * (1.0 - factor) + log(y2) * factor);
1112 else
1113 return y1 * (1.0 - factor) + y2 * factor;
1114}

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

Here is the caller graph for this function:

◆ SolveIntegrateInverseInterpolated()

static double SolveIntegrateInverseInterpolated ( double  y1,
double  y2,
double  time,
double  area,
bool  logarithmic 
)
static

Definition at line 1153 of file Envelope.cpp.

1154{
1155 // Calculates: solve (integral(1 / interpolate(y1, y2, x), x = 0 .. res) = area) for res
1156 // Don't try to derive these formulas by hand :). The threshold is 1.0e5 again.
1157 double a = area / time, res;
1158 if(logarithmic)
1159 {
1160 double l = log(y1 / y2);
1161 if(fabs(l) < 1.0e-5) // fall back to average
1162 res = a * (y1 + y2) * 0.5;
1163 else if(1.0 + a * y1 * l <= 0.0)
1164 res = 1.0;
1165 else
1166 res = log1p(a * y1 * l) / l;
1167 }
1168 else
1169 {
1170 if(fabs(y2 - y1) < 1.0e-5) // fall back to average
1171 res = a * (y1 + y2) * 0.5;
1172 else
1173 res = y1 * expm1(a * (y2 - y1)) / (y2 - y1);
1174 }
1175 return std::max(0.0, std::min(1.0, res)) * time;
1176}
int min(int a, int b)

References min().

Referenced by Envelope::SolveIntegralOfInverse().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ VALUE_TOLERANCE

const double VALUE_TOLERANCE = 0.001
static

Definition at line 42 of file Envelope.cpp.

Referenced by Envelope::RemoveUnneededPoints().