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