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