Logo Search packages:      
Sourcecode: ardour version File versions  Download package

crossfade.h

/*
    Copyright (C) 2000 Paul Davis 

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

    $Id: crossfade.h,v 1.17 2006/01/19 08:17:14 essej Exp $
*/

#ifndef __ardour_overlap_h__
#define __ardour_overlap_h__

#include <vector>
#include <algorithm>

#include <sigc++/signal_system.h>

#include <pbd/undo.h>

#include <ardour/ardour.h>
#include <ardour/curve.h>
#include <ardour/audioregion.h>
#include <ardour/state_manager.h>
#include <ardour/crossfade_compare.h>

namespace ARDOUR {

class AudioRegion;
class Playlist;

struct CrossfadeState : public StateManager::State {
    CrossfadeState (std::string reason) : StateManager::State (reason) {}

    UndoAction fade_in_memento;
    UndoAction fade_out_memento;
    jack_nframes_t position;
    jack_nframes_t length;
    AnchorPoint    anchor_point;
    bool           follow_overlap;
    bool           active;
};

class Crossfade : public Stateful, public StateManager
{
  public:

      class NoCrossfadeHere: std::exception {
        public:
            virtual const char *what() const throw() { return "no crossfade should be constructed here"; }
      };
      
      /* constructor for "fixed" xfades at each end of an internal overlap */

      Crossfade (ARDOUR::AudioRegion& in, ARDOUR::AudioRegion& out,
               jack_nframes_t position,
               jack_nframes_t initial_length,
               AnchorPoint);

      /* constructor for xfade between two regions that are overlapped in any way
         except the "internal" case.
      */
      
      Crossfade (ARDOUR::AudioRegion& in, ARDOUR::AudioRegion& out, CrossfadeModel, bool active);

      /* the usual XML constructor */

      Crossfade (const ARDOUR::Playlist&, XMLNode&);
      virtual ~Crossfade();

      bool operator== (const ARDOUR::Crossfade&);

      XMLNode& get_state (void);
      int set_state (const XMLNode&);

      ARDOUR::AudioRegion& in() const { return *_in; }
      ARDOUR::AudioRegion& out() const { return *_out; }
      
      jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer, 
                        float *gain_buffer, jack_nframes_t position, jack_nframes_t cnt, 
                        uint32_t chan_n,
                        jack_nframes_t read_frames = 0,
                        jack_nframes_t skip_frames = 0);
      
      bool refresh ();

      uint32_t upper_layer () const {
            return std::max (_in->layer(), _out->layer());
      }

      uint32_t lower_layer () const {
            return std::min (_in->layer(), _out->layer());
      }

      bool involves (ARDOUR::AudioRegion& region) const {
            return _in == &region || _out == &region;
      }

      bool involves (ARDOUR::AudioRegion& a, ARDOUR::AudioRegion& b) const {
            return (_in == &a && _out == &b) || (_in == &b && _out == &a);
      }

      jack_nframes_t length() const { return _length; }
      jack_nframes_t overlap_length() const;
      jack_nframes_t position() const { return _position; }

      SigC::Signal1<void,Crossfade*> Invalidated;
      SigC::Signal0<void>            GoingAway;

      bool covers (jack_nframes_t frame) const {
            return _position <= frame && frame < _position + _length;
      }

      OverlapType coverage (jack_nframes_t start, jack_nframes_t end) const;

      UndoAction get_memento() const;     

      static void set_buffer_size (jack_nframes_t);

      bool active () const { return _active; }
      void set_active (bool yn);

      bool following_overlap() const { return _follow_overlap; }
      bool can_follow_overlap() const;
      void set_follow_overlap (bool yn);

      Curve& fade_in() { return _fade_in; } 
      Curve& fade_out() { return _fade_out; }

      jack_nframes_t set_length (jack_nframes_t);
      
      static jack_nframes_t short_xfade_length() { return _short_xfade_length; }
      static void set_short_xfade_length (jack_nframes_t n);

      static Change ActiveChanged;

  private:
      friend struct CrossfadeComparePtr;

      static jack_nframes_t _short_xfade_length;

      ARDOUR::AudioRegion* _in;
      ARDOUR::AudioRegion* _out;
      bool                 _active;
      bool                 _in_update;
      OverlapType           overlap_type;
      jack_nframes_t       _length;
      jack_nframes_t       _position;
      AnchorPoint          _anchor_point;
      bool                 _follow_overlap;
      bool                 _fixed;
      Curve _fade_in;
      Curve _fade_out;

      static Sample* crossfade_buffer_out;
      static Sample* crossfade_buffer_in;

      void initialize (bool savestate=true);
      int  compute (ARDOUR::AudioRegion&, ARDOUR::AudioRegion&, CrossfadeModel);
      bool update (bool force);

      StateManager::State* state_factory (std::string why) const;
      Change restore_state (StateManager::State&);

      void member_changed (ARDOUR::Change);

};


} // namespace ARDOUR

#endif /* __ardour_overlap_h__ */   

Generated by  Doxygen 1.6.0   Back to index