Remove unnecessary 0 checks before delete; see http://www.parashift.com/c++-faq-lite...
[ardour.git] / libs / ardour / export_format_manager.cc
1 /*
2     Copyright (C) 2008 Paul Davis
3     Author: Sakari Bergen
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 */
20
21 #include <ardour/export_format_manager.h>
22
23 #include <ardour/types.h>
24 #include <ardour/export_format_specification.h>
25 #include <ardour/export_format_compatibility.h>
26
27 #include "i18n.h"
28
29 namespace ARDOUR
30 {
31
32 ExportFormatManager::ExportFormatManager (SpecPtr specification) :
33   pending_selection_change (false),
34   universal_set (new ExportFormatBase ())
35 {
36         current_selection = specification;
37
38         init_compatibilities ();
39         init_qualities ();
40         init_formats ();
41         init_sample_rates ();
42 }
43
44 ExportFormatManager::~ExportFormatManager ()
45 {
46
47 }
48
49 void
50 ExportFormatManager::init_compatibilities ()
51 {       
52         CompatPtr c_ptr;
53         
54         c_ptr.reset (new ExportFormatCompatibility (_("CD")));
55         c_ptr->add_sample_rate (ExportFormatBase::SR_44_1);
56         c_ptr->add_format_id (ExportFormatBase::F_WAV);
57         c_ptr->add_format_id (ExportFormatBase::F_AIFF);
58         c_ptr->add_quality (ExportFormatBase::Q_LosslessLinear);
59         c_ptr->add_sample_format (ExportFormatBase::SF_16);
60         c_ptr->add_endianness (ExportFormatBase::E_FileDefault);
61         add_compatibility (c_ptr);
62         
63         c_ptr.reset (new ExportFormatCompatibility (_("DVD-A")));
64         c_ptr->add_sample_rate (ExportFormatBase::SR_44_1);
65         c_ptr->add_sample_rate (ExportFormatBase::SR_48);
66         c_ptr->add_sample_rate (ExportFormatBase::SR_88_2);
67         c_ptr->add_sample_rate (ExportFormatBase::SR_96);
68         c_ptr->add_sample_rate (ExportFormatBase::SR_192);
69         c_ptr->add_format_id (ExportFormatBase::F_WAV);
70         c_ptr->add_format_id (ExportFormatBase::F_AIFF);
71         c_ptr->add_quality (ExportFormatBase::Q_LosslessLinear);
72         c_ptr->add_sample_format (ExportFormatBase::SF_16);
73         c_ptr->add_sample_format (ExportFormatBase::SF_24);
74         c_ptr->add_endianness (ExportFormatBase::E_FileDefault);
75         add_compatibility (c_ptr);
76         
77         c_ptr.reset (new ExportFormatCompatibility (_("iPod")));
78         c_ptr->add_sample_rate (ExportFormatBase::SR_44_1);
79         c_ptr->add_sample_rate (ExportFormatBase::SR_48);
80         c_ptr->add_format_id (ExportFormatBase::F_WAV);
81         c_ptr->add_format_id (ExportFormatBase::F_AIFF);
82         c_ptr->add_quality (ExportFormatBase::Q_LosslessLinear);
83         c_ptr->add_sample_format (ExportFormatBase::SF_16);
84         c_ptr->add_sample_format (ExportFormatBase::SF_24);
85         c_ptr->add_endianness (ExportFormatBase::E_FileDefault);
86         add_compatibility (c_ptr);
87         
88         c_ptr.reset (new ExportFormatCompatibility (_("Something else")));
89         c_ptr->add_sample_rate (ExportFormatBase::SR_44_1);
90         c_ptr->add_sample_rate (ExportFormatBase::SR_48);
91         c_ptr->add_format_id (ExportFormatBase::F_WAV);
92         c_ptr->add_format_id (ExportFormatBase::F_AIFF);
93         c_ptr->add_format_id (ExportFormatBase::F_AU);
94         c_ptr->add_format_id (ExportFormatBase::F_FLAC);
95         c_ptr->add_quality (ExportFormatBase::Q_LosslessLinear);
96         c_ptr->add_quality (ExportFormatBase::Q_LosslessCompression);
97         c_ptr->add_sample_format (ExportFormatBase::SF_16);
98         c_ptr->add_sample_format (ExportFormatBase::SF_24);
99         c_ptr->add_sample_format (ExportFormatBase::SF_32);
100         c_ptr->add_endianness (ExportFormatBase::E_FileDefault);
101         add_compatibility (c_ptr);
102 }
103
104 void
105 ExportFormatManager::init_qualities ()
106 {
107         add_quality (QualityPtr (new QualityState (ExportFormatBase::Q_Any, _("Any"))));
108         add_quality (QualityPtr (new QualityState (ExportFormatBase::Q_LosslessLinear, _("Lossless (linear PCM)"))));
109         add_quality (QualityPtr (new QualityState (ExportFormatBase::Q_LossyCompression, _("Lossy compression"))));
110         add_quality (QualityPtr (new QualityState (ExportFormatBase::Q_LosslessCompression, _("Lossless compression"))));
111 }
112
113 void
114 ExportFormatManager::init_formats ()
115 {       
116         FormatPtr f_ptr;
117         ExportFormatLinear * fl_ptr;
118         
119         f_ptr.reset (fl_ptr = new ExportFormatLinear ("AIFF", ExportFormatBase::F_AIFF));
120         fl_ptr->add_sample_format (ExportFormatBase::SF_U8);
121         fl_ptr->add_sample_format (ExportFormatBase::SF_8);
122         fl_ptr->add_sample_format (ExportFormatBase::SF_16);
123         fl_ptr->add_sample_format (ExportFormatBase::SF_24);
124         fl_ptr->add_sample_format (ExportFormatBase::SF_32);
125         fl_ptr->add_sample_format (ExportFormatBase::SF_Float);
126         fl_ptr->add_sample_format (ExportFormatBase::SF_Double);
127         fl_ptr->set_default_sample_format (ExportFormatBase::SF_16);
128         fl_ptr->set_extension ("aiff");
129         add_format (f_ptr);
130         
131         f_ptr.reset (fl_ptr = new ExportFormatLinear ("AU", ExportFormatBase::F_AU));
132         fl_ptr->add_sample_format (ExportFormatBase::SF_8);
133         fl_ptr->add_sample_format (ExportFormatBase::SF_16);
134         fl_ptr->add_sample_format (ExportFormatBase::SF_24);
135         fl_ptr->add_sample_format (ExportFormatBase::SF_32);
136         fl_ptr->add_sample_format (ExportFormatBase::SF_Float);
137         fl_ptr->add_sample_format (ExportFormatBase::SF_Double);
138         fl_ptr->set_default_sample_format (ExportFormatBase::SF_16);
139         fl_ptr->set_extension ("au");
140         add_format (f_ptr);
141         
142         f_ptr.reset (new ExportFormatBWF ());
143         add_format (f_ptr);
144         
145         f_ptr.reset (fl_ptr = new ExportFormatLinear ("IRCAM", ExportFormatBase::F_IRCAM));
146         fl_ptr->add_sample_format (ExportFormatBase::SF_16);
147         fl_ptr->add_sample_format (ExportFormatBase::SF_24);
148         fl_ptr->add_sample_format (ExportFormatBase::SF_32);
149         fl_ptr->add_sample_format (ExportFormatBase::SF_Float);
150         fl_ptr->set_default_sample_format (ExportFormatBase::SF_24);
151         fl_ptr->set_extension ("sf");
152         add_format (f_ptr);
153         
154         f_ptr.reset (fl_ptr = new ExportFormatLinear ("WAV", ExportFormatBase::F_WAV));
155         fl_ptr->add_sample_format (ExportFormatBase::SF_U8);
156         fl_ptr->add_sample_format (ExportFormatBase::SF_16);
157         fl_ptr->add_sample_format (ExportFormatBase::SF_24);
158         fl_ptr->add_sample_format (ExportFormatBase::SF_32);
159         fl_ptr->add_sample_format (ExportFormatBase::SF_Float);
160         fl_ptr->add_sample_format (ExportFormatBase::SF_Double);
161         fl_ptr->set_default_sample_format (ExportFormatBase::SF_16);
162         fl_ptr->set_extension ("wav");
163         add_format (f_ptr);
164         
165         f_ptr.reset (fl_ptr = new ExportFormatLinear ("W64", ExportFormatBase::F_W64));
166         fl_ptr->add_sample_format (ExportFormatBase::SF_U8);
167         fl_ptr->add_sample_format (ExportFormatBase::SF_16);
168         fl_ptr->add_sample_format (ExportFormatBase::SF_24);
169         fl_ptr->add_sample_format (ExportFormatBase::SF_32);
170         fl_ptr->add_sample_format (ExportFormatBase::SF_Float);
171         fl_ptr->add_sample_format (ExportFormatBase::SF_Double);
172         fl_ptr->set_default_sample_format (ExportFormatBase::SF_Double);
173         fl_ptr->set_extension ("w64");
174         add_format (f_ptr);
175         
176         f_ptr.reset (fl_ptr = new ExportFormatLinear ("RAW", ExportFormatBase::F_RAW));
177         fl_ptr->add_sample_format (ExportFormatBase::SF_U8);
178         fl_ptr->add_sample_format (ExportFormatBase::SF_8);
179         fl_ptr->add_sample_format (ExportFormatBase::SF_16);
180         fl_ptr->add_sample_format (ExportFormatBase::SF_24);
181         fl_ptr->add_sample_format (ExportFormatBase::SF_32);
182         fl_ptr->add_sample_format (ExportFormatBase::SF_Float);
183         fl_ptr->add_sample_format (ExportFormatBase::SF_Double);
184         fl_ptr->set_default_sample_format (ExportFormatBase::SF_Float);
185         fl_ptr->set_extension ("raw");
186         add_format (f_ptr);
187         
188         try {
189                 f_ptr.reset (new ExportFormatOggVorbis ());
190                 add_format (f_ptr);
191         } catch (ExportFormatIncompatible & e) {}
192         
193         try {
194                 f_ptr.reset (new ExportFormatFLAC ());
195                 add_format (f_ptr);
196         } catch (ExportFormatIncompatible & e) {}
197 }
198
199 void
200 ExportFormatManager::init_sample_rates ()
201 {
202         add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_22_05, "22,05 kHz")));
203         add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_44_1, "44,1 kHz")));
204         add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_48, "48 kHz")));      
205         add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_88_2, "88,2 kHz")));  
206         add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_96, "96 kHz")));      
207         add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_192, "192 kHz")));
208 }
209
210 void
211 ExportFormatManager::add_compatibility (CompatPtr ptr)
212 {
213         compatibilities.push_back (ptr);
214         ptr->SelectChanged.connect (sigc::bind (sigc::mem_fun (*this, &ExportFormatManager::change_compatibility_selection), WeakCompatPtr (ptr)));
215 }
216
217 void
218 ExportFormatManager::add_quality (QualityPtr ptr)
219 {
220         ptr->SelectChanged.connect (sigc::bind (sigc::mem_fun (*this, &ExportFormatManager::change_quality_selection), WeakQualityPtr (ptr)));
221         qualities.push_back (ptr);
222 }
223
224 void
225 ExportFormatManager::add_format (FormatPtr ptr)
226 {
227         formats.push_back (ptr);
228         ptr->SelectChanged.connect (sigc::bind (sigc::mem_fun (*this, &ExportFormatManager::change_format_selection), WeakFormatPtr (ptr)));
229         universal_set = universal_set->get_union (*ptr);
230         
231         /* Encoding options */
232         
233         boost::shared_ptr<HasSampleFormat> hsf;
234         
235         if (hsf = boost::dynamic_pointer_cast<HasSampleFormat> (ptr)) {
236                 hsf->SampleFormatSelectChanged.connect (sigc::mem_fun (*this, &ExportFormatManager::change_sample_format_selection));
237                 hsf->DitherTypeSelectChanged.connect (sigc::mem_fun (*this, &ExportFormatManager::change_dither_type_selection));
238         }
239 }
240
241 void
242 ExportFormatManager::add_sample_rate (SampleRatePtr ptr)
243 {
244         ptr->SelectChanged.connect (sigc::bind (sigc::mem_fun (*this, &ExportFormatManager::change_sample_rate_selection), WeakSampleRatePtr (ptr)));
245         sample_rates.push_back (ptr);
246 }
247
248 void
249 ExportFormatManager::set_name (Glib::ustring name)
250 {
251         current_selection->set_name (name);
252 }
253
254 void
255 ExportFormatManager::select_src_quality (ExportFormatBase::SRCQuality value)
256 {
257         current_selection->set_src_quality (value);
258 }
259
260 void
261 ExportFormatManager::select_trim_beginning (bool value)
262 {
263         current_selection->set_trim_beginning (value);
264 }
265
266 void
267 ExportFormatManager::select_silence_beginning (AnyTime const & time)
268 {
269         current_selection->set_silence_beginning (time);
270 }
271
272 void
273 ExportFormatManager::select_trim_end (bool value)
274 {
275         current_selection->set_trim_end (value);
276 }
277
278 void
279 ExportFormatManager::select_silence_end (AnyTime const & time)
280 {
281         current_selection->set_silence_end (time);
282 }
283
284 void
285 ExportFormatManager::select_normalize (bool value)
286 {
287         current_selection->set_normalize (value);
288 }
289
290 void
291 ExportFormatManager::select_normalize_target (float value)
292 {
293         current_selection->set_normalize_target (value);
294 }
295
296 void
297 ExportFormatManager::select_tagging (bool tag)
298 {
299         current_selection->set_tag (tag);
300 }
301
302 void
303 ExportFormatManager::change_compatibility_selection (bool select, WeakCompatPtr const & compat)
304 {
305         bool do_selection_changed = !pending_selection_change;
306         if (!pending_selection_change) {
307                 pending_selection_change = true;
308         }
309
310         CompatPtr ptr = compat.lock();
311         
312         if (ptr && select) {
313                 select_compatibility (ptr);
314         }
315
316         if (do_selection_changed) {
317                 selection_changed ();
318         }
319 }
320
321 void
322 ExportFormatManager::change_quality_selection (bool select, WeakQualityPtr const & quality)
323 {
324         QualityPtr ptr = quality.lock ();
325         
326         if (!ptr) {
327                 return;
328         }
329         
330         if (select) {
331                 select_quality (ptr);
332         } else if (ptr->quality == current_selection->quality()) {
333                 ptr.reset();
334                 select_quality (ptr);
335         }
336 }
337
338 void
339 ExportFormatManager::change_format_selection (bool select, WeakFormatPtr const & format)
340 {
341         FormatPtr ptr = format.lock();
342         
343         if (!ptr) {
344                 return;
345         }
346         
347         if (select) {
348                 select_format (ptr);
349         } else if (ptr->get_format_id() == current_selection->format_id()) {
350                 ptr.reset();
351                 select_format (ptr);
352         }
353 }
354
355 void
356 ExportFormatManager::change_sample_rate_selection (bool select, WeakSampleRatePtr const & rate)
357 {
358         SampleRatePtr ptr = rate.lock();
359         
360         if (!ptr) {
361                 return;
362         }
363         
364         if (select) {
365                 select_sample_rate (ptr);
366         } else if (ptr->rate == current_selection->sample_rate()) {
367                 ptr.reset();
368                 select_sample_rate (ptr);
369         }
370 }
371
372 void
373 ExportFormatManager::change_sample_format_selection (bool select, WeakSampleFormatPtr const & format)
374 {
375         SampleFormatPtr ptr = format.lock();
376         
377         if (!ptr) {
378                 return;
379         }
380         
381         if (select) {
382                 select_sample_format (ptr);
383         } else if (ptr->format == current_selection->sample_format()) {
384                 ptr.reset();
385                 select_sample_format (ptr);
386         }
387 }
388
389 void
390 ExportFormatManager::change_dither_type_selection (bool select, WeakDitherTypePtr const & type)
391 {
392         DitherTypePtr ptr = type.lock();
393         
394         if (!ptr) {
395                 return;
396         }
397         
398         if (select) {
399                 select_dither_type (ptr);
400         } else if (ptr->type == current_selection->dither_type()) {
401                 ptr.reset();
402                 select_dither_type (ptr);
403         }
404 }
405
406 void
407 ExportFormatManager::select_compatibility (WeakCompatPtr const & compat)
408 {
409         /* Calculate compatibility intersection for the selection */
410         
411         FormatBasePtr compat_intersect = get_compatibility_intersection ();
412         
413         /* Unselect incompatible items */
414         
415         boost::shared_ptr<ExportFormatBase> select_intersect;
416         
417         select_intersect = compat_intersect->get_intersection (*current_selection);
418         if (select_intersect->qualities_empty()) {
419                 select_quality (QualityPtr());
420         }
421         
422         select_intersect = compat_intersect->get_intersection (*current_selection);
423         if (select_intersect->formats_empty()) {
424                 select_format (FormatPtr());
425         }
426         
427         select_intersect = compat_intersect->get_intersection (*current_selection);
428         if (select_intersect->sample_rates_empty()) {
429                 select_sample_rate (SampleRatePtr());
430         }
431         
432         select_intersect = compat_intersect->get_intersection (*current_selection);
433         if (select_intersect->sample_formats_empty()) {
434                 select_sample_format (SampleFormatPtr());
435         }
436 }
437
438 void
439 ExportFormatManager::select_quality (QualityPtr const & quality)
440 {
441         bool do_selection_changed = !pending_selection_change;
442         if (!pending_selection_change) {
443                 pending_selection_change = true;
444         }
445
446         if (quality) {
447                 current_selection->set_quality (quality->quality);
448                 
449                 /* Deselect format if it is incompatible */
450         
451                 FormatPtr format = get_selected_format();
452                 if (format && !format->has_quality (quality->quality)) {
453                         format->set_selected (false);
454                 }
455                 
456         } else {
457                 current_selection->set_quality (ExportFormatBase::Q_None);
458                 
459                 QualityPtr current_quality = get_selected_quality();
460                 if (current_quality) {
461                         current_quality->set_selected (false);
462                 }
463                 
464                 /* Note:
465                  * A quality is never explicitly deselected without also deselecting the format
466                  * so we don't need to deselect the format here.
467                  * doing so causes extra complications
468                  */
469         }
470         
471         if (do_selection_changed) {
472                 selection_changed ();
473         }
474 }
475
476 void
477 ExportFormatManager::select_format (FormatPtr const & format)
478 {
479         bool do_selection_changed = !pending_selection_change;
480         if (!pending_selection_change) {
481                 pending_selection_change = true;
482         }
483
484         current_selection->set_format (format);
485
486         if (format) {
487                 
488                 /* Slect right quality for format */
489         
490                 ExportFormatBase::Quality quality = format->get_quality();
491                 for (QualityList::iterator it = qualities.begin (); it != qualities.end (); ++it) {
492                         if ((*it)->quality == quality) {
493                                 (*it)->set_selected (true);
494                         } else {
495                                 (*it)->set_selected (false);
496                         }
497                 }
498                 
499                 /* Handle sample formats */
500                 
501                 ExportFormatBase::SampleFormat format_to_select;
502                 if (format->sample_format_is_compatible (current_selection->sample_format())) {
503                         format_to_select = current_selection->sample_format();
504                 } else {
505                         format_to_select = format->default_sample_format();
506                 }
507                 
508                 boost::shared_ptr<HasSampleFormat> hsf;
509                 if ((hsf = boost::dynamic_pointer_cast<HasSampleFormat> (format))) {
510                         SampleFormatList sample_formats = hsf->get_sample_formats();
511                         for (SampleFormatList::iterator it = sample_formats.begin (); it != sample_formats.end (); ++it) {
512                                 if ((*it)->format == format_to_select) {
513                                         (*it)->set_selected (true);
514                                 } else {
515                                         (*it)->set_selected (false);
516                                 }
517                         }
518                 }
519                 
520                 current_selection->set_sample_format (format_to_select);
521                 
522         } else {
523                 FormatPtr current_format = get_selected_format ();
524                 if (current_format) {
525                         current_format->set_selected (false);
526                 }
527         }
528         
529         if (do_selection_changed) {
530                 selection_changed ();
531         }
532 }
533
534 void
535 ExportFormatManager::select_sample_rate (SampleRatePtr const & rate)
536 {
537
538         bool do_selection_changed = !pending_selection_change;
539         if (!pending_selection_change) {
540                 pending_selection_change = true;
541         }
542
543         if (rate) {
544                 current_selection->set_sample_rate (rate->rate);
545         } else {
546                 current_selection->set_sample_rate (ExportFormatBase::SR_None);
547                 
548                 SampleRatePtr current_rate = get_selected_sample_rate();
549                 if (current_rate) {
550                         current_rate->set_selected (false);
551                 }
552         }
553         
554         if (do_selection_changed) {
555                 selection_changed ();
556         }
557 }
558
559 void
560 ExportFormatManager::select_sample_format (SampleFormatPtr const & format)
561 {
562
563         bool do_selection_changed = !pending_selection_change;
564         if (!pending_selection_change) {
565                 pending_selection_change = true;
566         }
567
568         if (format) {
569                 current_selection->set_sample_format (format->format);
570         } else {
571                 current_selection->set_sample_format (ExportFormatBase::SF_None);
572                 
573                 SampleFormatPtr current_format = get_selected_sample_format();
574                 if (current_format) {
575                         current_format->set_selected (false);
576                 }
577         }
578         
579         if (do_selection_changed) {
580                 selection_changed ();
581         }
582 }
583
584 void
585 ExportFormatManager::select_dither_type (DitherTypePtr const & type)
586 {
587
588         bool do_selection_changed = !pending_selection_change;
589         if (!pending_selection_change) {
590                 pending_selection_change = true;
591         }
592
593         if (type) {
594                 current_selection->set_dither_type (type->type);
595         } else {
596                 current_selection->set_dither_type (ExportFormatBase::D_None);
597         }
598         
599         if (do_selection_changed) {
600                 selection_changed ();
601         }
602 }
603
604 void
605 ExportFormatManager::selection_changed ()
606 {
607         /* Get a list of incompatible compatibility selections */
608         
609         CompatList incompatibles;
610         for (CompatList::iterator it = compatibilities.begin(); it != compatibilities.end(); ++it) {
611                 if (!current_selection->is_compatible_with (**it)) {
612                         incompatibles.push_back (*it);
613                 }
614         }
615         
616         /* Deselect them */
617         
618         for (CompatList::iterator it = incompatibles.begin(); it != incompatibles.end(); ++it) {
619                 (*it)->set_selected (false);
620         }
621         
622         /* Mark compatibility for everything necessary */
623         
624         std::set<ExportFormatBase::Quality> compatible_qualities;
625         FormatBasePtr compat_intersect = get_compatibility_intersection ();
626         ExportFormatCompatibility global_compat (*compat_intersect);
627         
628         for (FormatList::iterator it = formats.begin(); it != formats.end(); ++it) {
629                 if ((*it)->set_compatibility_state (global_compat)) {
630                         compatible_qualities.insert ((*it)->get_quality());
631                 }
632         }
633         
634         bool any_quality_compatible = true;
635         for (QualityList::iterator it = qualities.begin(); it != qualities.end(); ++it) {
636                 if (compatible_qualities.find((*it)->quality) != compatible_qualities.end()) {
637                         (*it)->set_compatible (true);
638                         
639                 } else {
640                         (*it)->set_compatible (false);
641                         
642                         if ((*it)->quality != ExportFormatBase::Q_Any) {
643                                 any_quality_compatible = false;
644                         }
645                 }
646         }
647         
648         if (any_quality_compatible) {
649                 for (QualityList::iterator it = qualities.begin(); it != qualities.end(); ++it) {
650                         if ((*it)->quality == ExportFormatBase::Q_Any) {
651                                 (*it)->set_compatible (true);
652                                 break;
653                         }
654                 }
655         }
656         
657         for (SampleRateList::iterator it = sample_rates.begin(); it != sample_rates.end(); ++it) {
658                 if (compat_intersect->has_sample_rate ((*it)->rate)) {
659                         (*it)->set_compatible (true);
660                 } else {
661                         (*it)->set_compatible (false);
662                 }
663         }
664         
665         boost::shared_ptr<HasSampleFormat> hsf;
666         if (hsf = boost::dynamic_pointer_cast<HasSampleFormat> (get_selected_format())) {
667         
668                 SampleFormatList sf_list = hsf->get_sample_formats();
669                 for (SampleFormatList::iterator it = sf_list.begin(); it != sf_list.end(); ++it) {
670                         if (compat_intersect->has_sample_format ((*it)->format)) {
671                                 (*it)->set_compatible (true);
672                         } else {
673                                 (*it)->set_compatible (false);
674                         }
675                 }
676         
677         }
678         
679         /* Signal completeness */
680         
681         CompleteChanged (current_selection->is_complete());
682         
683         /* Reset pending state */
684         
685         pending_selection_change = false;
686 }
687
688 ExportFormatManager::QualityPtr
689 ExportFormatManager::get_selected_quality ()
690 {
691         for (QualityList::iterator it = qualities.begin(); it != qualities.end(); ++it) {
692                 if ((*it)->selected()) {
693                         return *it;
694                 }
695         }
696         
697         return QualityPtr();
698 }
699
700 ExportFormatManager::FormatPtr
701 ExportFormatManager::get_selected_format ()
702 {
703         FormatPtr format;
704
705         for (FormatList::iterator it = formats.begin(); it != formats.end(); ++it) {
706                 if ((*it)->selected()) {
707                         return *it;
708                 }
709         }
710         
711         return format;
712 }
713
714 ExportFormatManager::SampleRatePtr
715 ExportFormatManager::get_selected_sample_rate ()
716 {
717         for (SampleRateList::iterator it = sample_rates.begin(); it != sample_rates.end(); ++it) {
718                 if ((*it)->selected()) {
719                         return *it;
720                 }
721         }
722         
723         return SampleRatePtr();
724 }
725
726 ExportFormatManager::SampleFormatPtr
727 ExportFormatManager::get_selected_sample_format ()
728 {
729         boost::shared_ptr<HasSampleFormat> hsf;
730         
731         if (hsf = boost::dynamic_pointer_cast<HasSampleFormat> (get_selected_format())) {
732                 return hsf->get_selected_sample_format ();
733         } else {
734                 return SampleFormatPtr ();
735         }
736 }
737
738
739 ExportFormatManager::FormatBasePtr
740 ExportFormatManager::get_compatibility_intersection ()
741 {
742         FormatBasePtr compat_intersect = universal_set;
743         
744         for (CompatList::iterator it = compatibilities.begin(); it != compatibilities.end(); ++it) {
745                 if ((*it)->selected ()) {
746                         compat_intersect = compat_intersect->get_intersection (**it);
747                 }
748         }
749         
750         return compat_intersect;
751 }
752
753 }; // namespace ARDOUR