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