/********************************************************************** Audacity: A Digital Audio Editor WaveClip.h ?? Dominic Mazzoni ?? Markus Meyer *******************************************************************/ #ifndef __AUDACITY_WAVECLIP__ #define __AUDACITY_WAVECLIP__ #include "Audacity.h" #include "SampleFormat.h" #include "Sequence.h" #include "widgets/ProgressDialog.h" #include "ondemand/ODTaskThread.h" #include "xml/XMLTagHandler.h" #include "Experimental.h" #ifdef EXPERIMENTAL_USE_REALFFTF #include "RealFFTf.h" #endif #include #include #include #include class Envelope; class WaveCache; class SpecCache; class SpecPxCache { public: SpecPxCache(int cacheLen) { len = cacheLen; values = new float[len]; valid = false; } ~SpecPxCache() { delete[] values; } sampleCount len; float *values; bool valid; }; class WaveClip; WX_DECLARE_USER_EXPORTED_LIST(WaveClip, WaveClipList, AUDACITY_DLL_API); WX_DEFINE_USER_EXPORTED_ARRAY_PTR(WaveClip*, WaveClipArray, class AUDACITY_DLL_API); class AUDACITY_DLL_API WaveClip: public XMLTagHandler { private: WaveClip(const WaveClip&) { wxMessageBox(wxT("Fatal error - please report to audacity-devel@lists.sourceforge.net\n")); } public: // typical constructor WaveClip(DirManager *projDirManager, sampleFormat format, int rate); // essentially a copy constructor - but you must pass in the // current project's DirManager, because we might be copying // from one project to another WaveClip(WaveClip& orig, DirManager *projDirManager); virtual ~WaveClip(); void ConvertToSampleFormat(sampleFormat format); void TimeToSamplesClip(double t0, sampleCount *s0) const; int GetRate() const { return mRate; } // Set rate without resampling. This will change the length of the clip void SetRate(int rate); // Resample clip. This also will set the rate, but without changing // the length of the clip bool Resample(int rate, ProgressDialog *progress = NULL); void SetOffset(double offset); double GetOffset() const { return mOffset; } void Offset(double delta) { SetOffset(GetOffset() + delta); } double GetStartTime() const; double GetEndTime() const; sampleCount GetStartSample() const; sampleCount GetEndSample() const; sampleCount GetNumSamples() const { return mSequence->GetNumSamples(); } // 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, sampleCount start, sampleCount len) const; bool SetSamples(samplePtr buffer, sampleFormat format, sampleCount start, sampleCount len); Envelope* GetEnvelope() { return mEnvelope; } BlockArray* GetSequenceBlockArray() { return mSequence->GetBlockArray(); } // 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) Sequence* GetSequence() { return mSequence; } /** WaveTrack calls this whenever data in the wave clip changes. It is * called automatically when WaveClip has a chance to know that something * has changed, like when member functions SetSamples() etc. are called. */ void MarkChanged() { mDirty++; } /// Create clip from copy, discarding previous information in the clip bool CreateFromCopy(double t0, double t1, WaveClip* other); /** Getting high-level data from the for screen display and clipping * calculations and Contrast */ bool GetWaveDisplay(float *min, float *max, float *rms,int* bl, sampleCount *where, int numPixels, double t0, double pixelsPerSecond, bool &isLoadingOD); bool GetSpectrogram(float *buffer, sampleCount *where, int numPixels, double t0, double pixelsPerSecond, bool autocorrelation); bool GetMinMax(float *min, float *max, double t0, double t1); bool GetRMS(float *rms, double t0, double t1); // Set/clear/get rectangle that this WaveClip fills on screen. This is // called by TrackArtist while actually drawing the tracks and clips. void ClearDisplayRect(); void SetDisplayRect(const wxRect& r); void GetDisplayRect(wxRect* r); /** Whenever you do an operation to the sequence that will change the number * of samples (that is, the length of the clip), you will want to call this * function to tell the envelope about it. */ void UpdateEnvelopeTrackLen(); /// You must call Flush after the last Append bool Append(samplePtr buffer, sampleFormat format, sampleCount len, unsigned int stride=1, XMLWriter* blockFileLog = NULL); /// Flush must be called after last Append bool Flush(); bool AppendAlias(wxString fName, sampleCount start, sampleCount len, int channel,bool useOD); bool AppendCoded(wxString fName, sampleCount start, sampleCount len, int channel, int decodeType); /// This name is consistent with WaveTrack::Clear. It performs a "Cut" /// operation (but without putting the cutted audio to the clipboard) bool Clear(double t0, double t1); /// Clear, and add cut line that starts at t0 and contains everything until t1. bool ClearAndAddCutLine(double t0, double t1); /// Paste data from other clip, resampling it if not equal rate bool Paste(double t0, WaveClip* other); /** Insert silence - note that this is an efficient operation for large * amounts of silence */ bool InsertSilence(double t, double len); /// Get access to cut lines list WaveClipList* GetCutLines() { return &mCutLines; } /** Find cut line at (approximately) this position. Returns true and fills * in cutLineStart and cutLineEnd (if specified) if a cut line at this * position could be found. Return false otherwise. */ bool FindCutLine(double cutLinePosition, double* cutLineStart = NULL, double *cutLineEnd = NULL); /** Expand cut line (that is, re-insert audio, then delete audio saved in * cut line). Returns true if a cut line could be found and sucessfully * expanded, false otherwise */ bool ExpandCutLine(double cutLinePosition); /// Remove cut line, without expanding the audio in it bool RemoveCutLine(double cutLinePosition); void RemoveAllCutLines(); /// Offset cutlines right to time 't0' by time amount 'len' void OffsetCutLines(double t0, double len); /// Lock all blockfiles void Lock(); void CloseLock(); //similar to Lock but should be called when the project closes. /// Unlock all blockfiles void Unlock(); ///Delete the wave cache - force redraw. Thread-safe void DeleteWaveCache(); ///Adds an invalid region to the wavecache so it redraws that portion only. void AddInvalidRegion(long startSample, long endSample); // // XMLTagHandler callback methods for loading and saving // virtual bool HandleXMLTag(const wxChar *tag, const wxChar **attrs); virtual void HandleXMLEndTag(const wxChar *tag); virtual XMLTagHandler *HandleXMLChild(const wxChar *tag); virtual void WriteXML(XMLWriter &xmlFile); // Cache of values to colour pixels of Spectrogram - used by TrackArtist SpecPxCache *mSpecPxCache; // AWD, Oct 2009: for pasting whitespace at the end of selection bool GetIsPlaceholder() { return mIsPlaceholder; }; void SetIsPlaceholder(bool val) { mIsPlaceholder = val; }; protected: wxRect mDisplayRect; double mOffset; int mRate; int mDirty; bool mIsCutLine; Sequence *mSequence; Envelope *mEnvelope; WaveCache *mWaveCache; ODLock mWaveCacheMutex; SpecCache *mSpecCache; #ifdef EXPERIMENTAL_USE_REALFFTF // Variables used for computing the spectrum HFFT hFFT; float *mWindow; int mWindowType; int mWindowSize; #endif samplePtr mAppendBuffer; sampleCount mAppendBufferLen; // Cut Lines are nothing more than ordinary wave clips, with the // offset relative to the start of the clip. WaveClipList mCutLines; // AWD, Oct. 2009: for whitespace-at-end-of-selection pasting bool mIsPlaceholder; }; #endif