the Properties & 64bit region commit

git-svn-id: svn://localhost/ardour2/branches/3.0@6695 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2010-02-18 13:59:49 +00:00
parent cdcc4d3720
commit ce7a5e1c9f
107 changed files with 2680 additions and 2194 deletions

View file

@ -65,12 +65,11 @@ namespace ARDOUR {
return (microseconds_t) jack_get_time();
}
extern PBD::Change StartChanged;
extern PBD::Change LengthChanged;
extern PBD::Change PositionChanged;
extern PBD::Change NameChanged;
extern PBD::Change BoundsChanged;
extern PBD::Change FlagsChanged;
extern PBD::PropertyChange StartChanged;
extern PBD::PropertyChange LengthChanged;
extern PBD::PropertyChange PositionChanged;
extern PBD::PropertyChange NameChanged;
extern PBD::PropertyChange BoundsChanged;
static const double SHUTTLE_FRACT_SPEED1=0.48412291827; /* derived from A1,A2 */

View file

@ -79,8 +79,8 @@ class AudioPlaylist : public ARDOUR::Playlist
XMLNode& state (bool full_state);
void dump () const;
bool region_changed (PBD::Change, boost::shared_ptr<Region>);
void crossfade_changed (PBD::Change);
bool region_changed (PBD::PropertyChange, boost::shared_ptr<Region>);
void crossfade_changed (PBD::PropertyChange);
void add_crossfade (boost::shared_ptr<Crossfade>);
void source_offset_changed (boost::shared_ptr<AudioRegion> region);

View file

@ -34,24 +34,37 @@
class XMLNode;
namespace ARDOUR {
namespace Properties {
extern PBD::PropertyDescriptor<bool> envelope_active;
extern PBD::PropertyDescriptor<bool> default_fade_in;
extern PBD::PropertyDescriptor<bool> default_fade_out;
extern PBD::PropertyDescriptor<bool> fade_in_active;
extern PBD::PropertyDescriptor<bool> fade_out_active;
extern PBD::PropertyDescriptor<float> scale_amplitude;
}
class Route;
class Playlist;
class Session;
class Filter;
class AudioSource;
class AudioRegion : public Region
{
public:
static PBD::Change FadeInChanged;
static PBD::Change FadeOutChanged;
static PBD::Change FadeInActiveChanged;
static PBD::Change FadeOutActiveChanged;
static PBD::Change EnvelopeActiveChanged;
static PBD::Change ScaleAmplitudeChanged;
static PBD::Change EnvelopeChanged;
static void make_property_quarks ();
static PBD::PropertyChange FadeInChanged;
static PBD::PropertyChange FadeOutChanged;
static PBD::PropertyChange FadeInActiveChanged;
static PBD::PropertyChange FadeOutActiveChanged;
static PBD::PropertyChange EnvelopeActiveChanged;
static PBD::PropertyChange ScaleAmplitudeChanged;
static PBD::PropertyChange EnvelopeChanged;
~AudioRegion();
@ -68,9 +81,9 @@ class AudioRegion : public Region
void normalize_to (float target_in_dB = 0.0f);
bool envelope_active () const { return _flags & Region::EnvelopeActive; }
bool fade_in_active () const { return _flags & Region::FadeIn; }
bool fade_out_active () const { return _flags & Region::FadeOut; }
bool envelope_active () const { return _envelope_active; }
bool fade_in_active () const { return _fade_in_active; }
bool fade_out_active () const { return _fade_out_active; }
boost::shared_ptr<AutomationList> fade_in() { return _fade_in; }
boost::shared_ptr<AutomationList> fade_out() { return _fade_out; }
@ -90,26 +103,26 @@ class AudioRegion : public Region
ReadOpsFades = 0x8
};
virtual nframes_t read (Sample*, sframes_t pos, nframes_t cnt, int channel) const;
virtual nframes_t read_with_ops (Sample*, sframes_t pos, nframes_t cnt, int channel, ReadOps rops) const;
virtual nframes64_t readable_length() const { return length(); }
virtual framecnt_t read (Sample*, framepos_t pos, framecnt_t cnt, int channel) const;
virtual framecnt_t read_with_ops (Sample*, framepos_t pos, framecnt_t cnt, int channel, ReadOps rops) const;
virtual framecnt_t readable_length() const { return length(); }
virtual nframes_t read_at (Sample *buf, Sample *mixdown_buf, float *gain_buf,
sframes_t position,
nframes_t cnt,
uint32_t chan_n = 0,
nframes_t read_frames = 0,
nframes_t skip_frames = 0) const;
virtual nframes_t master_read_at (Sample *buf, Sample *mixdown_buf, float *gain_buf,
sframes_t position, nframes_t cnt, uint32_t chan_n=0) const;
virtual nframes_t read_raw_internal (Sample*, sframes_t, nframes_t, int channel) const;
virtual framecnt_t read_at (Sample *buf, Sample *mixdown_buf, float *gain_buf,
framepos_t position,
framecnt_t cnt,
uint32_t chan_n = 0,
framecnt_t read_frames = 0,
framecnt_t skip_frames = 0) const;
virtual framecnt_t master_read_at (Sample *buf, Sample *mixdown_buf, float *gain_buf,
framepos_t position, framecnt_t cnt, uint32_t chan_n=0) const;
virtual framecnt_t read_raw_internal (Sample*, framepos_t, framecnt_t, int channel) const;
XMLNode& state (bool);
int set_state (const XMLNode&, int version);
int set_state (const XMLNode&, int version);
static void set_default_fade (float steepness, nframes_t len);
static void set_default_fade (float steepness, framecnt_t len);
bool fade_in_is_default () const;
bool fade_out_is_default () const;
@ -123,14 +136,14 @@ class AudioRegion : public Region
void set_fade_in_active (bool yn);
void set_fade_in_shape (FadeShape);
void set_fade_in_length (nframes_t);
void set_fade_in (FadeShape, nframes_t);
void set_fade_in_length (framecnt_t);
void set_fade_in (FadeShape, framecnt_t);
void set_fade_in (boost::shared_ptr<AutomationList>);
void set_fade_out_active (bool yn);
void set_fade_out_shape (FadeShape);
void set_fade_out_length (nframes_t);
void set_fade_out (FadeShape, nframes_t);
void set_fade_out_length (framecnt_t);
void set_fade_out (FadeShape, framecnt_t);
void set_fade_out (boost::shared_ptr<AutomationList>);
void set_envelope_active (bool yn);
@ -162,22 +175,31 @@ class AudioRegion : public Region
void resume_fade_out ();
int get_transients (AnalysisFeatureList&, bool force_new = false);
std::list<std::pair<nframes_t, nframes_t> > find_silence (Sample, nframes_t) const;
std::list<std::pair<frameoffset_t, framecnt_t> > find_silence (Sample, framecnt_t) const;
private:
friend class RegionFactory;
friend class Crossfade;
AudioRegion (boost::shared_ptr<AudioSource>, nframes_t start, nframes_t length);
AudioRegion (boost::shared_ptr<AudioSource>, nframes_t start, nframes_t length, const std::string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
AudioRegion (const SourceList &, nframes_t start, nframes_t length, const std::string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
AudioRegion (boost::shared_ptr<const AudioRegion>, nframes_t start, nframes_t length, const std::string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
AudioRegion (boost::shared_ptr<const AudioRegion>, const SourceList&, nframes_t length, const std::string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
AudioRegion (boost::shared_ptr<const AudioRegion>);
AudioRegion (boost::shared_ptr<AudioSource>);
AudioRegion (const SourceList &);
AudioRegion (boost::shared_ptr<const AudioRegion>, frameoffset_t offset = 0, bool offset_relative = true);
AudioRegion (boost::shared_ptr<const AudioRegion>, const SourceList&);
AudioRegion (boost::shared_ptr<AudioSource>, const XMLNode&);
AudioRegion (SourceList &, const XMLNode&);
private:
PBD::Property<bool> _envelope_active;
PBD::Property<bool> _default_fade_in;
PBD::Property<bool> _default_fade_out;
PBD::Property<bool> _fade_in_active;
PBD::Property<bool> _fade_out_active;
PBD::Property<gain_t> _scale_amplitude;
void register_properties ();
PBD::PropertyChange set_property (const PBD::PropertyBase& prop);
void post_set ();
void init ();
void set_default_fades ();
void set_default_fade_in ();
@ -186,13 +208,13 @@ class AudioRegion : public Region
void recompute_gain_at_end ();
void recompute_gain_at_start ();
nframes_t _read_at (const SourceList&, nframes_t limit,
Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
sframes_t position, nframes_t cnt,
uint32_t chan_n = 0,
nframes_t read_frames = 0,
nframes_t skip_frames = 0,
ReadOps readops = ReadOps (~0)) const;
framecnt_t _read_at (const SourceList&, framecnt_t limit,
Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
framepos_t position, framecnt_t cnt,
uint32_t chan_n = 0,
framecnt_t read_frames = 0,
framecnt_t skip_frames = 0,
ReadOps readops = ReadOps (~0)) const;
void recompute_at_start ();
void recompute_at_end ();
@ -210,16 +232,15 @@ class AudioRegion : public Region
boost::shared_ptr<AutomationList> _fade_in;
boost::shared_ptr<AutomationList> _fade_out;
boost::shared_ptr<AutomationList> _envelope;
gain_t _scale_amplitude;
uint32_t _fade_in_disabled;
uint32_t _fade_out_disabled;
uint32_t _fade_in_suspended;
uint32_t _fade_out_suspended;
protected:
/* default constructor for derived (compound) types */
AudioRegion (Session& s, nframes_t, nframes_t, std::string name);
AudioRegion (Session& s, framepos_t, framecnt_t, std::string name);
int set_live_state (const XMLNode&, int version, PBD::Change&, bool send);
int _set_state (const XMLNode&, int version, PBD::PropertyChange& what_changed, bool send_signal);
};
} /* namespace ARDOUR */

View file

@ -45,16 +45,16 @@ class AudioSource : virtual public Source,
AudioSource (Session&, const XMLNode&);
virtual ~AudioSource ();
nframes64_t readable_length() const { return _length; }
uint32_t n_channels() const { return 1; }
framecnt_t readable_length() const { return _length; }
uint32_t n_channels() const { return 1; }
sframes_t length (sframes_t pos) const;
void update_length (sframes_t pos, sframes_t cnt);
framecnt_t length (framepos_t pos) const;
void update_length (framepos_t pos, framecnt_t cnt);
virtual nframes_t available_peaks (double zoom) const;
virtual framecnt_t available_peaks (double zoom) const;
virtual nframes_t read (Sample *dst, sframes_t start, nframes_t cnt, int channel=0) const;
virtual nframes_t write (Sample *src, nframes_t cnt);
virtual framecnt_t read (Sample *dst, framepos_t start, framecnt_t cnt, int channel=0) const;
virtual framecnt_t write (Sample *src, framecnt_t cnt);
virtual float sample_rate () const = 0;
@ -68,14 +68,14 @@ class AudioSource : virtual public Source,
uint32_t read_data_count() const { return _read_data_count; }
uint32_t write_data_count() const { return _write_data_count; }
int read_peaks (PeakData *peaks, nframes_t npeaks,
sframes_t start, nframes_t cnt, double samples_per_visual_peak) const;
int read_peaks (PeakData *peaks, framecnt_t npeaks,
framepos_t start, framecnt_t cnt, double samples_per_visual_peak) const;
int build_peaks ();
bool peaks_ready (boost::function<void()> callWhenReady, PBD::Connection& connection_created_if_not_ready, PBD::EventLoop* event_loop) const;
mutable PBD::Signal0<void> PeaksReady;
mutable PBD::Signal2<void,nframes_t,nframes_t> PeakRangeReady;
mutable PBD::Signal2<void,framepos_t,framepos_t> PeakRangeReady;
XMLNode& get_state ();
int set_state (const XMLNode&, int version);
@ -104,7 +104,7 @@ class AudioSource : virtual public Source,
static bool _build_missing_peakfiles;
static bool _build_peakfiles;
sframes_t _length;
framecnt_t _length;
bool _peaks_built;
mutable Glib::Mutex _peaks_ready_lock;
Glib::ustring peakpath;
@ -115,31 +115,32 @@ class AudioSource : virtual public Source,
int initialize_peakfile (bool newfile, Glib::ustring path);
int build_peaks_from_scratch ();
int compute_and_write_peaks (Sample* buf, sframes_t first_frame, nframes_t cnt,
int compute_and_write_peaks (Sample* buf, framepos_t first_frame, framecnt_t cnt,
bool force, bool intermediate_peaks_ready_signal);
void truncate_peakfile();
mutable off_t _peak_byte_max; // modified in compute_and_write_peak()
virtual nframes_t read_unlocked (Sample *dst, sframes_t start, nframes_t cnt) const = 0;
virtual nframes_t write_unlocked (Sample *dst, nframes_t cnt) = 0;
virtual framecnt_t read_unlocked (Sample *dst, framepos_t start, framecnt_t cnt) const = 0;
virtual framecnt_t write_unlocked (Sample *dst, framecnt_t cnt) = 0;
virtual Glib::ustring peak_path(Glib::ustring audio_path) = 0;
virtual Glib::ustring find_broken_peakfile (Glib::ustring missing_peak_path,
Glib::ustring audio_path) = 0;
virtual int read_peaks_with_fpp (PeakData *peaks,
nframes_t npeaks, sframes_t start, nframes_t cnt,
double samples_per_visual_peak, nframes_t fpp) const;
int compute_and_write_peaks (Sample* buf, sframes_t first_frame, nframes_t cnt,
bool force, bool intermediate_peaks_ready_signal, nframes_t frames_per_peak);
framecnt_t npeaks, framepos_t start, framecnt_t cnt,
double samples_per_visual_peak, framecnt_t fpp) const;
int compute_and_write_peaks (Sample* buf, framepos_t first_frame, framecnt_t cnt,
bool force, bool intermediate_peaks_ready_signal,
framecnt_t frames_per_peak);
private:
int peakfile;
nframes_t peak_leftover_cnt;
nframes_t peak_leftover_size;
Sample* peak_leftovers;
nframes_t peak_leftover_frame;
int peakfile;
framecnt_t peak_leftover_cnt;
framecnt_t peak_leftover_size;
Sample* peak_leftovers;
framepos_t peak_leftover_frame;
};
}

View file

@ -50,9 +50,9 @@ class Crossfade : public ARDOUR::AudioRegion
/* constructor for "fixed" xfades at each end of an internal overlap */
Crossfade (boost::shared_ptr<ARDOUR::AudioRegion> in, boost::shared_ptr<ARDOUR::AudioRegion> out,
nframes_t position,
nframes_t initial_length,
AnchorPoint);
framepos_t position,
framecnt_t initial_length,
AnchorPoint);
/* constructor for xfade between two regions that are overlapped in any way
except the "internal" case.
@ -79,11 +79,11 @@ class Crossfade : public ARDOUR::AudioRegion
boost::shared_ptr<ARDOUR::AudioRegion> in() const { return _in; }
boost::shared_ptr<ARDOUR::AudioRegion> out() const { return _out; }
nframes_t read_at (Sample *buf, Sample *mixdown_buffer,
float *gain_buffer, sframes_t position, nframes_t cnt,
uint32_t chan_n,
nframes_t read_frames = 0,
nframes_t skip_frames = 0) const;
framecnt_t read_at (Sample *buf, Sample *mixdown_buffer,
float *gain_buffer, framepos_t position, framecnt_t cnt,
uint32_t chan_n,
framecnt_t read_frames = 0,
framecnt_t skip_frames = 0) const;
bool refresh ();
@ -103,18 +103,18 @@ class Crossfade : public ARDOUR::AudioRegion
return (_in == a && _out == b) || (_in == b && _out == a);
}
nframes_t overlap_length() const;
framecnt_t overlap_length() const;
PBD::Signal1<void,boost::shared_ptr<Region> > Invalidated;
PBD::Signal1<void,PBD::Change> StateChanged;
PBD::Signal1<void,PBD::PropertyChange> StateChanged;
bool covers (nframes_t frame) const {
bool covers (framecnt_t frame) const {
return _position <= frame && frame < _position + _length;
}
OverlapType coverage (nframes_t start, nframes_t end) const;
OverlapType coverage (framepos_t start, framepos_t end) const;
static void set_buffer_size (nframes_t);
static void set_buffer_size (framecnt_t);
bool active () const { return _active; }
void set_active (bool yn);
@ -126,24 +126,24 @@ class Crossfade : public ARDOUR::AudioRegion
AutomationList& fade_in() { return _fade_in; }
AutomationList& fade_out() { return _fade_out; }
nframes_t set_xfade_length (nframes_t);
framecnt_t set_xfade_length (framecnt_t);
bool is_dependent() const { return true; }
bool depends_on (boost::shared_ptr<Region> other) const {
return other == _in || other == _out;
}
static nframes_t short_xfade_length() { return _short_xfade_length; }
static void set_short_xfade_length (nframes_t n);
static framecnt_t short_xfade_length() { return _short_xfade_length; }
static void set_short_xfade_length (framecnt_t n);
static PBD::Change ActiveChanged;
static PBD::Change FollowOverlapChanged;
static PBD::PropertyChange ActiveChanged;
static PBD::PropertyChange FollowOverlapChanged;
private:
friend struct CrossfadeComparePtr;
friend class AudioPlaylist;
static nframes_t _short_xfade_length;
static framecnt_t _short_xfade_length;
boost::shared_ptr<ARDOUR::AudioRegion> _in;
boost::shared_ptr<ARDOUR::AudioRegion> _out;
@ -167,7 +167,7 @@ class Crossfade : public ARDOUR::AudioRegion
bool update ();
protected:
nframes_t read_raw_internal (Sample*, sframes_t, nframes_t, int) const;
framecnt_t read_raw_internal (Sample*, framepos_t, framecnt_t, int) const;
};

View file

@ -52,7 +52,8 @@ namespace ARDOUR {
SessionEvents = 0x800,
MidiIO = 0x1000,
MackieControl = 0x2000,
MidiClock = 0x4000
MidiClock = 0x4000,
Properties = 0x8000
};
}

View file

@ -141,7 +141,7 @@ class Diskstream : public SessionObject
void remove_region_from_last_capture (boost::weak_ptr<Region> wregion);
void move_processor_automation (boost::weak_ptr<Processor>,
std::list< Evoral::RangeMove<nframes_t> > const &);
std::list<Evoral::RangeMove<framepos_t> > const &);
PBD::Signal0<void> RecordEnableChanged;
PBD::Signal0<void> SpeedChanged;
@ -206,9 +206,9 @@ class Diskstream : public SessionObject
/* XXX fix this redundancy ... */
virtual void playlist_changed (PBD::Change);
virtual void playlist_changed (PBD::PropertyChange);
virtual void playlist_deleted (boost::weak_ptr<Playlist>);
virtual void playlist_ranges_moved (std::list< Evoral::RangeMove<nframes_t> > const &);
virtual void playlist_ranges_moved (std::list< Evoral::RangeMove<framepos_t> > const &);
virtual void transport_stopped (struct tm&, time_t, bool abort) = 0;
virtual void transport_looped (nframes_t transport_frame) = 0;

View file

@ -179,7 +179,7 @@ class Locations : public PBD::StatefulDestructible
PBD::Signal0<void> changed;
PBD::Signal1<void,Location*> added;
PBD::Signal1<void,Location*> removed;
PBD::Signal1<void,PBD::Change> StateChanged;
PBD::Signal1<void,PBD::PropertyChange> StateChanged;
template<class T> void apply (T& obj, void (T::*method)(LocationList&)) {
Glib::Mutex::Lock lm (lock);

View file

@ -90,7 +90,7 @@ public:
};
/** Change note properties.
/** PropertyChange note properties.
* More efficient than DeltaCommand and has the important property that
* it leaves the objects in the MidiModel (Notes) the same, thus
* enabling selection and other state to persist across command

View file

@ -74,7 +74,7 @@ protected:
private:
void dump () const;
bool region_changed (PBD::Change, boost::shared_ptr<Region>);
bool region_changed (PBD::PropertyChange, boost::shared_ptr<Region>);
NoteMode _note_mode;

View file

@ -53,29 +53,29 @@ class MidiRegion : public Region
boost::shared_ptr<MidiSource> midi_source (uint32_t n=0) const;
/* Stub Readable interface */
virtual nframes_t read (Sample*, sframes_t /*pos*/, nframes_t /*cnt*/, int /*channel*/) const { return 0; }
virtual sframes_t readable_length() const { return length(); }
virtual framecnt_t read (Sample*, framepos_t /*pos*/, framecnt_t /*cnt*/, int /*channel*/) const { return 0; }
virtual framecnt_t readable_length() const { return length(); }
nframes_t read_at (Evoral::EventSink<nframes_t>& dst,
sframes_t position,
nframes_t dur,
uint32_t chan_n = 0,
NoteMode mode = Sustained,
MidiStateTracker* tracker = 0) const;
nframes_t master_read_at (MidiRingBuffer<nframes_t>& dst,
sframes_t position,
nframes_t dur,
uint32_t chan_n = 0,
NoteMode mode = Sustained) const;
framecnt_t read_at (Evoral::EventSink<nframes_t>& dst,
framepos_t position,
framecnt_t dur,
uint32_t chan_n = 0,
NoteMode mode = Sustained,
MidiStateTracker* tracker = 0) const;
framepos_t master_read_at (MidiRingBuffer<nframes_t>& dst,
framepos_t position,
framecnt_t dur,
uint32_t chan_n = 0,
NoteMode mode = Sustained) const;
XMLNode& state (bool);
int set_state (const XMLNode&, int version);
int separate_by_channel (ARDOUR::Session&, std::vector< boost::shared_ptr<Region> >&) const;
/* automation */
boost::shared_ptr<Evoral::Control>
control(const Evoral::Parameter& id, bool create=false) {
return model()->control(id, create);
@ -96,32 +96,26 @@ class MidiRegion : public Region
private:
friend class RegionFactory;
MidiRegion (boost::shared_ptr<MidiSource>, nframes_t start, nframes_t length);
MidiRegion (boost::shared_ptr<MidiSource>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
MidiRegion (const SourceList &, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
MidiRegion (boost::shared_ptr<const MidiRegion>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
MidiRegion (boost::shared_ptr<const MidiRegion>);
MidiRegion (boost::shared_ptr<MidiSource>);
MidiRegion (const SourceList&);
MidiRegion (boost::shared_ptr<const MidiRegion>, frameoffset_t offset = 0, bool offset_relative = true);
MidiRegion (boost::shared_ptr<MidiSource>, const XMLNode&);
MidiRegion (const SourceList &, const XMLNode&);
private:
nframes_t _read_at (const SourceList&, Evoral::EventSink<nframes_t>& dst,
sframes_t position,
nframes_t dur,
uint32_t chan_n = 0,
NoteMode mode = Sustained,
MidiStateTracker* tracker = 0) const;
framecnt_t _read_at (const SourceList&, Evoral::EventSink<nframes_t>& dst,
framepos_t position,
framecnt_t dur,
uint32_t chan_n = 0,
NoteMode mode = Sustained,
MidiStateTracker* tracker = 0) const;
void recompute_at_start ();
void recompute_at_end ();
void set_position_internal (nframes_t pos, bool allow_bbt_recompute);
void set_position_internal (framepos_t pos, bool allow_bbt_recompute);
void switch_source(boost::shared_ptr<Source> source);
protected:
int set_live_state (const XMLNode&, int version, PBD::Change&, bool send);
};
} /* namespace ARDOUR */

View file

@ -58,7 +58,7 @@ class Playlist : public SessionObject
Playlist (Session&, const XMLNode&, DataType type, bool hidden = false);
Playlist (Session&, std::string name, DataType type, bool hidden = false);
Playlist (boost::shared_ptr<const Playlist>, std::string name, bool hidden = false);
Playlist (boost::shared_ptr<const Playlist>, nframes_t start, nframes_t cnt, std::string name, bool hidden = false);
Playlist (boost::shared_ptr<const Playlist>, framepos_t start, framecnt_t cnt, std::string name, bool hidden = false);
virtual ~Playlist ();
@ -81,7 +81,7 @@ class Playlist : public SessionObject
bool hidden() const { return _hidden; }
bool empty() const;
uint32_t n_regions() const;
nframes_t get_maximum_extent () const;
framecnt_t get_maximum_extent () const;
layer_t top_layer() const;
EditMode get_edit_mode() const { return _edit_mode; }
@ -89,39 +89,39 @@ class Playlist : public SessionObject
/* Editing operations */
void add_region (boost::shared_ptr<Region>, nframes_t position, float times = 1, bool auto_partition = false);
void add_region (boost::shared_ptr<Region>, framepos_t position, float times = 1, bool auto_partition = false);
void remove_region (boost::shared_ptr<Region>);
void get_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
void get_region_list_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
void replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Region> newr, nframes_t pos);
void split_region (boost::shared_ptr<Region>, nframes_t position);
void split (nframes64_t at);
void shift (nframes64_t at, nframes64_t distance, bool move_intersected, bool ignore_music_glue);
void partition (nframes_t start, nframes_t end, bool cut = false);
void duplicate (boost::shared_ptr<Region>, nframes_t position, float times);
void nudge_after (nframes_t start, nframes_t distance, bool forwards);
void replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Region> newr, framepos_t pos);
void split_region (boost::shared_ptr<Region>, framepos_t position);
void split (framepos_t at);
void shift (framepos_t at, frameoffset_t distance, bool move_intersected, bool ignore_music_glue);
void partition (framepos_t start, framepos_t end, bool cut = false);
void duplicate (boost::shared_ptr<Region>, framepos_t position, float times);
void nudge_after (framepos_t start, framecnt_t distance, bool forwards);
void shuffle (boost::shared_ptr<Region>, int dir);
void update_after_tempo_map_change ();
boost::shared_ptr<Playlist> cut (std::list<AudioRange>&, bool result_is_hidden = true);
boost::shared_ptr<Playlist> copy (std::list<AudioRange>&, bool result_is_hidden = true);
int paste (boost::shared_ptr<Playlist>, nframes_t position, float times);
int paste (boost::shared_ptr<Playlist>, framepos_t position, float times);
const RegionList& region_list () const { return regions; }
RegionList* regions_at (nframes_t frame);
RegionList* regions_touched (nframes_t start, nframes_t end);
RegionList* regions_to_read (nframes_t start, nframes_t end);
RegionList* regions_at (framepos_t frame);
RegionList* regions_touched (framepos_t start, framepos_t end);
RegionList* regions_to_read (framepos_t start, framepos_t end);
boost::shared_ptr<Region> find_region (const PBD::ID&) const;
boost::shared_ptr<Region> top_region_at (nframes_t frame);
boost::shared_ptr<Region> top_unmuted_region_at (nframes_t frame);
boost::shared_ptr<Region> find_next_region (nframes_t frame, RegionPoint point, int dir);
nframes64_t find_next_region_boundary (nframes64_t frame, int dir);
boost::shared_ptr<Region> top_region_at (framepos_t frame);
boost::shared_ptr<Region> top_unmuted_region_at (framepos_t frame);
boost::shared_ptr<Region> find_next_region (framepos_t frame, RegionPoint point, int dir);
framepos_t find_next_region_boundary (framepos_t frame, int dir);
bool region_is_shuffle_constrained (boost::shared_ptr<Region>);
bool has_region_at (nframes64_t const) const;
bool has_region_at (framepos_t const) const;
nframes64_t find_next_transient (nframes64_t position, int dir);
framepos_t find_next_transient (framepos_t position, int dir);
void foreach_region (boost::function<void (boost::shared_ptr<Region>)>);
@ -136,7 +136,7 @@ class Playlist : public SessionObject
PBD::Signal0<void> NameChanged;
PBD::Signal0<void> LengthChanged;
PBD::Signal0<void> LayeringChanged;
PBD::Signal1<void,std::list< Evoral::RangeMove<nframes_t> > const &> RangesMoved;
PBD::Signal1<void,std::list< Evoral::RangeMove<framepos_t> > const &> RangesMoved;
static std::string bump_name (std::string old_name, Session&);
@ -205,7 +205,7 @@ class Playlist : public SessionObject
bool pending_contents_change;
bool pending_layering;
bool pending_length;
std::list< Evoral::RangeMove<nframes_t> > pending_range_moves;
std::list< Evoral::RangeMove<framepos_t> > pending_range_moves;
bool save_on_thaw;
std::string last_save_reason;
uint32_t in_set_state;
@ -223,7 +223,7 @@ class Playlist : public SessionObject
uint32_t _read_data_count;
PBD::ID _orig_diskstream_id;
uint64_t layer_op_counter;
nframes_t freeze_length;
framecnt_t freeze_length;
bool auto_partition;
/** true if relayering should be done using region's current layers and their `pending explicit relayer'
@ -249,25 +249,25 @@ class Playlist : public SessionObject
void notify_length_changed ();
void notify_layering_changed ();
void notify_contents_changed ();
void notify_state_changed (PBD::Change);
void notify_state_changed (PBD::PropertyChange);
void notify_region_moved (boost::shared_ptr<Region>);
void mark_session_dirty();
void region_changed_proxy (PBD::Change, boost::weak_ptr<Region>);
virtual bool region_changed (PBD::Change, boost::shared_ptr<Region>);
void region_changed_proxy (PBD::PropertyChange, boost::weak_ptr<Region>);
virtual bool region_changed (PBD::PropertyChange, boost::shared_ptr<Region>);
void region_bounds_changed (PBD::Change, boost::shared_ptr<Region>);
void region_bounds_changed (PBD::PropertyChange, boost::shared_ptr<Region>);
void region_deleted (boost::shared_ptr<Region>);
void sort_regions ();
void possibly_splice (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude = boost::shared_ptr<Region>());
void possibly_splice_unlocked(nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude = boost::shared_ptr<Region>());
void possibly_splice (framepos_t at, framecnt_t distance, boost::shared_ptr<Region> exclude = boost::shared_ptr<Region>());
void possibly_splice_unlocked(framepos_t at, framecnt_t distance, boost::shared_ptr<Region> exclude = boost::shared_ptr<Region>());
void core_splice (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude);
void splice_locked (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude);
void splice_unlocked (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude);
void core_splice (framepos_t at, framecnt_t distance, boost::shared_ptr<Region> exclude);
void splice_locked (framepos_t at, framecnt_t distance, boost::shared_ptr<Region> exclude);
void splice_unlocked (framepos_t at, framecnt_t distance, boost::shared_ptr<Region> exclude);
virtual void finalize_split_region (boost::shared_ptr<Region> /*original*/, boost::shared_ptr<Region> /*left*/, boost::shared_ptr<Region> /*right*/) {}
@ -279,19 +279,19 @@ class Playlist : public SessionObject
boost::shared_ptr<Region> region_by_id (PBD::ID);
bool add_region_internal (boost::shared_ptr<Region>, nframes_t position);
bool add_region_internal (boost::shared_ptr<Region>, framepos_t position);
int remove_region_internal (boost::shared_ptr<Region>);
RegionList *find_regions_at (nframes_t frame);
RegionList *find_regions_at (framepos_t frame);
void copy_regions (RegionList&) const;
void partition_internal (nframes_t start, nframes_t end, bool cutting, RegionList& thawlist);
void partition_internal (framepos_t start, framepos_t end, bool cutting, RegionList& thawlist);
nframes_t _get_maximum_extent() const;
framecnt_t _get_maximum_extent() const;
boost::shared_ptr<Playlist> cut_copy (boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t, nframes_t, bool),
std::list<AudioRange>& ranges, bool result_is_hidden);
boost::shared_ptr<Playlist> cut (nframes_t start, nframes_t cnt, bool result_is_hidden);
boost::shared_ptr<Playlist> copy (nframes_t start, nframes_t cnt, bool result_is_hidden);
boost::shared_ptr<Playlist> cut_copy (boost::shared_ptr<Playlist> (Playlist::*pmf)(framepos_t, framecnt_t, bool),
std::list<AudioRange>& ranges, bool result_is_hidden);
boost::shared_ptr<Playlist> cut (framepos_t start, framecnt_t cnt, bool result_is_hidden);
boost::shared_ptr<Playlist> copy (framepos_t start, framecnt_t cnt, bool result_is_hidden);
int move_region_to_layer (layer_t, boost::shared_ptr<Region> r, int dir);
void relayer ();
@ -301,7 +301,7 @@ class Playlist : public SessionObject
void timestamp_layer_op (boost::shared_ptr<Region>);
void _split_region (boost::shared_ptr<Region>, nframes_t position);
void _split_region (boost::shared_ptr<Region>, framepos_t position);
};
} /* namespace ARDOUR */

