Add "session rate" as a possible sample rate for export formats
[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 (SpecPtr 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         CompatPtr 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         FormatPtr 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 (CompatPtr ptr)
217 {
218         compatibilities.push_back (ptr);
219         ptr->SelectChanged.connect_same_thread (*this, boost::bind (&ExportFormatManager::change_compatibility_selection, this, _1, WeakCompatPtr (ptr)));
220 }
221
222 void
223 ExportFormatManager::add_quality (QualityPtr ptr)
224 {
225         ptr->SelectChanged.connect_same_thread (*this, boost::bind (&ExportFormatManager::change_quality_selection, this, _1, WeakQualityPtr (ptr)));
226         qualities.push_back (ptr);
227 }
228
229 void
230 ExportFormatManager::add_format (FormatPtr ptr)
231 {
232         formats.push_back (ptr);
233         ptr->SelectChanged.connect_same_thread (*this, boost::bind (&ExportFormatManager::change_format_selection, this, _1, WeakFormatPtr (ptr)));
234         universal_set = universal_set->get_union (*ptr);
235
236         /* Encoding options */
237
238         boost::shared_ptr<HasSampleFormat> hsf;
239
240         if (hsf = boost::dynamic_pointer_cast<HasSampleFormat> (ptr)) {
241                 hsf->SampleFormatSelectChanged.connect_same_thread (*this, boost::bind (&ExportFormatManager::change_sample_format_selection, this, _1, _2));
242                 hsf->DitherTypeSelectChanged.connect_same_thread (*this, boost::bind (&ExportFormatManager::change_dither_type_selection, this, _1, _2));
243         }
244 }
245
246 void
247 ExportFormatManager::add_sample_rate (SampleRatePtr ptr)
248 {
249         ptr->SelectChanged.connect_same_thread (*this, boost::bind (&ExportFormatManager::change_sample_rate_selection, this, _1, WeakSampleRatePtr (ptr)));
250         sample_rates.push_back (ptr);
251 }
252
253 void
254 ExportFormatManager::set_name (string name)
255 {
256         current_selection->set_name (name);
257 }
258
259 void
260 ExportFormatManager::select_src_quality (ExportFormatBase::SRCQuality value)
261 {
262         current_selection->set_src_quality (value);
263 }
264
265 void
266 ExportFormatManager::select_trim_beginning (bool value)
267 {
268         current_selection->set_trim_beginning (value);
269 }
270
271 void
272 ExportFormatManager::select_silence_beginning (AnyTime const & time)
273 {
274         current_selection->set_silence_beginning (time);
275 }
276
277 void
278 ExportFormatManager::select_trim_end (bool value)
279 {
280         current_selection->set_trim_end (value);
281 }
282
283 void
284 ExportFormatManager::select_silence_end (AnyTime const & time)
285 {
286         current_selection->set_silence_end (time);
287 }
288
289 void
290 ExportFormatManager::select_normalize (bool value)
291 {
292         current_selection->set_normalize (value);
293 }
294
295 void
296 ExportFormatManager::select_normalize_target (float value)
297 {
298         current_selection->set_normalize_target (value);
299 }
300
301 void
302 ExportFormatManager::select_tagging (bool tag)
303 {
304         current_selection->set_tag (tag);
305 }
306
307 void
308 ExportFormatManager::change_compatibility_selection (bool select, WeakCompatPtr const & compat)
309 {
310         bool do_selection_changed = !pending_selection_change;
311         if (!pending_selection_change) {
312                 pending_selection_change = true;
313         }
314
315         CompatPtr ptr = compat.lock();
316
317         if (ptr && select) {
318                 select_compatibility (ptr);
319         }
320
321         if (do_selection_changed) {
322                 selection_changed ();
323         }
324 }
325
326 void
327 ExportFormatManager::change_quality_selection (bool select, WeakQualityPtr const & quality)
328 {
329         QualityPtr ptr = quality.lock ();
330
331         if (!ptr) {
332                 return;
333         }
334
335         if (select) {
336                 select_quality (ptr);
337         } else if (ptr->quality == current_selection->quality()) {
338                 ptr.reset();
339                 select_quality (ptr);
340         }
341 }
342
343 void
344 ExportFormatManager::change_format_selection (bool select, WeakFormatPtr const & format)
345 {
346         FormatPtr ptr = format.lock();
347
348         if (!ptr) {
349                 return;
350         }
351
352         if (select) {
353                 select_format (ptr);
354         } else if (ptr->get_format_id() == current_selection->format_id()) {
355                 ptr.reset();
356                 select_format (ptr);
357         }
358 }
359
360 void
361 ExportFormatManager::change_sample_rate_selection (bool select, WeakSampleRatePtr const & rate)
362 {
363         SampleRatePtr ptr = rate.lock();
364
365         if (!ptr) {
366                 return;
367         }
368
369         if (select) {
370                 select_sample_rate (ptr);
371         } else if (ptr->rate == current_selection->sample_rate()) {
372                 ptr.reset();
373                 select_sample_rate (ptr);
374         }
375 }
376
377 void
378 ExportFormatManager::change_sample_format_selection (bool select, WeakSampleFormatPtr const & format)
379 {
380         SampleFormatPtr ptr = format.lock();
381
382         if (!ptr) {
383                 return;
384         }
385
386         if (select) {
387                 select_sample_format (ptr);
388         } else if (ptr->format == current_selection->sample_format()) {
389                 ptr.reset();
390                 select_sample_format (ptr);
391         }
392 }
393
394 void
395 ExportFormatManager::change_dither_type_selection (bool select, WeakDitherTypePtr const & type)
396 {
397         DitherTypePtr ptr = type.lock();
398
399         if (!ptr) {
400                 return;
401         }
402
403         if (select) {
404                 select_dither_type (ptr);
405         } else if (ptr->type == current_selection->dither_type()) {
406                 ptr.reset();
407                 select_dither_type (ptr);
408         }
409 }
410
411 void
412 ExportFormatManager::select_compatibility (WeakCompatPtr const & /*compat*/)
413 {
414         /* Calculate compatibility intersection for the selection */
415
416         FormatBasePtr compat_intersect = get_compatibility_intersection ();
417
418         /* Unselect incompatible items */
419
420         boost::shared_ptr<ExportFormatBase> select_intersect;
421
422         select_intersect = compat_intersect->get_intersection (*current_selection);
423         if (select_intersect->qualities_empty()) {
424                 select_quality (QualityPtr());
425         }
426
427         select_intersect = compat_intersect->get_intersection (*current_selection);
428         if (select_intersect->formats_empty()) {
429                 select_format (FormatPtr());
430         }
431
432         select_intersect = compat_intersect->get_intersection (*current_selection);
433         if (select_intersect->sample_rates_empty()) {
434                 select_sample_rate (SampleRatePtr());
435         }
436
437         select_intersect = compat_intersect->get_intersection (*current_selection);
438         if (select_intersect->sample_formats_empty()) {
439                 select_sample_format (SampleFormatPtr());
440         }
441 }
442
443 void
444 ExportFormatManager::select_quality (QualityPtr const & quality)
445 {
446         bool do_selection_changed = !pending_selection_change;
447         if (!pending_selection_change) {
448                 pending_selection_change = true;
449         }
450
451         if (quality) {
452                 current_selection->set_quality (quality->quality);
453
454                 /* Deselect format if it is incompatible */
455
456                 FormatPtr format = get_selected_format();
457                 if (format && !format->has_quality (quality->quality)) {
458                         format->set_selected (false);
459                 }
460
461         } else {
462                 current_selection->set_quality (ExportFormatBase::Q_None);
463
464                 QualityPtr current_quality = get_selected_quality();
465                 if (current_quality) {
466                         current_quality->set_selected (false);
467                 }
468
469                 /* Note:
470                  * A quality is never explicitly deselected without also deselecting the format
471                  * so we don't need to deselect the format here.
472                  * doing so causes extra complications
473                  */
474         }
475
476         if (do_selection_changed) {
477                 selection_changed ();
478         }
479 }
480
481 void
482 ExportFormatManager::select_format (FormatPtr const & format)
483 {
484         bool do_selection_changed = !pending_selection_change;
485         if (!pending_selection_change) {
486                 pending_selection_change = true;
487         }
488
489         current_selection->set_format (format);
490
491         if (format) {
492
493                 /* Slect right quality for format */
494
495                 ExportFormatBase::Quality quality = format->get_quality();
496                 for (QualityList::iterator it = qualities.begin (); it != qualities.end (); ++it) {
497                         if ((*it)->quality == quality) {
498                                 (*it)->set_selected (true);
499                         } else {
500                                 (*it)->set_selected (false);
501                         }
502                 }
503
504                 /* Handle sample formats */
505
506                 ExportFormatBase::SampleFormat format_to_select;
507                 if (format->sample_format_is_compatible (current_selection->sample_format())) {
508                         format_to_select = current_selection->sample_format();
509                 } else {
510                         format_to_select = format->default_sample_format();
511                 }
512
513                 boost::shared_ptr<HasSampleFormat> hsf;
514                 if ((hsf = boost::dynamic_pointer_cast<HasSampleFormat> (format))) {
515                         SampleFormatList sample_formats = hsf->get_sample_formats();
516                         for (SampleFormatList::iterator it = sample_formats.begin (); it != sample_formats.end (); ++it) {
517                                 if ((*it)->format == format_to_select) {
518                                         (*it)->set_selected (true);
519                                 } else {
520                                         (*it)->set_selected (false);
521                                 }
522                         }
523                 }
524
525                 current_selection->set_sample_format (format_to_select);
526
527         } else {
528                 FormatPtr current_format = get_selected_format ();
529                 if (current_format) {
530                         current_format->set_selected (false);
531                 }
532         }
533
534         if (do_selection_changed) {
535                 selection_changed ();
536         }
537 }
538
539 void
540 ExportFormatManager::select_sample_rate (SampleRatePtr const & rate)
541 {
542
543         bool do_selection_changed = !pending_selection_change;
544         if (!pending_selection_change) {
545                 pending_selection_change = true;
546         }
547
548         if (rate) {
549                 current_selection->set_sample_rate (rate->rate);
550         } else {
551                 current_selection->set_sample_rate (ExportFormatBase::SR_None);
552
553                 SampleRatePtr current_rate = get_selected_sample_rate();
554                 if (current_rate) {
555                         current_rate->set_selected (false);
556                 }
557         }
558
559         if (do_selection_changed) {
560                 selection_changed ();
561         }
562 }
563
564 void
565 ExportFormatManager::select_sample_format (SampleFormatPtr const & format)
566 {
567
568         bool do_selection_changed = !pending_selection_change;
569         if (!pending_selection_change) {
570                 pending_selection_change = true;
571         }
572
573         if (format) {
574                 current_selection->set_sample_format (format->format);
575         } else {
576                 current_selection->set_sample_format (ExportFormatBase::SF_None);
577
578                 SampleFormatPtr current_format = get_selected_sample_format();
579                 if (current_format) {
580                         current_format->set_selected (false);
581                 }
582         }
583
584         if (do_selection_changed) {
585                 selection_changed ();
586         }
587 }
588
589 void
590 ExportFormatManager::select_dither_type (DitherTypePtr const & type)
591 {
592
593         bool do_selection_changed = !pending_selection_change;
594         if (!pending_selection_change) {
595                 pending_selection_change = true;
596         }
597
598         if (type) {
599                 current_selection->set_dither_type (type->type);
600         } else {
601                 current_selection->set_dither_type (ExportFormatBase::D_None);
602         }
603
604         if (do_selection_changed) {
605                 selection_changed ();
606         }
607 }
608
609 void
610 ExportFormatManager::selection_changed ()
611 {
612         /* Get a list of incompatible compatibility selections */
613
614         CompatList incompatibles;
615         for (CompatList::iterator it = compatibilities.begin(); it != compatibilities.end(); ++it) {
616                 if (!current_selection->is_compatible_with (**it)) {
617                         incompatibles.push_back (*it);
618                 }
619         }
620
621         /* Deselect them */
622
623         for (CompatList::iterator it = incompatibles.begin(); it != incompatibles.end(); ++it) {
624                 (*it)->set_selected (false);
625         }
626
627         /* Mark compatibility for everything necessary */
628
629         std::set<ExportFormatBase::Quality> compatible_qualities;
630         FormatBasePtr compat_intersect = get_compatibility_intersection ();
631         ExportFormatCompatibility global_compat (*compat_intersect);
632
633         for (FormatList::iterator it = formats.begin(); it != formats.end(); ++it) {
634                 if ((*it)->set_compatibility_state (global_compat)) {
635                         compatible_qualities.insert ((*it)->get_quality());
636                 }
637         }
638
639         bool any_quality_compatible = true;
640         for (QualityList::iterator it = qualities.begin(); it != qualities.end(); ++it) {
641                 if (compatible_qualities.find((*it)->quality) != compatible_qualities.end()) {
642                         (*it)->set_compatible (true);
643
644                 } else {
645                         (*it)->set_compatible (false);
646
647                         if ((*it)->quality != ExportFormatBase::Q_Any) {
648                                 any_quality_compatible = false;
649                         }
650                 }
651         }
652
653         if (any_quality_compatible) {
654                 for (QualityList::iterator it = qualities.begin(); it != qualities.end(); ++it) {
655                         if ((*it)->quality == ExportFormatBase::Q_Any) {
656                                 (*it)->set_compatible (true);
657                                 break;
658                         }
659                 }
660         }
661
662         for (SampleRateList::iterator it = sample_rates.begin(); it != sample_rates.end(); ++it) {
663                 if (compat_intersect->has_sample_rate ((*it)->rate)) {
664                         (*it)->set_compatible (true);
665                 } else {
666                         (*it)->set_compatible (false);
667                 }
668         }
669
670         boost::shared_ptr<HasSampleFormat> hsf;
671         if (hsf = boost::dynamic_pointer_cast<HasSampleFormat> (get_selected_format())) {
672
673                 SampleFormatList sf_list = hsf->get_sample_formats();
674                 for (SampleFormatList::iterator it = sf_list.begin(); it != sf_list.end(); ++it) {
675                         if (compat_intersect->has_sample_format ((*it)->format)) {
676                                 (*it)->set_compatible (true);
677                         } else {
678                                 (*it)->set_compatible (false);
679                         }
680                 }
681
682         }
683
684         /* Signal completeness */
685
686         CompleteChanged (current_selection->is_complete());
687
688         /* Reset pending state */
689
690         pending_selection_change = false;
691 }
692
693 ExportFormatManager::QualityPtr
694 ExportFormatManager::get_selected_quality ()
695 {
696         for (QualityList::iterator it = qualities.begin(); it != qualities.end(); ++it) {
697                 if ((*it)->selected()) {
698                         return *it;
699                 }
700         }
701
702         return QualityPtr();
703 }
704
705 ExportFormatManager::FormatPtr
706 ExportFormatManager::get_selected_format ()
707 {
708         FormatPtr format;
709
710         for (FormatList::iterator it = formats.begin(); it != formats.end(); ++it) {
711                 if ((*it)->selected()) {
712                         return *it;
713                 }
714         }
715
716         return format;
717 }
718
719 ExportFormatManager::SampleRatePtr
720 ExportFormatManager::get_selected_sample_rate ()
721 {
722         for (SampleRateList::iterator it = sample_rates.begin(); it != sample_rates.end(); ++it) {
723                 if ((*it)->selected()) {
724                         return *it;
725                 }
726         }
727
728         return SampleRatePtr();
729 }
730
731 ExportFormatManager::SampleFormatPtr
732 ExportFormatManager::get_selected_sample_format ()
733 {
734         boost::shared_ptr<HasSampleFormat> hsf;
735
736         if (hsf = boost::dynamic_pointer_cast<HasSampleFormat> (get_selected_format())) {
737                 return hsf->get_selected_sample_format ();
738         } else {
739                 return SampleFormatPtr ();
740         }
741 }
742
743
744 ExportFormatManager::FormatBasePtr
745 ExportFormatManager::get_compatibility_intersection ()
746 {
747         FormatBasePtr compat_intersect = universal_set;
748
749         for (CompatList::iterator it = compatibilities.begin(); it != compatibilities.end(); ++it) {
750                 if ((*it)->selected ()) {
751                         compat_intersect = compat_intersect->get_intersection (**it);
752                 }
753         }
754
755         return compat_intersect;
756 }
757
758 }; // namespace ARDOUR