Use sys::basename instead of PBD::basename_nosuffix in Session::import_audiofile
[ardour.git] / libs / ardour / audioregion.cc
index 359c729368e25131a145468225e7e348570d9377..8034f3ddacf5963b4517fca7c4407583b62424d2 100644 (file)
 #include <pbd/xml++.h>
 #include <pbd/stacktrace.h>
 #include <pbd/enumwriter.h>
+#include <pbd/convert.h>
 
 #include <ardour/audioregion.h>
 #include <ardour/session.h>
 #include <ardour/gain.h>
 #include <ardour/dB.h>
 #include <ardour/playlist.h>
-#include <ardour/audiofilter.h>
 #include <ardour/audiofilesource.h>
 #include <ardour/region_factory.h>
 #include <ardour/runtime_functions.h>
@@ -48,6 +48,7 @@
 
 using namespace std;
 using namespace ARDOUR;
+using namespace PBD;
 
 /* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
 
@@ -71,11 +72,11 @@ AudioRegion::init ()
 }
 
 /* constructor for use by derived types only */
-AudioRegion::AudioRegion (nframes_t start, nframes_t length, string name)
-       : Region (start, length, name, DataType::AUDIO)
-       , _fade_in (new AutomationList(ParamID(FadeInAutomation), 0.0, 2.0, 1.0))
-       , _fade_out (new AutomationList(ParamID(FadeOutAutomation), 0.0, 2.0, 1.0))
-       , _envelope (new AutomationList(ParamID(EnvelopeAutomation), 0.0, 2.0, 1.0))
+AudioRegion::AudioRegion (Session& s, nframes_t start, nframes_t length, string name)
+       : Region (s, start, length, name, DataType::AUDIO)
+       , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0))
+       , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0))
+       , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0))
 {
        init ();
 }
@@ -83,9 +84,9 @@ AudioRegion::AudioRegion (nframes_t start, nframes_t length, string name)
 /** 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))
-       , _fade_in (new AutomationList(ParamID(FadeInAutomation), 0.0, 2.0, 1.0))
-       , _fade_out (new AutomationList(ParamID(FadeOutAutomation), 0.0, 2.0, 1.0))
-       , _envelope (new AutomationList(ParamID(EnvelopeAutomation), 0.0, 2.0, 1.0))
+       , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0))
+       , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0))
+       , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0))
 {
        boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
        if (afs) {
@@ -98,9 +99,9 @@ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, n
 /* 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)
-       , _fade_in (new AutomationList(ParamID(FadeInAutomation), 0.0, 2.0, 1.0))
-       , _fade_out (new AutomationList(ParamID(FadeOutAutomation), 0.0, 2.0, 1.0))
-       , _envelope (new AutomationList(ParamID(EnvelopeAutomation), 0.0, 2.0, 1.0))
+       , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0))
+       , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0))
+       , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0))
 {
        boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
        if (afs) {
@@ -113,9 +114,9 @@ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, n
 /* Basic AudioRegion constructor (many channels) */
 AudioRegion::AudioRegion (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)
-       , _fade_in (new AutomationList(ParamID(FadeInAutomation), 0.0, 2.0, 1.0))
-       , _fade_out (new AutomationList(ParamID(FadeOutAutomation), 0.0, 2.0, 1.0))
-       , _envelope (new AutomationList(ParamID(EnvelopeAutomation), 0.0, 2.0, 1.0))
+       , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0))
+       , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0))
+       , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0))
 {
        init ();
 }
@@ -124,14 +125,29 @@ AudioRegion::AudioRegion (SourceList& srcs, nframes_t start, nframes_t length, c
 /** 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)
-       , _fade_in (new AutomationList(ParamID(FadeInAutomation), 0.0, 2.0, 1.0))
-       , _fade_out (new AutomationList(ParamID(FadeOutAutomation), 0.0, 2.0, 1.0))
-       , _envelope (new AutomationList(ParamID(EnvelopeAutomation), 0.0, 2.0, 1.0))
+       , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0))
+       , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0))
+       , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0))
 {
-       /* return to default fades if the existing ones are too long */
-       _fade_in_disabled = 0;
-       _fade_out_disabled = 0;
+       set<boost::shared_ptr<Source> > unique_srcs;
+
+       for (SourceList::const_iterator i= other->_sources.begin(); i != other->_sources.end(); ++i) {
+               _sources.push_back (*i);
+
+               pair<set<boost::shared_ptr<Source> >::iterator,bool> result;
+
+               result = unique_srcs.insert (*i);
+               
+               if (result.second) {
+                       boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
+                       if (afs) {
+                               afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
+                       }
+               }
+       }
 
+       /* return to default fades if the existing ones are too long */
+       init ();
 
        if (_flags & LeftOfSplit) {
                if (_fade_in->back()->when >= _length) {
@@ -155,22 +171,19 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t
 
        _scale_amplitude = other->_scale_amplitude;
 
-       listen_to_my_curves ();
-       
        assert(_type == DataType::AUDIO);
 }
 
 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
        : Region (other)
-       , _fade_in (new AutomationList(ParamID(FadeInAutomation), 0.0, 2.0, 1.0))
-       , _fade_out (new AutomationList(ParamID(FadeOutAutomation), 0.0, 2.0, 1.0))
-       , _envelope (new AutomationList(ParamID(EnvelopeAutomation), 0.0, 2.0, 1.0))
+       , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0))
+       , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0))
+       , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0))
 {
        _scale_amplitude = other->_scale_amplitude;
        _envelope = other->_envelope;
 
-       _fade_in_disabled = 0;
-       _fade_out_disabled = 0;
+       set_default_fades ();
        
        listen_to_my_curves ();
 
@@ -179,41 +192,36 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
 
 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& node)
        : Region (src, node)
