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