PluginInfo::type added to copy constructor. But why is the copy constructor defined...
[ardour.git] / libs / ardour / audioregion.cc
index ecb2f9b4b349c36243efd51749d418064abfb0a4..6163897b2015c24ce9434fd23706efc5ff676649 100644 (file)
@@ -212,7 +212,8 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
        : Region (other),
          _fade_in (other->_fade_in),
          _fade_out (other->_fade_out),
-         _envelope (other->_envelope) 
+         _envelope (other->_envelope)
+         
 {
        /* Pure copy constructor */
 
@@ -241,11 +242,42 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
        }
 
        _scale_amplitude = other->_scale_amplitude;
-       _envelope = other->_envelope;
 
        _fade_in_disabled = 0;
        _fade_out_disabled = 0;
-       
+
+       listen_to_my_curves ();
+       listen_to_my_sources ();
+}
+
+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),
+         _fade_in (other->_fade_in),
+         _fade_out (other->_fade_out),
+         _envelope (other->_envelope)
+         
+{
+       /* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
+
+       set<boost::shared_ptr<AudioSource> > unique_srcs;
+
+       for (SourceList::const_iterator i=srcs.begin(); i != srcs.end(); ++i) {
+               sources.push_back (*i);
+               master_sources.push_back (*i);
+               (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
+               
+               boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> ((*i));
+               if (afs) {
+                       afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
+               }
+       }
+
+       _scale_amplitude = other->_scale_amplitude;
+
+       _fade_in_disabled = 0;
+       _fade_out_disabled = 0;
+
        listen_to_my_curves ();
        listen_to_my_sources ();
 }
@@ -388,6 +420,7 @@ AudioRegion::verify_start_and_length (nframes_t new_start, nframes_t& new_length
 
        return true;
 }
+
 bool
 AudioRegion::verify_start (nframes_t pos)
 {
@@ -458,26 +491,36 @@ AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nfra
 }
 
 nframes64_t
-AudioRegion::read (Sample* buf, nframes64_t position, nframes64_t cnt, int channel) const
+AudioRegion::read (Sample* buf, nframes64_t timeline_position, nframes64_t cnt, int channel) const
 {
        /* raw read, no fades, no gain, nada */
-       return _read_at (sources, _length, buf, 0, 0, _position + position, cnt, channel, 0, 0, true);
+       return _read_at (sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, 0, 0, ReadOps (0));
+}
+
+nframes64_t
+AudioRegion::read_with_ops (Sample* buf, nframes64_t file_position, nframes64_t cnt, int channel, ReadOps rops) const
+{
+       return _read_at (sources, _length, buf, 0, 0, file_position, cnt, channel, 0, 0, rops);
 }
 
 nframes_t
-AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position, 
+AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t file_position, 
                      nframes_t cnt, 
                      uint32_t chan_n, nframes_t read_frames, nframes_t skip_frames) const
 {
        /* regular diskstream/butler read complete with fades etc */
-       return _read_at (sources, _length, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, read_frames, skip_frames, false);
+       return _read_at (sources, _length, buf, mixdown_buffer, gain_buffer, file_position, cnt, 
+                        chan_n, read_frames, skip_frames, ReadOps (~0));
 }
 
 nframes_t
 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position, 
                             nframes_t cnt, uint32_t chan_n) const
 {
-       return _read_at (master_sources, master_sources.front()->length(), buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0);
+       /* do not read gain/scaling/fades and do not count this disk i/o in statistics */
+
+       return _read_at (master_sources, master_sources.front()->length(), buf, mixdown_buffer, 
+                        gain_buffer, position, cnt, chan_n, 0, 0, ReadOps (0));
 }
 
 nframes_t
