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