-       , _fade_in (new AutomationList(ParamID(FadeInAutomation), 0.0, 2.0, 1.0))
-       , _fade_out (new AutomationList(ParamID(FadeOutAutomation), 0.0, 2.0, 1.0))
-       , _envelope (new AutomationList(ParamID(EnvelopeAutomation), 0.0, 2.0, 1.0))
+       , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0))
+       , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0))
+       , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0))
 {
        boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
        if (afs) {
                afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
        }
 
-       set_default_fades ();
+       init ();
 
        if (set_state (node)) {
                throw failed_constructor();
        }
 
-       listen_to_my_curves ();
-
        assert(_type == DataType::AUDIO);
 }
 
 AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
        : Region (srcs, node)
-       , _fade_in (new AutomationList(ParamID(FadeInAutomation), 0.0, 2.0, 1.0))
-       , _fade_out (new AutomationList(ParamID(FadeOutAutomation), 0.0, 2.0, 1.0))
-       , _envelope (new AutomationList(ParamID(EnvelopeAutomation), 0.0, 2.0, 1.0))
+       , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0))
+       , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0))
+       , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0))
 {
-       set_default_fades ();
-       _scale_amplitude = 1.0;
+       init ();
 
        if (set_state (node)) {
                throw failed_constructor();
        }
 
-       listen_to_my_curves ();
-
        assert(_type == DataType::AUDIO);
 }
 
@@ -505,12 +513,20 @@ AudioRegion::state (bool full)
        snprintf (buf, sizeof(buf), "%.12g", _scale_amplitude);
        node.add_property ("scale-gain", buf);
 
+       // XXX these should move into Region
+
        for (uint32_t n=0; n < _sources.size(); ++n) {
                snprintf (buf2, sizeof(buf2), "source-%d", n);
                _sources[n]->id().print (buf, sizeof (buf));
                node.add_property (buf2, buf);
        }
 
+       for (uint32_t n=0; n < _master_sources.size(); ++n) {
+               snprintf (buf2, sizeof(buf2), "master-source-%d", n);
+               _master_sources[n]->id().print (buf, sizeof (buf));
+               node.add_property (buf2, buf);
+       }
+
        snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
        node.add_property ("channels", buf);
 
@@ -552,7 +568,7 @@ AudioRegion::state (bool full)
                                default_env = true;
                        }
                } 
-               
+
                if (default_env) {
                        child->add_property ("default", "yes");
                } else {
@@ -602,6 +618,7 @@ AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool sen
 
        if ((prop = node.property ("scale-gain")) != 0) {
                _scale_amplitude = atof (prop->value().c_str());
+               what_changed = Change (what_changed|ScaleAmplitudeChanged);
        } else {
                _scale_amplitude = 1.0;
        }
@@ -616,7 +633,7 @@ AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool sen
                child = (*niter);
                
                if (child->name() == "Envelope") {
-                       
+
                        _envelope->clear ();
 
                        if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child)) {
@@ -795,6 +812,10 @@ AudioRegion::set_fade_out (FadeShape shape, nframes_t len)
 void
 AudioRegion::set_fade_in_length (nframes_t len)
 {
+       if (len > _length) {
+               len = _length - 1;
+       }
+
        bool changed = _fade_in->extend_to (len);
 
        if (changed) {
@@ -806,13 +827,16 @@ AudioRegion::set_fade_in_length (nframes_t len)
 void
 AudioRegion::set_fade_out_length (nframes_t len)
 {
+       if (len > _length) {
+               len = _length - 1;
+       }
+
        bool changed =  _fade_out->extend_to (len);
 
        if (changed) {
                _flags = Flag (_flags & ~DefaultFadeOut);
+               send_change (FadeOutChanged);
        }
-
-       send_change (FadeOutChanged);
 }
 
 void
@@ -977,19 +1001,13 @@ AudioRegion::separate_by_channel (Session& session, vector<boost::shared_ptr<Aud
        return 0;
 }
 
-int
-AudioRegion::apply (AudioFilter& filter)
-{
-       boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (shared_from_this());
-       return filter.run (ar);
-}
-
 nframes_t
 AudioRegion::read_raw_internal (Sample* buf, nframes_t pos, nframes_t cnt) const
 {
        return audio_source()->read  (buf, pos, cnt);
 }
 
+
 int
 AudioRegion::exportme (Session& session, AudioExportSpecification& spec)
 {