@@ -487,11 +530,12 @@ AudioRegion::_read_at (const SourceList& srcs, nframes_t limit,
                       uint32_t chan_n, 
                       nframes_t read_frames, 
                       nframes_t skip_frames,
-                      bool raw) const
+                      ReadOps rops) const
 {
        nframes_t internal_offset;
        nframes_t buf_offset;
        nframes_t to_read;
+       bool raw = (rops == ReadOpsNone);
 
        if (muted() && !raw) {
                return 0; /* read nothing */
@@ -523,7 +567,7 @@ AudioRegion::_read_at (const SourceList& srcs, nframes_t limit,
                mixdown_buffer += buf_offset;
        }
 
-       if (!raw) {
+       if (rops & ReadOpsCount) {
                _read_data_count = 0;
        }
 
@@ -533,7 +577,7 @@ AudioRegion::_read_at (const SourceList& srcs, nframes_t limit,
                        return 0; /* "read nothing" */
                }
                
-               if (!raw) {
+               if (rops & ReadOpsCount) {
                        _read_data_count += srcs[chan_n]->read_data_count();
                }
 
@@ -544,18 +588,12 @@ AudioRegion::_read_at (const SourceList& srcs, nframes_t limit,
                */
 
                memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
-
-               /* no fades required */
-
-               if (!raw) {
-                       goto merge;
-               }
        }
 
-       /* fade in */
-
-       if (!raw) {
+       if (rops & ReadOpsFades) {
        
+               /* fade in */
+
                if ((_flags & FadeIn) && Config->get_use_region_fades()) {
                        
                        nframes_t fade_in_length = (nframes_t) _fade_in.back()->when;
@@ -564,13 +602,13 @@ AudioRegion::_read_at (const SourceList& srcs, nframes_t limit,
                        
                        if (internal_offset < fade_in_length) {
                                
-                               nframes_t limit;
+                               nframes_t fi_limit;
                                
-                               limit = min (to_read, fade_in_length - internal_offset);
+                               fi_limit = min (to_read, fade_in_length - internal_offset);
                                
-                               _fade_in.get_vector (internal_offset, internal_offset+limit, gain_buffer, limit);
+                               _fade_in.get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
                                
-                               for (nframes_t n = 0; n < limit; ++n) {
+                               for (nframes_t n = 0; n < fi_limit; ++n) {
                                        mixdown_buffer[n] *= gain_buffer[n];
                                }
                        }
@@ -583,12 +621,12 @@ AudioRegion::_read_at (const SourceList& srcs, nframes_t limit,
                        /* see if some part of this read is within the fade out */
                        
                /* .................        >|            REGION
-                                           limit
+                                            limit
                                            
                                  {           }            FADE
                                             fade_out_length
                                  ^                                          
-                                limit - fade_out_length
+                                 limit - fade_out_length
                         |--------------|
                         ^internal_offset
                                        ^internal_offset + to_read
@@ -618,39 +656,37 @@ AudioRegion::_read_at (const SourceList& srcs, nframes_t limit,
                        } 
                        
                }
+       }
                
-               /* Regular gain curves */
+        /* Regular gain curves and scaling */
+       
+       if ((rops & ReadOpsOwnAutomation) && envelope_active())  {
+               _envelope.get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
                
-               if (envelope_active())  {
-                       _envelope.get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
-                       
-                       if (_scale_amplitude != 1.0f) {
-                               for (nframes_t n = 0; n < to_read; ++n) {
-                                       mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
-                               }
-                       } else {
-                               for (nframes_t n = 0; n < to_read; ++n) {
-                                       mixdown_buffer[n] *= gain_buffer[n];
-                               }
+               if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
+                       for (nframes_t n = 0; n < to_read; ++n) {
+                               mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
+                       }
+               } else {
+                       for (nframes_t n = 0; n < to_read; ++n) {
+                               mixdown_buffer[n] *= gain_buffer[n];
                        }
-               } else if (_scale_amplitude != 1.0f) {
-                       Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
                }
+       } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
+               Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
+       }
        
-         merge:
+       if (!opaque()) {
                
-               if (!opaque()) {
-                       
-                       /* gack. the things we do for users.
-                        */
-                       
-                       buf += buf_offset;
+               /* gack. the things we do for users.
+                */
+               
+               buf += buf_offset;
                        
-                       for (nframes_t n = 0; n < to_read; ++n) {
-                               buf[n] += mixdown_buffer[n];
-                       }
-               } 
-       }
+               for (nframes_t n = 0; n < to_read; ++n) {
+                       buf[n] += mixdown_buffer[n];
+               }
+       } 
 
        return to_read;
 }
@@ -811,7 +847,7 @@ AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool sen
                        }
 
                        if ((prop = child->property ("active")) != 0) {
-                               if (prop->value() == "yes") {
+                               if (string_is_affirmative (prop->value())) {
                                        set_fade_in_active (true);
                                } else {
                                        set_fade_in_active (true);
@@ -832,7 +868,7 @@ AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool sen
                        }
 
                        if ((prop = child->property ("active")) != 0) {
-                               if (prop->value() == "yes") {
+                               if (string_is_affirmative (prop->value())) {
                                        set_fade_out_active (true);
                                } else {
                                        set_fade_out_active (false);
@@ -1600,14 +1636,21 @@ AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
 
        /* no existing/complete transient info */
 
+       static bool analyse_dialog_shown = false;
        if (!Config->get_auto_analyse_audio()) {
-               pl->session().Dialog (_("\
+               if ( !analyse_dialog_shown ) {
+                       pl->session().Dialog (_("\
 You have requested an operation that requires audio analysis.\n\n\
 You currently have \"auto-analyse-audio\" disabled, which means\n\
 that transient data must be generated every time it is required.\n\n\
 If you are doing work that will require transient data on a\n\
 regular basis, you should probably enable \"auto-analyse-audio\"\n\
-then quit ardour and restart."));
+then quit ardour and restart.\n\n\
+This dialog will not display again.  But you may notice a slight delay\n\
+in this and future transient-detection operations.\n\
+"));
+                       analyse_dialog_shown = true;  //only show this dialog once 
+                       }
        }
 
        TransientDetector t (pl->session().frame_rate());