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