View file

@ -10,8 +10,8 @@ class Readable {
Readable () {}
virtual ~Readable() {}
virtual nframes_t read (Sample*, sframes_t pos, nframes_t cnt, int channel) const = 0;
virtual sframes_t readable_length() const = 0;
virtual framecnt_t read (Sample*, framepos_t pos, framecnt_t cnt, int channel) const = 0;
virtual framecnt_t readable_length() const = 0;
virtual uint32_t n_channels () const = 0;
};

View file

@ -36,8 +36,33 @@
class XMLNode;
namespace ARDOUR {
namespace Properties {
extern PBD::PropertyDescriptor<bool> muted;
extern PBD::PropertyDescriptor<bool> opaque;
extern PBD::PropertyDescriptor<bool> locked;
extern PBD::PropertyDescriptor<bool> automatic;
extern PBD::PropertyDescriptor<bool> whole_file;
extern PBD::PropertyDescriptor<bool> import;
extern PBD::PropertyDescriptor<bool> external;
extern PBD::PropertyDescriptor<bool> sync_marked;
extern PBD::PropertyDescriptor<bool> left_of_split;
extern PBD::PropertyDescriptor<bool> right_of_split;
extern PBD::PropertyDescriptor<bool> hidden;
extern PBD::PropertyDescriptor<bool> position_locked;
extern PBD::PropertyDescriptor<framepos_t> start;
extern PBD::PropertyDescriptor<framecnt_t> length;
extern PBD::PropertyDescriptor<framepos_t> position;
extern PBD::PropertyDescriptor<framecnt_t> sync_position;
extern PBD::PropertyDescriptor<layer_t> layer;
extern PBD::PropertyDescriptor<framepos_t> ancestral_start;
extern PBD::PropertyDescriptor<framecnt_t> ancestral_length;
extern PBD::PropertyDescriptor<float> stretch;
extern PBD::PropertyDescriptor<float> shift;
};
class Playlist;
class Filter;
class ExportSpecification;
@ -48,6 +73,7 @@ enum RegionEditState {
EditChangesID = 2
};
class Region
: public SessionObject
, public boost::enable_shared_from_this<Region>
@ -56,106 +82,82 @@ class Region
public:
typedef std::vector<boost::shared_ptr<Source> > SourceList;
enum Flag {
Muted = 0x1,
Opaque = 0x2,
EnvelopeActive = 0x4,
DefaultFadeIn = 0x8,
DefaultFadeOut = 0x10,
Locked = 0x20,
Automatic = 0x40,
WholeFile = 0x80,
FadeIn = 0x100,
FadeOut = 0x200,
Copied = 0x400,
Import = 0x800,
External = 0x1000,
SyncMarked = 0x2000,
LeftOfSplit = 0x4000,
RightOfSplit = 0x8000,
Hidden = 0x10000,
DoNotSendPropertyChanges = 0x20000,
PositionLocked = 0x40000,
//
range_guarantoor = USHRT_MAX
};
static void make_property_quarks ();
enum PositionLockStyle {
AudioTime,
MusicTime
};
static const Flag DefaultFlags = Flag (Opaque|DefaultFadeIn|DefaultFadeOut|FadeIn|FadeOut);
static PBD::PropertyChange FadeChanged;
static PBD::PropertyChange SyncOffsetChanged;
static PBD::PropertyChange MuteChanged;
static PBD::PropertyChange OpacityChanged;
static PBD::PropertyChange LockChanged;
static PBD::PropertyChange LayerChanged;
static PBD::PropertyChange HiddenChanged;
static PBD::Change FadeChanged;
static PBD::Change SyncOffsetChanged;
static PBD::Change MuteChanged;
static PBD::Change OpacityChanged;
static PBD::Change LockChanged;
static PBD::Change LayerChanged;
static PBD::Change HiddenChanged;
PBD::Signal1<void,PBD::Change> StateChanged;
PBD::Signal1<void,PBD::PropertyChange> StateChanged;
static PBD::Signal1<void,boost::shared_ptr<ARDOUR::Region> > RegionPropertyChanged;
void unlock_property_changes () { _flags = Flag (_flags & ~DoNotSendPropertyChanges); }
void block_property_changes () { _flags = Flag (_flags | DoNotSendPropertyChanges); }
void unlock_property_changes () { _no_property_changes = false; }
void block_property_changes () { _no_property_changes = true; }
virtual ~Region();
/** Note: changing the name of a Region does not constitute an edit */
bool set_name (const std::string& str);
const DataType& data_type() const { return _type; }
/** How the region parameters play together:
* <PRE>
* |------------------------------------------------------------------- track
* |..........[------------------].....| region
* |-----------------------------| _position
* |------------------| _length
* |----------| _start
* </PRE>
*
* POSITION: first frame of the region along the timeline
* START: first frame of the region within its source(s)
* LENGTH: number of frames the region represents
*/
nframes_t position () const { return _position; }
nframes_t start () const { return _start; }
nframes_t length() const { return _length; }
layer_t layer () const { return _layer; }
sframes_t position () const { return _position; }
sframes_t start () const { return _start; }
framecnt_t length() const { return _length; }
layer_t layer () const { return _layer; }
sframes_t source_length(uint32_t n) const;
framecnt_t source_length(uint32_t n) const;
/* these two are valid ONLY during a StateChanged signal handler */
nframes_t last_position() const { return _last_position; }
nframes_t last_length() const { return _last_length; }
sframes_t last_position() const { return _last_position; }
framecnt_t last_length() const { return _last_length; }
nframes64_t ancestral_start () const { return _ancestral_start; }
nframes64_t ancestral_length () const { return _ancestral_length; }
sframes_t ancestral_start () const { return _ancestral_start; }
framecnt_t ancestral_length () const { return _ancestral_length; }
float stretch() const { return _stretch; }
float shift() const { return _shift; }
void set_ancestral_data (nframes64_t start, nframes64_t length, float stretch, float shift);
nframes_t sync_offset(int& dir) const;
nframes_t sync_position() const;
nframes_t sync_point () const;
nframes_t adjust_to_sync (nframes_t) const;
frameoffset_t sync_offset(int& dir) const;
framepos_t sync_position() const;
framepos_t sync_point () const;
framepos_t adjust_to_sync (framepos_t) const;
/* first_frame() is an alias; last_frame() just hides some math */
nframes_t first_frame() const { return _position; }
nframes_t last_frame() const { return _position + _length - 1; }
framepos_t first_frame() const { return _position; }
framepos_t last_frame() const { return _position + _length - 1; }
Flag flags() const { return _flags; }
bool hidden() const { return _flags & Hidden; }
bool muted() const { return _flags & Muted; }
bool opaque () const { return _flags & Opaque; }
bool locked() const { return _flags & Locked; }
bool position_locked() const { return _flags & PositionLocked; }
bool automatic() const { return _flags & Automatic; }
bool whole_file() const { return _flags & WholeFile ; }
bool captured() const { return !(_flags & (Region::Flag (Region::Import|Region::External))); }
bool can_move() const { return !(_flags & (Locked|PositionLocked)); }
bool hidden() const { return _hidden; }
bool muted() const { return _muted; }
bool opaque () const { return _opaque; }
bool locked() const { return _locked; }
bool position_locked() const { return _position_locked; }
bool automatic() const { return _automatic; }
bool whole_file() const { return _whole_file; }
bool captured() const { return !(_import || _external); }
bool can_move() const { return !_position_locked; }
bool sync_marked() const { return _sync_marked; }
bool external() const { return _external; }
bool import() const { return _import; }
PositionLockStyle positional_lock_style() const { return _positional_lock_style; }
void set_position_lock_style (PositionLockStyle ps);
@ -164,11 +166,11 @@ class Region
void freeze ();
void thaw ();
bool covers (nframes_t frame) const {
bool covers (framepos_t frame) const {
return first_frame() <= frame && frame <= last_frame();
}
OverlapType coverage (nframes_t start, nframes_t end) const {
OverlapType coverage (framepos_t start, framepos_t end) const {
return ARDOUR::coverage (first_frame(), last_frame(), start, end);
}
@ -181,21 +183,21 @@ class Region
/* EDITING OPERATIONS */
void set_length (nframes_t, void *src);
void set_start (nframes_t, void *src);
void set_position (nframes_t, void *src);
void set_position_on_top (nframes_t, void *src);
void special_set_position (nframes_t);
void set_length (framecnt_t, void *src);
void set_start (framepos_t, void *src);
void set_position (framepos_t, void *src);
void set_position_on_top (framepos_t, void *src);
void special_set_position (framepos_t);
void update_position_after_tempo_map_change ();
void nudge_position (nframes64_t, void *src);
void nudge_position (frameoffset_t, void *src);
bool at_natural_position () const;
void move_to_natural_position (void *src);
void trim_start (nframes_t new_position, void *src);
void trim_front (nframes_t new_position, void *src);
void trim_end (nframes_t new_position, void *src);
void trim_to (nframes_t position, nframes_t length, void *src);
void trim_start (framepos_t new_position, void *src);
void trim_front (framepos_t new_position, void *src);
void trim_end (framepos_t new_position, void *src);
void trim_to (framepos_t position, framecnt_t length, void *src);
void set_layer (layer_t l); /* ONLY Playlist can call this */
void raise ();
@ -203,17 +205,19 @@ class Region
void raise_to_top ();
void lower_to_bottom ();
void set_sync_position (nframes_t n);
void set_sync_position (framepos_t n);
void clear_sync_position ();
void set_hidden (bool yn);
void set_muted (bool yn);
void set_whole_file (bool yn);
void set_automatic (bool yn);
void set_opaque (bool yn);
void set_locked (bool yn);
void set_position_locked (bool yn);
int apply (Filter&);
virtual uint32_t read_data_count() const { return _read_data_count; }
virtual uint64_t read_data_count() const { return _read_data_count; }
boost::shared_ptr<ARDOUR::Playlist> playlist() const { return _playlist.lock(); }
virtual void set_playlist (boost::weak_ptr<ARDOUR::Playlist>);
@ -242,7 +246,6 @@ class Region
XMLNode& get_state ();
virtual XMLNode& state (bool);
virtual int set_state (const XMLNode&, int version);
virtual int set_live_state (const XMLNode&, int version, PBD::Change&, bool send);
virtual boost::shared_ptr<Region> get_parent() const;
@ -278,62 +281,77 @@ class Region
protected:
friend class RegionFactory;
Region (boost::shared_ptr<Source> src, nframes_t start, nframes_t length,
const std::string& name, DataType type, layer_t = 0, Flag flags = DefaultFlags);
Region (const SourceList& srcs, nframes_t start, nframes_t length,
const std::string& name, DataType type, layer_t = 0, Flag flags = DefaultFlags);
Region (boost::shared_ptr<const Region>, nframes_t start, nframes_t length, const std::string& name, layer_t = 0, Flag flags = DefaultFlags);
Region (boost::shared_ptr<const Region>, nframes_t length, const std::string& name, layer_t = 0, Flag flags = DefaultFlags);
/** Construct a region from a single source */
Region (boost::shared_ptr<Source> src);
/** Construct a region from multiple sources*/
Region (const SourceList& srcs);
/** Construct a region from another region, at an offset within that region */
Region (boost::shared_ptr<const Region>, frameoffset_t start_offset = 0, bool start_relative = true);
/** Construct a region as a copy of another region, but with different sources */
Region (boost::shared_ptr<const Region>, const SourceList&);
/** normal Region copy constructor */
Region (boost::shared_ptr<const Region>);
/** Construct a region from 1 source and XML state */
Region (boost::shared_ptr<Source> src, const XMLNode&);
/** Construct a region from multiple sources and XML state */
Region (const SourceList& srcs, const XMLNode&);
Region (Session& s, nframes_t start, nframes_t length, const std::string& name, DataType, layer_t = 0, Flag flags = DefaultFlags);
/** Constructor for derived types only */
Region (Session& s, framepos_t start, framecnt_t length, const std::string& name, DataType);
protected:
void copy_stuff (boost::shared_ptr<const Region>, nframes_t start, nframes_t length, const std::string& name, layer_t, Flag flags);
void send_change (PBD::PropertyChange);
XMLNode& get_short_state (); /* used only by Session */
void trim_to_internal (framepos_t position, framecnt_t length, void *src);
virtual void set_position_internal (framepos_t pos, bool allow_bbt_recompute);
void send_change (PBD::Change);
void trim_to_internal (nframes_t position, nframes_t length, void *src);
virtual void set_position_internal (nframes_t pos, bool allow_bbt_recompute);
bool copied() const { return _flags & Copied; }
void maybe_uncopy ();
void first_edit ();
bool verify_start (nframes_t);
bool verify_start_and_length (nframes_t, nframes_t&);
bool verify_start_mutable (nframes_t&_start);
bool verify_length (nframes_t);
bool verify_start (framepos_t);
bool verify_start_and_length (framepos_t, framecnt_t&);
bool verify_start_mutable (framepos_t&_start);
bool verify_length (framecnt_t);
virtual void recompute_at_start () = 0;
virtual void recompute_at_end () = 0;
DataType _type;
PBD::EnumState<Flag> _flags;
PBD::State<nframes_t> _start;
PBD::State<nframes_t> _length;
nframes_t _last_length;
PBD::State<nframes_t> _position;
nframes_t _last_position;
bool _no_property_changes;
PBD::Property<bool> _muted;
PBD::Property<bool> _opaque;
PBD::Property<bool> _locked;
PBD::Property<bool> _automatic;
PBD::Property<bool> _whole_file;
PBD::Property<bool> _import;
PBD::Property<bool> _external;
PBD::Property<bool> _sync_marked;
PBD::Property<bool> _left_of_split;
PBD::Property<bool> _right_of_split;
PBD::Property<bool> _hidden;
PBD::Property<bool> _position_locked;
PBD::Property<framepos_t> _start;
PBD::Property<framecnt_t> _length;
PBD::Property<framepos_t> _position;
PBD::Property<framepos_t> _sync_position;
PBD::Property<layer_t> _layer;
PBD::Property<framepos_t> _ancestral_start;
PBD::Property<framecnt_t> _ancestral_length;
PBD::Property<float> _stretch;
PBD::Property<float> _shift;
framecnt_t _last_length;
framepos_t _last_position;
PositionLockStyle _positional_lock_style;
PBD::State<nframes_t> _sync_position;
PBD::State<layer_t> _layer;
mutable RegionEditState _first_edit;
int _frozen;
PBD::State<nframes64_t> _ancestral_start;
PBD::State<nframes64_t> _ancestral_length;
PBD::State<float> _stretch;
PBD::State<float> _shift;
BBT_Time _bbt_time;
AnalysisFeatureList _transients;
bool _valid_transients;
mutable uint32_t _read_data_count; ///< modified in read()
PBD::Change _pending_changed;
mutable uint64_t _read_data_count; ///< modified in read()
PBD::PropertyChange _pending_changed;
uint64_t _last_layer_op; ///< timestamp
Glib::Mutex _lock;
SourceList _sources;
@ -345,9 +363,12 @@ class Region
boost::weak_ptr<ARDOUR::Playlist> _playlist;
private:
virtual int _set_state (const XMLNode&, int version, PBD::PropertyChange& what_changed, bool send_signal);
void register_states ();
PBD::PropertyChange set_property (const PBD::PropertyBase&);
void register_properties ();
private:
void use_sources (SourceList const &);
};

View file

@ -44,29 +44,35 @@ class RegionFactory {
/** This is emitted only when a new id is assigned. Therefore,
in a pure Region copy, it will not be emitted.
It must be emitted by derived classes, not Region
It must be emitted using a derived instance of Region, not Region
itself, to permit dynamic_cast<> to be used to
infer the type of Region.
*/
static PBD::Signal1<void,boost::shared_ptr<Region> > CheckNewRegion;
static boost::shared_ptr<Region> create (boost::shared_ptr<const Region>);
/** create a "pure copy" of Region @param other */
static boost::shared_ptr<Region> create (boost::shared_ptr<const Region> other);
/* note: both of the first two should use const shared_ptr as well, but
gcc 4.1 doesn't seem to be able to disambiguate them if they do.
*/
static boost::shared_ptr<Region> create (boost::shared_ptr<Region>, nframes_t start,
nframes_t length, const std::string& name,
layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
static boost::shared_ptr<Region> create (boost::shared_ptr<AudioRegion>, nframes_t start,
nframes_t length, const std::string& name,
layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
static boost::shared_ptr<Region> create (boost::shared_ptr<Region>, const SourceList&, const std::string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
static boost::shared_ptr<Region> create (boost::shared_ptr<Source>, nframes_t start, nframes_t length, const std::string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
static boost::shared_ptr<Region> create (const SourceList &, nframes_t start, nframes_t length, const std::string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
/** create a region from a single Source */
static boost::shared_ptr<Region> create (boost::shared_ptr<Source>,
const PBD::PropertyList&, bool announce = true);
/** create a region from a multiple sources */
static boost::shared_ptr<Region> create (const SourceList &,
const PBD::PropertyList&, bool announce = true);
/** create a copy of @other starting at zero within @param other's sources */
static boost::shared_ptr<Region> create (boost::shared_ptr<Region> other,
const PBD::PropertyList&, bool announce = true);
/** create a copy of @other starting at @param offset within @param other */
static boost::shared_ptr<Region> create (boost::shared_ptr<Region>, frameoffset_t offset,
const PBD::PropertyList&, bool announce = true);
/** create a "copy" of @param other but using a different set of sources @param srcs */
static boost::shared_ptr<Region> create (boost::shared_ptr<Region> other, const SourceList& srcs,
const PBD::PropertyList&, bool announce = true);
/** create a region with no sources, using XML state */
static boost::shared_ptr<Region> create (Session&, XMLNode&, bool);
static boost::shared_ptr<Region> create (SourceList &, const XMLNode&);
/** create a region with specified sources @param srcs and XML state */
static boost::shared_ptr<Region> create (SourceList& srcs, const XMLNode&);
private:
static std::map<PBD::ID,boost::weak_ptr<Region> > region_map;

View file

@ -24,46 +24,52 @@
#include <set>
#include <string>
#include <stdint.h>
#include "pbd/signals.h"
#include "pbd/signals.h"
#include "pbd/stateful.h"
#include "pbd/signals.h"
#include "ardour/types.h"
#include "ardour/session_object.h"
namespace ARDOUR {
namespace Properties {
extern PBD::PropertyDescriptor<bool> relative;
extern PBD::PropertyDescriptor<bool> active;
extern PBD::PropertyDescriptor<bool> gain;
extern PBD::PropertyDescriptor<bool> mute;
extern PBD::PropertyDescriptor<bool> solo;
extern PBD::PropertyDescriptor<bool> recenable;
extern PBD::PropertyDescriptor<bool> select;
extern PBD::PropertyDescriptor<bool> edit;
/* we use this, but its declared in region.cc */
extern PBD::PropertyDescriptor<bool> hidden;
};
class Route;
class Track;
class AudioTrack;
class Session;
class RouteGroup : public PBD::Stateful, public PBD::ScopedConnectionList {
public:
enum Flag {
Relative = 0x1,
Active = 0x2,
Hidden = 0x4
};
enum Property {
Gain = 0x1,
Mute = 0x2,
Solo = 0x4,
RecEnable = 0x8,
Select = 0x10,
Edit = 0x20
};
RouteGroup (Session& s, const std::string &n, Flag f = Flag(0), Property p = Property(0));
class RouteGroup : public SessionObject
{
public:
static void make_property_quarks();
RouteGroup (Session& s, const std::string &n);
~RouteGroup ();
const std::string& name() { return _name; }
void set_name (std::string str);
bool is_active () const { return _active.val(); }
bool is_relative () const { return _relative.val(); }
bool is_hidden () const { return _hidden.val(); }
bool is_gain () const { return _gain.val(); }
bool is_mute () const { return _mute.val(); }
bool is_solo () const { return _solo.val(); }
bool is_recenable () const { return _recenable.val(); }
bool is_select () const { return _select.val(); }
bool is_edit () const { return _edit.val(); }
bool is_active () const { return _flags & Active; }
bool is_relative () const { return _flags & Relative; }
bool is_hidden () const { return _flags & Hidden; }
bool empty() const {return routes->empty();}
size_t size() const { return routes->size();}
@ -74,20 +80,14 @@ public:
void set_relative (bool yn, void *src);
void set_hidden (bool yn, void *src);
bool property (Property p) const {
return ((_properties & p) == p);
}
void set_gain (bool yn);
void set_mute (bool yn);
void set_solo (bool yn);
void set_recenable (bool yn);
void set_select (bool yn);
void set_edit (bool yn);
bool active_property (Property p) const {
return is_active() && property (p);
}
void set_property (Property p, bool v) {
_properties = (Property) (_properties & ~p);
if (v) {
_properties = (Property) (_properties | p);
}
}
bool enabled_property (PBD::PropertyID);
int add (boost::shared_ptr<Route>);
int remove (boost::shared_ptr<Route>);
@ -131,17 +131,26 @@ public:
PBD::Signal0<void> changed;
PBD::Signal1<void,void*> FlagsChanged;
static PBD::PropertyChange FlagsChange;
static PBD::PropertyChange PropertiesChange;
XMLNode& get_state ();
int set_state (const XMLNode&, int version);
private:
Session& _session;
boost::shared_ptr<RouteList> routes;
boost::shared_ptr<Route> subgroup_bus;
std::string _name;
Flag _flags;
Property _properties;
PBD::Property<bool> _relative;
PBD::Property<bool> _active;
PBD::Property<bool> _hidden;
PBD::Property<bool> _gain;
PBD::Property<bool> _mute;
PBD::Property<bool> _solo;
PBD::Property<bool> _recenable;
PBD::Property<bool> _select;
PBD::Property<bool> _edit;
void remove_when_going_away (boost::weak_ptr<Route>);
int set_state_2X (const XMLNode&, int);

View file

@ -1210,7 +1210,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void xrun_recovery ();
TempoMap *_tempo_map;
void tempo_map_changed (PBD::Change);
void tempo_map_changed (PBD::PropertyChange);
/* edit/mix groups */
@ -1257,7 +1257,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
RegionList regions;
void add_region (boost::shared_ptr<Region>);
void region_changed (PBD::Change, boost::weak_ptr<Region>);
void region_changed (PBD::PropertyChange, boost::weak_ptr<Region>);
void remove_region (boost::weak_ptr<Region>);
int load_regions (const XMLNode& node);

View file

@ -1,5 +1,5 @@
/*
Copyright (C) 2000-2007 Paul Davis
Copyright (C) 2000-2010 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
@ -24,12 +24,17 @@
#include "pbd/statefuldestructible.h"
#include "pbd/signals.h"
#include "ardour/ardour.h"
#include "ardour/session_handle.h"
#include "i18n.h"
namespace ARDOUR {
namespace Properties {
extern PBD::PropertyDescriptor<std::string> name;
}
class Session;
/** A named object associated with a Session. Objects derived from this class are
@ -39,16 +44,20 @@ class Session;
class SessionObject : public SessionHandleRef, public PBD::StatefulDestructible
{
public:
static void make_property_quarks ();
SessionObject (Session& session, const std::string& name)
: SessionHandleRef (session)
, _name (X_("name"), PBD::Change (0), name)
, _name (Properties::name, PBD::PropertyChange (0), name)
{
add_state (_name);
add_property (_name);
}
Session& session() const { return _session; }
std::string name() const { return _name; }
PBD::PropertyChange set_property (const PBD::PropertyBase& prop);
virtual bool set_name (const std::string& str) {
if (_name != str) {
_name = str;
@ -60,7 +69,7 @@ class SessionObject : public SessionHandleRef, public PBD::StatefulDestructible
PBD::Signal0<void> NameChanged;
protected:
PBD::State<std::string> _name;
PBD::Property<std::string> _name;
};
} // namespace ARDOUR

View file

@ -39,7 +39,7 @@ public:
protected:
friend class SourceFactory;
SilentFileSource (Session& s, const XMLNode& x, nframes_t len, float srate)
SilentFileSource (Session& s, const XMLNode& x, framecnt_t len, float srate)
: Source (s, x)
, AudioFileSource (s, x, false)
, _sample_rate(srate)
@ -47,17 +47,17 @@ protected:
_length = len;
}
nframes_t read_unlocked (Sample *dst, sframes_t /*start*/, nframes_t cnt) const {
framecnt_t read_unlocked (Sample *dst, framepos_t /*start*/, framecnt_t cnt) const {
memset (dst, 0, sizeof (Sample) * cnt);
return cnt;
}
nframes_t write_unlocked (Sample */*dst*/, nframes_t /*cnt*/) { return 0; }
framecnt_t write_unlocked (Sample */*dst*/, framecnt_t /*cnt*/) { return 0; }
void set_header_timeline_position () {}
int read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, sframes_t /*start*/, nframes_t /*cnt*/,
double /*samples_per_unit*/, nframes_t /*fpp*/) const {
int read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t /*start*/, framecnt_t /*cnt*/,
double /*samples_per_unit*/, framecnt_t /*fpp*/) const {
memset (peaks, 0, sizeof (PeakData) * npeaks);
return 0;
}

View file

@ -65,10 +65,9 @@ class SndFileSource : public AudioFileSource {
protected:
void set_header_timeline_position ();
nframes_t read_unlocked (Sample *dst, sframes_t start, nframes_t cnt) const;
nframes_t write_unlocked (Sample *dst, nframes_t cnt);
nframes_t write_float (Sample* data, sframes_t pos, nframes_t cnt);
framecnt_t read_unlocked (Sample *dst, framepos_t start, framecnt_t cnt) const;
framecnt_t write_unlocked (Sample *dst, framecnt_t cnt);
framecnt_t write_float (Sample* data, framepos_t pos, framecnt_t cnt);
private:
SNDFILE *sf;
@ -77,26 +76,26 @@ class SndFileSource : public AudioFileSource {
void init_sndfile ();
int open();
int setup_broadcast_info (sframes_t when, struct tm&, time_t);
int setup_broadcast_info (framepos_t when, struct tm&, time_t);
/* destructive */
static nframes_t xfade_frames;
static framecnt_t xfade_frames;
static gain_t* out_coefficient;
static gain_t* in_coefficient;
bool _capture_start;
bool _capture_end;
sframes_t capture_start_frame;
sframes_t file_pos; // unit is frames
nframes_t xfade_out_count;
nframes_t xfade_in_count;
framepos_t capture_start_frame;
framepos_t file_pos; // unit is frames
framecnt_t xfade_out_count;
framecnt_t xfade_in_count;
Sample* xfade_buf;
nframes_t crossfade (Sample* data, nframes_t cnt, int dir);
void set_timeline_position (int64_t);
nframes_t destructive_write_unlocked (Sample *dst, nframes_t cnt);
nframes_t nondestructive_write_unlocked (Sample *dst, nframes_t cnt);
framecnt_t crossfade (Sample* data, framecnt_t cnt, int dir);
void set_timeline_position (framepos_t);
framecnt_t destructive_write_unlocked (Sample *dst, framecnt_t cnt);
framecnt_t nondestructive_write_unlocked (Sample *dst, framecnt_t cnt);
void handle_header_position_change ();
PBD::ScopedConnection header_position_connection;
};

View file

@ -59,12 +59,12 @@ class Source : public SessionObject
time_t timestamp() const { return _timestamp; }
void stamp (time_t when) { _timestamp = when; }
virtual sframes_t length (sframes_t pos) const = 0;
virtual void update_length (sframes_t pos, sframes_t cnt) = 0;
virtual framecnt_t length (framepos_t pos) const = 0;
virtual void update_length (framepos_t pos, framecnt_t cnt) = 0;
virtual const Glib::ustring& path() const = 0;
virtual nframes64_t natural_position() const { return 0; }
virtual framepos_t natural_position() const { return 0; }
void mark_for_remove();

View file

@ -258,7 +258,7 @@ class TempoMap : public PBD::StatefulDestructible
nframes_t frame_rate () const { return _frame_rate; }
PBD::Signal1<void,PBD::Change> StateChanged;
PBD::Signal1<void,PBD::PropertyChange> StateChanged;
private:
static Tempo _default_tempo;

View file

@ -63,6 +63,11 @@ namespace ARDOUR {
* don't want to pay for extremely long session times they don't need...
*/
typedef int64_t sframes_t;
typedef int64_t framepos_t;
/* any offset from a framepos_t, measured in audio frames */
typedef int64_t frameoffset_t;
/* any count of audio frames */
typedef int64_t framecnt_t;
enum IOChange {
NoChange = 0,

View file

@ -344,7 +344,12 @@ AudioDiskstream::setup_destructive_playlist ()
/* a single full-sized region */
boost::shared_ptr<Region> region (RegionFactory::create (srcs, 0, max_frames - srcs.front()->natural_position(), _name));
PropertyList plist;
plist.add (Properties::name, _name.val());
plist.add (Properties::start, 0);
plist.add (Properties::length, max_frames - max_frames - srcs.front()->natural_position());
boost::shared_ptr<Region> region (RegionFactory::create (srcs, plist));
_playlist->add_region (region, srcs.front()->natural_position());
}
@ -1465,10 +1470,15 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
*/
try {
boost::shared_ptr<Region> rx (RegionFactory::create (srcs,
c->front()->write_source->last_capture_start_frame(), total_capture,
whole_file_region_name, 0,
Region::Flag (Region::DefaultFlags|Region::Automatic|Region::WholeFile)));
PropertyList plist;
plist.add (Properties::start, c->front()->write_source->last_capture_start_frame());
plist.add (Properties::length, total_capture);
plist.add (Properties::name, whole_file_region_name);
boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
rx->set_automatic (true);
rx->set_whole_file (true);
region = boost::dynamic_pointer_cast<AudioRegion> (rx);
region->special_set_position (capture_info.front()->start);
@ -1496,7 +1506,14 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
// cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add region " << region_name << endl;
try {
boost::shared_ptr<Region> rx (RegionFactory::create (srcs, buffer_position, (*ci)->frames, region_name));
PropertyList plist;
plist.add (Properties::start, buffer_position);
plist.add (Properties::length, (*ci)->frames);
plist.add (Properties::name, region_name);
boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
region = boost::dynamic_pointer_cast<AudioRegion> (rx);
}
@ -2196,10 +2213,17 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
boost::shared_ptr<AudioRegion> region;
try {
region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (
pending_sources, 0, first_fs->length(first_fs->timeline_position()),
region_name_from_path (first_fs->name(), true), 0,
Region::Flag (Region::DefaultFlags|Region::Automatic|Region::WholeFile)));
PropertyList plist;
plist.add (Properties::start, 0);
plist.add (Properties::length, first_fs->length (first_fs->timeline_position()));
plist.add (Properties::name, region_name_from_path (first_fs->name(), true));
region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, plist));
region->set_automatic (true);
region->set_whole_file (true);
region->special_set_position (0);
}
@ -2211,20 +2235,6 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
return -1;
}
try {
region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (
pending_sources, 0, first_fs->length(first_fs->timeline_position()),
region_name_from_path (first_fs->name(), true)));
}
catch (failed_constructor& err) {
error << string_compose (_("%1: cannot create region from pending capture sources"),
_name)
<< endmsg;
return -1;
}
_playlist->add_region (region, position);
return 0;

View file

@ -420,7 +420,7 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
audio engineering.
*/
xfade_length = min ((nframes_t) 720, top->length());
xfade_length = min ((framecnt_t) 720, top->length());
if (top_region_at (top->first_frame()) == top) {
@ -454,7 +454,7 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
} else {
touched_regions = regions_touched (top->first_frame(),
top->first_frame() + min ((nframes_t)_session.config.get_short_xfade_seconds() * _session.frame_rate(),
top->first_frame() + min ((framecnt_t) _session.config.get_short_xfade_seconds() * _session.frame_rate(),
top->length()));
if (touched_regions->size() <= 2) {
xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other, _session.config.get_xfade_model(), _session.config.get_xfades_active()));
@ -480,7 +480,7 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
} else {
touched_regions = regions_touched (bottom->first_frame(),
bottom->first_frame() + min ((nframes_t)_session.config.get_short_xfade_seconds() * _session.frame_rate(),
bottom->first_frame() + min ((framecnt_t)_session.config.get_short_xfade_seconds() * _session.frame_rate(),
bottom->length()));
if (touched_regions->size() <= 2) {
xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other, _session.config.get_xfade_model(), _session.config.get_xfades_active()));
@ -726,7 +726,7 @@ AudioPlaylist::destroy_region (boost::shared_ptr<Region> region)
}
void
AudioPlaylist::crossfade_changed (Change)
AudioPlaylist::crossfade_changed (PropertyChange)
{
if (in_flush || in_set_state) {
return;
@ -742,13 +742,13 @@ AudioPlaylist::crossfade_changed (Change)
}
bool
AudioPlaylist::region_changed (Change what_changed, boost::shared_ptr<Region> region)
AudioPlaylist::region_changed (PropertyChange what_changed, boost::shared_ptr<Region> region)
{
if (in_flush || in_set_state) {
return false;
}
Change our_interests = Change (AudioRegion::FadeInChanged|
PropertyChange our_interests = PropertyChange (AudioRegion::FadeInChanged|
AudioRegion::FadeOutChanged|
AudioRegion::FadeInActiveChanged|
AudioRegion::FadeOutActiveChanged|

View file

@ -770,11 +770,14 @@ AudioTrack::freeze (InterThreadInfo& itt)
/* create a new region from all filesources, keep it private */
boost::shared_ptr<Region> region (RegionFactory::create (srcs, 0,
srcs[0]->length(srcs[0]->timeline_position()),
region_name, 0,
(Region::Flag) (Region::WholeFile|Region::DefaultFlags),
false));
PropertyList plist;
plist.add (Properties::start, 0);
plist.add (Properties::length, srcs[0]->length(srcs[0]->timeline_position()));
plist.add (Properties::name, region_name);
plist.add (Properties::whole_file, true);
boost::shared_ptr<Region> region (RegionFactory::create (srcs, plist, false));
new_playlist->set_orig_diskstream_id (diskstream->id());
new_playlist->add_region (region, _session.current_start_frame());

View file

@ -36,6 +36,7 @@
#include "evoral/Curve.hpp"
#include "ardour/audioregion.h"
#include "ardour/debug.h"
#include "ardour/session.h"
#include "ardour/gain.h"
#include "ardour/dB.h"
@ -52,186 +53,180 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
/* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
namespace ARDOUR {
namespace Properties {
PBD::PropertyDescriptor<bool> envelope_active;
PBD::PropertyDescriptor<bool> default_fade_in;
PBD::PropertyDescriptor<bool> default_fade_out;
PBD::PropertyDescriptor<bool> fade_in_active;
PBD::PropertyDescriptor<bool> fade_out_active;
PBD::PropertyDescriptor<float> scale_amplitude;
}
}
Change AudioRegion::FadeInChanged = PBD::new_change();
Change AudioRegion::FadeOutChanged = PBD::new_change();
Change AudioRegion::FadeInActiveChanged = PBD::new_change();
Change AudioRegion::FadeOutActiveChanged = PBD::new_change();
Change AudioRegion::EnvelopeActiveChanged = PBD::new_change();
Change AudioRegion::ScaleAmplitudeChanged = PBD::new_change();
Change AudioRegion::EnvelopeChanged = PBD::new_change();
void
AudioRegion::make_property_quarks ()
{
Properties::envelope_active.id = g_quark_from_static_string (X_("envelope-active"));
Properties::default_fade_in.id = g_quark_from_static_string (X_("default-fade-in"));
Properties::default_fade_out.id = g_quark_from_static_string (X_("default-fade-out"));
Properties::fade_in_active.id = g_quark_from_static_string (X_("fade-in-active"));
Properties::fade_out_active.id = g_quark_from_static_string (X_("fade-out-active"));
Properties::scale_amplitude.id = g_quark_from_static_string (X_("scale-amplitude"));
}
void
AudioRegion::register_properties ()
{
/* no need to register parent class properties */
add_property (_envelope_active);
add_property (_default_fade_in);
add_property (_default_fade_out);
add_property (_fade_in_active);
add_property (_fade_out_active);
add_property (_scale_amplitude);
}
#define AUDIOREGION_STATE_DEFAULT \
_envelope_active (Properties::envelope_active, EnvelopeActiveChanged, false) \
, _default_fade_in (Properties::default_fade_in, FadeInChanged, true) \
, _default_fade_out (Properties::default_fade_out, FadeOutChanged, true) \
, _fade_in_active (Properties::fade_in_active, FadeInActiveChanged, true) \
, _fade_out_active (Properties::fade_out_active, FadeOutActiveChanged, true) \
, _scale_amplitude (Properties::scale_amplitude, ScaleAmplitudeChanged, 1.0)
#define AUDIOREGION_COPY_STATE(other) \
_envelope_active (other->_envelope_active) \
, _default_fade_in (other->_default_fade_in) \
, _default_fade_out (other->_default_fade_out) \
, _fade_in_active (other->_fade_in_active) \
, _fade_out_active (other->_fade_out_active) \
, _scale_amplitude (other->_scale_amplitude)
PropertyChange AudioRegion::FadeInChanged = PBD::new_change();
PropertyChange AudioRegion::FadeOutChanged = PBD::new_change();
PropertyChange AudioRegion::FadeInActiveChanged = PBD::new_change();
PropertyChange AudioRegion::FadeOutActiveChanged = PBD::new_change();
PropertyChange AudioRegion::EnvelopeActiveChanged = PBD::new_change();
PropertyChange AudioRegion::ScaleAmplitudeChanged = PBD::new_change();
PropertyChange AudioRegion::EnvelopeChanged = PBD::new_change();
/* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
void
AudioRegion::init ()
{
_scale_amplitude = 1.0;
register_properties ();
set_default_fades ();
set_default_envelope ();
listen_to_my_curves ();
connect_to_analysis_changed ();
connect_to_header_position_offset_changed ();
}
/** Constructor for use by derived types only */
AudioRegion::AudioRegion (Session& s, nframes_t start, nframes_t length, string name)
: Region (s, start, length, name, DataType::AUDIO)
, _automatable(s)
AudioRegion::AudioRegion (Session& s, framepos_t start, framecnt_t len, std::string name)
: Region (s, start, len, name, DataType::AUDIO)
, AUDIOREGION_STATE_DEFAULT
, _automatable (s)
, _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
, _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
, _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
, _fade_in_suspended (0)
, _fade_out_suspended (0)
{
init ();
assert (_sources.size() == _master_sources.size());
}
/** Basic AudioRegion constructor (one channel) */
AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length)
: Region (src, start, length, PBD::basename_nosuffix(src->name()), DataType::AUDIO, 0, Region::Flag(Region::DefaultFlags|Region::External))
AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src)
: Region (boost::static_pointer_cast<Source>(src))
, AUDIOREGION_STATE_DEFAULT
, _automatable(src->session())
, _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
, _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
, _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
, _fade_in_suspended (0)
, _fade_out_suspended (0)
{
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
if (afs) {
afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
}
init ();
assert (_sources.size() == _master_sources.size());
}
/* XXX why is this set here ? - set in a property list given to RegionFactory */
_external = true;
/* Basic AudioRegion constructor (one channel) */
AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags)
: Region (src, start, length, name, DataType::AUDIO, layer, flags)
, _automatable(src->session())
, _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
, _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
, _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
{
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
if (afs) {
afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
}
init ();
assert (_sources.size() == _master_sources.size());
}
/** Basic AudioRegion constructor (many channels) */
AudioRegion::AudioRegion (const SourceList& srcs, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags)
: Region (srcs, start, length, name, DataType::AUDIO, layer, flags)
AudioRegion::AudioRegion (const SourceList& srcs)
: Region (srcs)
, AUDIOREGION_STATE_DEFAULT
, _automatable(srcs[0]->session())
, _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
, _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
, _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
, _fade_in_suspended (0)
, _fade_out_suspended (0)
{
init ();
connect_to_analysis_changed ();
assert (_sources.size() == _master_sources.size());
}
/** Create a new AudioRegion, that is part of an existing one */
AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags)
: Region (other, offset, length, name, layer, flags)
, _automatable(other->session())
, _fade_in (new AutomationList(*other->_fade_in))
, _fade_out (new AutomationList(*other->_fade_out))
, _envelope (new AutomationList(*other->_envelope, offset, offset + length))
AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes64_t offset, bool offset_relative)
: Region (other, offset, offset_relative)
, AUDIOREGION_COPY_STATE (other)
, _automatable (other->session())
, _fade_in (new AutomationList (*other->_fade_in))
, _fade_out (new AutomationList (*other->_fade_out))
/* XXX is this guaranteed to work for all values of offset+offset_relative? */
, _envelope (new AutomationList (*other->_envelope, _start, _start + _length))
, _fade_in_suspended (0)
, _fade_out_suspended (0)
{
/* don't use init here, because we got fade in/out from the other region
*/
register_properties ();
listen_to_my_curves ();
connect_to_analysis_changed ();
connect_to_header_position_offset_changed ();
/* return to default fades if the existing ones are too long */
if (_flags & LeftOfSplit) {
if (_fade_in->back()->when >= _length) {
set_default_fade_in ();
} else {
_fade_in_disabled = other->_fade_in_disabled;
}
set_default_fade_out ();
_flags = Flag (_flags & ~Region::LeftOfSplit);
}
if (_flags & RightOfSplit) {
if (_fade_out->back()->when >= _length) {
set_default_fade_out ();
} else {
_fade_out_disabled = other->_fade_out_disabled;
}
set_default_fade_in ();
_flags = Flag (_flags & ~Region::RightOfSplit);
}
_scale_amplitude = other->_scale_amplitude;
assert(_type == DataType::AUDIO);
listen_to_my_curves ();
connect_to_analysis_changed ();
assert (_sources.size() == _master_sources.size());
}
AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
: Region (other)
, _automatable (other->session())
, _fade_in (new AutomationList (*other->_fade_in))
, _fade_out (new AutomationList (*other->_fade_out))
, _envelope (new AutomationList (*other->_envelope))
{
assert(_type == DataType::AUDIO);
_scale_amplitude = other->_scale_amplitude;
listen_to_my_curves ();
connect_to_analysis_changed ();
assert (_sources.size() == _master_sources.size());
}
AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& /*srcs*/,
nframes_t length, const string& name, layer_t layer, Flag flags)
: Region (other, length, name, layer, flags)
AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& srcs)
: Region (boost::static_pointer_cast<const Region>(other), srcs)
, AUDIOREGION_COPY_STATE (other)
, _automatable (other->session())
, _fade_in (new AutomationList (*other->_fade_in))
, _fade_out (new AutomationList (*other->_fade_out))
, _envelope (new AutomationList (*other->_envelope))
, _fade_in_suspended (0)
, _fade_out_suspended (0)
{
/* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> ((*i));
if (afs) {
afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
}
}
_scale_amplitude = other->_scale_amplitude;
_fade_in_disabled = 0;
_fade_out_disabled = 0;
register_properties ();
listen_to_my_curves ();
connect_to_analysis_changed ();
connect_to_header_position_offset_changed ();
assert (_sources.size() == _master_sources.size());
}
AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& node)
: Region (src, node)
, AUDIOREGION_STATE_DEFAULT
, _automatable(src->session())
, _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
, _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
, _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
{
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
if (afs) {
afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
}
init ();
if (set_state (node, Stateful::loading_state_version)) {
@ -239,17 +234,18 @@ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& nod
}
assert(_type == DataType::AUDIO);
connect_to_analysis_changed ();
assert (_sources.size() == _master_sources.size());
}
AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
: Region (srcs, node)
, AUDIOREGION_STATE_DEFAULT
, _automatable(srcs[0]->session())
, _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
, _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
, _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
, _fade_in_suspended (0)
, _fade_out_suspended (0)
{
init ();
@ -266,6 +262,33 @@ AudioRegion::~AudioRegion ()
{
}
void
AudioRegion::post_set ()
{
if (!_sync_marked) {
_sync_position = _start;
}
/* return to default fades if the existing ones are too long */
if (_left_of_split) {
if (_fade_in->back()->when >= _length) {
set_default_fade_in ();
}
set_default_fade_out ();
_left_of_split = false;
}
if (_right_of_split) {
if (_fade_out->back()->when >= _length) {
set_default_fade_out ();
}
set_default_fade_in ();
_right_of_split = false;
}
}
void
AudioRegion::connect_to_analysis_changed ()
{
@ -294,8 +317,6 @@ AudioRegion::connect_to_header_position_offset_changed ()
void
AudioRegion::listen_to_my_curves ()
{
cerr << _name << ": listeing my own curves\n";
_envelope->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::envelope_changed, this));
_fade_in->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_in_changed, this));
_fade_out->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_out_changed, this));
@ -305,11 +326,7 @@ void
AudioRegion::set_envelope_active (bool yn)
{
if (envelope_active() != yn) {
if (yn) {
_flags = Flag (_flags|EnvelopeActive);
} else {
_flags = Flag (_flags & ~EnvelopeActive);
}
_envelope_active = yn;
send_change (EnvelopeActiveChanged);
}
}
@ -324,7 +341,7 @@ AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nfra
if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
return 0;
} else {
if (_scale_amplitude != 1.0) {
if (_scale_amplitude != 1.0f) {
for (nframes_t n = 0; n < npeaks; ++n) {
buf[n].max *= _scale_amplitude;
buf[n].min *= _scale_amplitude;
@ -334,32 +351,32 @@ AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nfra
}
}
nframes_t
AudioRegion::read (Sample* buf, sframes_t timeline_position, nframes_t cnt, int channel) const
framecnt_t
AudioRegion::read (Sample* buf, framepos_t timeline_position, framecnt_t cnt, int channel) const
{
/* raw read, no fades, no gain, nada */
return _read_at (_sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, 0, 0, ReadOps (0));
}
nframes_t
AudioRegion::read_with_ops (Sample* buf, sframes_t file_position, nframes_t cnt, int channel, ReadOps rops) const
framecnt_t
AudioRegion::read_with_ops (Sample* buf, framepos_t file_position, framecnt_t cnt, int channel, ReadOps rops) const
{
return _read_at (_sources, _length, buf, 0, 0, file_position, cnt, channel, 0, 0, rops);
}
nframes_t
framecnt_t
AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
sframes_t file_position, nframes_t cnt, uint32_t chan_n,
nframes_t read_frames, nframes_t skip_frames) const
framepos_t file_position, framecnt_t cnt, uint32_t chan_n,
framecnt_t read_frames, framecnt_t skip_frames) const
{
/* regular diskstream/butler read complete with fades etc */
return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer,
file_position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
}
nframes_t
framecnt_t
AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
sframes_t position, nframes_t cnt, uint32_t chan_n) const
framepos_t position, framecnt_t cnt, uint32_t chan_n) const
{
/* do not read gain/scaling/fades and do not count this disk i/o in statistics */
@ -367,18 +384,19 @@ AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_bu
buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0, ReadOps (0));
}
nframes_t
AudioRegion::_read_at (const SourceList& /*srcs*/, nframes_t limit,
Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
sframes_t position, nframes_t cnt,
uint32_t chan_n,
nframes_t /*read_frames*/,
nframes_t /*skip_frames*/,
ReadOps rops) const
framecnt_t
AudioRegion::_read_at (const SourceList& /*srcs*/, framecnt_t limit,
Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
framepos_t position,
framecnt_t cnt,
uint32_t chan_n,
framecnt_t /*read_frames*/,
framecnt_t /*skip_frames*/,
ReadOps rops) const
{
nframes_t internal_offset;
nframes_t buf_offset;
nframes_t to_read;
frameoffset_t internal_offset;
frameoffset_t buf_offset;
framecnt_t to_read;
bool raw = (rops == ReadOpsNone);
if (muted() && !raw) {
@ -439,7 +457,7 @@ AudioRegion::_read_at (const SourceList& /*srcs*/, nframes_t limit,
/* fade in */
if ((_flags & FadeIn) && _session.config.get_use_region_fades()) {
if (_fade_in_active && _session.config.get_use_region_fades()) {
nframes_t fade_in_length = (nframes_t) _fade_in->back()->when;
@ -462,7 +480,7 @@ AudioRegion::_read_at (const SourceList& /*srcs*/, nframes_t limit,
/* fade out */
if ((_flags & FadeOut) && _session.config.get_use_region_fades()) {
if (_fade_out_active && _session.config.get_use_region_fades()) {
/* see if some part of this read is within the fade out */
@ -552,8 +570,6 @@ AudioRegion::state (bool full)
char buf2[64];
LocaleGuard lg (X_("POSIX"));
snprintf (buf, sizeof(buf), "%.12g", _scale_amplitude);
node.add_property ("scale-gain", buf);
// XXX these should move into Region
@ -573,26 +589,7 @@ AudioRegion::state (bool full)
node.add_property ("channels", buf);
if (full) {
child = node.add_child (X_("FadeIn"));
if ((_flags & DefaultFadeIn)) {
child->add_property (X_("default"), X_("yes"));
} else {
child->add_child_nocopy (_fade_in->get_state ());
}
child->add_property (X_("active"), fade_in_active () ? X_("yes") : X_("no"));
child = node.add_child (X_("FadeOut"));
if ((_flags & DefaultFadeOut)) {
child->add_property (X_("default"), X_("yes"));
} else {
child->add_child_nocopy (_fade_out->get_state ());
}
child->add_property (X_("active"), fade_out_active () ? X_("yes") : X_("no"));
Stateful::add_properties (node);
}
child = node.add_child ("Envelope");
@ -629,7 +626,7 @@ AudioRegion::state (bool full)
}
int
AudioRegion::set_live_state (const XMLNode& node, int version, Change& what_changed, bool send)
AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_changed, bool send)
{
const XMLNodeList& nlist = node.children();
const XMLProperty *prop;
@ -637,36 +634,32 @@ AudioRegion::set_live_state (const XMLNode& node, int version, Change& what_chan
boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
freeze ();
if (the_playlist) {
the_playlist->freeze ();
}
Region::set_live_state (node, version, what_changed, false);
cerr << "After region SLS, wc = " << what_changed << endl;
/* this will set all our State members and stuff controlled by the Region.
It should NOT send any changed signals - that is our responsibility.
*/
if ((prop = node.property ("flags")) != 0) {
_flags = Flag (_flags & ~Region::LeftOfSplit);
_flags = Flag (_flags & ~Region::RightOfSplit);
}
/* find out if any flags changed that we signal about */
Region::_set_state (node, version, what_changed, false);
if ((prop = node.property ("scale-gain")) != 0) {
float a = atof (prop->value().c_str());
if (a != _scale_amplitude) {
_scale_amplitude = a;
what_changed = Change (what_changed|ScaleAmplitudeChanged);
what_changed = PropertyChange (what_changed|ScaleAmplitudeChanged);
cerr << _name << " amp changed\n";
}
}
/* Now find envelope description and other misc child items */
/* Now find envelope description and other related child items */
_envelope->freeze ();
for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
#if 0
XMLNode *child;
XMLProperty *prop;
@ -731,7 +724,6 @@ AudioRegion::set_live_state (const XMLNode& node, int version, Change& what_chan
cerr << _name << " fadeout changd\n";
}
#endif
}
_envelope->thaw ();
@ -749,15 +741,61 @@ AudioRegion::set_live_state (const XMLNode& node, int version, Change& what_chan
return 0;
}
PropertyChange
AudioRegion::set_property (const PropertyBase& prop)
{
PropertyChange c = PropertyChange (0);
DEBUG_TRACE (DEBUG::Properties, string_compose ("audio region %1 set property %2\n", _name.val(), prop.property_name()));
if (prop == Properties::envelope_active.id) {
bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
if (val != _envelope_active) {
_envelope_active = val;
c = EnvelopeActiveChanged;
}
} else if (prop == Properties::default_fade_in.id) {
bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
if (val != _default_fade_in) {
_default_fade_in = val;
c = FadeInChanged;
}
} else if (prop == Properties::default_fade_out.id) {
bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
if (val != _default_fade_out) {
_default_fade_out = val;
c = FadeOutChanged;
}
} else if (prop == Properties::fade_in_active.id) {
bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
if (val != _fade_in_active) {
_fade_in_active = val;
c = FadeInActiveChanged;
}
} else if (prop == Properties::fade_out_active.id) {
bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
if (val != _fade_out_active) {
_fade_out_active = val;
c = FadeOutChanged;
}
} else if (prop == Properties::scale_amplitude.id) {
gain_t val = dynamic_cast<const PropertyTemplate<gain_t>*>(&prop)->val();
if (val != _scale_amplitude) {
_scale_amplitude = val;
c = ScaleAmplitudeChanged;
}
} else {
return Region::set_property (prop);
}
return c;
}
int
AudioRegion::set_state (const XMLNode& node, int version)
{
/* Region::set_state() calls the virtual set_live_state(),
which will get us back to AudioRegion::set_live_state()
to handle the relevant stuff.
*/
return Region::set_state (node, version);
PropertyChange what_changed;
return _set_state (node, version, what_changed, true);
}
void
@ -783,7 +821,7 @@ AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
}
void
AudioRegion::set_fade_in (FadeShape shape, nframes_t len)
AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
{
_fade_in->freeze ();
_fade_in->clear ();
@ -850,7 +888,7 @@ AudioRegion::set_fade_out (boost::shared_ptr<AutomationList> f)
}
void
AudioRegion::set_fade_out (FadeShape shape, nframes_t len)
AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
{
_fade_out->freeze ();
_fade_out->clear ();
@ -905,7 +943,7 @@ AudioRegion::set_fade_out (FadeShape shape, nframes_t len)
}
void
AudioRegion::set_fade_in_length (nframes_t len)
AudioRegion::set_fade_in_length (framecnt_t len)
{
if (len > _length) {
len = _length - 1;
@ -914,13 +952,13 @@ AudioRegion::set_fade_in_length (nframes_t len)
bool changed = _fade_in->extend_to (len);
if (changed) {
_flags = Flag (_flags & ~DefaultFadeIn);
_default_fade_in = false;
send_change (FadeInChanged);
}
}
void
AudioRegion::set_fade_out_length (nframes_t len)
AudioRegion::set_fade_out_length (framecnt_t len)
{
if (len > _length) {
len = _length - 1;
@ -929,7 +967,7 @@ AudioRegion::set_fade_out_length (nframes_t len)
bool changed = _fade_out->extend_to (len);
if (changed) {
_flags = Flag (_flags & ~DefaultFadeOut);
_default_fade_out = false;
send_change (FadeOutChanged);
}
}
@ -937,30 +975,21 @@ AudioRegion::set_fade_out_length (nframes_t len)
void
AudioRegion::set_fade_in_active (bool yn)
{
if (yn == (_flags & FadeIn)) {
if (yn == _fade_in_active) {
return;
}
if (yn) {
_flags = Flag (_flags|FadeIn);
} else {
_flags = Flag (_flags & ~FadeIn);
}
_fade_in_active = yn;
send_change (FadeInActiveChanged);
}
void
AudioRegion::set_fade_out_active (bool yn)
{
if (yn == (_flags & FadeOut)) {
if (yn == _fade_out_active) {
return;
}
if (yn) {
_flags = Flag (_flags | FadeOut);
} else {
_flags = Flag (_flags & ~FadeOut);
}
_fade_out_active = yn;
send_change (FadeOutActiveChanged);
}
@ -979,14 +1008,14 @@ AudioRegion::fade_out_is_default () const
void
AudioRegion::set_default_fade_in ()
{
_fade_in_disabled = 0;
_fade_in_suspended = 0;
set_fade_in (Linear, 64);
}
void
AudioRegion::set_default_fade_out ()
{
_fade_out_disabled = 0;
_fade_out_suspended = 0;
set_fade_out (Linear, 64);
}
@ -1080,9 +1109,15 @@ AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr
"whole file" even if it covers the entire source file(s).
*/
Flag f = Flag (_flags & ~WholeFile);
PropertyList plist;
plist.add (Properties::start, _start.val());
plist.add (Properties::length, _length.val());
plist.add (Properties::name, new_name);
plist.add (Properties::layer, _layer.val());
v.push_back(RegionFactory::create (srcs, _start, _length, new_name, _layer, f));
v.push_back(RegionFactory::create (srcs, plist));
v.back()->set_whole_file (false);
++n;
}
@ -1090,8 +1125,8 @@ AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr
return 0;
}
nframes_t
AudioRegion::read_raw_internal (Sample* buf, sframes_t pos, nframes_t cnt, int channel) const
framecnt_t
AudioRegion::read_raw_internal (Sample* buf, framepos_t pos, framecnt_t cnt, int channel) const
{
return audio_source()->read (buf, pos, cnt, channel);
}
@ -1183,11 +1218,11 @@ AudioRegion::set_scale_amplitude (gain_t g)
void
AudioRegion::normalize_to (float target_dB)
{
const nframes_t blocksize = 64 * 1024;
const framecnt_t blocksize = 64 * 1024;
Sample buf[blocksize];
nframes_t fpos;
nframes_t fend;
nframes_t to_read;
framepos_t fpos;
framepos_t fend;
framecnt_t to_read;
double maxamp = 0;
gain_t target = dB_to_coefficient (target_dB);
@ -1271,7 +1306,7 @@ AudioRegion::envelope_changed ()
void
AudioRegion::suspend_fade_in ()
{
if (++_fade_in_disabled == 1) {
if (++_fade_in_suspended == 1) {
if (fade_in_is_default()) {
set_fade_in_active (false);
}
@ -1281,7 +1316,7 @@ AudioRegion::suspend_fade_in ()
void
AudioRegion::resume_fade_in ()
{
if (--_fade_in_disabled == 0 && _fade_in_disabled) {
if (--_fade_in_suspended == 0 && _fade_in_suspended) {
set_fade_in_active (true);
}
}
@ -1289,7 +1324,7 @@ AudioRegion::resume_fade_in ()
void
AudioRegion::suspend_fade_out ()
{
if (++_fade_out_disabled == 1) {
if (++_fade_out_suspended == 1) {
if (fade_out_is_default()) {
set_fade_out_active (false);
}
@ -1299,7 +1334,7 @@ AudioRegion::suspend_fade_out ()
void
AudioRegion::resume_fade_out ()
{
if (--_fade_out_disabled == 0 &&_fade_out_disabled) {
if (--_fade_out_suspended == 0 &&_fade_out_suspended) {
set_fade_out_active (true);
}
}
@ -1474,20 +1509,20 @@ then quit ardour and restart."));
* @return Silent periods; first of pair is the offset within the region, second is the length of the period
*/
std::list<std::pair<nframes_t, nframes_t> >
AudioRegion::find_silence (Sample threshold, nframes_t min_length) const
std::list<std::pair<frameoffset_t, framecnt_t> >
AudioRegion::find_silence (Sample threshold, framecnt_t min_length) const
{
nframes_t const block_size = 64 * 1024;
framecnt_t const block_size = 64 * 1024;
Sample loudest[block_size];
Sample buf[block_size];
nframes_t pos = _start;
nframes_t const end = _start + _length - 1;
framepos_t pos = _start;
framepos_t const end = _start + _length - 1;
std::list<std::pair<nframes_t, nframes_t> > silent_periods;
std::list<std::pair<frameoffset_t, framecnt_t> > silent_periods;
bool in_silence = false;
nframes_t silence_start = 0;
frameoffset_t silence_start = 0;
bool silence;
while (pos < end) {
@ -1497,13 +1532,13 @@ AudioRegion::find_silence (Sample threshold, nframes_t min_length) const
for (uint32_t n = 0; n < n_channels(); ++n) {
read_raw_internal (buf, pos, block_size, n);
for (nframes_t i = 0; i < block_size; ++i) {
for (framecnt_t i = 0; i < block_size; ++i) {
loudest[i] = max (loudest[i], abs (buf[i]));
}
}
/* now look for silence */
for (nframes_t i = 0; i < block_size; ++i) {
for (framecnt_t i = 0; i < block_size; ++i) {
silence = abs (loudest[i]) < threshold;
if (silence && !in_silence) {
/* non-silence to silence */
@ -1530,11 +1565,12 @@ AudioRegion::find_silence (Sample threshold, nframes_t min_length) const
}
extern "C" {
int region_read_peaks_from_c (void *arg, uint32_t npeaks, uint32_t start, uint32_t cnt, intptr_t data, uint32_t n_chan, double samples_per_unit)
{
return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (nframes_t) npeaks, (nframes_t) start, (nframes_t) cnt, n_chan,samples_per_unit);
return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (framecnt_t) npeaks, (framepos_t) start, (framecnt_t) cnt, n_chan,samples_per_unit);
}
uint32_t region_length_from_c (void *arg)

View file

@ -265,15 +265,15 @@ AudioSource::initialize_peakfile (bool newfile, ustring audio_path)
return 0;
}
nframes_t
AudioSource::read (Sample *dst, sframes_t start, nframes_t cnt, int /*channel*/) const
framecnt_t
AudioSource::read (Sample *dst, framepos_t start, framecnt_t cnt, int /*channel*/) const
{
Glib::Mutex::Lock lm (_lock);
return read_unlocked (dst, start, cnt);
}
nframes_t
AudioSource::write (Sample *dst, nframes_t cnt)
framecnt_t
AudioSource::write (Sample *dst, framecnt_t cnt)
{
Glib::Mutex::Lock lm (_lock);
/* any write makes the fill not removable */
@ -282,7 +282,7 @@ AudioSource::write (Sample *dst, nframes_t cnt)
}
int
AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, sframes_t start, nframes_t cnt, double samples_per_visual_peak) const
AudioSource::read_peaks (PeakData *peaks, framecnt_t npeaks, framepos_t start, framecnt_t cnt, double samples_per_visual_peak) const
{
return read_peaks_with_fpp (peaks, npeaks, start, cnt, samples_per_visual_peak, _FPP);
}
@ -292,8 +292,8 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, sframes_t start, nfr
*/
int
AudioSource::read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, sframes_t start, nframes_t cnt,
double samples_per_visual_peak, nframes_t samples_per_file_peak) const
AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t start, framecnt_t cnt,
double samples_per_visual_peak, framecnt_t samples_per_file_peak) const
{
Glib::Mutex::Lock lm (_lock);
double scale;
@ -302,7 +302,7 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, sframes_t s
PeakData::PeakDatum xmin;
int32_t to_read;
uint32_t nread;
nframes_t zero_fill = 0;
framecnt_t zero_fill = 0;
int ret = -1;
PeakData* staging = 0;
Sample* raw_staging = 0;
@ -329,8 +329,8 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, sframes_t s
if (cnt > _length - start) {
// cerr << "too close to end @ " << _length << " given " << start << " + " << cnt << endl;
cnt = _length - start;
nframes_t old = npeaks;
npeaks = min ((nframes_t) floor (cnt / samples_per_visual_peak), npeaks);
framecnt_t old = npeaks;
npeaks = min ((framecnt_t) floor (cnt / samples_per_visual_peak), npeaks);
zero_fill = old - npeaks;
}
@ -352,7 +352,7 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, sframes_t s
return -1;
}
for (nframes_t i = 0; i < npeaks; ++i) {
for (framecnt_t i = 0; i < npeaks; ++i) {
peaks[i].max = raw_staging[i];
peaks[i].min = raw_staging[i];
}
@ -403,7 +403,7 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, sframes_t s
}
nframes_t tnp;
framecnt_t tnp;
if (scale < 1.0) {
@ -420,20 +420,20 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, sframes_t s
to avoid confusion, I'll refer to the requested peaks as visual_peaks and the peakfile peaks as stored_peaks
*/
const uint32_t chunksize = (uint32_t) min (expected_peaks, 65536.0);
const framecnt_t chunksize = (framecnt_t) min (expected_peaks, 65536.0);
staging = new PeakData[chunksize];
/* compute the rounded up frame position */
nframes_t current_frame = start;
nframes_t current_stored_peak = (nframes_t) ceil (current_frame / (double) samples_per_file_peak);
uint32_t next_visual_peak = (uint32_t) ceil (current_frame / samples_per_visual_peak);
double next_visual_peak_frame = next_visual_peak * samples_per_visual_peak;
uint32_t stored_peak_before_next_visual_peak = (nframes_t) next_visual_peak_frame / samples_per_file_peak;
uint32_t nvisual_peaks = 0;
uint32_t stored_peaks_read = 0;
uint32_t i = 0;
framepos_t current_frame = start;
framepos_t current_stored_peak = (framepos_t) ceil (current_frame / (double) samples_per_file_peak);
framepos_t next_visual_peak = (framepos_t) ceil (current_frame / samples_per_visual_peak);
double next_visual_peak_frame = next_visual_peak * samples_per_visual_peak;
framepos_t stored_peak_before_next_visual_peak = (framepos_t) next_visual_peak_frame / samples_per_file_peak;
framecnt_t nvisual_peaks = 0;
framecnt_t stored_peaks_read = 0;
framecnt_t i = 0;
/* handle the case where the initial visual peak is on a pixel boundary */
@ -452,7 +452,7 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, sframes_t s
if (i == stored_peaks_read) {
uint32_t start_byte = current_stored_peak * sizeof(PeakData);
tnp = min ((nframes_t)(_length/samples_per_file_peak - current_stored_peak), (nframes_t) expected_peaks);
tnp = min ((framecnt_t)(_length/samples_per_file_peak - current_stored_peak), (framecnt_t) expected_peaks);
to_read = min (chunksize, tnp);
#ifdef DEBUG_READ_PEAKS
@ -527,14 +527,14 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, sframes_t s
data on the fly.
*/
nframes_t frames_read = 0;
nframes_t current_frame = start;
nframes_t i = 0;
nframes_t nvisual_peaks = 0;
nframes_t chunksize = (nframes_t) min (cnt, (nframes_t) 4096);
framecnt_t frames_read = 0;
framepos_t current_frame = start;
framecnt_t i = 0;
framecnt_t nvisual_peaks = 0;
framecnt_t chunksize = (framecnt_t) min (cnt, (framecnt_t) 4096);
raw_staging = new Sample[chunksize];
nframes_t frame_pos = start;
framepos_t frame_pos = start;
double pixel_pos = floor (frame_pos / samples_per_visual_peak);
double next_pixel_pos = ceil (frame_pos / samples_per_visual_peak);
double pixels_per_frame = 1.0 / samples_per_visual_peak;
@ -546,7 +546,7 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, sframes_t s
if (i == frames_read) {
to_read = min (chunksize, nframes_t(_length - current_frame));
to_read = min (chunksize, (framecnt_t)(_length - current_frame));
if (to_read == 0) {
/* XXX ARGH .. out by one error ... need to figure out why this happens
@ -612,12 +612,12 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, sframes_t s
int
AudioSource::build_peaks_from_scratch ()
{
nframes_t current_frame;
nframes_t cnt;
framepos_t current_frame;
framecnt_t cnt;
Sample* buf = 0;
nframes_t frames_read;
nframes_t frames_to_read;
const nframes_t bufsize = 65536; // 256kB per disk read for mono data is about ideal
framecnt_t frames_read;
framecnt_t frames_to_read;
const framecnt_t bufsize = 65536; // 256kB per disk read for mono data is about ideal
int ret = -1;
@ -708,23 +708,23 @@ AudioSource::done_with_peakfile_writes (bool done)
}
int
AudioSource::compute_and_write_peaks (Sample* buf, sframes_t first_frame, nframes_t cnt,
bool force, bool intermediate_peaks_ready)
AudioSource::compute_and_write_peaks (Sample* buf, framepos_t first_frame, framecnt_t cnt,
bool force, bool intermediate_peaks_ready)
{
return compute_and_write_peaks (buf, first_frame, cnt, force, intermediate_peaks_ready, _FPP);
}
int
AudioSource::compute_and_write_peaks (Sample* buf, sframes_t first_frame, nframes_t cnt,
bool force, bool intermediate_peaks_ready, nframes_t fpp)
AudioSource::compute_and_write_peaks (Sample* buf, framepos_t first_frame, framecnt_t cnt,
bool force, bool intermediate_peaks_ready, framecnt_t fpp)
{
Sample* buf2 = 0;
nframes_t to_do;
framecnt_t to_do;
uint32_t peaks_computed;
PeakData* peakbuf = 0;
int ret = -1;
nframes_t current_frame;
nframes_t frames_done;
framepos_t current_frame;
framecnt_t frames_done;
const size_t blocksize = (128 * 1024);
off_t first_peak_byte;
@ -828,7 +828,7 @@ AudioSource::compute_and_write_peaks (Sample* buf, sframes_t first_frame, nframe
break;
}
nframes_t this_time = min (fpp, to_do);
framecnt_t this_time = min (fpp, to_do);
peakbuf[peaks_computed].max = buf[0];
peakbuf[peaks_computed].min = buf[0];
@ -903,7 +903,7 @@ AudioSource::truncate_peakfile ()
}
}
nframes_t
framecnt_t
AudioSource::available_peaks (double zoom_factor) const
{
if (zoom_factor < _FPP) {

View file

@ -36,9 +36,9 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
nframes_t Crossfade::_short_xfade_length = 0;
Change Crossfade::ActiveChanged = new_change();
Change Crossfade::FollowOverlapChanged = new_change();
framecnt_t Crossfade::_short_xfade_length = 0;
PropertyChange Crossfade::ActiveChanged = new_change();
PropertyChange Crossfade::FollowOverlapChanged = new_change();
/* XXX if and when we ever implement parallel processing of the process()
callback, these will need to be handled on a per-thread basis.
@ -48,7 +48,7 @@ Sample* Crossfade::crossfade_buffer_out = 0;
Sample* Crossfade::crossfade_buffer_in = 0;
void
Crossfade::set_buffer_size (nframes_t sz)
Crossfade::set_buffer_size (framecnt_t sz)
{
delete [] crossfade_buffer_out;
crossfade_buffer_out = 0;
@ -69,8 +69,8 @@ Crossfade::operator== (const Crossfade& other)
}
Crossfade::Crossfade (boost::shared_ptr<AudioRegion> in, boost::shared_ptr<AudioRegion> out,
nframes_t length,
nframes_t position,
framecnt_t length,
framepos_t position,
AnchorPoint ap)
: AudioRegion (in->session(), position, length, in->name() + string ("<>") + out->name()),
_fade_in (Evoral::Parameter(FadeInAutomation)), // linear (gain coefficient) => -inf..+6dB
@ -162,9 +162,9 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node)
}
Crossfade::Crossfade (boost::shared_ptr<Crossfade> orig, boost::shared_ptr<AudioRegion> newin, boost::shared_ptr<AudioRegion> newout)
: AudioRegion (boost::dynamic_pointer_cast<const AudioRegion> (orig)),
_fade_in (orig->_fade_in),
_fade_out (orig->_fade_out)
: AudioRegion (boost::dynamic_pointer_cast<const AudioRegion> (orig), 0, true)
, _fade_in (orig->_fade_in)
, _fade_out (orig->_fade_out)
{
_active = orig->_active;
_in_update = orig->_in_update;
@ -267,32 +267,28 @@ Crossfade::initialize ()
layer_relation = (int32_t) (_in->layer() - _out->layer());
}
nframes_t
Crossfade::read_raw_internal (Sample* /*buf*/, sframes_t /*start*/, nframes_t cnt, int /*channel*/) const
framecnt_t
Crossfade::read_raw_internal (Sample* buf, framecnt_t start, framecnt_t cnt, int channel) const
{
// FIXME: Why is this disabled?
#if 0
Sample* mixdown = new Sample[cnt];
float* gain = new float[cnt];
nframes_t ret;
ret = read_at (buf, mixdown, gain, start, cnt, chan_n, cnt);
framecnt_t ret;
ret = read_at (buf, mixdown, gain, start, cnt, channel, cnt);
delete [] mixdown;
delete [] gain;
return ret;
#endif
return cnt;
}
nframes_t
framecnt_t
Crossfade::read_at (Sample *buf, Sample *mixdown_buffer,
float *gain_buffer, sframes_t start, nframes_t cnt, uint32_t chan_n,
nframes_t read_frames, nframes_t skip_frames) const
float *gain_buffer, framepos_t start, framecnt_t cnt, uint32_t chan_n,
framecnt_t read_frames, framecnt_t skip_frames) const
{
nframes_t offset;
nframes_t to_write;
frameoffset_t offset;
framecnt_t to_write;
if (!_active) {
return 0;
@ -314,11 +310,11 @@ Crossfade::read_at (Sample *buf, Sample *mixdown_buffer,
start = _position;
buf += offset;
to_write = min (_length.val(), cnt);
to_write = min (_length.val(), (nframes64_t) cnt);
} else {
to_write = min (nframes_t(_length - (start - _position)), cnt);
to_write = min ((_length - (start - _position)), cnt);
}
@ -346,7 +342,7 @@ Crossfade::read_at (Sample *buf, Sample *mixdown_buffer,
position and length, and so we know precisely how much data they could return.
*/
for (nframes_t n = 0; n < to_write; ++n) {
for (framecnt_t n = 0; n < to_write; ++n) {
buf[n] = (crossfade_buffer_out[n] * fov[n]) + (crossfade_buffer_in[n] * fiv[n]);
}
@ -357,9 +353,9 @@ Crossfade::read_at (Sample *buf, Sample *mixdown_buffer,
}
OverlapType
Crossfade::coverage (nframes_t start, nframes_t end) const
Crossfade::coverage (framepos_t start, framepos_t end) const
{
nframes_t my_end = _position + _length;
framepos_t my_end = _position + _length;
if ((start >= _position) && (end <= my_end)) {
return OverlapInternal;
@ -457,7 +453,7 @@ Crossfade::refresh ()
bool
Crossfade::update ()
{
nframes_t newlen;
framecnt_t newlen;
if (_follow_overlap) {
newlen = _out->first_frame() + _out->length() - _in->first_frame();
@ -503,7 +499,7 @@ Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioReg
{
boost::shared_ptr<AudioRegion> top;
boost::shared_ptr<AudioRegion> bottom;
nframes_t short_xfade_length;
framecnt_t short_xfade_length;
short_xfade_length = _short_xfade_length;
@ -679,11 +675,11 @@ Crossfade::get_state ()
node->add_property ("active", (_active ? "yes" : "no"));
node->add_property ("follow-overlap", (_follow_overlap ? "yes" : "no"));
node->add_property ("fixed", (_fixed ? "yes" : "no"));
snprintf (buf, sizeof(buf), "%" PRIu32, _length.val());
snprintf (buf, sizeof(buf), "%" PRId64, _length.val());
node->add_property ("length", buf);
snprintf (buf, sizeof(buf), "%" PRIu32, (uint32_t) _anchor_point);
node->add_property ("anchor-point", buf);
snprintf (buf, sizeof(buf), "%" PRIu32, (uint32_t) _position);
snprintf (buf, sizeof(buf), "%" PRId64, _position.val());
node->add_property ("position", buf);
child = node->add_child ("FadeIn");
@ -693,7 +689,7 @@ Crossfade::get_state ()
pnode = new XMLNode ("point");
snprintf (buf, sizeof (buf), "%" PRIu32, (nframes_t) floor ((*ii)->when));
snprintf (buf, sizeof (buf), "%" PRId64, (framepos_t) floor ((*ii)->when));
pnode->add_property ("x", buf);
snprintf (buf, sizeof (buf), "%.12g", (*ii)->value);
pnode->add_property ("y", buf);
@ -707,7 +703,7 @@ Crossfade::get_state ()
pnode = new XMLNode ("point");
snprintf (buf, sizeof (buf), "%" PRIu32, (nframes_t) floor ((*ii)->when));
snprintf (buf, sizeof (buf), "%" PRId64, (framepos_t) floor ((*ii)->when));
pnode->add_property ("x", buf);
snprintf (buf, sizeof (buf), "%.12g", (*ii)->value);
pnode->add_property ("y", buf);
@ -726,14 +722,14 @@ Crossfade::set_state (const XMLNode& node, int /*version*/)
XMLNode* fo;
const XMLProperty* prop;
LocaleGuard lg (X_("POSIX"));
Change what_changed = Change (0);
nframes_t val;
PropertyChange what_changed = PropertyChange (0);
framepos_t val;
if ((prop = node.property ("position")) != 0) {
sscanf (prop->value().c_str(), "%" PRIu32, &val);
sscanf (prop->value().c_str(), "%" PRId64, &val);
if (val != _position) {
_position = val;
what_changed = Change (what_changed | PositionChanged);
what_changed = PropertyChange (what_changed | PositionChanged);
}
} else {
warning << _("old-style crossfade information - no position information") << endmsg;
@ -744,7 +740,7 @@ Crossfade::set_state (const XMLNode& node, int /*version*/)
bool x = string_is_affirmative (prop->value());
if (x != _active) {
_active = x;
what_changed = Change (what_changed | ActiveChanged);
what_changed = PropertyChange (what_changed | ActiveChanged);
}
} else {
_active = true;
@ -770,10 +766,10 @@ Crossfade::set_state (const XMLNode& node, int /*version*/)
if ((prop = node.property ("length")) != 0) {
sscanf (prop->value().c_str(), "%" PRIu32, &val);
sscanf (prop->value().c_str(), "%" PRId64, &val);
if (val != _length) {
_length = atol (prop->value().c_str());
what_changed = Change (what_changed | LengthChanged);
_length = val;
what_changed = PropertyChange (what_changed | LengthChanged);
}
} else {
@ -804,11 +800,11 @@ Crossfade::set_state (const XMLNode& node, int /*version*/)
for (i = children.begin(); i != children.end(); ++i) {
if ((*i)->name() == "point") {
nframes_t x;
framepos_t x;
float y;
prop = (*i)->property ("x");
sscanf (prop->value().c_str(), "%" PRIu32, &x);
sscanf (prop->value().c_str(), "%" PRId64, &x);
prop = (*i)->property ("y");
sscanf (prop->value().c_str(), "%f", &y);
@ -828,12 +824,12 @@ Crossfade::set_state (const XMLNode& node, int /*version*/)
for (i = children.begin(); i != children.end(); ++i) {
if ((*i)->name() == "point") {
nframes_t x;
framepos_t x;
float y;
XMLProperty* prop;
prop = (*i)->property ("x");
sscanf (prop->value().c_str(), "%" PRIu32, &x);
sscanf (prop->value().c_str(), "%" PRId64, &x);
prop = (*i)->property ("y");
sscanf (prop->value().c_str(), "%f", &y);
@ -873,10 +869,10 @@ Crossfade::set_follow_overlap (bool yn)
StateChanged (FollowOverlapChanged);
}
nframes_t
Crossfade::set_xfade_length (nframes_t len)
framecnt_t
Crossfade::set_xfade_length (framecnt_t len)
{
nframes_t limit = 0;
framecnt_t limit = 0;
switch (_anchor_point) {
case StartOfIn:
@ -909,7 +905,7 @@ Crossfade::set_xfade_length (nframes_t len)
return len;
}
nframes_t
framecnt_t
Crossfade::overlap_length () const
{
if (_fixed) {
@ -919,7 +915,7 @@ Crossfade::overlap_length () const
}
void
Crossfade::set_short_xfade_length (nframes_t n)
Crossfade::set_short_xfade_length (framecnt_t n)
{
_short_xfade_length = n;
}

View file

@ -92,6 +92,8 @@ ARDOUR::parse_debug_options (const char* str)
bits |= ARDOUR::DEBUG::MidiIO;
} else if (strncasecmp (p, "midiclock", strlen (p)) == 0) {
bits |= ARDOUR::DEBUG::MidiClock;
} else if (strncasecmp (p, "properties", strlen (p)) == 0) {
bits |= ARDOUR::DEBUG::Properties;
}
p = strtok_r (0, ",", &sp);
@ -122,4 +124,5 @@ ARDOUR::list_debug_options ()
cerr << "\tMidiIO" << endl;
cerr << "\tLatencyCompensation" << endl;
cerr << "\tMidiClock" << endl;
cerr << "\tProperties" << endl;
}

View file

@ -361,7 +361,7 @@ Diskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
}
void
Diskstream::playlist_changed (Change)
Diskstream::playlist_changed (PropertyChange)
{
playlist_modified ();
}
@ -426,7 +426,7 @@ Diskstream::remove_region_from_last_capture (boost::weak_ptr<Region> wregion)
}
void
Diskstream::playlist_ranges_moved (list< Evoral::RangeMove<nframes_t> > const & movements_frames)
Diskstream::playlist_ranges_moved (list< Evoral::RangeMove<framepos_t> > const & movements_frames)
{
if (!_route || Config->get_automation_follows_regions () == false) {
return;
@ -434,7 +434,7 @@ Diskstream::playlist_ranges_moved (list< Evoral::RangeMove<nframes_t> > const &
list< Evoral::RangeMove<double> > movements;
for (list< Evoral::RangeMove<nframes_t> >::const_iterator i = movements_frames.begin();
for (list< Evoral::RangeMove<framepos_t> >::const_iterator i = movements_frames.begin();
i != movements_frames.end();
++i) {
@ -458,7 +458,7 @@ Diskstream::playlist_ranges_moved (list< Evoral::RangeMove<nframes_t> > const &
}
void
Diskstream::move_processor_automation (boost::weak_ptr<Processor> p, list< Evoral::RangeMove<nframes_t> > const & movements_frames)
Diskstream::move_processor_automation (boost::weak_ptr<Processor> p, list< Evoral::RangeMove<framepos_t> > const & movements_frames)
{
boost::shared_ptr<Processor> processor (p.lock ());
if (!processor) {
@ -466,7 +466,7 @@ Diskstream::move_processor_automation (boost::weak_ptr<Processor> p, list< Evora
}
list< Evoral::RangeMove<double> > movements;
for (list< Evoral::RangeMove<nframes_t> >::const_iterator i = movements_frames.begin();
for (list< Evoral::RangeMove<framepos_t> >::const_iterator i = movements_frames.begin();
i != movements_frames.end(); ++i) {
movements.push_back(Evoral::RangeMove<double>(i->from, i->length, i->to));
}

View file

@ -33,7 +33,6 @@
#include "ardour/midi_track.h"
#include "ardour/mute_master.h"
#include "ardour/panner.h"
#include "ardour/region_command.h"
#include "ardour/route_group.h"
#include "ardour/session.h"
#include "ardour/track.h"
@ -94,9 +93,6 @@ setup_enum_writer ()
Source::Flag _Source_Flag;
Diskstream::Flag _Diskstream_Flag;
Location::Flags _Location_Flags;
RouteGroup::Flag _RouteGroup_Flag;
RouteGroup::Property _RouteGroup_Property;
Region::Flag _Region_Flag;
Region::PositionLockStyle _Region_PositionLockStyle;
Track::FreezeState _Track_FreezeState;
AutomationList::InterpolationStyle _AutomationList_InterpolationStyle;
@ -122,7 +118,6 @@ setup_enum_writer ()
Session::PostTransportWork _Session_PostTransportWork;
Session::SlaveState _Session_SlaveState;
MTC_Status _MIDI_MTC_Status;
RegionCommand::Property _RegionCommandProperty;
#define REGISTER(e) enum_writer.register_distinct (typeid(e).name(), i, s); i.clear(); s.clear()
#define REGISTER_BITS(e) enum_writer.register_bits (typeid(e).name(), i, s); i.clear(); s.clear()
@ -410,44 +405,10 @@ setup_enum_writer ()
REGISTER_CLASS_ENUM (Location, IsStart);
REGISTER_BITS (_Location_Flags);
REGISTER_CLASS_ENUM (RouteGroup, Relative);
REGISTER_CLASS_ENUM (RouteGroup, Active);
REGISTER_CLASS_ENUM (RouteGroup, Hidden);
REGISTER_BITS (_RouteGroup_Flag);
REGISTER_CLASS_ENUM (RouteGroup, Gain);
REGISTER_CLASS_ENUM (RouteGroup, Mute);
REGISTER_CLASS_ENUM (RouteGroup, Solo);
REGISTER_CLASS_ENUM (RouteGroup, RecEnable);
REGISTER_CLASS_ENUM (RouteGroup, Select);
REGISTER_CLASS_ENUM (RouteGroup, Edit);
REGISTER_BITS (_RouteGroup_Property);
REGISTER_CLASS_ENUM (Panner, SameDirection);
REGISTER_CLASS_ENUM (Panner, OppositeDirection);
REGISTER (_Panner_LinkDirection);
REGISTER_CLASS_ENUM (Region, Muted);
REGISTER_CLASS_ENUM (Region, Opaque);
REGISTER_CLASS_ENUM (Region, EnvelopeActive);
REGISTER_CLASS_ENUM (Region, DefaultFadeIn);
REGISTER_CLASS_ENUM (Region, DefaultFadeOut);
REGISTER_CLASS_ENUM (Region, Locked);
REGISTER_CLASS_ENUM (Region, PositionLocked);
REGISTER_CLASS_ENUM (Region, Automatic);
REGISTER_CLASS_ENUM (Region, WholeFile);
REGISTER_CLASS_ENUM (Region, FadeIn);
REGISTER_CLASS_ENUM (Region, FadeOut);
REGISTER_CLASS_ENUM (Region, Copied);
REGISTER_CLASS_ENUM (Region, Import);
REGISTER_CLASS_ENUM (Region, External);
REGISTER_CLASS_ENUM (Region, SyncMarked);
REGISTER_CLASS_ENUM (Region, LeftOfSplit);
REGISTER_CLASS_ENUM (Region, RightOfSplit);
REGISTER_CLASS_ENUM (Region, Hidden);
REGISTER_CLASS_ENUM (Region, DoNotSendPropertyChanges);
REGISTER_BITS (_Region_Flag);
REGISTER_CLASS_ENUM (Region, AudioTime);
REGISTER_CLASS_ENUM (Region, MusicTime);
REGISTER_BITS (_Region_PositionLockStyle);
@ -584,32 +545,6 @@ setup_enum_writer ()
REGISTER_ENUM(Legato);
REGISTER_ENUM(Groove);
REGISTER(_QuantizeType);
REGISTER_CLASS_ENUM (RegionCommand, Name);
REGISTER_CLASS_ENUM (RegionCommand, PositionLockStyle);
REGISTER_CLASS_ENUM (RegionCommand, Length);
REGISTER_CLASS_ENUM (RegionCommand, Start);
REGISTER_CLASS_ENUM (RegionCommand, Position);
REGISTER_CLASS_ENUM (RegionCommand, PositionOnTop);
REGISTER_CLASS_ENUM (RegionCommand, Layer);
REGISTER_CLASS_ENUM (RegionCommand, SyncPosition);
REGISTER_CLASS_ENUM (RegionCommand, Hidden);
REGISTER_CLASS_ENUM (RegionCommand, Muted);
REGISTER_CLASS_ENUM (RegionCommand, Opaque);
REGISTER_CLASS_ENUM (RegionCommand, Locked);
REGISTER_CLASS_ENUM (RegionCommand, PositionLocked);
REGISTER_CLASS_ENUM (RegionCommand, ScaleAmplitude);
REGISTER_CLASS_ENUM (RegionCommand, FadeInActive);
REGISTER_CLASS_ENUM (RegionCommand, FadeInShape);
REGISTER_CLASS_ENUM (RegionCommand, FadeInLength);
REGISTER_CLASS_ENUM (RegionCommand, FadeIn);
REGISTER_CLASS_ENUM (RegionCommand, FadeOutActive);
REGISTER_CLASS_ENUM (RegionCommand, FadeOutShape);
REGISTER_CLASS_ENUM (RegionCommand, FadeOutLength);
REGISTER_CLASS_ENUM (RegionCommand, FadeOut);
REGISTER_CLASS_ENUM (RegionCommand, EnvelopActive);
REGISTER_CLASS_ENUM (RegionCommand, DefaultEnvelope);
REGISTER(_RegionCommandProperty);
}
} /* namespace ARDOUR */

View file

@ -120,9 +120,15 @@ Filter::finish (boost::shared_ptr<Region> region, SourceList& nsrcs, string regi
}
results.clear ();
boost::shared_ptr<Region> r = RegionFactory::create (nsrcs, 0, region->length(), region_name, 0,
Region::Flag (Region::WholeFile|Region::DefaultFlags));
r->set_position (region->position(), 0);
PropertyList plist;
plist.add (Properties::start, 0);
plist.add (Properties::length, region->length());
plist.add (Properties::name, region_name);
plist.add (Properties::whole_file, true);
plist.add (Properties::position, region->position());
boost::shared_ptr<Region> r = RegionFactory::create (nsrcs, plist);
boost::shared_ptr<AudioRegion> audio_region = boost::dynamic_pointer_cast<AudioRegion> (region);
boost::shared_ptr<AudioRegion> audio_r = boost::dynamic_pointer_cast<AudioRegion> (r);

View file

@ -62,6 +62,7 @@
#include "ardour/ardour.h"
#include "ardour/audio_library.h"
#include "ardour/audioengine.h"
#include "ardour/audioregion.h"
#include "ardour/audiosource.h"
#include "ardour/control_protocol_manager.h"
#include "ardour/debug.h"
@ -69,7 +70,9 @@
#include "ardour/mix.h"
#include "ardour/plugin_manager.h"
#include "ardour/profile.h"
#include "ardour/region.h"
#include "ardour/rc_configuration.h"
#include "ardour/route_group.h"
#include "ardour/runtime_functions.h"
#include "ardour/session.h"
#include "ardour/session_event.h"
@ -99,12 +102,11 @@ MIDI::Port *ARDOUR::default_mtc_port = 0;
MIDI::Port *ARDOUR::default_midi_port = 0;
MIDI::Port *ARDOUR::default_midi_clock_port = 0;
PBD::Change ARDOUR::StartChanged = PBD::new_change ();
PBD::Change ARDOUR::LengthChanged = PBD::new_change ();
PBD::Change ARDOUR::PositionChanged = PBD::new_change ();
PBD::Change ARDOUR::NameChanged = PBD::new_change ();
PBD::Change ARDOUR::BoundsChanged = Change (0); // see init(), below
PBD::Change ARDOUR::FlagsChanged = PBD::new_change ();
PropertyChange ARDOUR::StartChanged = PBD::new_change ();
PropertyChange ARDOUR::LengthChanged = PBD::new_change ();
PropertyChange ARDOUR::PositionChanged = PBD::new_change ();
PropertyChange ARDOUR::NameChanged = PBD::new_change ();
PropertyChange ARDOUR::BoundsChanged = PropertyChange (0); // see init(), below
compute_peak_t ARDOUR::compute_peak = 0;
find_peaks_t ARDOUR::find_peaks = 0;
@ -301,6 +303,10 @@ ARDOUR::init (bool use_vst, bool try_optimization)
PBD::ID::init ();
SessionEvent::init_event_pool ();
SessionObject::make_property_quarks ();
Region::make_property_quarks ();
AudioRegion::make_property_quarks ();
RouteGroup::make_property_quarks ();
/* provide a state version for the few cases that need it and are not
driven by reading state from disk (e.g. undo/redo)
@ -361,7 +367,7 @@ ARDOUR::init (bool use_vst, bool try_optimization)
/* singleton - first object is "it" */
new PluginManager ();
BoundsChanged = Change (StartChanged|PositionChanged|LengthChanged);
BoundsChanged = PropertyChange (StartChanged|PositionChanged|LengthChanged);
return 0;
}

View file

@ -373,7 +373,7 @@ trace_midi (ostream& o, MIDI::byte *msg, size_t len)
o << trace_prefix
<< "Channel "
<< (msg[0]&0xF)+1
<< " Program Change ProgNum "
<< " Program PropertyChange ProgNum "
<< (int) msg[1]
<< endl;
break;
@ -985,9 +985,16 @@ MidiDiskstream::transport_stopped (struct tm& /*when*/, time_t /*twhen*/, bool a
*/
try {
boost::shared_ptr<Region> rx (RegionFactory::create (srcs, 0,
total_capture, whole_file_region_name, 0,
Region::Flag (Region::DefaultFlags|Region::Automatic|Region::WholeFile)));
PropertyList plist;
plist.add (Properties::name, whole_file_region_name);
plist.add (Properties::whole_file, true);
plist.add (Properties::automatic, true);
plist.add (Properties::start, 0);
plist.add (Properties::length, total_capture);
plist.add (Properties::layer, 0);
boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
region = boost::dynamic_pointer_cast<MidiRegion> (rx);
region->special_set_position (capture_info.front()->start);
@ -1015,7 +1022,13 @@ MidiDiskstream::transport_stopped (struct tm& /*when*/, time_t /*twhen*/, bool a
// cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
try {
boost::shared_ptr<Region> rx (RegionFactory::create (srcs, buffer_position, (*ci)->frames, region_name));
PropertyList plist;
plist.add (Properties::start, buffer_position);
plist.add (Properties::length, (*ci)->frames);
plist.add (Properties::name, region_name);
boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
region = boost::dynamic_pointer_cast<MidiRegion> (rx);
}

View file

@ -415,7 +415,7 @@ MidiPlaylist::contained_automation()
bool
MidiPlaylist::region_changed (PBD::Change what_changed, boost::shared_ptr<Region> region)
MidiPlaylist::region_changed (PBD::PropertyChange what_changed, boost::shared_ptr<Region> region)
{
if (in_flush || in_set_state) {
return false;
@ -423,7 +423,7 @@ MidiPlaylist::region_changed (PBD::Change what_changed, boost::shared_ptr<Region
// Feeling rather uninterested today, but thanks for the heads up anyway!
PBD::Change our_interests = PBD::Change (/*MidiRegion::FadeInChanged|
PBD::PropertyChange our_interests = PBD::PropertyChange (/*MidiRegion::FadeInChanged|
MidiRegion::FadeOutChanged|
MidiRegion::FadeInActiveChanged|
MidiRegion::FadeOutActiveChanged|

View file

@ -48,24 +48,16 @@ using namespace ARDOUR;
using namespace PBD;
/** Basic MidiRegion constructor (one channel) */
MidiRegion::MidiRegion (boost::shared_ptr<MidiSource> src, nframes_t start, nframes_t length)
: Region (src, start, length, PBD::basename_nosuffix(src->name()), DataType::MIDI, 0, Region::Flag(Region::DefaultFlags|Region::External))
{
assert(_name.val().find("/") == string::npos);
midi_source(0)->Switched.connect_same_thread (*this, boost::bind (&MidiRegion::switch_source, this, _1));
}
/* Basic MidiRegion constructor (one channel) */
MidiRegion::MidiRegion (boost::shared_ptr<MidiSource> src, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags)
: Region (src, start, length, name, DataType::MIDI, layer, flags)
MidiRegion::MidiRegion (boost::shared_ptr<MidiSource> src)
: Region (src)
{
assert(_name.val().find("/") == string::npos);
midi_source(0)->Switched.connect_same_thread (*this, boost::bind (&MidiRegion::switch_source, this, _1));
}
/* Basic MidiRegion constructor (many channels) */
MidiRegion::MidiRegion (const SourceList& srcs, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags)
: Region (srcs, start, length, name, DataType::MIDI, layer, flags)
MidiRegion::MidiRegion (const SourceList& srcs)
: Region (srcs)
{
assert(_name.val().find("/") == string::npos);
midi_source(0)->Switched.connect_same_thread (*this, boost::bind (&MidiRegion::switch_source, this, _1));
@ -73,15 +65,8 @@ MidiRegion::MidiRegion (const SourceList& srcs, nframes_t start, nframes_t lengt
/** Create a new MidiRegion, that is part of an existing one */
MidiRegion::MidiRegion (boost::shared_ptr<const MidiRegion> other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags)
: Region (other, offset, length, name, layer, flags)
{
assert(_name.val().find("/") == string::npos);
midi_source(0)->Switched.connect_same_thread (*this, boost::bind (&MidiRegion::switch_source, this, _1));
}
MidiRegion::MidiRegion (boost::shared_ptr<const MidiRegion> other)
: Region (other)
MidiRegion::MidiRegion (boost::shared_ptr<const MidiRegion> other, frameoffset_t offset, bool offset_relative)
: Region (other, offset, offset_relative)
{
assert(_name.val().find("/") == string::npos);
midi_source(0)->Switched.connect_same_thread (*this, boost::bind (&MidiRegion::switch_source, this, _1));
@ -116,7 +101,7 @@ MidiRegion::~MidiRegion ()
}
void
MidiRegion::set_position_internal (nframes_t pos, bool allow_bbt_recompute)
MidiRegion::set_position_internal (framepos_t pos, bool allow_bbt_recompute)
{
BeatsFramesConverter old_converter(_session.tempo_map(), _position - _start);
double length_beats = old_converter.from(_length);
@ -128,25 +113,25 @@ MidiRegion::set_position_internal (nframes_t pos, bool allow_bbt_recompute)
set_length(new_converter.to(length_beats), 0);
}
nframes_t
MidiRegion::read_at (Evoral::EventSink<nframes_t>& out, sframes_t position, nframes_t dur, uint32_t chan_n, NoteMode mode, MidiStateTracker* tracker) const
framecnt_t
MidiRegion::read_at (Evoral::EventSink<nframes_t>& out, framepos_t position, framecnt_t dur, uint32_t chan_n, NoteMode mode, MidiStateTracker* tracker) const
{
return _read_at (_sources, out, position, dur, chan_n, mode, tracker);
}
nframes_t
MidiRegion::master_read_at (MidiRingBuffer<nframes_t>& out, sframes_t position, nframes_t dur, uint32_t chan_n, NoteMode mode) const
framecnt_t
MidiRegion::master_read_at (MidiRingBuffer<nframes_t>& out, framepos_t position, framecnt_t dur, uint32_t chan_n, NoteMode mode) const
{
return _read_at (_master_sources, out, position, dur, chan_n, mode); /* no tracker */
}
nframes_t
MidiRegion::_read_at (const SourceList& /*srcs*/, Evoral::EventSink<nframes_t>& dst, sframes_t position, nframes_t dur, uint32_t chan_n,
framecnt_t
MidiRegion::_read_at (const SourceList& /*srcs*/, Evoral::EventSink<nframes_t>& dst, framepos_t position, framecnt_t dur, uint32_t chan_n,
NoteMode mode, MidiStateTracker* tracker) const
{
nframes_t internal_offset = 0;
nframes_t src_offset = 0;
nframes_t to_read = 0;
frameoffset_t internal_offset = 0;
frameoffset_t src_offset = 0;
framecnt_t to_read = 0;
/* precondition: caller has verified that we cover the desired section */
@ -178,8 +163,8 @@ MidiRegion::_read_at (const SourceList& /*srcs*/, Evoral::EventSink<nframes_t>&
boost::shared_ptr<MidiSource> src = midi_source(chan_n);
src->set_note_mode(mode);
nframes_t output_buffer_position = 0;
nframes_t negative_output_buffer_position = 0;
framepos_t output_buffer_position = 0;
framepos_t negative_output_buffer_position = 0;
if (_position >= _start) {
// handle resizing of beginnings of regions correctly
output_buffer_position = _position - _start;
@ -243,50 +228,9 @@ MidiRegion::state (bool full)
return node;
}
int
MidiRegion::set_live_state (const XMLNode& node, int version, Change& what_changed, bool send)
{
const XMLProperty *prop;
LocaleGuard lg (X_("POSIX"));
Region::set_live_state (node, version, what_changed, false);
uint32_t old_flags = _flags;
if ((prop = node.property ("flags")) != 0) {
_flags = Flag (string_2_enum (prop->value(), _flags));
//_flags = Flag (strtol (prop->value().c_str(), (char **) 0, 16));
_flags = Flag (_flags & ~Region::LeftOfSplit);
_flags = Flag (_flags & ~Region::RightOfSplit);
}
if ((old_flags ^ _flags) & Muted) {
what_changed = Change (what_changed|MuteChanged);
}
if ((old_flags ^ _flags) & Opaque) {
what_changed = Change (what_changed|OpacityChanged);
}
if ((old_flags ^ _flags) & Locked) {
what_changed = Change (what_changed|LockChanged);
}
if (send) {
send_change (what_changed);
}
return 0;
}
int
MidiRegion::set_state (const XMLNode& node, int version)
{
/* Region::set_state() calls the virtual set_live_state(),
which will get us back to AudioRegion::set_live_state()
to handle the relevant stuff.
*/
return Region::set_state (node, version);
}

View file

@ -148,14 +148,14 @@ Playlist::Playlist (boost::shared_ptr<const Playlist> other, string namestr, boo
freeze_length = other->freeze_length;
}
Playlist::Playlist (boost::shared_ptr<const Playlist> other, nframes_t start, nframes_t cnt, string str, bool hide)
Playlist::Playlist (boost::shared_ptr<const Playlist> other, framepos_t start, framecnt_t cnt, string str, bool hide)
: SessionObject(other->_session, str)
, _type(other->_type)
, _orig_diskstream_id(other->_orig_diskstream_id)
{
RegionLock rlock2 (const_cast<Playlist*> (other.get()));
nframes_t end = start + cnt - 1;
framepos_t end = start + cnt - 1;
init (hide);
@ -165,9 +165,9 @@ Playlist::Playlist (boost::shared_ptr<const Playlist> other, nframes_t start, nf
boost::shared_ptr<Region> region;
boost::shared_ptr<Region> new_region;
nframes_t offset = 0;
nframes_t position = 0;
nframes_t len = 0;
frameoffset_t offset = 0;
framepos_t position = 0;
framecnt_t len = 0;
string new_name;
OverlapType overlap;
@ -206,7 +206,14 @@ Playlist::Playlist (boost::shared_ptr<const Playlist> other, nframes_t start, nf
_session.region_name (new_name, region->name(), false);
new_region = RegionFactory::RegionFactory::create (region, offset, len, new_name, region->layer(), region->flags());
PropertyList plist;
plist.add (Properties::start, offset);
plist.add (Properties::length, len);
plist.add (Properties::name, new_name);
plist.add (Properties::layer, region->layer());
new_region = RegionFactory::RegionFactory::create (region, plist);
add_region_internal (new_region, position);
}
@ -391,7 +398,7 @@ Playlist::notify_region_removed (boost::shared_ptr<Region> r)
void
Playlist::notify_region_moved (boost::shared_ptr<Region> r)
{
Evoral::RangeMove<nframes_t> const move (r->last_position (), r->length (), r->position ());
Evoral::RangeMove<framepos_t> const move (r->last_position (), r->length (), r->position ());
if (holding_state ()) {
@ -399,7 +406,7 @@ Playlist::notify_region_moved (boost::shared_ptr<Region> r)
} else {
list< Evoral::RangeMove<nframes_t> > m;
list< Evoral::RangeMove<framepos_t> > m;
m.push_back (move);
RangesMoved (m);
}
@ -450,7 +457,7 @@ Playlist::flush_notifications ()
set<boost::shared_ptr<Region> >::iterator s;
uint32_t regions_changed = false;
bool check_length = false;
nframes64_t old_length = 0;
framecnt_t old_length = 0;
if (in_flush) {
return;
@ -547,17 +554,17 @@ Playlist::clear_pending ()
*************************************************************/
void
Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, float times, bool auto_partition)
Playlist::add_region (boost::shared_ptr<Region> region, framepos_t position, float times, bool auto_partition)
{
RegionLock rlock (this);
times = fabs (times);
int itimes = (int) floor (times);
nframes_t pos = position;
framepos_t pos = position;
if (times == 1 && auto_partition){
partition(pos, (nframes_t) (pos + region->length()), true);
partition(pos, (pos + region->length()), true);
}
if (itimes >= 1) {
@ -577,14 +584,24 @@ Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, floa
pos += region->length();
}
nframes_t length = 0;
framecnt_t length = 0;
if (floor (times) != times) {
length = (nframes_t) floor (region->length() * (times - floor (times)));
length = (framecnt_t) floor (region->length() * (times - floor (times)));
string name;
_session.region_name (name, region->name(), false);
boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags());
add_region_internal (sub, pos);
{
PropertyList plist;
plist.add (Properties::start, 0);
plist.add (Properties::length, length);
plist.add (Properties::name, name);
plist.add (Properties::layer, region->layer());
boost::shared_ptr<Region> sub = RegionFactory::create (region, plist);
add_region_internal (sub, pos);
}
}
possibly_splice_unlocked (position, (pos + length) - position, boost::shared_ptr<Region>());
@ -603,7 +620,7 @@ Playlist::set_region_ownership ()
}
bool
Playlist::add_region_internal (boost::shared_ptr<Region> region, nframes_t position)
Playlist::add_region_internal (boost::shared_ptr<Region> region, framepos_t position)
{
if (region->data_type() != _type){
return false;
@ -611,7 +628,7 @@ Playlist::add_region_internal (boost::shared_ptr<Region> region, nframes_t posit
RegionSortByPosition cmp;
nframes_t old_length = 0;
framecnt_t old_length = 0;
if (!holding_state()) {
old_length = _get_maximum_extent();
@ -655,7 +672,7 @@ Playlist::add_region_internal (boost::shared_ptr<Region> region, nframes_t posit
}
void
Playlist::replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Region> newr, nframes_t pos)
Playlist::replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Region> newr, framepos_t pos)
{
RegionLock rlock (this);
@ -667,7 +684,7 @@ Playlist::replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Regio
_splicing = old_sp;
possibly_splice_unlocked (pos, (nframes64_t) old->length() - (nframes64_t) newr->length());
possibly_splice_unlocked (pos, old->length() - newr->length());
}
void
@ -681,7 +698,7 @@ int
Playlist::remove_region_internal (boost::shared_ptr<Region> region)
{
RegionList::iterator i;
nframes_t old_length = 0;
framecnt_t old_length = 0;
int ret = -1;
if (!holding_state()) {
@ -698,8 +715,8 @@ Playlist::remove_region_internal (boost::shared_ptr<Region> region)
for (i = regions.begin(); i != regions.end(); ++i) {
if (*i == region) {
nframes_t pos = (*i)->position();
nframes64_t distance = (*i)->length();
framepos_t pos = (*i)->position();
framecnt_t distance = (*i)->length();
regions.erase (i);
@ -755,7 +772,7 @@ Playlist::get_region_list_equivalent_regions (boost::shared_ptr<Region> other, v
}
void
Playlist::partition (nframes_t start, nframes_t end, bool cut)
Playlist::partition (framepos_t start, framepos_t end, bool cut)
{
RegionList thawlist;
@ -767,7 +784,7 @@ Playlist::partition (nframes_t start, nframes_t end, bool cut)
}
void
Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, RegionList& thawlist)
Playlist::partition_internal (framepos_t start, framepos_t end, bool cutting, RegionList& thawlist)
{
RegionList new_regions;
@ -779,7 +796,7 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
string new_name;
RegionList::iterator tmp;
OverlapType overlap;
nframes_t pos1, pos2, pos3, pos4;
framepos_t pos1, pos2, pos3, pos4;
in_partition = true;
@ -843,8 +860,18 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
/* "middle" ++++++ */
_session.region_name (new_name, current->name(), false);
region = RegionFactory::create (current, pos2 - pos1, pos3 - pos2, new_name,
regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit|Region::RightOfSplit));
PropertyList plist;
plist.add (Properties::start, pos2 - pos1);
plist.add (Properties::length, pos3 - pos2);
plist.add (Properties::name, new_name);
plist.add (Properties::layer, regions.size());
plist.add (Properties::automatic, true);
plist.add (Properties::left_of_split, true);
plist.add (Properties::right_of_split, true);
region = RegionFactory::create (current, plist);
add_region_internal (region, start);
new_regions.push_back (region);
}
@ -852,8 +879,17 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
/* "end" ====== */
_session.region_name (new_name, current->name(), false);
region = RegionFactory::create (current, pos3 - pos1, pos4 - pos3, new_name,
regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit));
PropertyList plist;
plist.add (Properties::start, pos3 - pos1);
plist.add (Properties::length, pos4 - pos3);
plist.add (Properties::name, new_name);
plist.add (Properties::layer, regions.size());
plist.add (Properties::automatic, true);
plist.add (Properties::right_of_split, true);
region = RegionFactory::create (current, plist);
add_region_internal (region, end);
new_regions.push_back (region);
@ -881,8 +917,17 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
/* end +++++ */
_session.region_name (new_name, current->name(), false);
region = RegionFactory::create (current, pos2 - pos1, pos4 - pos2, new_name, (layer_t) regions.size(),
Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit));
PropertyList plist;
plist.add (Properties::start, pos2 - pos1);
plist.add (Properties::length, pos4 - pos2);
plist.add (Properties::name, new_name);
plist.add (Properties::layer, regions.size());
plist.add (Properties::automatic, true);
plist.add (Properties::left_of_split, true);
region = RegionFactory::create (current, plist);
add_region_internal (region, start);
new_regions.push_back (region);
@ -915,8 +960,17 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
if (!cutting) {
/* front **** */
_session.region_name (new_name, current->name(), false);
region = RegionFactory::create (current, 0, pos3 - pos1, new_name,
regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit));
PropertyList plist;
plist.add (Properties::start, 0);
plist.add (Properties::length, pos3 - pos1);
plist.add (Properties::name, new_name);
plist.add (Properties::layer, regions.size());
plist.add (Properties::automatic, true);
plist.add (Properties::right_of_split, true);
region = RegionFactory::create (current, plist);
add_region_internal (region, pos1);
new_regions.push_back (region);
@ -962,11 +1016,11 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
}
boost::shared_ptr<Playlist>
Playlist::cut_copy (boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t, nframes_t,bool), list<AudioRange>& ranges, bool result_is_hidden)
Playlist::cut_copy (boost::shared_ptr<Playlist> (Playlist::*pmf)(framepos_t, framecnt_t,bool), list<AudioRange>& ranges, bool result_is_hidden)
{
boost::shared_ptr<Playlist> ret;
boost::shared_ptr<Playlist> pl;
nframes_t start;
framepos_t start;
if (ranges.empty()) {
return boost::shared_ptr<Playlist>();
@ -997,19 +1051,19 @@ Playlist::cut_copy (boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t, nfra
boost::shared_ptr<Playlist>
Playlist::cut (list<AudioRange>& ranges, bool result_is_hidden)
{
boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t,nframes_t,bool) = &Playlist::cut;
boost::shared_ptr<Playlist> (Playlist::*pmf)(framepos_t,framecnt_t,bool) = &Playlist::cut;
return cut_copy (pmf, ranges, result_is_hidden);
}
boost::shared_ptr<Playlist>
Playlist::copy (list<AudioRange>& ranges, bool result_is_hidden)
{
boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t,nframes_t,bool) = &Playlist::copy;
boost::shared_ptr<Playlist> (Playlist::*pmf)(framepos_t,framecnt_t,bool) = &Playlist::copy;
return cut_copy (pmf, ranges, result_is_hidden);
}
boost::shared_ptr<Playlist>
Playlist::cut (nframes_t start, nframes_t cnt, bool result_is_hidden)
Playlist::cut (framepos_t start, framecnt_t cnt, bool result_is_hidden)
{
boost::shared_ptr<Playlist> the_copy;
RegionList thawlist;
@ -1034,7 +1088,7 @@ Playlist::cut (nframes_t start, nframes_t cnt, bool result_is_hidden)
}
boost::shared_ptr<Playlist>
Playlist::copy (nframes_t start, nframes_t cnt, bool result_is_hidden)
Playlist::copy (framepos_t start, framecnt_t cnt, bool result_is_hidden)
{
char buf[32];
@ -1048,10 +1102,10 @@ Playlist::copy (nframes_t start, nframes_t cnt, bool result_is_hidden)
}
int
Playlist::paste (boost::shared_ptr<Playlist> other, nframes_t position, float times)
Playlist::paste (boost::shared_ptr<Playlist> other, framepos_t position, float times)
{
times = fabs (times);
nframes_t old_length;
framecnt_t old_length;
{
RegionLock rl1 (this);
@ -1060,8 +1114,8 @@ Playlist::paste (boost::shared_ptr<Playlist> other, nframes_t position, float ti
old_length = _get_maximum_extent();
int itimes = (int) floor (times);
nframes_t pos = position;
nframes_t shift = other->_get_maximum_extent();
framepos_t pos = position;
framecnt_t shift = other->_get_maximum_extent();
layer_t top_layer = regions.size();
while (itimes--) {
@ -1093,13 +1147,13 @@ Playlist::paste (boost::shared_ptr<Playlist> other, nframes_t position, float ti
void
Playlist::duplicate (boost::shared_ptr<Region> region, nframes_t position, float times)
Playlist::duplicate (boost::shared_ptr<Region> region, framepos_t position, float times)
{
times = fabs (times);
RegionLock rl (this);
int itimes = (int) floor (times);
nframes_t pos = position;
framepos_t pos = position;
while (itimes--) {
boost::shared_ptr<Region> copy = RegionFactory::create (region);
@ -1108,16 +1162,25 @@ Playlist::duplicate (boost::shared_ptr<Region> region, nframes_t position, float
}
if (floor (times) != times) {
nframes_t length = (nframes_t) floor (region->length() * (times - floor (times)));
framecnt_t length = (framecnt_t) floor (region->length() * (times - floor (times)));
string name;
_session.region_name (name, region->name(), false);
boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags());
add_region_internal (sub, pos);
{
PropertyList plist;
plist.add (Properties::start, 0);
plist.add (Properties::length, length);
plist.add (Properties::name, name);
boost::shared_ptr<Region> sub = RegionFactory::create (region, plist);
add_region_internal (sub, pos);
}
}
}
void
Playlist::shift (nframes64_t at, nframes64_t distance, bool move_intersected, bool ignore_music_glue)
Playlist::shift (framepos_t at, frameoffset_t distance, bool move_intersected, bool ignore_music_glue)
{
RegionLock rlock (this);
RegionList copy (regions);
@ -1155,7 +1218,7 @@ Playlist::shift (nframes64_t at, nframes64_t distance, bool move_intersected, bo
}
void
Playlist::split (nframes64_t at)
Playlist::split (framepos_t at)
{
RegionLock rlock (this);
RegionList copy (regions);
@ -1169,14 +1232,14 @@ Playlist::split (nframes64_t at)
}
void
Playlist::split_region (boost::shared_ptr<Region> region, nframes_t playlist_position)
Playlist::split_region (boost::shared_ptr<Region> region, framepos_t playlist_position)
{
RegionLock rl (this);
_split_region (region, playlist_position);
}
void
Playlist::_split_region (boost::shared_ptr<Region> region, nframes_t playlist_position)
Playlist::_split_region (boost::shared_ptr<Region> region, framepos_t playlist_position)
{
if (!region->covers (playlist_position)) {
return;
@ -1189,8 +1252,8 @@ Playlist::_split_region (boost::shared_ptr<Region> region, nframes_t playlist_po
boost::shared_ptr<Region> left;
boost::shared_ptr<Region> right;
nframes_t before;
nframes_t after;
frameoffset_t before;
frameoffset_t after;
string before_name;
string after_name;
@ -1203,10 +1266,30 @@ Playlist::_split_region (boost::shared_ptr<Region> region, nframes_t playlist_po
after = region->length() - before;
_session.region_name (before_name, region->name(), false);
left = RegionFactory::create (region, 0, before, before_name, region->layer(), Region::Flag (region->flags()|Region::LeftOfSplit));
{
PropertyList plist;
plist.add (Properties::start, 0);
plist.add (Properties::length, before);
plist.add (Properties::name, before_name);
plist.add (Properties::left_of_split, true);
left = RegionFactory::create (region, plist);
}
_session.region_name (after_name, region->name(), false);
right = RegionFactory::create (region, before, after, after_name, region->layer(), Region::Flag (region->flags()|Region::RightOfSplit));
{
PropertyList plist;
plist.add (Properties::start, before);
plist.add (Properties::length, after);
plist.add (Properties::name, after_name);
plist.add (Properties::right_of_split, true);
right = RegionFactory::create (region, plist);
}
add_region_internal (left, region->position());
add_region_internal (right, region->position() + before);
@ -1231,7 +1314,7 @@ Playlist::_split_region (boost::shared_ptr<Region> region, nframes_t playlist_po
}
void
Playlist::possibly_splice (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude)
Playlist::possibly_splice (framepos_t at, framecnt_t distance, boost::shared_ptr<Region> exclude)
{
if (_splicing || in_set_state) {
/* don't respond to splicing moves or state setting */
@ -1244,7 +1327,7 @@ Playlist::possibly_splice (nframes_t at, nframes64_t distance, boost::shared_ptr
}
void
Playlist::possibly_splice_unlocked (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude)
Playlist::possibly_splice_unlocked (framepos_t at, framecnt_t distance, boost::shared_ptr<Region> exclude)
{
if (_splicing || in_set_state) {
/* don't respond to splicing moves or state setting */
@ -1257,7 +1340,7 @@ Playlist::possibly_splice_unlocked (nframes_t at, nframes64_t distance, boost::s
}
void
Playlist::splice_locked (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude)
Playlist::splice_locked (framepos_t at, framecnt_t distance, boost::shared_ptr<Region> exclude)
{
{
RegionLock rl (this);
@ -1266,13 +1349,13 @@ Playlist::splice_locked (nframes_t at, nframes64_t distance, boost::shared_ptr<R
}
void
Playlist::splice_unlocked (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude)
Playlist::splice_unlocked (framepos_t at, framecnt_t distance, boost::shared_ptr<Region> exclude)
{
core_splice (at, distance, exclude);
}
void
Playlist::core_splice (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude)
Playlist::core_splice (framepos_t at, framecnt_t distance, boost::shared_ptr<Region> exclude)
{
_splicing = true;
@ -1283,7 +1366,7 @@ Playlist::core_splice (nframes_t at, nframes64_t distance, boost::shared_ptr<Reg
}
if ((*i)->position() >= at) {
nframes64_t new_pos = (*i)->position() + distance;
framepos_t new_pos = (*i)->position() + distance;
if (new_pos < 0) {
new_pos = 0;
} else if (new_pos >= max_frames - (*i)->length()) {
@ -1300,7 +1383,7 @@ Playlist::core_splice (nframes_t at, nframes64_t distance, boost::shared_ptr<Reg
}
void
Playlist::region_bounds_changed (Change what_changed, boost::shared_ptr<Region> region)
Playlist::region_bounds_changed (PropertyChange what_changed, boost::shared_ptr<Region> region)
{
if (in_set_state || _splicing || _nudging || _shuffling) {
return;
@ -1327,16 +1410,16 @@ Playlist::region_bounds_changed (Change what_changed, boost::shared_ptr<Region>
regions.insert (upper_bound (regions.begin(), regions.end(), region, cmp), region);
}
if (what_changed & Change (ARDOUR::PositionChanged|ARDOUR::LengthChanged)) {
if (what_changed & PropertyChange (ARDOUR::PositionChanged|ARDOUR::LengthChanged)) {
nframes64_t delta = 0;
frameoffset_t delta = 0;
if (what_changed & ARDOUR::PositionChanged) {
delta = (nframes64_t) region->position() - (nframes64_t) region->last_position();
delta = region->position() - region->last_position();
}
if (what_changed & ARDOUR::LengthChanged) {
delta += (nframes64_t) region->length() - (nframes64_t) region->last_length();
delta += region->length() - region->last_length();
}
if (delta) {
@ -1359,7 +1442,7 @@ Playlist::region_bounds_changed (Change what_changed, boost::shared_ptr<Region>
}
void
Playlist::region_changed_proxy (Change what_changed, boost::weak_ptr<Region> weak_region)
Playlist::region_changed_proxy (PropertyChange what_changed, boost::weak_ptr<Region> weak_region)
{
boost::shared_ptr<Region> region (weak_region.lock());
@ -1373,9 +1456,9 @@ Playlist::region_changed_proxy (Change what_changed, boost::weak_ptr<Region> wea
}
bool
Playlist::region_changed (Change what_changed, boost::shared_ptr<Region> region)
Playlist::region_changed (PropertyChange what_changed, boost::shared_ptr<Region> region)
{
Change our_interests = Change (Region::MuteChanged|Region::LayerChanged|Region::OpacityChanged);
PropertyChange our_interests = PropertyChange (Region::MuteChanged|Region::LayerChanged|Region::OpacityChanged);
bool save = false;
if (in_set_state || in_flush) {
@ -1388,11 +1471,11 @@ Playlist::region_changed (Change what_changed, boost::shared_ptr<Region> region)
}
if ((what_changed & our_interests) &&
!(what_changed & Change (ARDOUR::PositionChanged|ARDOUR::LengthChanged))) {
!(what_changed & PropertyChange (ARDOUR::PositionChanged|ARDOUR::LengthChanged))) {
check_dependents (region, false);
}
if (what_changed & Change (ARDOUR::PositionChanged)) {
if (what_changed & PropertyChange (ARDOUR::PositionChanged)) {
notify_region_moved (region);
}
@ -1447,7 +1530,7 @@ Playlist::clear (bool with_signals)
**********************************************************************/
Playlist::RegionList *
Playlist::regions_at (nframes_t frame)
Playlist::regions_at (framepos_t frame)
{
RegionLock rlock (this);
@ -1455,7 +1538,7 @@ Playlist::regions_at (nframes_t frame)
}
boost::shared_ptr<Region>
Playlist::top_region_at (nframes_t frame)
Playlist::top_region_at (framepos_t frame)
{
RegionLock rlock (this);
@ -1473,7 +1556,7 @@ Playlist::top_region_at (nframes_t frame)
}
boost::shared_ptr<Region>
Playlist::top_unmuted_region_at (nframes_t frame)
Playlist::top_unmuted_region_at (framepos_t frame)
{
RegionLock rlock (this);
@ -1504,12 +1587,12 @@ Playlist::top_unmuted_region_at (nframes_t frame)
}
Playlist::RegionList*
Playlist::regions_to_read (nframes_t start, nframes_t end)
Playlist::regions_to_read (framepos_t start, framepos_t end)
{
/* Caller must hold lock */
RegionList covering;
set<nframes_t> to_check;
set<framepos_t> to_check;
set<boost::shared_ptr<Region> > unique;
RegionList here;
@ -1562,7 +1645,7 @@ Playlist::regions_to_read (nframes_t start, nframes_t end)
} else {
for (set<nframes_t>::iterator t = to_check.begin(); t != to_check.end(); ++t) {
for (set<framepos_t>::iterator t = to_check.begin(); t != to_check.end(); ++t) {
here.clear ();
@ -1607,7 +1690,7 @@ Playlist::regions_to_read (nframes_t start, nframes_t end)
}
Playlist::RegionList *
Playlist::find_regions_at (nframes_t frame)
Playlist::find_regions_at (framepos_t frame)
{
/* Caller must hold lock */
@ -1623,7 +1706,7 @@ Playlist::find_regions_at (nframes_t frame)
}
Playlist::RegionList *
Playlist::regions_touched (nframes_t start, nframes_t end)
Playlist::regions_touched (framepos_t start, framepos_t end)
{
RegionLock rlock (this);
RegionList *rlist = new RegionList;
@ -1637,8 +1720,8 @@ Playlist::regions_touched (nframes_t start, nframes_t end)
return rlist;
}
nframes64_t
Playlist::find_next_transient (nframes64_t from, int dir)
framepos_t
Playlist::find_next_transient (framepos_t from, int dir)
{
RegionLock rlock (this);
AnalysisFeatureList points;
@ -1698,11 +1781,11 @@ Playlist::find_next_transient (nframes64_t from, int dir)
}
boost::shared_ptr<Region>
Playlist::find_next_region (nframes_t frame, RegionPoint point, int dir)
Playlist::find_next_region (framepos_t frame, RegionPoint point, int dir)
{
RegionLock rlock (this);
boost::shared_ptr<Region> ret;
nframes_t closest = max_frames;
framepos_t closest = max_frames;
bool end_iter = false;
@ -1710,9 +1793,9 @@ Playlist::find_next_region (nframes_t frame, RegionPoint point, int dir)
if(end_iter) break;
nframes_t distance;
frameoffset_t distance;
boost::shared_ptr<Region> r = (*i);
nframes_t pos = 0;
framepos_t pos = 0;
switch (point) {
case Start:
@ -1759,20 +1842,20 @@ Playlist::find_next_region (nframes_t frame, RegionPoint point, int dir)
return ret;
}
nframes64_t
Playlist::find_next_region_boundary (nframes64_t frame, int dir)
framepos_t
Playlist::find_next_region_boundary (framepos_t frame, int dir)
{
RegionLock rlock (this);
nframes64_t closest = max_frames;
nframes64_t ret = -1;
framepos_t closest = max_frames;
framepos_t ret = -1;
if (dir > 0) {
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
boost::shared_ptr<Region> r = (*i);
nframes64_t distance;
frameoffset_t distance;
if (r->first_frame() > frame) {
@ -1800,7 +1883,7 @@ Playlist::find_next_region_boundary (nframes64_t frame, int dir)
for (RegionList::reverse_iterator i = regions.rbegin(); i != regions.rend(); ++i) {
boost::shared_ptr<Region> r = (*i);
nframes64_t distance;
frameoffset_t distance;
if (r->last_frame() < frame) {
@ -1895,15 +1978,13 @@ Playlist::set_state (const XMLNode& node, int version)
if ((region = region_by_id (id))) {
Change what_changed = Change (0);
region->freeze ();
if (region->set_live_state (*child, version, what_changed, false)) {
if (region->set_state (*child, version)) {
region->thaw ();
continue;
}
} else if ((region = RegionFactory::create (_session, *child, true)) != 0) {
region->freeze ();
} else {
@ -1991,19 +2072,19 @@ Playlist::n_regions() const
return regions.size();
}
nframes_t
framecnt_t
Playlist::get_maximum_extent () const
{
RegionLock rlock (const_cast<Playlist *>(this), false);
return _get_maximum_extent ();
}
ARDOUR::nframes_t
framecnt_t
Playlist::_get_maximum_extent () const
{
RegionList::const_iterator i;
nframes_t max_extent = 0;
nframes_t end = 0;
framecnt_t max_extent = 0;
framepos_t end = 0;
for (i = regions.begin(); i != regions.end(); ++i) {
if ((end = (*i)->position() + (*i)->length()) > max_extent) {
@ -2063,8 +2144,8 @@ Playlist::relayer ()
int const divisions = 512;
/* find the start and end positions of the regions on this playlist */
nframes_t start = UINT_MAX;
nframes_t end = 0;
framepos_t start = UINT_MAX;
framepos_t end = 0;
for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
start = min (start, (*i)->position());
end = max (end, (*i)->position() + (*i)->length());
@ -2286,10 +2367,10 @@ Playlist::move_region_to_layer (layer_t target_layer, boost::shared_ptr<Region>
}
void
Playlist::nudge_after (nframes_t start, nframes_t distance, bool forwards)
Playlist::nudge_after (framepos_t start, framecnt_t distance, bool forwards)
{
RegionList::iterator i;
nframes_t new_pos;
framepos_t new_pos;
bool moved = false;
_nudging = true;
@ -2400,7 +2481,7 @@ void
Playlist::shuffle (boost::shared_ptr<Region> region, int dir)
{
bool moved = false;
nframes_t new_pos;
framepos_t new_pos;
if (region->locked()) {
return;
@ -2570,7 +2651,7 @@ Playlist::set_explicit_relayering (bool e)
bool
Playlist::has_region_at (nframes64_t const p) const
Playlist::has_region_at (framepos_t const p) const
{
RegionLock (const_cast<Playlist *> (this));

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,6 @@
#include "pbd/enumwriter.h"
#include "ardour/region.h"
#include "ardour/region_command.h"
#include "ardour/utils.h"
#include "i18n.h"

View file

@ -37,83 +37,137 @@ using namespace PBD;
PBD::Signal1<void,boost::shared_ptr<Region> > RegionFactory::CheckNewRegion;
map<PBD::ID,boost::weak_ptr<Region> > RegionFactory::region_map;
boost::shared_ptr<Region>
RegionFactory::create (boost::shared_ptr<Region> region, nframes_t start,
nframes_t length, const std::string& name,
layer_t layer, Region::Flag flags, bool announce)
{
boost::shared_ptr<const AudioRegion> other_a;
boost::shared_ptr<const MidiRegion> other_m;
if ((other_a = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) {
AudioRegion* ar = new AudioRegion (other_a, start, length, name, layer, flags);
boost_debug_shared_ptr_mark_interesting (ar, "Region");
boost::shared_ptr<AudioRegion> arp (ar);
boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp));
ret->unlock_property_changes ();
map_add (ret);
if (announce) {
CheckNewRegion (ret);
}
return ret;
} else if ((other_m = boost::dynamic_pointer_cast<MidiRegion>(region)) != 0) {
MidiRegion* ar = new MidiRegion (other_m, start, length, name, layer, flags);
boost::shared_ptr<MidiRegion> arp (ar);
boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp));
ret->unlock_property_changes ();
map_add (ret);
if (announce) {
CheckNewRegion (ret);
}
return ret;
} else {
fatal << _("programming error: RegionFactory::create() called with unknown Region type")
<< endmsg;
/*NOTREACHED*/
return boost::shared_ptr<Region>();
}
}
boost::shared_ptr<Region>
RegionFactory::create (boost::shared_ptr<const Region> region)
{
boost::shared_ptr<Region> ret;
boost::shared_ptr<const AudioRegion> ar;
boost::shared_ptr<const MidiRegion> mr;
if ((ar = boost::dynamic_pointer_cast<const AudioRegion>(region)) != 0) {
AudioRegion* arn = new AudioRegion (ar);
AudioRegion* arn = new AudioRegion (ar, 0, true);
boost_debug_shared_ptr_mark_interesting (arn, "Region");
boost::shared_ptr<Region> ret (arn);
boost::shared_ptr<AudioRegion> arp (arn);
ret = boost::static_pointer_cast<Region> (arp);
} else if ((mr = boost::dynamic_pointer_cast<const MidiRegion>(region)) != 0) {
MidiRegion* mrn = new MidiRegion (mr, 0, true);
boost::shared_ptr<MidiRegion> mrp (mrn);
ret = boost::static_pointer_cast<Region> (mrp);
} else {
fatal << _("programming error: RegionFactory::create() called with unknown Region type")
<< endmsg;
/*NOTREACHED*/
}
if (ret) {
ret->unlock_property_changes ();
map_add (ret);
/* pure copy constructor - no property list */
/* pure copy constructor - no CheckNewRegion emitted */
return ret;
} else if ((mr = boost::dynamic_pointer_cast<const MidiRegion>(region)) != 0) {
boost::shared_ptr<Region> ret (new MidiRegion (mr));
ret->unlock_property_changes ();
/* pure copy constructor - no CheckNewRegion emitted */
return ret;
}
return ret;
}
boost::shared_ptr<Region>
RegionFactory::create (boost::shared_ptr<Region> region, frameoffset_t offset, const PropertyList& plist, bool announce)
{
boost::shared_ptr<Region> ret;
boost::shared_ptr<const AudioRegion> other_a;
boost::shared_ptr<const MidiRegion> other_m;
if ((other_a = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) {
AudioRegion* ar = new AudioRegion (other_a, offset, true);
boost_debug_shared_ptr_mark_interesting (ar, "Region");
boost::shared_ptr<AudioRegion> arp (ar);
ret = boost::static_pointer_cast<Region> (arp);
} else if ((other_m = boost::dynamic_pointer_cast<MidiRegion>(region)) != 0) {
MidiRegion* mr = new MidiRegion (other_m, offset, true);
boost::shared_ptr<MidiRegion> mrp (mr);
ret = boost::static_pointer_cast<Region> (mrp);
} else {
fatal << _("programming error: RegionFactory::create() called with unknown Region type")
<< endmsg;
/*NOTREACHED*/
return boost::shared_ptr<Region>();
}
if (ret) {
ret->set_properties (plist);
ret->unlock_property_changes ();
map_add (ret);
if (announce) {
CheckNewRegion (ret);
}
}
return ret;
}
boost::shared_ptr<Region>
RegionFactory::create (boost::shared_ptr<AudioRegion> region, nframes_t start,
nframes_t length, const std::string& name,
layer_t layer, Region::Flag flags, bool announce)
RegionFactory::create (boost::shared_ptr<Region> region, const PropertyList& plist, bool announce)
{
return create (boost::static_pointer_cast<Region> (region), start, length, name, layer, flags, announce);
boost::shared_ptr<Region> ret;
boost::shared_ptr<const AudioRegion> other_a;
boost::shared_ptr<const MidiRegion> other_m;
if ((other_a = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) {
AudioRegion* ar = new AudioRegion (other_a, 0, false);
boost_debug_shared_ptr_mark_interesting (ar, "Region");
boost::shared_ptr<AudioRegion> arp (ar);
ret = boost::static_pointer_cast<Region> (arp);
} else if ((other_m = boost::dynamic_pointer_cast<MidiRegion>(region)) != 0) {
MidiRegion* mr = new MidiRegion (other_m, 0, false);
boost::shared_ptr<MidiRegion> mrp (mr);
ret = boost::static_pointer_cast<Region> (mrp);
} else {
fatal << _("programming error: RegionFactory::create() called with unknown Region type")
<< endmsg;
/*NOTREACHED*/
return boost::shared_ptr<Region>();
}
if (ret) {
ret->set_properties (plist);
ret->unlock_property_changes ();
map_add (ret);
if (announce) {
CheckNewRegion (ret);
}
}
return ret;
}
boost::shared_ptr<Region>
RegionFactory::create (boost::shared_ptr<Region> region, const SourceList& srcs,
const std::string& name, layer_t layer, Region::Flag flags, bool announce)
boost::shared_ptr<Region>
RegionFactory::create (boost::shared_ptr<Region> region, const SourceList& srcs, const PropertyList& plist, bool announce)
{
boost::shared_ptr<Region> ret;
boost::shared_ptr<const AudioRegion> other;
/* used by AudioFilter when constructing a new region that is intended to have nearly
@ -121,22 +175,109 @@ RegionFactory::create (boost::shared_ptr<Region> region, const SourceList& srcs,
*/
if ((other = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) {
AudioRegion* ar = new AudioRegion (other, srcs, srcs.front()->length(srcs.front()->timeline_position()), name, layer, flags);
// XXX use me in caller where plist is setup, this is start i think srcs.front()->length (srcs.front()->timeline_position())
AudioRegion* ar = new AudioRegion (other, srcs);
boost_debug_shared_ptr_mark_interesting (ar, "Region");
boost::shared_ptr<AudioRegion> arp (ar);
boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp));
ret->unlock_property_changes ();
map_add (ret);
if (announce) {
CheckNewRegion (ret);
}
return ret;
ret = boost::static_pointer_cast<Region> (arp);
} else {
fatal << _("programming error: RegionFactory::create() called with unknown Region type")
<< endmsg;
/*NOTREACHED*/
return boost::shared_ptr<Region>();
}
if (ret) {
ret->set_properties (plist);
ret->unlock_property_changes ();
map_add (ret);
if (announce) {
CheckNewRegion (ret);
}
}
return ret;
}
boost::shared_ptr<Region>
RegionFactory::create (boost::shared_ptr<Source> src, const PropertyList& plist, bool announce)
{
boost::shared_ptr<Region> ret;
boost::shared_ptr<AudioSource> as;
boost::shared_ptr<MidiSource> ms;
if ((as = boost::dynamic_pointer_cast<AudioSource>(src)) != 0) {
AudioRegion* ar = new AudioRegion (as);
boost_debug_shared_ptr_mark_interesting (ar, "Region");
boost::shared_ptr<AudioRegion> arp (ar);
ret = boost::static_pointer_cast<Region> (arp);
} else if ((ms = boost::dynamic_pointer_cast<MidiSource>(src)) != 0) {
MidiRegion* mr = new MidiRegion (ms);
boost_debug_shared_ptr_mark_interesting (mr, "Region");
boost::shared_ptr<MidiRegion> mrp (mr);
ret = boost::static_pointer_cast<Region> (mrp);
}
if (ret) {
ret->set_properties (plist);
ret->unlock_property_changes ();
map_add (ret);
if (announce) {
CheckNewRegion (ret);
}
}
return ret;
}
boost::shared_ptr<Region>
RegionFactory::create (const SourceList& srcs, const PropertyList& plist, bool announce)
{
boost::shared_ptr<Region> ret;
boost::shared_ptr<AudioSource> as;
boost::shared_ptr<MidiSource> ms;
if ((as = boost::dynamic_pointer_cast<AudioSource>(srcs[0])) != 0) {
AudioRegion* ar = new AudioRegion (srcs);
boost_debug_shared_ptr_mark_interesting (ar, "Region");
boost::shared_ptr<AudioRegion> arp (ar);
ret = boost::static_pointer_cast<Region> (arp);
} else if ((ms = boost::dynamic_pointer_cast<MidiSource>(srcs[0])) != 0) {
MidiRegion* mr = new MidiRegion (srcs);
boost_debug_shared_ptr_mark_interesting (mr, "Region");
boost::shared_ptr<MidiRegion> mrp (mr);
ret = boost::static_pointer_cast<Region> (mrp);
}
if (ret) {
ret->set_properties (plist);
ret->unlock_property_changes ();
map_add (ret);
if (announce) {
CheckNewRegion (ret);
}
}
return ret;
}
boost::shared_ptr<Region>
@ -153,97 +294,45 @@ RegionFactory::create (Session& session, XMLNode& node, bool yn)
return r;
}
boost::shared_ptr<Region>
RegionFactory::create (const SourceList& srcs, nframes_t start, nframes_t length, const string& name, layer_t layer, Region::Flag flags, bool announce)
{
if (srcs.empty()) {
return boost::shared_ptr<Region>();
}
if (srcs[0]->type() == DataType::AUDIO) {
AudioRegion* ar = new AudioRegion (srcs, start, length, name, layer, flags);
boost_debug_shared_ptr_mark_interesting (ar, "Region");
boost::shared_ptr<AudioRegion> arp (ar);
boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp));
ret->unlock_property_changes ();
map_add (ret);
if (announce) {
CheckNewRegion (ret);
}
return ret;
} else if (srcs[0]->type() == DataType::MIDI) {
MidiRegion* ar = new MidiRegion (srcs, start, length, name, layer, flags);
boost::shared_ptr<MidiRegion> mrp (ar);
boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (mrp));
ret->unlock_property_changes ();
map_add (ret);
if (announce) {
CheckNewRegion (ret);
}
return ret;
}
return boost::shared_ptr<Region> ();
}
boost::shared_ptr<Region>
RegionFactory::create (SourceList& srcs, const XMLNode& node)
{
boost::shared_ptr<Region> ret;
if (srcs.empty()) {
return boost::shared_ptr<Region>();
return ret;
}
if (srcs[0]->type() == DataType::AUDIO) {
AudioRegion* ar = new AudioRegion (srcs, node);
boost_debug_shared_ptr_mark_interesting (ar, "Region");
boost::shared_ptr<AudioRegion> arp (ar);
ret = boost::static_pointer_cast<Region> (arp);
boost::shared_ptr<Region> ret (ar);
ret->unlock_property_changes ();
map_add (ret);
CheckNewRegion (ret);
return ret;
} else if (srcs[0]->type() == DataType::MIDI) {
boost::shared_ptr<Region> ret (new MidiRegion (srcs, node));
MidiRegion* mr = new MidiRegion (srcs, node);
boost::shared_ptr<MidiRegion> mrp (mr);
ret = boost::static_pointer_cast<Region> (mrp);
}
if (ret) {
ret->unlock_property_changes ();
map_add (ret);
CheckNewRegion (ret);
return ret;
}
return boost::shared_ptr<Region> ();
return ret;
}
boost::shared_ptr<Region>
RegionFactory::create (boost::shared_ptr<Source> src, nframes_t start, nframes_t length, const string& name, layer_t layer, Region::Flag flags, bool announce)
{
boost::shared_ptr<AudioSource> as;
boost::shared_ptr<MidiSource> ms;
if ((as = boost::dynamic_pointer_cast<AudioSource>(src)) != 0) {
AudioRegion* ar = new AudioRegion (as, start, length, name, layer, flags);
boost_debug_shared_ptr_mark_interesting (ar, "Region");
boost::shared_ptr<Region> ret (ar);
ret->unlock_property_changes ();
map_add (ret);
if (announce) {
CheckNewRegion (ret);
}
return ret;
} else if ((ms = boost::dynamic_pointer_cast<MidiSource>(src)) != 0) {
boost::shared_ptr<Region> ret (new MidiRegion (ms, start, length, name, layer, flags));
ret->unlock_property_changes ();
map_add (ret);
if (announce) {
CheckNewRegion (ret);
}
return ret;
}
return boost::shared_ptr<Region>();
}
void
RegionFactory::map_add (boost::shared_ptr<Region> r)

View file

@ -46,11 +46,11 @@ Reverse::run (boost::shared_ptr<Region> r)
{
SourceList nsrcs;
SourceList::iterator si;
nframes_t blocksize = 256 * 1024;
framecnt_t blocksize = 256 * 1024;
Sample* buf = 0;
nframes_t fpos;
nframes_t fstart;
nframes_t to_read;
framepos_t fpos;
framepos_t fstart;
framecnt_t to_read;
int ret = -1;
boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion>(r);

View file

@ -281,7 +281,7 @@ Route::inc_gain (gain_t fraction, void *src)
void
Route::set_gain (gain_t val, void *src)
{
if (src != 0 && _route_group && src != _route_group && _route_group->active_property (RouteGroup::Gain)) {
if (src != 0 && _route_group && src != _route_group && _route_group->is_active() && _route_group->is_gain()) {
if (_route_group->is_relative()) {
@ -563,7 +563,7 @@ Route::set_solo (bool yn, void *src)
return;
}
if (_route_group && src != _route_group && _route_group->active_property (RouteGroup::Solo)) {
if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_solo()) {
_route_group->apply (&Route::set_solo, yn, _route_group);
return;
}
@ -624,7 +624,7 @@ Route::set_solo_isolated (bool yn, void *src)
return;
}
if (_route_group && src != _route_group && _route_group->active_property (RouteGroup::Solo)) {
if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_solo()) {
_route_group->apply (&Route::set_solo_isolated, yn, _route_group);
return;
}
@ -682,7 +682,7 @@ Route::set_mute_points (MuteMaster::MutePoint mp)
void
Route::set_mute (bool yn, void *src)
{
if (_route_group && src != _route_group && _route_group->active_property (RouteGroup::Mute)) {
if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_mute()) {
_route_group->apply (&Route::set_mute, yn, _route_group);
return;
}

View file

@ -37,15 +37,65 @@
#include "i18n.h"
using namespace ARDOUR;
using namespace PBD;
using namespace std;
RouteGroup::RouteGroup (Session& s, const string &n, Flag f, Property p)
: _session (s)
, routes (new RouteList)
, _name (n)
, _flags (f)
, _properties (Property (p))
PropertyChange RouteGroup::FlagsChange = new_change ();
PropertyChange RouteGroup::PropertiesChange = new_change ();
namespace ARDOUR {
namespace Properties {
PropertyDescriptor<bool> relative;
PropertyDescriptor<bool> active;
PropertyDescriptor<bool> gain;
PropertyDescriptor<bool> mute;
PropertyDescriptor<bool> solo;
PropertyDescriptor<bool> recenable;
PropertyDescriptor<bool> select;
PropertyDescriptor<bool> edit;
}
}
void
RouteGroup::make_property_quarks ()
{
Properties::relative.id = g_quark_from_static_string (X_("relative"));
Properties::active.id = g_quark_from_static_string (X_("active"));
Properties::hidden.id = g_quark_from_static_string (X_("hidden"));
Properties::gain.id = g_quark_from_static_string (X_("gain"));
Properties::mute.id = g_quark_from_static_string (X_("mute"));
Properties::solo.id = g_quark_from_static_string (X_("solo"));
Properties::recenable.id = g_quark_from_static_string (X_("recenable"));
Properties::select.id = g_quark_from_static_string (X_("select"));
Properties::edit.id = g_quark_from_static_string (X_("edit"));
}
#define ROUTE_GROUP_DEFAULT_PROPERTIES _relative (Properties::relative, FlagsChange, false) \
, _active (Properties::active, FlagsChange, false) \
, _hidden (Properties::hidden, FlagsChange, false) \
, _gain (Properties::gain, PropertiesChange, false) \
, _mute (Properties::mute, PropertiesChange, false) \
, _solo (Properties::solo, PropertiesChange , false) \
, _recenable (Properties::recenable, PropertiesChange, false) \
, _select (Properties::select, PropertiesChange, false) \
, _edit (Properties::edit, PropertiesChange , false)
RouteGroup::RouteGroup (Session& s, const string &n)
: SessionObject (s, n)
, routes (new RouteList)
, ROUTE_GROUP_DEFAULT_PROPERTIES
{
_xml_node_name = X_("RegionGroup");
add_property (_relative);
add_property (_active);
add_property (_hidden);
add_property (_gain);
add_property (_mute);
add_property (_solo);
add_property (_recenable);
add_property (_select);
add_property (_edit);
}
RouteGroup::~RouteGroup ()
@ -60,14 +110,6 @@ RouteGroup::~RouteGroup ()
}
}
void
RouteGroup::set_name (string str)
{
_name = str;
_session.set_dirty ();
FlagsChanged (0); /* EMIT SIGNAL */
}
/** Add a route to a group. Adding a route which is already in the group is allowed; nothing will happen.
* @param r Route to add.
*/
@ -163,9 +205,8 @@ XMLNode&
RouteGroup::get_state (void)
{
XMLNode *node = new XMLNode ("RouteGroup");
node->add_property ("name", _name);
node->add_property ("flags", enum_2_string (_flags));
node->add_property ("properties", enum_2_string (_properties));
add_properties (*node);
if (!routes->empty()) {
stringstream str;
@ -189,18 +230,6 @@ RouteGroup::set_state (const XMLNode& node, int version)
const XMLProperty *prop;
if ((prop = node.property ("name")) != 0) {
_name = prop->value();
}
if ((prop = node.property ("flags")) != 0) {
_flags = Flag (string_2_enum (prop->value(), _flags));
}
if ((prop = node.property ("properties")) != 0) {
_properties = Property (string_2_enum (prop->value(), _properties));
}
if ((prop = node.property ("routes")) != 0) {
stringstream str (prop->value());
vector<string> ids;
@ -222,36 +251,86 @@ RouteGroup::set_state (const XMLNode& node, int version)
int
RouteGroup::set_state_2X (const XMLNode& node, int /*version*/)
{
XMLProperty const * prop;
if ((prop = node.property ("name")) != 0) {
_name = prop->value();
}
if ((prop = node.property ("flags")) != 0) {
_flags = Flag (string_2_enum (prop->value(), _flags));
}
set_properties (node);
if (node.name() == "MixGroup") {
_properties = Property (Gain | Mute | Solo | RecEnable);
_gain = true;
_mute = true;
_solo = true;
_recenable = true;
_edit = false;
} else if (node.name() == "EditGroup") {
_properties = Property (Select | Edit);
_gain = false;
_mute = false;
_solo = false;
_recenable = false;
_edit = true;
}
return 0;
}
void
RouteGroup::set_gain (bool yn)
{
if (is_gain() == yn) {
return;
}
_gain = yn;
}
void
RouteGroup::set_mute (bool yn)
{
if (is_mute() == yn) {
return;
}
_mute = yn;
}
void
RouteGroup::set_solo (bool yn)
{
if (is_solo() == yn) {
return;
}
_solo = yn;
}
void
RouteGroup::set_recenable (bool yn)
{
if (is_recenable() == yn) {
return;
}
_recenable = yn;
}
void
RouteGroup::set_select (bool yn)
{
if (is_select() == yn) {
return;
}
_select = yn;
}
void
RouteGroup::set_edit (bool yn)
{
if (is_edit() == yn) {
return;
}
_edit = yn;
}
void
RouteGroup::set_active (bool yn, void *src)
{
if (is_active() == yn) {
return;
}
if (yn) {
_flags = Flag (_flags | Active);
} else {
_flags = Flag (_flags & ~Active);
}
_active = yn;
_session.set_dirty ();
FlagsChanged (src); /* EMIT SIGNAL */
}
@ -263,31 +342,26 @@ RouteGroup::set_relative (bool yn, void *src)
if (is_relative() == yn) {
return;
}
if (yn) {
_flags = Flag (_flags | Relative);
} else {
_flags = Flag (_flags & ~Relative);
}
_relative = yn;
_session.set_dirty ();
FlagsChanged (src); /* EMIT SIGNAL */
}
void
RouteGroup::set_hidden (bool yn, void *src)
{
if (is_hidden() == yn) {
return;
}
if (yn) {
_flags = Flag (_flags | Hidden);
_hidden = true;
if (Config->get_hiding_groups_deactivates_groups()) {
_flags = Flag (_flags & ~Active);
_active = false;
}
} else {
_flags = Flag (_flags & ~Hidden);
_hidden = false;
if (Config->get_hiding_groups_deactivates_groups()) {
_flags = Flag (_flags | Active);
_active = true;
}
}
_session.set_dirty ();
@ -357,3 +431,29 @@ RouteGroup::destroy_subgroup ()
_session.remove_route (subgroup_bus);
subgroup_bus.reset ();
}
bool
RouteGroup::enabled_property (PBD::PropertyID prop)
{
if (Properties::relative.id == prop) {
return is_relative();
} else if (Properties::active.id == prop) {
return is_active();
} else if (Properties::hidden.id == prop) {
return is_hidden();
} else if (Properties::gain.id == prop) {
return is_gain();
} else if (Properties::mute.id == prop) {
return is_mute();
} else if (Properties::solo.id == prop) {
return is_solo();
} else if (Properties::recenable.id == prop) {
return is_recenable();
} else if (Properties::select.id == prop) {
return is_select();
} else if (Properties::edit.id == prop) {
return is_edit();
}
return false;
}

View file

@ -2840,7 +2840,7 @@ Session::update_region_name_map (boost::shared_ptr<Region> region)
}
void
Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
Session::region_changed (PropertyChange what_changed, boost::weak_ptr<Region> weak_region)
{
boost::shared_ptr<Region> region (weak_region.lock ());
@ -3675,7 +3675,7 @@ Session::bundle_by_name (string name) const
}
void
Session::tempo_map_changed (Change)
Session::tempo_map_changed (PropertyChange)
{
clear_clicks ();
@ -4069,9 +4069,14 @@ Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
/* construct a region to represent the bounced material */
result = RegionFactory::create (srcs, 0,
srcs.front()->length(srcs.front()->timeline_position()),
region_name_from_path (srcs.front()->name(), true));
PropertyList plist;
plist.add (Properties::start, 0);
plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
result = RegionFactory::create (srcs, plist);
}
out:

View file

@ -92,7 +92,6 @@
#include "ardour/midi_track.h"
#include "ardour/named_selection.h"
#include "ardour/processor.h"
#include "ardour/region_command.h"
#include "ardour/region_factory.h"
#include "ardour/route_group.h"
#include "ardour/send.h"
@ -2946,16 +2945,6 @@ Session::restore_history (string snapshot_name)
error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
}
} else if (n->name() == "RegionCommand") {
PBD::ID id (n->property ("region")->value());
boost::shared_ptr<Region> region = RegionFactory::region_by_id (id);
if (region) {
ut->add_command (new RegionCommand (region, *n));
} else {
error << string_compose (_("Region command references an unknown region ID=%1"), id.to_s()) << endmsg;
}
} else if (n->name() == "StatefulDiffCommand") {
if ((c = stateful_diff_command_factory (n))) {
ut->add_command (c);

View file

@ -48,7 +48,7 @@ using Glib::ustring;
gain_t* SndFileSource::out_coefficient = 0;
gain_t* SndFileSource::in_coefficient = 0;
nframes_t SndFileSource::xfade_frames = 64;
framecnt_t SndFileSource::xfade_frames = 64;
const Source::Flag SndFileSource::default_writable_flags = Source::Flag (
Source::Writable |
Source::Removable |
@ -269,13 +269,13 @@ SndFileSource::sample_rate () const
return _info.samplerate;
}
nframes_t
SndFileSource::read_unlocked (Sample *dst, sframes_t start, nframes_t cnt) const
framecnt_t
SndFileSource::read_unlocked (Sample *dst, framepos_t start, framecnt_t cnt) const
{
int32_t nread;
float *ptr;
uint32_t real_cnt;
nframes_t file_cnt;
framepos_t file_cnt;
if (start > _length) {
@ -297,7 +297,7 @@ SndFileSource::read_unlocked (Sample *dst, sframes_t start, nframes_t cnt) const
}
if (file_cnt != cnt) {
nframes_t delta = cnt - file_cnt;
framepos_t delta = cnt - file_cnt;
memset (dst+file_cnt, 0, sizeof (Sample) * delta);
}
@ -342,8 +342,8 @@ SndFileSource::read_unlocked (Sample *dst, sframes_t start, nframes_t cnt) const
return nread;
}
nframes_t
SndFileSource::write_unlocked (Sample *data, nframes_t cnt)
framecnt_t
SndFileSource::write_unlocked (Sample *data, framecnt_t cnt)
{
if (destructive()) {
return destructive_write_unlocked (data, cnt);
@ -352,8 +352,8 @@ SndFileSource::write_unlocked (Sample *data, nframes_t cnt)
}
}
nframes_t
SndFileSource::nondestructive_write_unlocked (Sample *data, nframes_t cnt)
framecnt_t
SndFileSource::nondestructive_write_unlocked (Sample *data, framecnt_t cnt)
{
if (!writable()) {
warning << string_compose (_("attempt to write a non-writable audio file source (%1)"), _path) << endmsg;
@ -366,7 +366,7 @@ SndFileSource::nondestructive_write_unlocked (Sample *data, nframes_t cnt)
return 0;
}
nframes_t oldlen;
framecnt_t oldlen;
int32_t frame_pos = _length;
if (write_float (data, frame_pos, cnt) != cnt) {
@ -385,10 +385,10 @@ SndFileSource::nondestructive_write_unlocked (Sample *data, nframes_t cnt)
return cnt;
}
nframes_t
SndFileSource::destructive_write_unlocked (Sample* data, nframes_t cnt)
framecnt_t
SndFileSource::destructive_write_unlocked (Sample* data, framecnt_t cnt)
{
nframes_t old_file_pos;
framepos_t old_file_pos;
if (!writable()) {
warning << string_compose (_("attempt to write a non-writable audio file source (%1)"), _path) << endmsg;
@ -551,8 +551,8 @@ SndFileSource::set_header_timeline_position ()
}
}
nframes_t
SndFileSource::write_float (Sample* data, sframes_t frame_pos, nframes_t cnt)
framecnt_t
SndFileSource::write_float (Sample* data, framepos_t frame_pos, framecnt_t cnt)
{
if (sf_seek (sf, frame_pos, SEEK_SET|SFM_WRITE) < 0) {
char errbuf[256];
@ -568,7 +568,7 @@ SndFileSource::write_float (Sample* data, sframes_t frame_pos, nframes_t cnt)
return cnt;
}
sframes_t
framepos_t
SndFileSource::natural_position() const
{
return _timeline_position;
@ -621,15 +621,15 @@ SndFileSource::mark_capture_end()
}
}
nframes_t
SndFileSource::crossfade (Sample* data, nframes_t cnt, int fade_in)
framecnt_t
SndFileSource::crossfade (Sample* data, framecnt_t cnt, int fade_in)
{
nframes_t xfade = min (xfade_frames, cnt);
nframes_t nofade = cnt - xfade;
framecnt_t xfade = min (xfade_frames, cnt);
framecnt_t nofade = cnt - xfade;
Sample* fade_data = 0;
nframes_t fade_position = 0; // in frames
framepos_t fade_position = 0; // in frames
ssize_t retval;
nframes_t file_cnt;
framecnt_t file_cnt;
if (fade_in) {
fade_position = file_pos;
@ -673,7 +673,7 @@ SndFileSource::crossfade (Sample* data, nframes_t cnt, int fade_in)
}
if (file_cnt != xfade) {
nframes_t delta = xfade - file_cnt;
framecnt_t delta = xfade - file_cnt;
memset (xfade_buf+file_cnt, 0, sizeof (Sample) * delta);
}
@ -686,7 +686,7 @@ SndFileSource::crossfade (Sample* data, nframes_t cnt, int fade_in)
if (xfade == xfade_frames) {
nframes_t n;
framecnt_t n;
/* use the standard xfade curve */
@ -717,10 +717,10 @@ SndFileSource::crossfade (Sample* data, nframes_t cnt, int fade_in)
compute_equal_power_fades (xfade, in, out);
for (nframes_t n = 0; n < xfade; ++n) {
for (framecnt_t n = 0; n < xfade; ++n) {
xfade_buf[n] = (xfade_buf[n] * out[n]) + (fade_data[n] * in[n]);
}
} else if (xfade) {
/* long xfade length, has to be computed across several calls */
@ -775,7 +775,7 @@ SndFileSource::setup_standard_crossfades (Session const & s, nframes_t rate)
before any DFS's are created.
*/
xfade_frames = (nframes_t) floor ((s.config.get_destructive_xfade_msecs () / 1000.0) * rate);
xfade_frames = (framecnt_t) floor ((s.config.get_destructive_xfade_msecs () / 1000.0) * rate);
delete [] out_coefficient;
delete [] in_coefficient;

View file

@ -52,7 +52,7 @@ StripSilence::run (boost::shared_ptr<Region> r)
}
/* find periods of silence in the region */
std::list<std::pair<nframes_t, nframes_t> > const silence =
std::list<std::pair<frameoffset_t, framecnt_t> > const silence =
region->find_silence (dB_to_coefficient (_threshold), _minimum_length);
if (silence.size () == 1 && silence.front().first == 0 && silence.front().second == region->length() - 1) {
@ -66,10 +66,10 @@ StripSilence::run (boost::shared_ptr<Region> r)
return 0;
}
std::list<std::pair<nframes_t, nframes_t > >::const_iterator s = silence.begin ();
nframes_t const pos = region->position ();
nframes_t const end = region->start () + region->length() - 1;
nframes_t const start = region->start ();
std::list<std::pair<framepos_t, framecnt_t > >::const_iterator s = silence.begin ();
framepos_t const pos = region->position ();
framepos_t const end = region->start () + region->length() - 1;
framepos_t const start = region->start ();
region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region));
region->set_name (session.new_region_name (region->name ()));

View file

@ -299,7 +299,7 @@ void
TempoMap::move_tempo (TempoSection& tempo, const BBT_Time& when)
{
if (move_metric_section (tempo, when) == 0) {
StateChanged (Change (0));
StateChanged (PropertyChange (0));
}
}
@ -307,7 +307,7 @@ void
TempoMap::move_meter (MeterSection& meter, const BBT_Time& when)
{
if (move_metric_section (meter, when) == 0) {
StateChanged (Change (0));
StateChanged (PropertyChange (0));
}
}
@ -334,7 +334,7 @@ TempoMap::remove_tempo (const TempoSection& tempo)
}
if (removed) {
StateChanged (Change (0));
StateChanged (PropertyChange (0));
}
}
@ -361,7 +361,7 @@ TempoMap::remove_meter (const MeterSection& tempo)
}
if (removed) {
StateChanged (Change (0));
StateChanged (PropertyChange (0));
}
}
@ -406,7 +406,7 @@ TempoMap::add_tempo (const Tempo& tempo, BBT_Time where)
do_insert (new TempoSection (where, tempo.beats_per_minute(), tempo.note_type()), true);
}
StateChanged (Change (0));
StateChanged (PropertyChange (0));
}
void
@ -417,7 +417,7 @@ TempoMap::add_tempo (const Tempo& tempo, nframes64_t where)
do_insert (new TempoSection (where, tempo.beats_per_minute(), tempo.note_type()), false);
}
StateChanged (Change (0));
StateChanged (PropertyChange (0));
}
void
@ -445,7 +445,7 @@ TempoMap::replace_tempo (TempoSection& existing, const Tempo& replacement)
}
if (replaced) {
StateChanged (Change (0));
StateChanged (PropertyChange (0));
}
}
@ -474,7 +474,7 @@ TempoMap::add_meter (const Meter& meter, BBT_Time where)
do_insert (new MeterSection (where, meter.beats_per_bar(), meter.note_divisor()), true);
}
StateChanged (Change (0));
StateChanged (PropertyChange (0));
}
void
@ -485,7 +485,7 @@ TempoMap::add_meter (const Meter& meter, nframes64_t where)
do_insert (new MeterSection (where, meter.beats_per_bar(), meter.note_divisor()), false);
}
StateChanged (Change (0));
StateChanged (PropertyChange (0));
}
void
@ -511,7 +511,7 @@ TempoMap::replace_meter (MeterSection& existing, const Meter& replacement)
}
if (replaced) {
StateChanged (Change (0));
StateChanged (PropertyChange (0));
}
}
@ -524,7 +524,7 @@ TempoMap::change_initial_tempo (double beats_per_minute, double note_type)
for (Metrics::iterator i = metrics->begin(); i != metrics->end(); ++i) {
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
*((Tempo*) t) = newtempo;
StateChanged (Change (0));
StateChanged (PropertyChange (0));
break;
}
}
@ -570,7 +570,7 @@ TempoMap::change_existing_tempo_at (nframes64_t where, double beats_per_minute,
/* reset */
*((Tempo*)prev) = newtempo;
StateChanged (Change (0));
StateChanged (PropertyChange (0));
}
const MeterSection&
@ -1609,7 +1609,7 @@ TempoMap::set_state (const XMLNode& node, int /*version*/)
}
}
StateChanged (Change (0));
StateChanged (PropertyChange (0));
return 0;
}
@ -1673,7 +1673,7 @@ TempoMap::insert_time (nframes64_t where, nframes64_t amount)
timestamp_metrics (false);
StateChanged (Change (0));
StateChanged (PropertyChange (0));
}
BBT_Time

View file

@ -171,7 +171,7 @@ Track::set_record_enable (bool yn, void *src)
return;
}
if (_route_group && src != _route_group && _route_group->active_property (RouteGroup::RecEnable)) {
if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_recenable()) {
_route_group->apply (&Track::set_record_enable, yn, _route_group);
return;
}

View file

@ -143,10 +143,9 @@ libardour_sources = [
'quantize.cc',
'rc_configuration.cc',
'recent_sessions.cc',
'region.cc',
'region_command.cc',
'region_factory.cc',
'resampled_source.cc',
'region.cc',
'return.cc',
'reverse.cc',
'route.cc',
@ -165,6 +164,7 @@ libardour_sources = [
'session_handle.cc',
'session_metadata.cc',
'session_midi.cc',
'session_object.cc',
'session_playlists.cc',
'session_process.cc',
'session_rtevents.cc',

View file

@ -107,8 +107,8 @@
#define MIDI_CMD_NOTE_OFF 0x80 /**< Note Off */
#define MIDI_CMD_NOTE_ON 0x90 /**< Note On */
#define MIDI_CMD_NOTE_PRESSURE 0xA0 /**< Key Pressure */
#define MIDI_CMD_CONTROL 0xB0 /**< Control Change */
#define MIDI_CMD_PGM_CHANGE 0xC0 /**< Program Change */
#define MIDI_CMD_CONTROL 0xB0 /**< Control PropertyChange */
#define MIDI_CMD_PGM_CHANGE 0xC0 /**< Program PropertyChange */
#define MIDI_CMD_CHANNEL_PRESSURE 0xD0 /**< Channel Pressure */
#define MIDI_CMD_BENDER 0xE0 /**< Pitch Bender */
#define MIDI_CMD_COMMON_SYSEX 0xF0 /**< Sysex (System Exclusive) Begin */

View file

@ -186,11 +186,11 @@
* adding the event (using smf_track_add_event_seconds(), smf_track_add_event_pulses() or
* smf_track_add_event_delta_pulses()); the remaining two values are computed from that.
*
* Tempo related stuff happens automatically - when you add a metaevent that is Tempo Change or
* Time Signature, libsmf adds that event to the tempo map. If you remove Tempo Change event
* Tempo related stuff happens automatically - when you add a metaevent that is Tempo PropertyChange or
* Time Signature, libsmf adds that event to the tempo map. If you remove Tempo PropertyChange event
* that is in the middle of the song, the rest of the events will have their event->time_seconds
* recomputed from event->time_pulses before smf_event_remove_from_track() function returns.
* Adding Tempo Change in the middle of the song works in a similar way.
* Adding Tempo PropertyChange in the middle of the song works in a similar way.
*
* MIDI data (event->midi_buffer) is always kept in normalized form - it always begins with
* status byte (no running status), there are no System Realtime events embedded in them etc.

View file

@ -40,9 +40,9 @@ inline static const char* midi_name(uint8_t status)
case MIDI_CMD_NOTE_PRESSURE:
return "Key Pressure"; break;
case MIDI_CMD_CONTROL:
return "Control Change"; break;
return "Control PropertyChange"; break;
case MIDI_CMD_PGM_CHANGE:
return "Program Change"; break;
return "Program PropertyChange"; break;
case MIDI_CMD_CHANNEL_PRESSURE:
return "Channel Pressure"; break;
case MIDI_CMD_BENDER:

View file

@ -196,7 +196,7 @@ Parser::trace_event (Parser &, byte *msg, size_t len)
*o << trace_prefix
<< "Channel "
<< (msg[0]&0xF)+1
<< " Program Change ProgNum "
<< " Program PropertyChange ProgNum "
<< (int) msg[1]
<< endmsg;
break;

View file

@ -21,26 +21,35 @@
#define __pbd_properties_h__
#include <string>
#include <sstream>
#include <list>
#include <glib/glib.h>
#include <glib.h>
class XMLNode;
#include "pbd/xml++.h"
namespace PBD {
enum PropertyChange {
range_guarantee = ~0
range_guarantee = ~0ULL
};
PropertyChange new_change ();
typedef GQuark PropertyID;
template<typename T>
struct PropertyDescriptor {
PropertyID id;
typedef T value_type;
};
/** Base (non template) part of Property */
class PropertyBase
{
public:
PropertyBase (GQuark quark, PropertyChange c)
PropertyBase (PropertyID pid, PropertyChange c)
: _have_old (false)
, _property_quark (q)
, _property_id (pid)
, _change (c)
{
@ -52,19 +61,21 @@ public:
}
virtual void diff (XMLNode *, XMLNode *) const = 0;
virtual void diff (PropertyChange&) const = 0;
virtual PropertyChange set_state (XMLNode const &) = 0;
virtual void add_state (XMLNode &) const = 0;
std::string property_name() const { return g_quark_to_string (_property_quark); }
const gchar* property_name() const { return g_quark_to_string (_property_id); }
PropertyChange change() const { return _change; }
PropertyID id() const { return _property_id; }
bool operator== (GQuark q) const {
return _property_quark == q;
bool operator== (PropertyID pid) const {
return _property_id == pid;
}
protected:
bool _have_old;
GQuark _property_quark;
PropertyID _property_id;
PropertyChange _change;
};
@ -73,17 +84,16 @@ template <class T>
class PropertyTemplate : public PropertyBase
{
public:
PropertyTemplate (GQuark q, PropertyChange c, T const & v)
: PropertyBase (q, c)
PropertyTemplate (PropertyDescriptor<T> p, PropertyChange c, T const & v)
: PropertyBase (p.id, c)
, _current (v)
{
}
PropertyTemplate<T> & operator= (PropertyTemplate<T> const & s) {
/* XXX: isn't there a nicer place to do this? */
_have_old = s._have_old;
_property_quark = s._property_quark;
_property_id = s._property_id;
_change = s._change;
_current = s._current;
@ -119,8 +129,14 @@ public:
void diff (XMLNode* old, XMLNode* current) const {
if (_have_old) {
old->add_property (g_quark_to_string (_property_quark), to_string (_old));
current->add_property (g_quark_to_string (_property_quark), to_string (_current));
old->add_property (g_quark_to_string (_property_id), to_string (_old));
current->add_property (g_quark_to_string (_property_id), to_string (_current));
}
}
void diff (PropertyChange& c) const {
if (_have_old && _change) {
c = PropertyChange (c | _change);
}
}
@ -129,24 +145,23 @@ public:
* @return PropertyChange effected, or 0.
*/
PropertyChange set_state (XMLNode const & node) {
XMLProperty const * p = node.property (g_quark_to_string (_property_quark));
XMLProperty const * p = node.property (g_quark_to_string (_property_id));
PropertyChange c = PropertyChange (0);
if (p) {
T const v = from_string (p->value ());
if (v == _current) {
return PropertyChange (0);
if (v != _current) {
set (v);
c = _change;
}
set (v);
return _change;
}
return PropertyChange (0);
return c;
}
void add_state (XMLNode & node) const {
node.add_property (g_quark_to_string (_property_quark), to_string (_current));
node.add_property (g_quark_to_string (_property_id), to_string (_current));
}
protected:
@ -176,10 +191,16 @@ template <class T>
class Property : public PropertyTemplate<T>
{
public:
Property (GQuark q, PropertyChange c, T const & v)
Property (PropertyDescriptor<T> q, PropertyChange c, T const & v)
: PropertyTemplate<T> (q, c, v)
{
}
Property (PropertyDescriptor<T> q, T const & v)
: PropertyTemplate<T> (q, PropertyChange (0), v)
{
}
T & operator= (T const & v) {
@ -188,8 +209,14 @@ public:
}
private:
std::string to_string (T const & v) const {
// XXX LocaleGuard
/* note that we do not set a locale for the streams used
in to_string() or from_string(), because we want the
format to be portable across locales (i.e. C or
POSIX). Also, there is the small matter of
std::locale aborting on OS X if used with anything
other than C or POSIX locales.
*/
std::string to_string (T const & v) const {
std::stringstream s;
s.precision (12); // in case its floating point
s << v;
@ -197,15 +224,53 @@ private:
}
T from_string (std::string const & s) const {
// XXX LocaleGuard
std::stringstream t (s);
T v;
t.precision (12); // in case its floating point
t >> v;
return v;
}
};
class PropertyList : public std::map<PropertyID,PropertyBase*>
{
public:
PropertyList() : property_owner (true) {}
virtual ~PropertyList() {
if (property_owner)
for (std::map<PropertyID,PropertyBase*>::iterator i = begin(); i != end(); ++i) {
delete i->second;
}
}
/* classes that own property lists use this to add their
property members to their plists.
*/
bool add (PropertyBase& p) {
return insert (value_type (p.id(), &p)).second;
}
/* code that is constructing a property list for use
in setting the state of an object uses this.
*/
template<typename T, typename V> bool add (PropertyDescriptor<T> pid, const V& v) {
return insert (value_type (pid.id, new Property<T> (pid, (T) v))).second;
}
protected:
bool property_owner;
};
/** A variant of PropertyList that does not delete its
property list in its destructor. Objects with their
own Properties store them in an OwnedPropertyList
to avoid having them deleted at the wrong time.
*/
class OwnedPropertyList : public PropertyList
{
public:
OwnedPropertyList() { property_owner = false; }
};
} /* namespace PBD */
#endif /* __pbd_properties_h__ */

View file

@ -21,10 +21,12 @@
#define __pbd_stateful_h__
#include <string>
#include <list>
#include <cassert>
#include "pbd/id.h"
#include "pbd/xml++.h"
#include "pbd/enumwriter.h"
#include "pbd/properties.h"
class XMLNode;
@ -34,201 +36,6 @@ namespace sys {
class path;
}
enum Change {
range_guarantee = ~0
};
Change new_change ();
/** Base (non template) part of State */
class StateBase
{
public:
StateBase (std::string const & p, Change c)
: _have_old (false)
, _xml_property_name (p)
, _change (c)
{
}
/** Forget about any old value for this state */
void clear_history () {
_have_old = false;
}
virtual void diff (XMLNode *, XMLNode *) const = 0;
virtual Change set_state (XMLNode const &) = 0;
virtual void add_state (XMLNode &) const = 0;
protected:
bool _have_old;
std::string _xml_property_name;
Change _change;
};
/** Parent class for classes which represent a single piece of state in a Stateful object */
template <class T>
class StateTemplate : public StateBase
{
public:
StateTemplate (std::string const & p, Change c, T const & v)
: StateBase (p, c)
, _current (v)
{
}
StateTemplate<T> & operator= (StateTemplate<T> const & s) {
/* XXX: isn't there a nicer place to do this? */
_have_old = s._have_old;
_xml_property_name = s._xml_property_name;
_change = s._change;
_current = s._current;
_old = s._old;
return *this;
}
T & operator= (T const & v) {
set (v);
return _current;
}
T & operator+= (T const & v) {
set (_current + v);
return _current;
}
bool operator== (const T& other) const {
return _current == other;
}
bool operator!= (const T& other) const {
return _current != other;
}
operator T const & () const {
return _current;
}
T const & val () const {
return _current;
}
void diff (XMLNode* old, XMLNode* current) const {
if (_have_old) {
old->add_property (_xml_property_name.c_str(), to_string (_old));
current->add_property (_xml_property_name.c_str(), to_string (_current));
}
}
/** Try to set state from the property of an XML node.
* @param node XML node.
* @return Change effected, or 0.
*/
Change set_state (XMLNode const & node) {
XMLProperty const * p = node.property (_xml_property_name.c_str());
if (p) {
T const v = from_string (p->value ());
if (v == _current) {
return Change (0);
}
set (v);
return _change;
}
return Change (0);
}
void add_state (XMLNode & node) const {
node.add_property (_xml_property_name.c_str(), to_string (_current));
}
protected:
void set (T const & v) {
_old = _current;
_have_old = true;
_current = v;
}
virtual std::string to_string (T const & v) const = 0;
virtual T from_string (std::string const & s) const = 0;
T _current;
T _old;
};
template<class T>
std::ostream& operator<< (std::ostream& os, StateTemplate<T> const & s)
{
os << s.val();
return os;
}
/** Representation of a single piece of state in a Stateful; for use
* with types that can be written to / read from stringstreams.
*/
template <class T>
class State : public StateTemplate<T>
{
public:
State (std::string const & p, Change c, T const & v)
: StateTemplate<T> (p, c, v)
{
}
T & operator= (T const & v) {
this->set (v);
return this->_current;
}
private:
std::string to_string (T const & v) const {
std::stringstream s;
s.precision (12); // in case its floating point
s << v;
return s.str ();
}
T from_string (std::string const & s) const {
std::stringstream t (s);
T v;
t.precision (12); // in case its floating point
t >> v;
return v;
}
};
template <class T>
class EnumState : public StateTemplate<T>
{
public:
EnumState (std::string const & p, Change c, T const & v)
: StateTemplate<T> (p, c, v)
{
}
T & operator= (T const & v) {
this->set (v);
return this->_current;
}
private:
std::string to_string (T const & v) const {
return enum_2_string (v);
}
T from_string (std::string const & v) const {
return T (string_2_enum (v, this->_current));
}
};
/** Base class for objects with saveable and undoable state */
class Stateful {
public:
@ -236,14 +43,21 @@ class Stateful {
virtual ~Stateful();
virtual XMLNode& get_state (void) = 0;
virtual int set_state (const XMLNode&, int version) = 0;
/* derived types do not have to implement this, but probably should
give it serious attention.
*/
virtual PropertyChange set_property (const PropertyBase&) { return PropertyChange (0); }
void add_state (StateBase & s) {
_states.push_back (&s);
PropertyChange set_properties (const PropertyList&);
void add_property (PropertyBase& s) {
_properties.add (s);
}
/* Extra XML nodes */
/* Extra XML node: so that 3rd parties can attach state to the XMLNode
representing the state of this object.
*/
void add_extra_xml (XMLNode&);
XMLNode *extra_xml (const std::string& str);
@ -251,7 +65,8 @@ class Stateful {
const PBD::ID& id() const { return _id; }
void clear_history ();
std::pair<XMLNode *, XMLNode*> diff ();
std::pair<XMLNode *, XMLNode*> diff () const;
void changed (PropertyChange&) const;
static int current_state_version;
static int loading_state_version;
@ -260,15 +75,25 @@ class Stateful {
void add_instant_xml (XMLNode&, const sys::path& directory_path);
XMLNode *instant_xml (const std::string& str, const sys::path& directory_path);
Change set_state_using_states (XMLNode const &);
void add_states (XMLNode &);
void add_properties (XMLNode &);
/* derived types can call this from ::set_state() (or elsewhere)
to get basic property setting done.
*/
PropertyChange set_properties (XMLNode const &);
/* derived classes can implement this to do cross-checking
of property values after either a PropertyList or XML
driven property change.
*/
virtual void post_set () { };
XMLNode *_extra_xml;
XMLNode *_instant_xml;
PBD::ID _id;
std::string _xml_node_name; ///< name of node to use for this object in XML
std::list<StateBase*> _states; ///< state variables that this object has
OwnedPropertyList _properties;
};
} // namespace PBD

View file

@ -17,6 +17,8 @@
*/
#include <stdint.h>
#include "pbd/properties.h"
#include "pbd/error.h"
@ -25,7 +27,7 @@
using namespace PBD;
PropertyChange
new_change ()
PBD::new_change ()
{
static uint64_t change_bit = 1;

View file

@ -35,27 +35,6 @@ namespace PBD {
int Stateful::current_state_version = 0;
int Stateful::loading_state_version = 0;
PBD::Change
new_change ()
{
Change c;
static uint32_t change_bit = 1;
/* catch out-of-range */
if (!change_bit)
{
fatal << _("programming error: ")
<< "change_bit out of range in ARDOUR::new_change()"
<< endmsg;
/*NOTREACHED*/
}
c = Change (change_bit);
change_bit <<= 1; // if it shifts too far, change_bit == 0
return c;
}
Stateful::Stateful ()
{
_extra_xml = 0;
@ -174,8 +153,8 @@ Stateful::instant_xml (const string& str, const sys::path& directory_path)
void
Stateful::clear_history ()
{
for (list<StateBase*>::iterator i = _states.begin(); i != _states.end(); ++i) {
(*i)->clear_history ();
for (OwnedPropertyList::iterator i = _properties.begin(); i != _properties.end(); ++i) {
i->second->clear_history ();
}
}
@ -185,42 +164,75 @@ Stateful::clear_history ()
* It is the caller's responsibility to delete the returned XMLNodes.
*/
pair<XMLNode *, XMLNode *>
Stateful::diff ()
Stateful::diff () const
{
XMLNode* old = new XMLNode (_xml_node_name);
XMLNode* current = new XMLNode (_xml_node_name);
for (list<StateBase*>::iterator i = _states.begin(); i != _states.end(); ++i) {
(*i)->diff (old, current);
for (OwnedPropertyList::const_iterator i = _properties.begin(); i != _properties.end(); ++i) {
i->second->diff (old, current);
}
return make_pair (old, current);
}
/** Set state of _states from an XML node.
* @param node Node.
* @return Changes made.
*/
Change
Stateful::set_state_using_states (XMLNode const & node)
/** Modifies PropertyChange @param c to indicate what properties have changed since the last
time clear_history was called on this object. Note that not all properties have change
values - if this object has any such Property members, they will never show up in
the value of @param c. Note also that @param c is not cleared by this function.
*/
void
Stateful::changed (PropertyChange& c) const
{
Change c = Change (0);
for (list<StateBase*>::iterator i = _states.begin(); i != _states.end(); ++i) {
c = Change (c | (*i)->set_state (node));
for (OwnedPropertyList::const_iterator i = _properties.begin(); i != _properties.end(); ++i) {
i->second->diff (c);
}
}
/** Set state of some/all _properties from an XML node.
* @param node Node.
* @return PropertyChanges made.
*/
PropertyChange
Stateful::set_properties (XMLNode const & node)
{
PropertyChange c = PropertyChange (0);
for (OwnedPropertyList::iterator i = _properties.begin(); i != _properties.end(); ++i) {
c = PropertyChange (c | i->second->set_state (node));
}
post_set ();
return c;
}
/** Add state of _states to an XML node.
PropertyChange
Stateful::set_properties (const PropertyList& property_list)
{
PropertyChange c = PropertyChange (0);
PropertyList::const_iterator p;
for (OwnedPropertyList::iterator i = _properties.begin(); i != _properties.end(); ++i) {
if ((p = property_list.find (i->first)) != property_list.end()) {
c = PropertyChange (c|set_property (*(p->second)));
}
}
post_set ();
return c;
}
/** Add property states to an XML node.
* @param node Node.
*/
void
Stateful::add_states (XMLNode & node)
Stateful::add_properties (XMLNode & node)
{
for (list<StateBase*>::iterator i = _states.begin(); i != _states.end(); ++i) {
(*i)->add_state (node);
for (OwnedPropertyList::iterator i = _properties.begin(); i != _properties.end(); ++i) {
i->second->add_state (node);
}
}

View file

@ -74,6 +74,7 @@ def build(bld):
mountpoint.cc
pathscanner.cc
pool.cc
property.cc
pthread_utils.cc
receiver.cc
search_path.cc