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