Audacity 3.2.0
WaveClipUtilities.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 @file WaveClipUtilities.cpp
6
7 Paul Licameli split from WaveClip.cpp
8
9**********************************************************************/
10
11#include "WaveClipUtilities.h"
12
13#include <cmath>
14#include <wx/debug.h>
15#include "SampleCount.h"
16
17void findCorrection(const std::vector<sampleCount> &oldWhere, size_t oldLen,
18 size_t newLen, double t0, double rate, double samplesPerPixel,
19 int &oldX0, double &correction)
20{
21 // Mitigate the accumulation of location errors
22 // in copies of copies of ... of caches.
23 // Look at the loop that populates "where" below to understand this.
24
25 // Find the sample position that is the origin in the old cache.
26 const double oldWhere0 = oldWhere[1].as_double() - samplesPerPixel;
27 const double oldWhereLast = oldWhere0 + oldLen * samplesPerPixel;
28 // Find the length in samples of the old cache.
29 const double denom = oldWhereLast - oldWhere0;
30
31 // What sample would go in where[0] with no correction?
32 const double guessWhere0 = t0 * rate;
33
34 if ( // Skip if old and NEW are disjoint:
35 oldWhereLast <= guessWhere0 ||
36 guessWhere0 + newLen * samplesPerPixel <= oldWhere0 ||
37 // Skip unless denom rounds off to at least 1.
38 denom < 0.5)
39 {
40 // The computation of oldX0 in the other branch
41 // may underflow and the assertion would be violated.
42 oldX0 = oldLen;
43 correction = 0.0;
44 }
45 else
46 {
47 // What integer position in the old cache array does that map to?
48 // (even if it is out of bounds)
49 oldX0 = floor(0.5 + oldLen * (guessWhere0 - oldWhere0) / denom);
50 // What sample count would the old cache have put there?
51 const double where0 = oldWhere0 + double(oldX0) * samplesPerPixel;
52 // What correction is needed to align the NEW cache with the old?
53 const double correction0 = where0 - guessWhere0;
54 correction = std::max(-samplesPerPixel, std::min(samplesPerPixel, correction0));
55 wxASSERT(correction == correction0);
56 }
57}
58
60 std::vector<sampleCount> &where, size_t len, double bias, double correction,
61 double t0, double rate, double samplesPerPixel)
62{
63 // Be careful to make the first value non-negative
64 const double w0 = 0.5 + correction + bias + t0 * rate;
65 where[0] = sampleCount( std::max(0.0, floor(w0)) );
66 for (decltype(len) x = 1; x < len + 1; x++)
67 where[x] = sampleCount( floor(w0 + double(x) * samplesPerPixel) );
68}
int min(int a, int b)
void findCorrection(const std::vector< sampleCount > &oldWhere, size_t oldLen, size_t newLen, double t0, double rate, double samplesPerPixel, int &oldX0, double &correction)
void fillWhere(std::vector< sampleCount > &where, size_t len, double bias, double correction, double t0, double rate, double samplesPerPixel)
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19