2 Copyright (C) 2008 Paul Davis
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.
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.
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.
21 #include "ardour/export_format_manager.h"
23 #include "ardour/export_format_specification.h"
24 #include "ardour/export_format_compatibility.h"
33 ExportFormatManager::ExportFormatManager (ExportFormatSpecPtr specification) :
34 pending_selection_change (false),
35 universal_set (new ExportFormatBase ())
37 current_selection = specification;
39 init_compatibilities ();
45 ExportFormatManager::~ExportFormatManager ()
51 ExportFormatManager::init_compatibilities ()
53 ExportFormatCompatibilityPtr c_ptr;
55 c_ptr.reset (new ExportFormatCompatibility (_("CD")));
56 c_ptr->add_sample_rate (ExportFormatBase::SR_44_1);
57 c_ptr->add_format_id (ExportFormatBase::F_WAV);
58 c_ptr->add_format_id (ExportFormatBase::F_AIFF);
59 c_ptr->add_quality (ExportFormatBase::Q_LosslessLinear);
60 c_ptr->add_sample_format (ExportFormatBase::SF_16);
61 c_ptr->add_endianness (ExportFormatBase::E_FileDefault);
62 add_compatibility (c_ptr);
64 c_ptr.reset (new ExportFormatCompatibility (_("DVD-A")));
65 c_ptr->add_sample_rate (ExportFormatBase::SR_44_1);
66 c_ptr->add_sample_rate (ExportFormatBase::SR_48);
67 c_ptr->add_sample_rate (ExportFormatBase::SR_88_2);
68 c_ptr->add_sample_rate (ExportFormatBase::SR_96);
69 c_ptr->add_sample_rate (ExportFormatBase::SR_192);
70 c_ptr->add_format_id (ExportFormatBase::F_WAV);
71 c_ptr->add_format_id (ExportFormatBase::F_AIFF);
72 c_ptr->add_quality (ExportFormatBase::Q_LosslessLinear);
73 c_ptr->add_sample_format (ExportFormatBase::SF_16);
74 c_ptr->add_sample_format (ExportFormatBase::SF_24);
75 c_ptr->add_endianness (ExportFormatBase::E_FileDefault);
76 add_compatibility (c_ptr);
78 c_ptr.reset (new ExportFormatCompatibility (_("iPod")));
79 c_ptr->add_sample_rate (ExportFormatBase::SR_44_1);
80 c_ptr->add_sample_rate (ExportFormatBase::SR_48);
81 c_ptr->add_format_id (ExportFormatBase::F_WAV);
82 c_ptr->add_format_id (ExportFormatBase::F_AIFF);
83 c_ptr->add_quality (ExportFormatBase::Q_LosslessLinear);
84 c_ptr->add_sample_format (ExportFormatBase::SF_16);
85 c_ptr->add_sample_format (ExportFormatBase::SF_24);
86 c_ptr->add_endianness (ExportFormatBase::E_FileDefault);
87 add_compatibility (c_ptr);
89 c_ptr.reset (new ExportFormatCompatibility (_("Something else")));
90 c_ptr->add_sample_rate (ExportFormatBase::SR_44_1);
91 c_ptr->add_sample_rate (ExportFormatBase::SR_48);
92 c_ptr->add_format_id (ExportFormatBase::F_WAV);
93 c_ptr->add_format_id (ExportFormatBase::F_AIFF);
94 c_ptr->add_format_id (ExportFormatBase::F_AU);
95 c_ptr->add_format_id (ExportFormatBase::F_FLAC);
96 c_ptr->add_quality (ExportFormatBase::Q_LosslessLinear);
97 c_ptr->add_quality (ExportFormatBase::Q_LosslessCompression);
98 c_ptr->add_sample_format (ExportFormatBase::SF_16);
99 c_ptr->add_sample_format (ExportFormatBase::SF_24);
100 c_ptr->add_sample_format (ExportFormatBase::SF_32);
101 c_ptr->add_endianness (ExportFormatBase::E_FileDefault);
102 add_compatibility (c_ptr);
106 ExportFormatManager::init_qualities ()
108 add_quality (QualityPtr (new QualityState (ExportFormatBase::Q_Any, _("Any"))));
109 add_quality (QualityPtr (new QualityState (ExportFormatBase::Q_LosslessLinear, _("Lossless (linear PCM)"))));
110 add_quality (QualityPtr (new QualityState (ExportFormatBase::Q_LossyCompression, _("Lossy compression"))));
111 add_quality (QualityPtr (new QualityState (ExportFormatBase::Q_LosslessCompression, _("Lossless compression"))));
115 ExportFormatManager::init_formats ()
117 ExportFormatPtr f_ptr;
118 ExportFormatLinear * fl_ptr;
120 f_ptr.reset (fl_ptr = new ExportFormatLinear ("AIFF", ExportFormatBase::F_AIFF));
121 fl_ptr->add_sample_format (ExportFormatBase::SF_U8);
122 fl_ptr->add_sample_format (ExportFormatBase::SF_8);
123 fl_ptr->add_sample_format (ExportFormatBase::SF_16);
124 fl_ptr->add_sample_format (ExportFormatBase::SF_24);
125 fl_ptr->add_sample_format (ExportFormatBase::SF_32);
126 fl_ptr->add_sample_format (ExportFormatBase::SF_Float);
127 fl_ptr->add_sample_format (ExportFormatBase::SF_Double);
128 fl_ptr->add_endianness (ExportFormatBase::E_Big);
129 fl_ptr->set_default_sample_format (ExportFormatBase::SF_16);
130 fl_ptr->set_extension ("aiff");
133 f_ptr.reset (fl_ptr = new ExportFormatLinear ("AU", ExportFormatBase::F_AU));
134 fl_ptr->add_sample_format (ExportFormatBase::SF_8);
135 fl_ptr->add_sample_format (ExportFormatBase::SF_16);
136 fl_ptr->add_sample_format (ExportFormatBase::SF_24);
137 fl_ptr->add_sample_format (ExportFormatBase::SF_32);
138 fl_ptr->add_sample_format (ExportFormatBase::SF_Float);
139 fl_ptr->add_sample_format (ExportFormatBase::SF_Double);
140 fl_ptr->set_default_sample_format (ExportFormatBase::SF_16);
141 fl_ptr->set_extension ("au");
144 f_ptr.reset (new ExportFormatBWF ());
147 f_ptr.reset (fl_ptr = new ExportFormatLinear ("IRCAM", ExportFormatBase::F_IRCAM));
148 fl_ptr->add_sample_format (ExportFormatBase::SF_16);
149 fl_ptr->add_sample_format (ExportFormatBase::SF_24);
150 fl_ptr->add_sample_format (ExportFormatBase::SF_32);
151 fl_ptr->add_sample_format (ExportFormatBase::SF_Float);
152 fl_ptr->set_default_sample_format (ExportFormatBase::SF_24);
153 fl_ptr->set_extension ("sf");
156 f_ptr.reset (fl_ptr = new ExportFormatLinear ("WAV", ExportFormatBase::F_WAV));
157 fl_ptr->add_sample_format (ExportFormatBase::SF_U8);
158 fl_ptr->add_sample_format (ExportFormatBase::SF_16);
159 fl_ptr->add_sample_format (ExportFormatBase::SF_24);
160 fl_ptr->add_sample_format (ExportFormatBase::SF_32);
161 fl_ptr->add_sample_format (ExportFormatBase::SF_Float);
162 fl_ptr->add_sample_format (ExportFormatBase::SF_Double);
163 fl_ptr->add_endianness (ExportFormatBase::E_Little);
164 fl_ptr->set_default_sample_format (ExportFormatBase::SF_16);
165 fl_ptr->set_extension ("wav");
168 f_ptr.reset (fl_ptr = new ExportFormatLinear ("W64", ExportFormatBase::F_W64));
169 fl_ptr->add_sample_format (ExportFormatBase::SF_U8);
170 fl_ptr->add_sample_format (ExportFormatBase::SF_16);
171 fl_ptr->add_sample_format (ExportFormatBase::SF_24);
172 fl_ptr->add_sample_format (ExportFormatBase::SF_32);
173 fl_ptr->add_sample_format (ExportFormatBase::SF_Float);
174 fl_ptr->add_sample_format (ExportFormatBase::SF_Double);
175 fl_ptr->set_default_sample_format (ExportFormatBase::SF_Double);
176 fl_ptr->set_extension ("w64");
179 f_ptr.reset (fl_ptr = new ExportFormatLinear ("RAW", ExportFormatBase::F_RAW));
180 fl_ptr->add_sample_format (ExportFormatBase::SF_U8);
181 fl_ptr->add_sample_format (ExportFormatBase::SF_8);
182 fl_ptr->add_sample_format (ExportFormatBase::SF_16);
183 fl_ptr->add_sample_format (ExportFormatBase::SF_24);
184 fl_ptr->add_sample_format (ExportFormatBase::SF_32);
185 fl_ptr->add_sample_format (ExportFormatBase::SF_Float);
186 fl_ptr->add_sample_format (ExportFormatBase::SF_Double);
187 fl_ptr->set_default_sample_format (ExportFormatBase::SF_Float);
188 fl_ptr->set_extension ("raw");
192 f_ptr.reset (new ExportFormatOggVorbis ());
194 } catch (ExportFormatIncompatible & e) {}
197 f_ptr.reset (new ExportFormatFLAC ());
199 } catch (ExportFormatIncompatible & e) {}
203 ExportFormatManager::init_sample_rates ()
205 add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_Session, _("Session rate"))));
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")));
215 ExportFormatManager::add_compatibility (ExportFormatCompatibilityPtr ptr)
217 compatibilities.push_back (ptr);
218 ptr->SelectChanged.connect_same_thread (*this,
219 boost::bind (&ExportFormatManager::change_compatibility_selection,
220 this, _1, WeakExportFormatCompatibilityPtr (ptr)));
224 ExportFormatManager::add_quality (QualityPtr ptr)
226 ptr->SelectChanged.connect_same_thread (*this, boost::bind (&ExportFormatManager::change_quality_selection, this, _1, WeakQualityPtr (ptr)));
227 qualities.push_back (ptr);
231 ExportFormatManager::add_format (ExportFormatPtr ptr)
233 formats.push_back (ptr);
234 ptr->SelectChanged.connect_same_thread (*this, boost::bind (&ExportFormatManager::change_format_selection, this, _1, WeakExportFormatPtr (ptr)));
235 universal_set = universal_set->get_union (*ptr);
237 /* Encoding options */
239 boost::shared_ptr<HasSampleFormat> hsf;
241 if ((hsf = boost::dynamic_pointer_cast<HasSampleFormat> (ptr))) {
242 hsf->SampleFormatSelectChanged.connect_same_thread (*this, boost::bind (&ExportFormatManager::change_sample_format_selection, this, _1, _2));
243 hsf->DitherTypeSelectChanged.connect_same_thread (*this, boost::bind (&ExportFormatManager::change_dither_type_selection, this, _1, _2));
248 ExportFormatManager::add_sample_rate (SampleRatePtr ptr)
250 ptr->SelectChanged.connect_same_thread (*this, boost::bind (&ExportFormatManager::change_sample_rate_selection, this, _1, WeakSampleRatePtr (ptr)));
251 sample_rates.push_back (ptr);
255 ExportFormatManager::set_name (string name)
257 current_selection->set_name (name);
261 ExportFormatManager::select_src_quality (ExportFormatBase::SRCQuality value)
263 current_selection->set_src_quality (value);
267 ExportFormatManager::select_with_cue (bool value)
269 current_selection->set_with_cue (value);
273 ExportFormatManager::select_with_toc (bool value)
275 current_selection->set_with_toc (value);
279 ExportFormatManager::select_trim_beginning (bool value)
281 current_selection->set_trim_beginning (value);
285 ExportFormatManager::select_silence_beginning (AnyTime const & time)
287 current_selection->set_silence_beginning (time);
291 ExportFormatManager::select_trim_end (bool value)
293 current_selection->set_trim_end (value);
297 ExportFormatManager::select_silence_end (AnyTime const & time)
299 current_selection->set_silence_end (time);
303 ExportFormatManager::select_normalize (bool value)
305 current_selection->set_normalize (value);
309 ExportFormatManager::select_normalize_target (float value)
311 current_selection->set_normalize_target (value);
315 ExportFormatManager::select_tagging (bool tag)
317 current_selection->set_tag (tag);
321 ExportFormatManager::change_compatibility_selection (bool select, WeakExportFormatCompatibilityPtr const & compat)
323 bool do_selection_changed = !pending_selection_change;
324 if (!pending_selection_change) {
325 pending_selection_change = true;
328 ExportFormatCompatibilityPtr ptr = compat.lock();
331 select_compatibility (ptr);
334 if (do_selection_changed) {
335 selection_changed ();
340 ExportFormatManager::change_quality_selection (bool select, WeakQualityPtr const & quality)
342 QualityPtr ptr = quality.lock ();
349 select_quality (ptr);
350 } else if (ptr->quality == current_selection->quality()) {
352 select_quality (ptr);
357 ExportFormatManager::change_format_selection (bool select, WeakExportFormatPtr const & format)
359 ExportFormatPtr ptr = format.lock();
367 } else if (ptr->get_format_id() == current_selection->format_id()) {
374 ExportFormatManager::change_sample_rate_selection (bool select, WeakSampleRatePtr const & rate)
376 SampleRatePtr ptr = rate.lock();
383 select_sample_rate (ptr);
384 } else if (ptr->rate == current_selection->sample_rate()) {
386 select_sample_rate (ptr);
391 ExportFormatManager::change_sample_format_selection (bool select, WeakSampleFormatPtr const & format)
393 SampleFormatPtr ptr = format.lock();
400 select_sample_format (ptr);
401 } else if (ptr->format == current_selection->sample_format()) {
403 select_sample_format (ptr);
408 ExportFormatManager::change_dither_type_selection (bool select, WeakDitherTypePtr const & type)
410 DitherTypePtr ptr = type.lock();
417 select_dither_type (ptr);
418 } else if (ptr->type == current_selection->dither_type()) {
420 select_dither_type (ptr);
425 ExportFormatManager::select_compatibility (WeakExportFormatCompatibilityPtr const & /*compat*/)
427 /* Calculate compatibility intersection for the selection */
429 ExportFormatBasePtr compat_intersect = get_compatibility_intersection ();
431 /* Unselect incompatible items */
433 boost::shared_ptr<ExportFormatBase> select_intersect;
435 select_intersect = compat_intersect->get_intersection (*current_selection);
436 if (select_intersect->qualities_empty()) {
437 select_quality (QualityPtr());
440 select_intersect = compat_intersect->get_intersection (*current_selection);
441 if (select_intersect->formats_empty()) {
442 select_format (ExportFormatPtr());
445 select_intersect = compat_intersect->get_intersection (*current_selection);
446 if (select_intersect->sample_rates_empty()) {
447 select_sample_rate (SampleRatePtr());
450 select_intersect = compat_intersect->get_intersection (*current_selection);
451 if (select_intersect->sample_formats_empty()) {
452 select_sample_format (SampleFormatPtr());
457 ExportFormatManager::select_quality (QualityPtr const & quality)
459 bool do_selection_changed = !pending_selection_change;
460 if (!pending_selection_change) {
461 pending_selection_change = true;
465 current_selection->set_quality (quality->quality);
467 /* Deselect format if it is incompatible */
469 ExportFormatPtr format = get_selected_format();
470 if (format && !format->has_quality (quality->quality)) {
471 format->set_selected (false);
475 current_selection->set_quality (ExportFormatBase::Q_None);
477 QualityPtr current_quality = get_selected_quality();
478 if (current_quality) {
479 current_quality->set_selected (false);
483 * A quality is never explicitly deselected without also deselecting the format
484 * so we don't need to deselect the format here.
485 * doing so causes extra complications
489 if (do_selection_changed) {
490 selection_changed ();
495 ExportFormatManager::select_format (ExportFormatPtr const & format)
497 bool do_selection_changed = !pending_selection_change;
498 if (!pending_selection_change) {
499 pending_selection_change = true;
502 current_selection->set_format (format);
506 /* Slect right quality for format */
508 ExportFormatBase::Quality quality = format->get_quality();
509 for (QualityList::iterator it = qualities.begin (); it != qualities.end (); ++it) {
510 if ((*it)->quality == quality) {
511 (*it)->set_selected (true);
513 (*it)->set_selected (false);
517 /* Handle sample formats */
519 ExportFormatBase::SampleFormat format_to_select;
520 if (format->sample_format_is_compatible (current_selection->sample_format())) {
521 format_to_select = current_selection->sample_format();
523 format_to_select = format->default_sample_format();
526 boost::shared_ptr<HasSampleFormat> hsf;
527 if ((hsf = boost::dynamic_pointer_cast<HasSampleFormat> (format))) {
528 SampleFormatList sample_formats = hsf->get_sample_formats();
529 for (SampleFormatList::iterator it = sample_formats.begin (); it != sample_formats.end (); ++it) {
530 if ((*it)->format == format_to_select) {
531 (*it)->set_selected (true);
533 (*it)->set_selected (false);
538 current_selection->set_sample_format (format_to_select);
541 ExportFormatPtr current_format = get_selected_format ();
542 if (current_format) {
543 current_format->set_selected (false);
547 if (do_selection_changed) {
548 selection_changed ();
553 ExportFormatManager::select_sample_rate (SampleRatePtr const & rate)
556 bool do_selection_changed = !pending_selection_change;
557 if (!pending_selection_change) {
558 pending_selection_change = true;
562 current_selection->set_sample_rate (rate->rate);
564 current_selection->set_sample_rate (ExportFormatBase::SR_None);
566 SampleRatePtr current_rate = get_selected_sample_rate();
568 current_rate->set_selected (false);
572 if (do_selection_changed) {
573 selection_changed ();
578 ExportFormatManager::select_sample_format (SampleFormatPtr const & format)
581 bool do_selection_changed = !pending_selection_change;
582 if (!pending_selection_change) {
583 pending_selection_change = true;
587 current_selection->set_sample_format (format->format);
589 current_selection->set_sample_format (ExportFormatBase::SF_None);
591 SampleFormatPtr current_format = get_selected_sample_format();
592 if (current_format) {
593 current_format->set_selected (false);
597 if (do_selection_changed) {
598 selection_changed ();
603 ExportFormatManager::select_dither_type (DitherTypePtr const & type)
606 bool do_selection_changed = !pending_selection_change;
607 if (!pending_selection_change) {
608 pending_selection_change = true;
612 current_selection->set_dither_type (type->type);
614 current_selection->set_dither_type (ExportFormatBase::D_None);
617 if (do_selection_changed) {
618 selection_changed ();
623 ExportFormatManager::selection_changed ()
625 /* Get a list of incompatible compatibility selections */
627 CompatList incompatibles;
628 for (CompatList::iterator it = compatibilities.begin(); it != compatibilities.end(); ++it) {
629 if (!current_selection->is_compatible_with (**it)) {
630 incompatibles.push_back (*it);
636 for (CompatList::iterator it = incompatibles.begin(); it != incompatibles.end(); ++it) {
637 (*it)->set_selected (false);
640 /* Mark compatibility for everything necessary */
642 std::set<ExportFormatBase::Quality> compatible_qualities;
643 ExportFormatBasePtr compat_intersect = get_compatibility_intersection ();
644 ExportFormatCompatibility global_compat (*compat_intersect);
646 for (FormatList::iterator it = formats.begin(); it != formats.end(); ++it) {
647 if ((*it)->set_compatibility_state (global_compat)) {
648 compatible_qualities.insert ((*it)->get_quality());
652 bool any_quality_compatible = true;
653 for (QualityList::iterator it = qualities.begin(); it != qualities.end(); ++it) {
654 if (compatible_qualities.find((*it)->quality) != compatible_qualities.end()) {
655 (*it)->set_compatible (true);
658 (*it)->set_compatible (false);
660 if ((*it)->quality != ExportFormatBase::Q_Any) {
661 any_quality_compatible = false;
666 if (any_quality_compatible) {
667 for (QualityList::iterator it = qualities.begin(); it != qualities.end(); ++it) {
668 if ((*it)->quality == ExportFormatBase::Q_Any) {
669 (*it)->set_compatible (true);
675 for (SampleRateList::iterator it = sample_rates.begin(); it != sample_rates.end(); ++it) {
676 if (compat_intersect->has_sample_rate ((*it)->rate)) {
677 (*it)->set_compatible (true);
679 (*it)->set_compatible (false);
683 boost::shared_ptr<HasSampleFormat> hsf;
684 if ((hsf = boost::dynamic_pointer_cast<HasSampleFormat> (get_selected_format()))) {
686 SampleFormatList sf_list = hsf->get_sample_formats();
687 for (SampleFormatList::iterator it = sf_list.begin(); it != sf_list.end(); ++it) {
688 if (compat_intersect->has_sample_format ((*it)->format)) {
689 (*it)->set_compatible (true);
691 (*it)->set_compatible (false);
697 /* Signal completeness */
699 CompleteChanged (current_selection->is_complete());
701 /* Reset pending state */
703 pending_selection_change = false;
706 ExportFormatManager::QualityPtr
707 ExportFormatManager::get_selected_quality ()
709 for (QualityList::iterator it = qualities.begin(); it != qualities.end(); ++it) {
710 if ((*it)->selected()) {
719 ExportFormatManager::get_selected_format ()
721 ExportFormatPtr format;
723 for (FormatList::iterator it = formats.begin(); it != formats.end(); ++it) {
724 if ((*it)->selected()) {
732 ExportFormatManager::SampleRatePtr
733 ExportFormatManager::get_selected_sample_rate ()
735 for (SampleRateList::iterator it = sample_rates.begin(); it != sample_rates.end(); ++it) {
736 if ((*it)->selected()) {
741 return SampleRatePtr();
744 ExportFormatManager::SampleFormatPtr
745 ExportFormatManager::get_selected_sample_format ()
747 boost::shared_ptr<HasSampleFormat> hsf;
749 if ((hsf = boost::dynamic_pointer_cast<HasSampleFormat> (get_selected_format()))) {
750 return hsf->get_selected_sample_format ();
752 return SampleFormatPtr ();
758 ExportFormatManager::get_compatibility_intersection ()
760 ExportFormatBasePtr compat_intersect = universal_set;
762 for (CompatList::iterator it = compatibilities.begin(); it != compatibilities.end(); ++it) {
763 if ((*it)->selected ()) {
764 compat_intersect = compat_intersect->get_intersection (**it);
768 return compat_intersect;
771 }; // namespace ARDOUR