add new sigc++2 directory
[ardour.git] / libs / ardour / audioregion.cc
1 /*
2     Copyright (C) 2000-2006 Paul Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <cmath>
21 #include <climits>
22 #include <cfloat>
23 #include <algorithm>
24
25 #include <set>
26
27 #include <sigc++/bind.h>
28 #include <sigc++/class_slot.h>
29
30 #include <glibmm/thread.h>
31
32 #include <pbd/basename.h>
33 #include <pbd/xml++.h>
34 #include <pbd/stacktrace.h>
35 #include <pbd/enumwriter.h>
36 #include <pbd/convert.h>
37
38 #include <ardour/audioregion.h>
39 #include <ardour/session.h>
40 #include <ardour/gain.h>
41 #include <ardour/dB.h>
42 #include <ardour/playlist.h>
43 #include <ardour/audiofilesource.h>
44 #include <ardour/region_factory.h>
45 #include <ardour/runtime_functions.h>
46 #include <ardour/transient_detector.h>
47
48 #include "i18n.h"
49 #include <locale.h>
50
51 using namespace std;
52 using namespace ARDOUR;
53 using namespace PBD;
54
55 /* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
56
57 Change AudioRegion::FadeInChanged         = ARDOUR::new_change();
58 Change AudioRegion::FadeOutChanged        = ARDOUR::new_change();
59 Change AudioRegion::FadeInActiveChanged   = ARDOUR::new_change();
60 Change AudioRegion::FadeOutActiveChanged  = ARDOUR::new_change();
61 Change AudioRegion::EnvelopeActiveChanged = ARDOUR::new_change();
62 Change AudioRegion::ScaleAmplitudeChanged = ARDOUR::new_change();
63 Change AudioRegion::EnvelopeChanged       = ARDOUR::new_change();
64
65 void
66 AudioRegion::init ()
67 {
68         _scale_amplitude = 1.0;
69
70         set_default_fades ();
71         set_default_envelope ();
72
73         listen_to_my_curves ();
74         listen_to_my_sources ();
75 }
76
77 /* constructor for use by derived types only */
78 AudioRegion::AudioRegion (Session& s, nframes_t start, nframes_t length, string name)
79         : Region (s, start, length, name, DataType::AUDIO)
80         , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0))
81         , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0))
82         , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0))
83 {
84         init ();
85 }
86
87 /** Basic AudioRegion constructor (one channel) */
88 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length)
89         : Region (src, start, length, PBD::basename_nosuffix(src->name()), DataType::AUDIO, 0,  Region::Flag(Region::DefaultFlags|Region::External))
90         , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0))
91         , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0))
92         , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0))
93 {
94         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
95         if (afs) {
96                 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
97         }
98
99         init ();
100 }
101
102 /* Basic AudioRegion constructor (one channel) */
103 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags)
104         : Region (src, start, length, name, DataType::AUDIO, layer, flags)
105         , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0))
106         , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0))
107         , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0))
108 {
109         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
110         if (afs) {
111                 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
112         }
113
114         init ();
115 }
116
117 /* Basic AudioRegion constructor (many channels) */
118 AudioRegion::AudioRegion (const SourceList& srcs, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags)
119         : Region (srcs, start, length, name, DataType::AUDIO, layer, flags)
120         , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0))
121         , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0))
122         , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0))
123 {
124         init ();
125         listen_to_my_sources ();
126 }
127
128 /** Create a new AudioRegion, that is part of an existing one */
129 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags)
130         : Region (other, offset, length, name, layer, flags)
131         , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0))
132         , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0))
133         , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0))
134 {
135         set<boost::shared_ptr<Source> > unique_srcs;
136
137         for (SourceList::const_iterator i= other->_sources.begin(); i != other->_sources.end(); ++i) {
138                 _sources.push_back (*i);
139
140                 pair<set<boost::shared_ptr<Source> >::iterator,bool> result;
141
142                 result = unique_srcs.insert (*i);
143                 
144                 if (result.second) {
145                         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
146                         if (afs) {
147                                 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
148                         }
149                 }
150         }
151
152         /* return to default fades if the existing ones are too long */
153         init ();
154
155         if (_flags & LeftOfSplit) {
156                 if (_fade_in->back()->when >= _length) {
157                         set_default_fade_in ();
158                 } else {
159                         _fade_in_disabled = other->_fade_in_disabled;
160                 }
161                 set_default_fade_out ();
162                 _flags = Flag (_flags & ~Region::LeftOfSplit);
163         }
164
165         if (_flags & RightOfSplit) {
166                 if (_fade_out->back()->when >= _length) {
167                         set_default_fade_out ();
168                 } else {
169                         _fade_out_disabled = other->_fade_out_disabled;
170                 }
171                 set_default_fade_in ();
172                 _flags = Flag (_flags & ~Region::RightOfSplit);
173         }
174
175         _scale_amplitude = other->_scale_amplitude;
176
177         assert(_type == DataType::AUDIO);
178         listen_to_my_sources ();
179 }
180
181 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
182         : Region (other)
183         , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0))
184         , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0))
185         , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0))
186 {
187         assert(_type == DataType::AUDIO);
188         _scale_amplitude = other->_scale_amplitude;
189         _envelope = other->_envelope;
190
191         set_default_fades ();
192         
193         listen_to_my_curves ();
194         listen_to_my_sources ();
195 }
196
197 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& node)
198         : Region (src, node)
199         , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0))
200         , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0))
201         , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0))
202 {
203         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
204         if (afs) {
205                 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
206         }
207
208         init ();
209
210         if (set_state (node)) {
211                 throw failed_constructor();
212         }
213
214         assert(_type == DataType::AUDIO);
215         listen_to_my_sources ();
216 }
217
218 AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
219         : Region (srcs, node)
220         , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0))
221         , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0))
222         , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0))
223 {
224         init ();
225
226         if (set_state (node)) {
227                 throw failed_constructor();
228         }
229
230         assert(_type == DataType::AUDIO);
231         listen_to_my_sources ();
232 }
233
234 AudioRegion::~AudioRegion ()
235 {
236 }
237
238 void
239 AudioRegion::listen_to_my_sources ()
240 {
241         for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
242                 (*i)->AnalysisChanged.connect (mem_fun (*this, &AudioRegion::invalidate_transients));
243         }
244 }
245
246 void
247 AudioRegion::listen_to_my_curves ()
248 {
249         _envelope->StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
250         _fade_in->StateChanged.connect (mem_fun (*this, &AudioRegion::fade_in_changed));
251         _fade_out->StateChanged.connect (mem_fun (*this, &AudioRegion::fade_out_changed));
252 }
253
254 void
255 AudioRegion::set_envelope_active (bool yn)
256 {
257         if (envelope_active() != yn) {
258                 char buf[64];
259                 if (yn) {
260                         snprintf (buf, sizeof (buf), "envelope active");
261                         _flags = Flag (_flags|EnvelopeActive);
262                 } else {
263                         snprintf (buf, sizeof (buf), "envelope off");
264                         _flags = Flag (_flags & ~EnvelopeActive);
265                 }
266                 send_change (EnvelopeActiveChanged);
267         }
268 }
269
270 ARDOUR::nframes_t
271 AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const
272 {
273         if (chan_n >= _sources.size()) {
274                 return 0; 
275         }
276
277         if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
278                 return 0;
279         } else {
280                 if (_scale_amplitude != 1.0) {
281                         for (nframes_t n = 0; n < npeaks; ++n) {
282                                 buf[n].max *= _scale_amplitude;
283                                 buf[n].min *= _scale_amplitude;
284                         }
285                 }
286                 return cnt;
287         }
288 }
289
290 nframes64_t
291 AudioRegion::read (Sample* buf, nframes64_t position, nframes64_t cnt, int channel) const
292 {
293         /* raw read, no fades, no gain, nada */
294         return _read_at (_sources, _length, buf, 0, 0, _position + position, cnt, channel, 0, 0, true);
295 }
296
297 nframes_t
298 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position, 
299                       nframes_t cnt, 
300                       uint32_t chan_n, nframes_t read_frames, nframes_t skip_frames) const
301 {
302         /* regular diskstream/butler read complete with fades etc */
303         return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, read_frames, skip_frames, false);
304 }
305
306 nframes_t
307 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position, 
308                              nframes_t cnt, uint32_t chan_n) const
309 {
310         return _read_at (_master_sources, _master_sources.front()->length(), buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0);
311 }
312
313 nframes_t
314 AudioRegion::_read_at (const SourceList& srcs, nframes_t limit,
315                        Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
316                        nframes_t position, nframes_t cnt, 
317                        uint32_t chan_n, 
318                        nframes_t read_frames, 
319                        nframes_t skip_frames,
320                        bool raw) const
321 {
322         nframes_t internal_offset;
323         nframes_t buf_offset;
324         nframes_t to_read;
325
326         if (muted() && !raw) {
327                 return 0; /* read nothing */
328         }
329
330         /* precondition: caller has verified that we cover the desired section */
331
332         if (position < _position) {
333                 internal_offset = 0;
334                 buf_offset = _position - position;
335                 cnt -= buf_offset;
336         } else {
337                 internal_offset = position - _position;
338                 buf_offset = 0;
339         }
340
341         if (internal_offset >= limit) {
342                 return 0; /* read nothing */
343         }
344
345         if ((to_read = min (cnt, limit - internal_offset)) == 0) {
346                 return 0; /* read nothing */
347         }
348
349         if (opaque() || raw) {
350                 /* overwrite whatever is there */
351                 mixdown_buffer = buf + buf_offset;
352         } else {
353                 mixdown_buffer += buf_offset;
354         }
355
356         if (!raw) {
357                 _read_data_count = 0;
358         }
359
360         if (chan_n < n_channels()) {
361
362                 boost::shared_ptr<AudioSource> src = audio_source(chan_n);
363                 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
364                         return 0; /* "read nothing" */
365                 }
366                 
367                 if (!raw) {
368                         _read_data_count += src->read_data_count();
369                 }
370
371         } else {
372                 
373                 /* track is N-channel, this region has less channels; silence the ones
374                    we don't have.
375                 */
376
377                 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
378
379                 /* no fades required */
380
381                 if (!raw) {
382                         goto merge;
383                 }
384         }
385
386         /* fade in */
387
388         if (!raw) {
389         
390                 if (_flags & FadeIn) {
391                         
392                         nframes_t fade_in_length = (nframes_t) _fade_in->back()->when;
393                         
394                         /* see if this read is within the fade in */
395                         
396                         if (internal_offset < fade_in_length) {
397                                 
398                                 nframes_t fi_limit;
399                                 
400                                 fi_limit = min (to_read, fade_in_length - internal_offset);
401                                 
402                                 _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
403                                 
404                                 for (nframes_t n = 0; n < fi_limit; ++n) {
405                                         mixdown_buffer[n] *= gain_buffer[n];
406                                 }
407                         }
408                 }
409                 
410                 /* fade out */
411                 
412                 if (_flags & FadeOut) {
413
414                         /* see if some part of this read is within the fade out */
415                         
416                 /* .................        >|            REGION
417                                             limit
418                                             
419                                  {           }            FADE
420                                              fade_out_length
421                                  ^                                           
422                                 limit - fade_out_length
423                         |--------------|
424                         ^internal_offset
425                                        ^internal_offset + to_read
426                                        
427                                        we need the intersection of [internal_offset,internal_offset+to_read] with
428                                        [limit - fade_out_length, limit]
429                                        
430                 */
431
432         
433                         nframes_t fade_out_length = (nframes_t) _fade_out->back()->when;
434                         nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
435                         nframes_t fade_interval_end   = min(internal_offset + to_read, limit);
436
437                         if (fade_interval_end > fade_interval_start) {
438                                 /* (part of the) the fade out is  in this buffer */
439
440                                 nframes_t fo_limit = fade_interval_end - fade_interval_start;
441                                 nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
442                                 nframes_t fade_offset = fade_interval_start - internal_offset;
443                                 
444                                 _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
445
446                                 for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
447                                         mixdown_buffer[m] *= gain_buffer[n];
448                                 }
449                         } 
450                         
451                 }
452                 
453                 /* Regular gain curves */
454                 
455                 if (envelope_active())  {
456                         _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
457                         
458                         if (_scale_amplitude != 1.0f) {
459                                 for (nframes_t n = 0; n < to_read; ++n) {
460                                         mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
461                                 }
462                         } else {
463                                 for (nframes_t n = 0; n < to_read; ++n) {
464                                         mixdown_buffer[n] *= gain_buffer[n];
465                                 }
466                         }
467                 } else if (_scale_amplitude != 1.0f) {
468                         Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
469                 }
470         
471           merge:
472                 
473                 if (!opaque()) {
474                         
475                         /* gack. the things we do for users.
476                          */
477                         
478                         buf += buf_offset;
479                         
480                         for (nframes_t n = 0; n < to_read; ++n) {
481                                 buf[n] += mixdown_buffer[n];
482                         }
483                 } 
484         }
485
486         return to_read;
487 }
488         
489 XMLNode&
490 AudioRegion::state (bool full)
491 {
492         XMLNode& node (Region::state (full));
493         XMLNode *child;
494         char buf[64];
495         char buf2[64];
496         LocaleGuard lg (X_("POSIX"));
497         
498         node.add_property ("flags", enum_2_string (_flags));
499
500         snprintf (buf, sizeof(buf), "%.12g", _scale_amplitude);
501         node.add_property ("scale-gain", buf);
502
503         // XXX these should move into Region
504
505         for (uint32_t n=0; n < _sources.size(); ++n) {
506                 snprintf (buf2, sizeof(buf2), "source-%d", n);
507                 _sources[n]->id().print (buf, sizeof (buf));
508                 node.add_property (buf2, buf);
509         }
510
511         for (uint32_t n=0; n < _master_sources.size(); ++n) {
512                 snprintf (buf2, sizeof(buf2), "master-source-%d", n);
513                 _master_sources[n]->id().print (buf, sizeof (buf));
514                 node.add_property (buf2, buf);
515         }
516
517         snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
518         node.add_property ("channels", buf);
519
520         if (full) {
521         
522                 child = node.add_child (X_("FadeIn"));
523                 
524                 if ((_flags & DefaultFadeIn)) {
525                         child->add_property (X_("default"), X_("yes"));
526                 } else {
527                         child->add_child_nocopy (_fade_in->get_state ());
528                 }
529
530                 child->add_property (X_("active"), _fade_in_disabled ? X_("no") : X_("yes"));
531                 
532                 child = node.add_child (X_("FadeOut"));
533                 
534                 if ((_flags & DefaultFadeOut)) {
535                         child->add_property (X_("default"), X_("yes"));
536                 } else {
537                         child->add_child_nocopy (_fade_out->get_state ());
538                 }
539                 
540                 child->add_property (X_("active"), _fade_out_disabled ? X_("no") : X_("yes"));
541         }
542         
543         child = node.add_child ("Envelope");
544
545         if (full) {
546                 bool default_env = false;
547                 
548                 // If there are only two points, the points are in the start of the region and the end of the region
549                 // so, if they are both at 1.0f, that means the default region.
550
551                 if (_envelope->size() == 2 &&
552                     _envelope->front()->value == 1.0f &&
553                     _envelope->back()->value==1.0f) {
554                         if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
555                                 default_env = true;
556                         }
557                 } 
558
559                 if (default_env) {
560                         child->add_property ("default", "yes");
561                 } else {
562                         child->add_child_nocopy (_envelope->get_state ());
563                 }
564
565         } else {
566                 child->add_property ("default", "yes");
567         }
568
569         if (full && _extra_xml) {
570                 node.add_child_copy (*_extra_xml);
571         }
572
573         return node;
574 }
575
576 int
577 AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool send)
578 {
579         const XMLNodeList& nlist = node.children();
580         const XMLProperty *prop;
581         LocaleGuard lg (X_("POSIX"));
582
583         Region::set_live_state (node, what_changed, false);
584
585         uint32_t old_flags = _flags;
586
587         if ((prop = node.property ("flags")) != 0) {
588                 _flags = Flag (string_2_enum (prop->value(), _flags));
589
590                 //_flags = Flag (strtol (prop->value().c_str(), (char **) 0, 16));
591
592                 _flags = Flag (_flags & ~Region::LeftOfSplit);
593                 _flags = Flag (_flags & ~Region::RightOfSplit);
594         }
595
596         if ((old_flags ^ _flags) & Muted) {
597                 what_changed = Change (what_changed|MuteChanged);
598         }
599         if ((old_flags ^ _flags) & Opaque) {
600                 what_changed = Change (what_changed|OpacityChanged);
601         }
602         if ((old_flags ^ _flags) & Locked) {
603                 what_changed = Change (what_changed|LockChanged);
604         }
605
606         if ((prop = node.property ("scale-gain")) != 0) {
607                 _scale_amplitude = atof (prop->value().c_str());
608                 what_changed = Change (what_changed|ScaleAmplitudeChanged);
609         } else {
610                 _scale_amplitude = 1.0;
611         }
612         
613         /* Now find envelope description and other misc child items */
614                                 
615         for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
616                 
617                 XMLNode *child;
618                 XMLProperty *prop;
619                 
620                 child = (*niter);
621                 
622                 if (child->name() == "Envelope") {
623
624                         _envelope->clear ();
625
626                         if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child)) {
627                                 set_default_envelope ();
628                         }
629
630                         _envelope->set_max_xval (_length);
631                         _envelope->truncate_end (_length);
632
633                 } else if (child->name() == "FadeIn") {
634                         
635                         _fade_in->clear ();
636                         
637                         if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
638                                 set_default_fade_in ();
639                         } else {
640                                 XMLNode* grandchild = child->child ("AutomationList");
641                                 if (grandchild) {
642                                         _fade_in->set_state (*grandchild);
643                                 }
644                         }
645
646                         if ((prop = child->property ("active")) != 0) {
647                                 if (prop->value() == "yes") {
648                                         set_fade_in_active (true);
649                                 } else {
650                                         set_fade_in_active (true);
651                                 }
652                         }
653
654                 } else if (child->name() == "FadeOut") {
655                         
656                         _fade_out->clear ();
657
658                         if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
659                                 set_default_fade_out ();
660                         } else {
661                                 XMLNode* grandchild = child->child ("AutomationList");
662                                 if (grandchild) {
663                                         _fade_out->set_state (*grandchild);
664                                 } 
665                         }
666
667                         if ((prop = child->property ("active")) != 0) {
668                                 if (prop->value() == "yes") {
669                                         set_fade_out_active (true);
670                                 } else {
671                                         set_fade_out_active (false);
672                                 }
673                         }
674
675                 } 
676         }
677
678         if (send) {
679                 send_change (what_changed);
680         }
681
682         return 0;
683 }
684
685 int
686 AudioRegion::set_state (const XMLNode& node)
687 {
688         /* Region::set_state() calls the virtual set_live_state(),
689            which will get us back to AudioRegion::set_live_state()
690            to handle the relevant stuff.
691         */
692
693         return Region::set_state (node);
694 }
695
696 void
697 AudioRegion::set_fade_in_shape (FadeShape shape)
698 {
699         set_fade_in (shape, (nframes_t) _fade_in->back()->when);
700 }
701
702 void
703 AudioRegion::set_fade_out_shape (FadeShape shape)
704 {
705         set_fade_out (shape, (nframes_t) _fade_out->back()->when);
706 }
707
708 void
709 AudioRegion::set_fade_in (FadeShape shape, nframes_t len)
710 {
711         _fade_in->freeze ();
712         _fade_in->clear ();
713
714         switch (shape) {
715         case Linear:
716                 _fade_in->fast_simple_add (0.0, 0.0);
717                 _fade_in->fast_simple_add (len, 1.0);
718                 break;
719
720         case Fast:
721                 _fade_in->fast_simple_add (0, 0);
722                 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
723                 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
724                 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
725                 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
726                 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
727                 _fade_in->fast_simple_add (len, 1);
728                 break;
729
730         case Slow:
731                 _fade_in->fast_simple_add (0, 0);
732                 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
733                 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
734                 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
735                 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
736                 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
737                 _fade_in->fast_simple_add (len * 0.767281, 1);
738                 _fade_in->fast_simple_add (len, 1);
739                 break;
740
741         case LogA:
742                 _fade_in->fast_simple_add (0, 0);
743                 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
744                 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
745                 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
746                 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
747                 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
748                 _fade_in->fast_simple_add (len, 1);
749                 break;
750
751         case LogB:
752                 _fade_in->fast_simple_add (0, 0);
753                 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
754                 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
755                 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
756                 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
757                 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
758                 _fade_in->fast_simple_add (len, 1);
759                 break;
760         }
761
762         _fade_in->thaw ();
763         _fade_in_shape = shape;
764
765         send_change (FadeInChanged);
766 }
767
768 void
769 AudioRegion::set_fade_out (FadeShape shape, nframes_t len)
770 {
771         _fade_out->freeze ();
772         _fade_out->clear ();
773
774         switch (shape) {
775         case Fast:
776                 _fade_out->fast_simple_add (len * 0, 1);
777                 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
778                 _fade_out->fast_simple_add (len * 0.0553,   0.483333);
779                 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
780                 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
781                 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
782                 _fade_out->fast_simple_add (len * 1, 0);
783                 break;
784
785         case LogA:
786                 _fade_out->fast_simple_add (len * 0, 1);
787                 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
788                 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
789                 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
790                 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
791                 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
792                 _fade_out->fast_simple_add (len * 1, 0);
793                 break;
794
795         case Slow:
796                 _fade_out->fast_simple_add (len * 0, 1);
797                 _fade_out->fast_simple_add (len * 0.305556, 1);
798                 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
799                 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
800                 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
801                 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
802                 _fade_out->fast_simple_add (len * 1, 0);
803                 break;
804
805         case LogB:
806                 _fade_out->fast_simple_add (len * 0, 1);
807                 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
808                 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
809                 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
810                 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
811                 _fade_out->fast_simple_add (len * 1, 0);
812                 break;
813
814         case Linear:
815                 _fade_out->fast_simple_add (len * 0, 1);
816                 _fade_out->fast_simple_add (len * 1, 0);
817                 break;
818         }
819
820         _fade_out->thaw ();
821         _fade_out_shape = shape;
822
823         send_change (FadeOutChanged);
824 }
825
826 void
827 AudioRegion::set_fade_in_length (nframes_t len)
828 {
829         if (len > _length) {
830                 len = _length - 1;
831         }
832
833         bool changed = _fade_in->extend_to (len);
834
835         if (changed) {
836                 _flags = Flag (_flags & ~DefaultFadeIn);
837                 send_change (FadeInChanged);
838         }
839 }
840
841 void
842 AudioRegion::set_fade_out_length (nframes_t len)
843 {
844         if (len > _length) {
845                 len = _length - 1;
846         }
847
848         bool changed =  _fade_out->extend_to (len);
849
850         if (changed) {
851                 _flags = Flag (_flags & ~DefaultFadeOut);
852                 send_change (FadeOutChanged);
853         }
854 }
855
856 void
857 AudioRegion::set_fade_in_active (bool yn)
858 {
859         if (yn == (_flags & FadeIn)) {
860                 return;
861         }
862         if (yn) {
863                 _flags = Flag (_flags|FadeIn);
864         } else {
865                 _flags = Flag (_flags & ~FadeIn);
866         }
867
868         send_change (FadeInActiveChanged);
869 }
870
871 void
872 AudioRegion::set_fade_out_active (bool yn)
873 {
874         if (yn == (_flags & FadeOut)) {
875                 return;
876         }
877         if (yn) {
878                 _flags = Flag (_flags | FadeOut);
879         } else {
880                 _flags = Flag (_flags & ~FadeOut);
881         }
882
883         send_change (FadeOutActiveChanged);
884 }
885
886 bool
887 AudioRegion::fade_in_is_default () const
888 {
889         return _fade_in_shape == Linear && _fade_in->back()->when == 64;
890 }
891
892 bool
893 AudioRegion::fade_out_is_default () const
894 {
895         return _fade_out_shape == Linear && _fade_out->back()->when == 64;
896 }
897
898 void
899 AudioRegion::set_default_fade_in ()
900 {
901         set_fade_in (Linear, 64);
902 }
903
904 void
905 AudioRegion::set_default_fade_out ()
906 {
907         set_fade_out (Linear, 64);
908 }
909
910 void
911 AudioRegion::set_default_fades ()
912 {
913         _fade_in_disabled = 0;
914         _fade_out_disabled = 0;
915         set_default_fade_in ();
916         set_default_fade_out ();
917 }
918
919 void
920 AudioRegion::set_default_envelope ()
921 {
922         _envelope->freeze ();
923         _envelope->clear ();
924         _envelope->fast_simple_add (0, 1.0f);
925         _envelope->fast_simple_add (_length, 1.0f);
926         _envelope->thaw ();
927 }
928
929 void
930 AudioRegion::recompute_at_end ()
931 {
932         /* our length has changed. recompute a new final point by interpolating 
933            based on the the existing curve.
934         */
935         
936         _envelope->freeze ();
937         _envelope->truncate_end (_length);
938         _envelope->set_max_xval (_length);
939         _envelope->thaw ();
940
941         if (_fade_in->back()->when > _length) {
942                 _fade_in->extend_to (_length);
943                 send_change (FadeInChanged);
944         }
945
946         if (_fade_out->back()->when > _length) {
947                 _fade_out->extend_to (_length);
948                 send_change (FadeOutChanged);
949         }
950 }       
951
952 void
953 AudioRegion::recompute_at_start ()
954 {
955         /* as above, but the shift was from the front */
956
957         _envelope->truncate_start (_length);
958
959         if (_fade_in->back()->when > _length) {
960                 _fade_in->extend_to (_length);
961                 send_change (FadeInChanged);
962         }
963
964         if (_fade_out->back()->when > _length) {
965                 _fade_out->extend_to (_length);
966                 send_change (FadeOutChanged);
967         }
968 }
969
970 int
971 AudioRegion::separate_by_channel (Session& session, vector<boost::shared_ptr<AudioRegion> >& v) const
972 {
973         SourceList srcs;
974         string new_name;
975         int n;
976
977         if (_sources.size() < 2) {
978                 return 0;
979         }
980
981         n = 0;
982
983         for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
984
985                 srcs.clear ();
986                 srcs.push_back (*i);
987
988                 new_name = _name;
989
990                 if (_sources.size() == 2) {
991                         if (n == 0) {
992                                 new_name += "-L";
993                         } else {
994                                 new_name += "-R";
995                         }
996                 } else {
997                         new_name += '-';
998                         new_name += ('0' + n + 1);
999                 }
1000
1001                 /* create a copy with just one source. prevent if from being thought of as "whole file" even if 
1002                    it covers the entire source file(s).
1003                  */
1004
1005                 Flag f = Flag (_flags & ~WholeFile);
1006
1007                 boost::shared_ptr<Region> r = RegionFactory::create (srcs, _start, _length, new_name, _layer, f);
1008                 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (r);
1009
1010                 v.push_back (ar);
1011                 
1012                 ++n;
1013         }
1014
1015         return 0;
1016 }
1017
1018 nframes_t
1019 AudioRegion::read_raw_internal (Sample* buf, nframes_t pos, nframes_t cnt) const
1020 {
1021         return audio_source()->read  (buf, pos, cnt);
1022 }
1023
1024 int
1025 AudioRegion::exportme (Session& session, ARDOUR::ExportSpecification& spec)
1026 {
1027         const nframes_t blocksize = 4096;
1028         nframes_t to_read;
1029         int status = -1;
1030
1031         spec.channels = _sources.size();
1032
1033         if (spec.prepare (blocksize, session.frame_rate())) {
1034                 goto out;
1035         }
1036
1037         spec.pos = 0;
1038         spec.total_frames = _length;
1039
1040         while (spec.pos < _length && !spec.stop) {
1041                 
1042                 
1043                 /* step 1: interleave */
1044                 
1045                 to_read = min (_length - spec.pos, blocksize);
1046                 
1047                 if (spec.channels == 1) {
1048
1049                         if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1050                                 goto out;
1051                         }
1052
1053                 } else {
1054
1055                         Sample buf[blocksize];
1056
1057                         for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1058                                 
1059                                 if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1060                                         goto out;
1061                                 }
1062                                 
1063                                 for (nframes_t x = 0; x < to_read; ++x) {
1064                                         spec.dataF[chan+(x*spec.channels)] = buf[x];
1065                                 }
1066                         }
1067                 }
1068                 
1069                 if (spec.process (to_read)) {
1070                         goto out;
1071                 }
1072                 
1073                 spec.pos += to_read;
1074                 spec.progress = (double) spec.pos /_length;
1075                 
1076         }
1077         
1078         status = 0;
1079
1080   out:  
1081         spec.running = false;
1082         spec.status = status;
1083         spec.clear();
1084         
1085         return status;
1086 }
1087
1088 void
1089 AudioRegion::set_scale_amplitude (gain_t g)
1090 {
1091         boost::shared_ptr<Playlist> pl (playlist());
1092
1093         _scale_amplitude = g;
1094
1095         /* tell the diskstream we're in */
1096         
1097         if (pl) {
1098                 pl->Modified();
1099         }
1100
1101         /* tell everybody else */
1102
1103         send_change (ScaleAmplitudeChanged);
1104 }
1105
1106 void
1107 AudioRegion::normalize_to (float target_dB)
1108 {
1109         const nframes_t blocksize = 64 * 1024;
1110         Sample buf[blocksize];
1111         nframes_t fpos;
1112         nframes_t fend;
1113         nframes_t to_read;
1114         double maxamp = 0;
1115         gain_t target = dB_to_coefficient (target_dB);
1116
1117         if (target == 1.0f) {
1118                 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1119                    that we may have clipped.
1120                 */
1121                 target -= FLT_EPSILON;
1122         }
1123
1124         fpos = _start;
1125         fend = _start + _length;
1126
1127         /* first pass: find max amplitude */
1128
1129         while (fpos < fend) {
1130
1131                 uint32_t n;
1132
1133                 to_read = min (fend - fpos, blocksize);
1134
1135                 for (n = 0; n < n_channels(); ++n) {
1136
1137                         /* read it in */
1138
1139                         if (read_raw_internal (buf, fpos, to_read) != to_read) {
1140                                 return;
1141                         }
1142                         
1143                         maxamp = compute_peak (buf, to_read, maxamp);
1144                 }
1145
1146                 fpos += to_read;
1147         };
1148
1149         if (maxamp == 0.0f) {
1150                 /* don't even try */
1151                 return;
1152         }
1153
1154         if (maxamp == target) {
1155                 /* we can't do anything useful */
1156                 return;
1157         }
1158
1159         /* compute scale factor */
1160
1161         _scale_amplitude = target/maxamp;
1162
1163         /* tell the diskstream we're in */
1164
1165         boost::shared_ptr<Playlist> pl (playlist());
1166
1167         if (pl) {
1168                 pl->Modified();
1169         }
1170
1171         /* tell everybody else */
1172
1173         send_change (ScaleAmplitudeChanged);
1174 }
1175
1176 void
1177 AudioRegion::fade_in_changed ()
1178 {
1179         send_change (FadeInChanged);
1180 }
1181
1182 void
1183 AudioRegion::fade_out_changed ()
1184 {
1185         send_change (FadeOutChanged);
1186 }
1187
1188 void
1189 AudioRegion::envelope_changed ()
1190 {
1191         send_change (EnvelopeChanged);
1192 }
1193
1194 void
1195 AudioRegion::suspend_fade_in ()
1196 {
1197         if (++_fade_in_disabled == 1) {
1198                 if (fade_in_is_default()) {
1199                         set_fade_in_active (false);
1200                 }
1201         }
1202 }
1203
1204 void
1205 AudioRegion::resume_fade_in ()
1206 {
1207         if (--_fade_in_disabled == 0 && _fade_in_disabled) {
1208                 set_fade_in_active (true);
1209         }
1210 }
1211
1212 void
1213 AudioRegion::suspend_fade_out ()
1214 {
1215         if (++_fade_out_disabled == 1) {
1216                 if (fade_out_is_default()) {
1217                         set_fade_out_active (false);
1218                 }
1219         }
1220 }
1221
1222 void
1223 AudioRegion::resume_fade_out ()
1224 {
1225         if (--_fade_out_disabled == 0 &&_fade_out_disabled) {
1226                 set_fade_out_active (true);
1227         }
1228 }
1229
1230 bool
1231 AudioRegion::speed_mismatch (float sr) const
1232 {
1233         if (_sources.empty()) {
1234                 /* impossible, but ... */
1235                 return false;
1236         }
1237
1238         float fsr = audio_source()->sample_rate();
1239
1240         return fsr != sr;
1241 }
1242
1243 void
1244 AudioRegion::source_offset_changed ()
1245 {
1246         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1247
1248         if (afs && afs->destructive()) {
1249                 // set_start (source()->natural_position(), this);
1250                 set_position (source()->natural_position(), this);
1251         } 
1252 }
1253
1254 boost::shared_ptr<AudioSource>
1255 AudioRegion::audio_source (uint32_t n) const
1256 {
1257         // Guaranteed to succeed (use a static cast for speed?)
1258         return boost::dynamic_pointer_cast<AudioSource>(source(n));
1259 }
1260
1261 int
1262 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1263 {
1264         boost::shared_ptr<Playlist> pl = playlist();
1265
1266         if (!pl) {
1267                 return -1;
1268         }
1269
1270         if (_valid_transients && !force_new) {
1271                 results = _transients;
1272                 return 0;
1273         }
1274
1275         SourceList::iterator s;
1276         
1277         for (s = _sources.begin() ; s != _sources.end(); ++s) {
1278                 if (!(*s)->has_been_analysed()) {
1279                         cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1280                         break;
1281                 }
1282         }
1283         
1284         if (s == _sources.end()) {
1285                 /* all sources are analyzed, merge data from each one */
1286
1287                 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1288
1289                         /* find the set of transients within the bounds of this region */
1290
1291                         AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1292                                                                          (*s)->transients.end(),
1293                                                                          _start);
1294
1295                         AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1296                                                                           (*s)->transients.end(),
1297                                                                           _start + _length);
1298                                                                          
1299                         /* and add them */
1300
1301                         results.insert (results.end(), low, high);
1302                 }
1303
1304                 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1305                 
1306                 /* translate all transients to current position */
1307
1308                 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1309                         (*x) -= _start;
1310                         (*x) += _position;
1311                 }
1312
1313                 _transients = results;
1314                 _valid_transients = true;
1315
1316                 return 0;
1317         }
1318
1319         /* no existing/complete transient info */
1320
1321         if (!Config->get_auto_analyse_audio()) {
1322                 pl->session().Dialog (_("\
1323 You have requested an operation that requires audio analysis.\n\n\
1324 You currently have \"auto-analyse-audio\" disabled, which means\n\
1325 that transient data must be generated every time it is required.\n\n\
1326 If you are doing work that will require transient data on a\n\
1327 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1328 then quit ardour and restart."));
1329         }
1330
1331         TransientDetector t (pl->session().frame_rate());
1332         bool existing_results = !results.empty();
1333
1334         _transients.clear ();
1335         _valid_transients = false;
1336
1337         for (uint32_t i = 0; i < n_channels(); ++i) {
1338
1339                 AnalysisFeatureList these_results;
1340
1341                 t.reset ();
1342
1343                 if (t.run ("", this, i, these_results)) {
1344                         return -1;
1345                 }
1346
1347                 /* translate all transients to give absolute position */
1348                 
1349                 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1350                         (*i) += _position;
1351                 }
1352
1353                 /* merge */
1354                 
1355                 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1356         }
1357         
1358         if (!results.empty()) {
1359                 if (existing_results) {
1360                         
1361                         /* merge our transients into the existing ones, then clean up
1362                            those.
1363                         */
1364
1365                         results.insert (results.end(), _transients.begin(), _transients.end());
1366                         TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1367                 }
1368
1369                 /* make sure ours are clean too */
1370
1371                 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1372
1373         } else {
1374
1375                 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1376                 results = _transients;
1377         }
1378
1379         _valid_transients = true;
1380
1381         return 0;
1382 }
1383
1384 extern "C" {
1385
1386         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) 
1387 {
1388         return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (nframes_t) npeaks, (nframes_t) start, (nframes_t) cnt, n_chan,samples_per_unit);
1389 }
1390
1391 uint32_t region_length_from_c (void *arg)
1392 {
1393
1394         return ((AudioRegion *) arg)->length();
1395 }
1396
1397 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1398 {
1399         return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;
1400 }
1401
1402 } /* extern "C" */