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