wavetrack.h

Upload User: jinmianbs
Upload Date: 2008-12-17
Package Size: 6493k
Code Size: 11k
Category: Audio program
Development Platform: C++
  1. /**********************************************************************
  2.   Audacity: A Digital Audio Editor
  3.   WaveTrack.h
  4.   Dominic Mazzoni
  5. **********************************************************************/
  6. #ifndef __AUDACITY_WAVETRACK__
  7. #define __AUDACITY_WAVETRACK__
  8. #include "Track.h"
  9. #include "SampleFormat.h"
  10. #include "Sequence.h"
  11. #include "WaveClip.h"
  12. #include <wx/gdicmn.h>
  13. #include <wx/longlong.h>
  14. #include <wx/thread.h>
  15. //
  16. // Tolerance for merging wave tracks (in seconds)
  17. //
  18. #define WAVETRACK_MERGE_POINT_TOLERANCE 0.01
  19. typedef wxLongLong_t longSampleCount; /* 64-bit int */
  20. /// brief Structure to hold region of a wavetrack and a comparison function
  21. /// for sortability.
  22. typedef struct REGION
  23. {
  24.    double start, end;
  25.    
  26.    //used for sorting
  27.    static int cmp( REGION **a, REGION **b )
  28.    { 
  29.       return ( ( *a )->start < ( *b )->start ) ? -1 : 1; 
  30.    }
  31. }Region;
  32. WX_DEFINE_ARRAY( Region*, Regions );
  33. class Envelope;
  34. class WaveTrack: public Track {
  35.  private:
  36.    //
  37.    // Constructor / Destructor / Duplicator
  38.    //
  39.    // Private since only factories are allowed to construct WaveTracks
  40.    //
  41.    WaveTrack(DirManager * projDirManager, 
  42.              sampleFormat format = (sampleFormat)0,
  43.              double rate = 0);
  44.    WaveTrack(WaveTrack &orig);
  45.    void Init(const WaveTrack &orig);
  46.    virtual Track *Duplicate();
  47.    friend class TrackFactory;
  48.  public:
  49.  
  50.    enum LocationType {
  51.       locationCutLine = 1,
  52.       locationMergePoint
  53.    };
  54.    struct Location {
  55.       // Position of track location
  56.       double pos;
  57.       
  58.       // Type of track location
  59.       LocationType typ;
  60.       
  61.       // Only for typ==locationMergePoint
  62.       int clipidx1; // first clip (left one)
  63.       int clipidx2; // second clip (right one)
  64.    };
  65.       
  66.    virtual ~WaveTrack();
  67.    virtual double GetOffset();
  68.    virtual void SetOffset (double o);
  69.    // Start time is the earliest time there is a clip
  70.    double GetStartTime();
  71.    // End time is where the last clip ends, plus recorded stuff
  72.    double GetEndTime();
  73.    //
  74.    // Identifying the type of track
  75.    //
  76.    virtual int GetKind() const { return Wave; } 
  77.    //
  78.    // WaveTrack parameters
  79.    //
  80.    double GetRate() const;
  81.    void SetRate(double newRate);
  82.    // Multiplicative factor.  Only converted to dB for display.
  83.    float GetGain() const;
  84.    void SetGain(float newGain);
  85.    // -1.0 (left) -> 1.0 (right)
  86.    float GetPan() const;
  87.    void SetPan(float newPan);
  88.    // Takes gain and pan into account
  89.    float GetChannelGain(int channel);
  90.    sampleFormat GetSampleFormat() { return mFormat; }
  91.    bool ConvertToSampleFormat(sampleFormat format);
  92.    //
  93.    // High-level editing
  94.    //
  95.    virtual bool Cut  (double t0, double t1, Track **dest);
  96.    virtual bool Copy (double t0, double t1, Track **dest);
  97.    virtual bool Clear(double t0, double t1);
  98.    virtual bool Paste(double t, Track *src);
  99.    virtual bool Silence(double t0, double t1);
  100.    virtual bool InsertSilence(double t, double len);
  101.    virtual bool SplitAt(double t);
  102.    virtual bool Split( double t0, double t1 );
  103.    virtual bool CutAndAddCutLine(double t0, double t1, Track **dest);
  104.    virtual bool ClearAndAddCutLine(double t0, double t1);
  105.    virtual bool SplitCut   (double t0, double t1, Track **dest);
  106.    virtual bool SplitDelete(double t0, double t1);
  107.    virtual bool Join       (double t0, double t1);
  108.    virtual bool Disjoin    (double t0, double t1);
  109.    typedef bool ( WaveTrack::* EditFunction )( double, double );
  110.    typedef bool ( WaveTrack::* EditDestFunction )( double, double, Track** );
  111.    virtual bool Trim (double t0, double t1);
  112.    bool HandleClear(double t0, double t1,
  113.                     bool addCutLines, bool split);
  114.    // Returns true if there are no WaveClips in that region
  115.    bool IsEmpty(double t0, double t1);
  116.    /// You must call Flush after the last Append
  117.    bool Append(samplePtr buffer, sampleFormat format,
  118.                sampleCount len, unsigned int stride=1,
  119.                XMLWriter* blockFileLog=NULL);
  120.    /// Flush must be called after last Append
  121.    bool Flush();
  122.    bool AppendAlias(wxString fName, sampleCount start,
  123.                     sampleCount len, int channel);
  124.                     
  125.    ///
  126.    /// MM: Now that each wave track can contain multiple clips, we don't
  127.    /// have a continous space of samples anymore, but we simulate it,
  128.    /// because there are alot of places (e.g. effects) using this interface.
  129.    /// This interface makes much sense for modifying samples, but note that
  130.    /// it is not time-accurate, because the "offset" is a double value and
  131.    /// therefore can lie inbetween samples. But as long as you use the
  132.    /// same value for "start" in both calls to "Set" and "Get" it is
  133.    /// guaranteed that the same samples are affected.
  134.    ///
  135.    bool Get(samplePtr buffer, sampleFormat format,
  136.                    longSampleCount start, sampleCount len);
  137.    bool Set(samplePtr buffer, sampleFormat format,
  138.                    longSampleCount start, sampleCount len);
  139.    void GetEnvelopeValues(double *buffer, int bufferLen,
  140.                          double t0, double tstep);
  141.    bool GetMinMax(float *min, float *max,
  142.                   double t0, double t1);
  143.    //
  144.    // MM: We now have more than one sequence and envelope per track, so
  145.    // instead of GetSequence() and GetEnvelope() we have the following
  146.    // function which give the sequence and envelope which is under the
  147.    // given X coordinate of the mouse pointer.
  148.    //
  149.    WaveClip* GetClipAtX(int xcoord);
  150.    Sequence* GetSequenceAtX(int xcoord);
  151.    Envelope* GetEnvelopeAtX(int xcoord);
  152.    //
  153.    // Getting information about the track's internal block sizes
  154.    // for efficiency
  155.    //
  156.    sampleCount GetBestBlockSize(longSampleCount t);
  157.    sampleCount GetMaxBlockSize();
  158.    sampleCount GetIdealBlockSize();
  159.    //
  160.    // XMLTagHandler callback methods for loading and saving
  161.    //
  162.    virtual bool HandleXMLTag(const wxChar *tag, const wxChar **attrs);
  163.    virtual void HandleXMLEndTag(const wxChar *tag);
  164.    virtual XMLTagHandler *HandleXMLChild(const wxChar *tag);
  165.    virtual void WriteXML(XMLWriter &xmlFile);
  166.    // Returns true if an error occurred while reading from XML
  167.    virtual bool GetErrorOpening();
  168.    //
  169.    // Lock and unlock the track: you must lock the track before
  170.    // doing a copy and paste between projects.
  171.    //
  172.    bool Lock();
  173.    bool Unlock();
  174.    // Utility functions to convert between times in seconds
  175.    // and sample positions
  176.    longSampleCount TimeToLongSamples(double t0);
  177.    double LongSamplesToTime(longSampleCount pos);
  178.    // Get access to the clips in the tracks. This is used by
  179.    // track artists and also by TrackPanel when sliding...it would
  180.    // be cleaner if this could be removed, though...
  181.    WaveClipList::Node* GetClipIterator() { return mClips.GetFirst(); }
  182.    // Create new clip and add it to this track. Returns a pointer
  183.    // to the newly created clip.
  184.    WaveClip* CreateClip();
  185.    // Get access to the last clip, or create a clip, if there is not
  186.    // already one.
  187.    WaveClip* GetLastOrCreateClip();
  188.    // Get the linear index of a given clip (-1 if the clip is not found)
  189.    int GetClipIndex(WaveClip* clip);
  190.    // Get the nth clip in this WaveTrack (will return NULL if not found).
  191.    // Use this only in special cases (like getting the linked clip), because
  192.    // it is much slower than GetClipIterator().
  193.    WaveClip* GetClipByIndex(int index);
  194.    // Get number of clips in this WaveTrack
  195.    int GetNumClips() const;
  196.    
  197.    // Add all wave clips to the given array 'clips' and sort the array by
  198.    // clip start time. The array is emptied prior to adding the clips.
  199.    void FillSortedClipArray(WaveClipArray& clips);
  200.    // Before calling 'Offset' on a clip, use this function to see if the
  201.    // offsetting is allowed with respect to the other clips in this track.
  202.    // This function can optionally return the amount that is allowed for offsetting
  203.    // in this direction maximally.
  204.    bool CanOffsetClip(WaveClip* clip, double amount, double *allowedAmount=NULL);
  205.    // Before moving a clip into a track (or inserting a clip), use this 
  206.    // function to see if the times are valid (i.e. don't overlap with
  207.    // existing clips).
  208.    bool CanInsertClip(WaveClip* clip);
  209.    // Move a clip into a new track. This will remove the clip
  210.    // in this cliplist and add it to the cliplist of the
  211.    // other clip. No fancy additional stuff is done.
  212.    void MoveClipToTrack(int clipIndex, WaveTrack* dest);
  213.    void MoveClipToTrack(WaveClip *clip, WaveTrack* dest);
  214.    
  215.    // Merge two clips, that is append data from clip2 to clip1,
  216.    // then remove clip2 from track.
  217.    // clipidx1 and clipidx2 are indices into the clip list.
  218.    bool MergeClips(int clipidx1, int clipidx2);
  219.    // Set/get rectangle that this WaveClip fills on screen. This is
  220.    // called by TrackArtist while actually drawing the tracks and clips.
  221.    void SetDisplayRect(const wxRect& r) { mDisplayRect = r; }
  222.    void GetDisplayRect(wxRect* r) { *r = mDisplayRect; }
  223.    // Cache special locations (e.g. cut lines) for later speedy access
  224.    void UpdateLocationsCache();
  225.    // Get number of cached locations
  226.    int GetNumCachedLocations() { return mDisplayNumLocations; }
  227.    Location GetCachedLocation(int index) { return mDisplayLocations[index]; }
  228.    // Expand cut line (that is, re-insert audio, then delete audio saved in cut line)
  229.    bool ExpandCutLine(double cutLinePosition, double* cutlineStart = NULL, double* cutlineEnd = NULL);
  230.    // Remove cut line, without expanding the audio in it
  231.    bool RemoveCutLine(double cutLinePosition);
  232.    // This track has been merged into a stereo track.  Copy shared parameters
  233.    // from the new partner.
  234.    virtual void Merge(const Track &orig);
  235.    
  236.    // Resample track (i.e. all clips in the track)
  237.    bool Resample(int rate, bool progress = false);
  238.    //
  239.    // The following code will eventually become part of a GUIWaveTrack
  240.    // and will be taken out of the WaveTrack class:
  241.    //
  242.    
  243.    enum {
  244.       WaveformDisplay,
  245.       WaveformDBDisplay,
  246.       SpectrumDisplay,
  247.       PitchDisplay
  248.    } WaveTrackDisplay;
  249.    void SetDisplay(int display) {mDisplay = display;}
  250.    int GetDisplay() {return mDisplay;}
  251.    void GetDisplayBounds(float *min, float *max);
  252.    void SetDisplayBounds(float min, float max);
  253.  protected:
  254.    //
  255.    // Protected variables
  256.    //
  257.    WaveClipList mClips;
  258.    wxRect        mDisplayRect;
  259.    sampleFormat  mFormat;
  260.    int           mRate;
  261.    float         mGain;
  262.    float         mPan;
  263.    //
  264.    // Data that should be part of GUIWaveTrack
  265.    // and will be taken out of the WaveTrack class:
  266.    //
  267.    float         mDisplayMin;
  268.    float         mDisplayMax;
  269.    int           mDisplay; // type of display, from WaveTrackDisplay enum
  270.    int           mDisplayNumLocations;
  271.    int           mDisplayNumLocationsAllocated;
  272.    Location*       mDisplayLocations;
  273.    //
  274.    // Protected methods
  275.    //
  276.  private:
  277.    //
  278.    // Private variables
  279.    //
  280.    wxCriticalSection mFlushCriticalSection;
  281.    wxCriticalSection mAppendCriticalSection;
  282.    double mLegacyProjectFileOffset;
  283. };
  284. #endif // __AUDACITY_WAVETRACK__
  285. // Indentation settings for Vim and Emacs and unique identifier for Arch, a
  286. // version control system. Please do not modify past this point.
  287. //
  288. // Local Variables:
  289. // c-basic-offset: 3
  290. // indent-tabs-mode: nil
  291. // End:
  292. //
  293. // vim: et sts=3 sw=3
  294. // arch-tag: bf4c1c84-7a1d-4689-86fd-f6926b5d3f9a