2010-01-23 19:44:49 +00:00
|
|
|
/**********************************************************************
|
|
|
|
|
|
|
|
Audacity: A Digital Audio Editor
|
|
|
|
|
|
|
|
WaveClip.h
|
|
|
|
|
|
|
|
?? Dominic Mazzoni
|
|
|
|
?? Markus Meyer
|
|
|
|
|
|
|
|
*******************************************************************/
|
|
|
|
|
|
|
|
#ifndef __AUDACITY_WAVECLIP__
|
|
|
|
#define __AUDACITY_WAVECLIP__
|
|
|
|
|
|
|
|
#include "Audacity.h"
|
2016-04-11 00:24:30 +00:00
|
|
|
#include "MemoryX.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
#include "SampleFormat.h"
|
|
|
|
#include "widgets/ProgressDialog.h"
|
|
|
|
#include "ondemand/ODTaskThread.h"
|
|
|
|
#include "xml/XMLTagHandler.h"
|
|
|
|
|
|
|
|
#include "Experimental.h"
|
|
|
|
#include "RealFFTf.h"
|
|
|
|
|
|
|
|
#include <wx/gdicmn.h>
|
|
|
|
#include <wx/longlong.h>
|
|
|
|
#include <wx/msgdlg.h>
|
|
|
|
|
2015-06-03 17:11:17 +00:00
|
|
|
#include <vector>
|
|
|
|
|
2015-07-05 15:22:03 +00:00
|
|
|
class BlockArray;
|
|
|
|
class DirManager;
|
2010-01-23 19:44:49 +00:00
|
|
|
class Envelope;
|
2015-07-05 15:22:03 +00:00
|
|
|
class Sequence;
|
2015-06-09 18:01:44 +00:00
|
|
|
class SpectrogramSettings;
|
2010-01-23 19:44:49 +00:00
|
|
|
class WaveCache;
|
2015-05-26 22:11:36 +00:00
|
|
|
class WaveTrackCache;
|
2015-06-09 18:01:44 +00:00
|
|
|
|
|
|
|
class SpecCache {
|
|
|
|
public:
|
|
|
|
|
|
|
|
// Make invalid cache
|
|
|
|
SpecCache()
|
2016-09-08 18:28:34 +00:00
|
|
|
: algorithm(-1)
|
2015-06-09 18:01:44 +00:00
|
|
|
, pps(-1.0)
|
|
|
|
, start(-1.0)
|
|
|
|
, windowType(-1)
|
|
|
|
, frequencyGain(-1)
|
2015-08-09 11:03:42 +00:00
|
|
|
#if 0
|
2015-06-09 18:01:44 +00:00
|
|
|
, freq(NULL)
|
|
|
|
, where(NULL)
|
2015-08-09 11:03:42 +00:00
|
|
|
#endif
|
2015-06-09 18:01:44 +00:00
|
|
|
, dirty(-1)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make valid cache, to be filled in
|
2016-09-08 18:28:34 +00:00
|
|
|
SpecCache(size_t cacheLen, int algorithm_,
|
|
|
|
double pps_, double start_, int windowType_, size_t windowSize_,
|
|
|
|
unsigned zeroPaddingFactor_, int frequencyGain_)
|
2015-06-09 18:01:44 +00:00
|
|
|
: len(cacheLen)
|
2015-08-16 23:17:25 +00:00
|
|
|
, algorithm(algorithm_)
|
2015-06-09 18:01:44 +00:00
|
|
|
, pps(pps_)
|
|
|
|
, start(start_)
|
|
|
|
, windowType(windowType_)
|
|
|
|
, windowSize(windowSize_)
|
|
|
|
, zeroPaddingFactor(zeroPaddingFactor_)
|
|
|
|
, frequencyGain(frequencyGain_)
|
2017-02-13 20:29:35 +00:00
|
|
|
, freq{}
|
2015-06-09 18:01:44 +00:00
|
|
|
|
|
|
|
// Sample counts corresponding to the columns, and to one past the end.
|
|
|
|
, where(len + 1)
|
|
|
|
|
|
|
|
, dirty(-1)
|
|
|
|
{
|
|
|
|
where[0] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
~SpecCache()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-08-16 23:17:25 +00:00
|
|
|
bool Matches(int dirty_, double pixelsPerSecond,
|
2015-06-09 18:01:44 +00:00
|
|
|
const SpectrogramSettings &settings, double rate) const;
|
|
|
|
|
2015-08-17 14:03:45 +00:00
|
|
|
bool CalculateOneSpectrum
|
2015-06-09 18:01:44 +00:00
|
|
|
(const SpectrogramSettings &settings,
|
|
|
|
WaveTrackCache &waveTrackCache,
|
|
|
|
int xx, sampleCount numSamples,
|
2015-06-04 16:55:47 +00:00
|
|
|
double offset, double rate, double pixelsPerSecond,
|
|
|
|
int lowerBoundX, int upperBoundX,
|
2015-08-17 01:14:41 +00:00
|
|
|
const std::vector<float> &gainFactors,
|
2016-08-25 17:41:40 +00:00
|
|
|
float* __restrict scratch,
|
|
|
|
float* __restrict out) const;
|
2015-06-09 18:01:44 +00:00
|
|
|
|
2017-02-13 20:29:35 +00:00
|
|
|
void Allocate(const SpectrogramSettings &settings);
|
|
|
|
|
2015-06-09 18:01:44 +00:00
|
|
|
void Populate
|
|
|
|
(const SpectrogramSettings &settings, WaveTrackCache &waveTrackCache,
|
2016-09-08 18:28:34 +00:00
|
|
|
int copyBegin, int copyEnd, size_t numPixels,
|
2015-06-09 18:01:44 +00:00
|
|
|
sampleCount numSamples,
|
2015-06-04 16:55:47 +00:00
|
|
|
double offset, double rate, double pixelsPerSecond);
|
2015-06-09 18:01:44 +00:00
|
|
|
|
2016-09-08 18:28:34 +00:00
|
|
|
const size_t len { 0 }; // counts pixels, not samples
|
2015-08-16 23:17:25 +00:00
|
|
|
const int algorithm;
|
2015-06-09 18:01:44 +00:00
|
|
|
const double pps;
|
|
|
|
const double start;
|
|
|
|
const int windowType;
|
2016-09-08 18:28:34 +00:00
|
|
|
const size_t windowSize { 0 };
|
|
|
|
const unsigned zeroPaddingFactor { 0 };
|
2015-06-09 18:01:44 +00:00
|
|
|
const int frequencyGain;
|
|
|
|
std::vector<float> freq;
|
|
|
|
std::vector<sampleCount> where;
|
|
|
|
|
|
|
|
int dirty;
|
|
|
|
};
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
class SpecPxCache {
|
|
|
|
public:
|
2016-09-06 13:19:27 +00:00
|
|
|
SpecPxCache(size_t cacheLen)
|
2016-04-14 16:17:59 +00:00
|
|
|
: len{ cacheLen }
|
|
|
|
, values{ len }
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
valid = false;
|
2015-06-16 04:55:34 +00:00
|
|
|
scaleType = 0;
|
2015-06-04 03:02:37 +00:00
|
|
|
range = gain = -1;
|
2015-06-10 06:04:07 +00:00
|
|
|
minFreq = maxFreq = -1;
|
2010-01-23 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2016-09-06 13:19:27 +00:00
|
|
|
size_t len;
|
2016-04-14 16:17:59 +00:00
|
|
|
Floats values;
|
2010-01-23 19:44:49 +00:00
|
|
|
bool valid;
|
2015-06-04 03:02:37 +00:00
|
|
|
|
2015-06-16 04:55:34 +00:00
|
|
|
int scaleType;
|
2015-06-04 03:02:37 +00:00
|
|
|
int range;
|
|
|
|
int gain;
|
2015-06-10 06:04:07 +00:00
|
|
|
int minFreq;
|
|
|
|
int maxFreq;
|
2010-01-23 19:44:49 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class WaveClip;
|
|
|
|
|
2016-02-20 23:43:08 +00:00
|
|
|
// Array of pointers that assume ownership
|
2017-03-24 19:01:19 +00:00
|
|
|
using WaveClipHolder = movable_ptr< WaveClip >;
|
|
|
|
using WaveClipHolders = std::vector < WaveClipHolder >;
|
2016-02-20 23:43:08 +00:00
|
|
|
using WaveClipConstHolders = std::vector < movable_ptr< const WaveClip > >;
|
2016-08-11 17:06:24 +00:00
|
|
|
|
|
|
|
// Temporary arrays of mere pointers
|
|
|
|
using WaveClipPointers = std::vector < WaveClip* >;
|
|
|
|
using WaveClipConstPointers = std::vector < const WaveClip* >;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2015-06-09 18:12:28 +00:00
|
|
|
// A bundle of arrays needed for drawing waveforms. The object may or may not
|
|
|
|
// own the storage for those arrays. If it does, it destroys them.
|
2015-06-02 23:15:29 +00:00
|
|
|
class WaveDisplay
|
2015-06-01 23:50:28 +00:00
|
|
|
{
|
2015-06-02 23:15:29 +00:00
|
|
|
public:
|
2015-06-01 23:50:28 +00:00
|
|
|
int width;
|
|
|
|
sampleCount *where;
|
|
|
|
float *min, *max, *rms;
|
|
|
|
int* bl;
|
|
|
|
|
2015-06-09 18:12:28 +00:00
|
|
|
std::vector<sampleCount> ownWhere;
|
|
|
|
std::vector<float> ownMin, ownMax, ownRms;
|
|
|
|
std::vector<int> ownBl;
|
|
|
|
|
|
|
|
public:
|
2015-06-05 13:47:56 +00:00
|
|
|
WaveDisplay(int w)
|
|
|
|
: width(w), where(0), min(0), max(0), rms(0), bl(0)
|
2015-06-01 23:50:28 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-06-09 18:12:28 +00:00
|
|
|
// Create "own" arrays.
|
|
|
|
void Allocate()
|
|
|
|
{
|
|
|
|
ownWhere.resize(width + 1);
|
|
|
|
ownMin.resize(width);
|
|
|
|
ownMax.resize(width);
|
|
|
|
ownRms.resize(width);
|
|
|
|
ownBl.resize(width);
|
|
|
|
|
|
|
|
where = &ownWhere[0];
|
|
|
|
if (width > 0) {
|
|
|
|
min = &ownMin[0];
|
|
|
|
max = &ownMax[0];
|
|
|
|
rms = &ownRms[0];
|
|
|
|
bl = &ownBl[0];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
min = max = rms = 0;
|
|
|
|
bl = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-01 23:50:28 +00:00
|
|
|
~WaveDisplay()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-02-24 06:06:39 +00:00
|
|
|
class AUDACITY_DLL_API WaveClip final : public XMLTagHandler
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
2010-09-10 22:02:04 +00:00
|
|
|
private:
|
|
|
|
// It is an error to copy a WaveClip without specifying the DirManager.
|
2016-02-20 23:43:08 +00:00
|
|
|
|
2016-04-11 00:24:30 +00:00
|
|
|
WaveClip(const WaveClip&) PROHIBITED;
|
|
|
|
WaveClip& operator= (const WaveClip&) PROHIBITED;
|
2010-09-10 22:02:04 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
public:
|
|
|
|
// typical constructor
|
2016-08-13 04:38:31 +00:00
|
|
|
WaveClip(const std::shared_ptr<DirManager> &projDirManager, sampleFormat format, int rate);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
// essentially a copy constructor - but you must pass in the
|
|
|
|
// current project's DirManager, because we might be copying
|
|
|
|
// from one project to another
|
2016-11-26 20:20:28 +00:00
|
|
|
WaveClip(const WaveClip& orig,
|
|
|
|
const std::shared_ptr<DirManager> &projDirManager,
|
|
|
|
bool copyCutlines);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2016-11-26 16:47:45 +00:00
|
|
|
// Copy only a range from the given WaveClip
|
|
|
|
WaveClip(const WaveClip& orig,
|
|
|
|
const std::shared_ptr<DirManager> &projDirManager,
|
2016-11-26 20:20:28 +00:00
|
|
|
bool copyCutlines,
|
2016-11-26 16:47:45 +00:00
|
|
|
double t0, double t1);
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
virtual ~WaveClip();
|
|
|
|
|
|
|
|
void ConvertToSampleFormat(sampleFormat format);
|
|
|
|
|
|
|
|
void TimeToSamplesClip(double t0, sampleCount *s0) const;
|
|
|
|
int GetRate() const { return mRate; }
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
// Set rate without resampling. This will change the length of the clip
|
|
|
|
void SetRate(int rate);
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
// Resample clip. This also will set the rate, but without changing
|
|
|
|
// the length of the clip
|
2017-03-22 18:55:07 +00:00
|
|
|
void Resample(int rate, ProgressDialog *progress = NULL);
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
void SetOffset(double offset);
|
|
|
|
double GetOffset() const { return mOffset; }
|
2017-04-02 02:20:38 +00:00
|
|
|
void Offset(double delta) // NOFAIL-GUARANTEE
|
|
|
|
{ SetOffset(GetOffset() + delta); }
|
2010-01-23 19:44:49 +00:00
|
|
|
double GetStartTime() const;
|
|
|
|
double GetEndTime() const;
|
|
|
|
sampleCount GetStartSample() const;
|
|
|
|
sampleCount GetEndSample() const;
|
2015-07-05 15:22:03 +00:00
|
|
|
sampleCount GetNumSamples() const;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
// One and only one of the following is true for a given t (unless the clip
|
|
|
|
// has zero length -- then BeforeClip() and AfterClip() can both be true).
|
|
|
|
// Within() is true if the time is substantially within the clip
|
|
|
|
bool WithinClip(double t) const;
|
|
|
|
bool BeforeClip(double t) const;
|
|
|
|
bool AfterClip(double t) const;
|
|
|
|
|
|
|
|
bool GetSamples(samplePtr buffer, sampleFormat format,
|
2017-03-20 14:54:03 +00:00
|
|
|
sampleCount start, size_t len, bool mayThrow = true) const;
|
2017-03-22 18:55:07 +00:00
|
|
|
void SetSamples(samplePtr buffer, sampleFormat format,
|
2016-09-06 13:19:27 +00:00
|
|
|
sampleCount start, size_t len);
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2016-04-08 05:56:06 +00:00
|
|
|
Envelope* GetEnvelope() { return mEnvelope.get(); }
|
|
|
|
const Envelope* GetEnvelope() const { return mEnvelope.get(); }
|
2015-07-05 15:22:03 +00:00
|
|
|
BlockArray* GetSequenceBlockArray();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
// Get low-level access to the sequence. Whenever possible, don't use this,
|
|
|
|
// but use more high-level functions inside WaveClip (or add them if you
|
|
|
|
// think they are useful for general use)
|
2016-04-11 00:24:30 +00:00
|
|
|
Sequence* GetSequence() { return mSequence.get(); }
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
/** WaveTrack calls this whenever data in the wave clip changes. It is
|
2013-02-20 23:42:58 +00:00
|
|
|
* called automatically when WaveClip has a chance to know that something
|
|
|
|
* has changed, like when member functions SetSamples() etc. are called. */
|
2017-04-02 02:20:38 +00:00
|
|
|
void MarkChanged() // NOFAIL-GUARANTEE
|
|
|
|
{ mDirty++; }
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
/** Getting high-level data from the for screen display and clipping
|
2013-02-20 23:42:58 +00:00
|
|
|
* calculations and Contrast */
|
2015-06-01 23:50:28 +00:00
|
|
|
bool GetWaveDisplay(WaveDisplay &display,
|
2016-02-27 17:12:40 +00:00
|
|
|
double t0, double pixelsPerSecond, bool &isLoadingOD) const;
|
2015-05-26 22:11:36 +00:00
|
|
|
bool GetSpectrogram(WaveTrackCache &cache,
|
2017-02-13 20:29:35 +00:00
|
|
|
const float *& spectrogram,
|
|
|
|
const sampleCount *& where,
|
2016-09-08 18:28:34 +00:00
|
|
|
size_t numPixels,
|
2016-02-27 17:12:40 +00:00
|
|
|
double t0, double pixelsPerSecond) const;
|
2016-12-25 13:40:15 +00:00
|
|
|
std::pair<float, float> GetMinMax(
|
|
|
|
double t0, double t1, bool mayThrow = true) const;
|
|
|
|
float GetRMS(double t0, double t1, bool mayThrow = true) const;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
// Set/clear/get rectangle that this WaveClip fills on screen. This is
|
|
|
|
// called by TrackArtist while actually drawing the tracks and clips.
|
2016-08-11 17:06:24 +00:00
|
|
|
void ClearDisplayRect() const;
|
2016-02-27 17:12:40 +00:00
|
|
|
void SetDisplayRect(const wxRect& r) const;
|
2010-01-23 19:44:49 +00:00
|
|
|
void GetDisplayRect(wxRect* r);
|
|
|
|
|
|
|
|
/** Whenever you do an operation to the sequence that will change the number
|
2013-02-20 23:42:58 +00:00
|
|
|
* of samples (that is, the length of the clip), you will want to call this
|
|
|
|
* function to tell the envelope about it. */
|
2010-01-23 19:44:49 +00:00
|
|
|
void UpdateEnvelopeTrackLen();
|
|
|
|
|
|
|
|
/// You must call Flush after the last Append
|
2017-03-22 18:55:07 +00:00
|
|
|
void Append(samplePtr buffer, sampleFormat format,
|
2016-09-06 13:19:27 +00:00
|
|
|
size_t len, unsigned int stride=1,
|
2010-01-23 19:44:49 +00:00
|
|
|
XMLWriter* blockFileLog = NULL);
|
|
|
|
/// Flush must be called after last Append
|
2017-04-03 01:19:12 +00:00
|
|
|
void Flush();
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2017-03-22 18:55:07 +00:00
|
|
|
void AppendAlias(const wxString &fName, sampleCount start,
|
2016-09-06 13:19:27 +00:00
|
|
|
size_t len, int channel,bool useOD);
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2017-03-22 18:55:07 +00:00
|
|
|
void AppendCoded(const wxString &fName, sampleCount start,
|
2016-09-06 13:19:27 +00:00
|
|
|
size_t len, int channel, int decodeType);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
/// This name is consistent with WaveTrack::Clear. It performs a "Cut"
|
|
|
|
/// operation (but without putting the cutted audio to the clipboard)
|
2017-03-22 18:55:07 +00:00
|
|
|
void Clear(double t0, double t1);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
/// Clear, and add cut line that starts at t0 and contains everything until t1.
|
2017-03-22 18:55:07 +00:00
|
|
|
void ClearAndAddCutLine(double t0, double t1);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
/// Paste data from other clip, resampling it if not equal rate
|
2017-03-22 18:55:07 +00:00
|
|
|
void Paste(double t0, const WaveClip* other);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
/** Insert silence - note that this is an efficient operation for large
|
2013-02-20 23:42:58 +00:00
|
|
|
* amounts of silence */
|
2017-05-06 04:57:38 +00:00
|
|
|
void InsertSilence( double t, double len, double *pEnvelopeValue = nullptr );
|
|
|
|
|
|
|
|
/** Insert silence at the end, and causes the envelope to ramp
|
|
|
|
linearly to the given value */
|
|
|
|
void AppendSilence( double len, double envelopeValue );
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
/// Get access to cut lines list
|
2016-08-11 17:06:24 +00:00
|
|
|
WaveClipHolders &GetCutLines() { return mCutLines; }
|
|
|
|
const WaveClipConstHolders &GetCutLines() const
|
|
|
|
{ return reinterpret_cast< const WaveClipConstHolders& >( mCutLines ); }
|
|
|
|
size_t NumCutLines() const { return mCutLines.size(); }
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
/** Find cut line at (approximately) this position. Returns true and fills
|
2013-02-20 23:42:58 +00:00
|
|
|
* in cutLineStart and cutLineEnd (if specified) if a cut line at this
|
|
|
|
* position could be found. Return false otherwise. */
|
2010-01-23 19:44:49 +00:00
|
|
|
bool FindCutLine(double cutLinePosition,
|
|
|
|
double* cutLineStart = NULL,
|
2017-03-24 18:59:22 +00:00
|
|
|
double *cutLineEnd = NULL) const;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2016-02-14 23:50:45 +00:00
|
|
|
/** Expand cut line (that is, re-insert audio, then DELETE audio saved in
|
2013-02-20 23:42:58 +00:00
|
|
|
* cut line). Returns true if a cut line could be found and sucessfully
|
|
|
|
* expanded, false otherwise */
|
2017-03-22 18:55:07 +00:00
|
|
|
void ExpandCutLine(double cutLinePosition);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
/// Remove cut line, without expanding the audio in it
|
|
|
|
bool RemoveCutLine(double cutLinePosition);
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
/// Offset cutlines right to time 't0' by time amount 'len'
|
|
|
|
void OffsetCutLines(double t0, double len);
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
/// Lock all blockfiles
|
|
|
|
void Lock();
|
|
|
|
/// Unlock all blockfiles
|
|
|
|
void Unlock();
|
|
|
|
|
2016-04-12 03:38:33 +00:00
|
|
|
void CloseLock(); //similar to Lock but should be called when the project closes.
|
|
|
|
// not balanced by unlocking calls.
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
///Delete the wave cache - force redraw. Thread-safe
|
2016-04-08 05:56:06 +00:00
|
|
|
void ClearWaveCache();
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
///Adds an invalid region to the wavecache so it redraws that portion only.
|
2016-08-22 22:06:34 +00:00
|
|
|
void AddInvalidRegion(sampleCount startSample, sampleCount endSample);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// XMLTagHandler callback methods for loading and saving
|
|
|
|
//
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2016-02-24 06:06:47 +00:00
|
|
|
bool HandleXMLTag(const wxChar *tag, const wxChar **attrs) override;
|
|
|
|
void HandleXMLEndTag(const wxChar *tag) override;
|
|
|
|
XMLTagHandler *HandleXMLChild(const wxChar *tag) override;
|
2017-02-22 19:23:35 +00:00
|
|
|
void WriteXML(XMLWriter &xmlFile) const /* not override */;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
// AWD, Oct 2009: for pasting whitespace at the end of selection
|
2015-04-08 16:09:30 +00:00
|
|
|
bool GetIsPlaceholder() const { return mIsPlaceholder; }
|
|
|
|
void SetIsPlaceholder(bool val) { mIsPlaceholder = val; }
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2017-05-16 13:23:07 +00:00
|
|
|
// used by commands which interact with clips using the keyboard
|
|
|
|
bool SharesBoundaryWithNextClip(const WaveClip* next) const;
|
|
|
|
|
2016-11-26 16:47:45 +00:00
|
|
|
public:
|
|
|
|
// Cache of values to colour pixels of Spectrogram - used by TrackArtist
|
|
|
|
mutable std::unique_ptr<SpecPxCache> mSpecPxCache;
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
protected:
|
2016-11-26 16:47:45 +00:00
|
|
|
mutable wxRect mDisplayRect {};
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2016-11-26 16:47:45 +00:00
|
|
|
double mOffset { 0 };
|
2010-01-23 19:44:49 +00:00
|
|
|
int mRate;
|
2016-11-26 16:47:45 +00:00
|
|
|
int mDirty { 0 };
|
2016-04-11 00:24:30 +00:00
|
|
|
std::unique_ptr<Sequence> mSequence;
|
2016-04-08 05:56:06 +00:00
|
|
|
std::unique_ptr<Envelope> mEnvelope;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2016-04-08 05:56:06 +00:00
|
|
|
mutable std::unique_ptr<WaveCache> mWaveCache;
|
2016-11-26 16:47:45 +00:00
|
|
|
mutable ODLock mWaveCacheMutex {};
|
2016-04-08 05:56:06 +00:00
|
|
|
mutable std::unique_ptr<SpecCache> mSpecCache;
|
2016-11-26 16:47:45 +00:00
|
|
|
SampleBuffer mAppendBuffer {};
|
|
|
|
size_t mAppendBufferLen { 0 };
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
// Cut Lines are nothing more than ordinary wave clips, with the
|
|
|
|
// offset relative to the start of the clip.
|
2016-11-26 16:47:45 +00:00
|
|
|
WaveClipHolders mCutLines {};
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
// AWD, Oct. 2009: for whitespace-at-end-of-selection pasting
|
2016-11-26 16:47:45 +00:00
|
|
|
bool mIsPlaceholder { false };
|
2010-01-23 19:44:49 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|