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