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_formats.h"
31 ExportFormat::has_sample_format ()
33 return dynamic_cast<HasSampleFormat *> (this);
37 ExportFormat::has_codec_quality ()
39 return dynamic_cast<HasCodecQuality *> (this);
44 ExportFormat::sample_format_is_compatible (SampleFormat format) const
46 return (sample_formats.find (format) != sample_formats.end());
49 /*** HasSampleFormat ***/
51 HasSampleFormat::HasSampleFormat (ExportFormatBase::SampleFormatSet & sample_formats) :
52 _sample_formats (sample_formats)
56 add_dither_type (ExportFormatBase::D_Shaped, _("Shaped Noise"));
57 add_dither_type (ExportFormatBase::D_Tri, _("Triangular"));
58 add_dither_type (ExportFormatBase::D_Rect, _("Rectangular"));
59 add_dither_type (ExportFormatBase::D_None, _("None"));
63 HasSampleFormat::add_sample_format (ExportFormatBase::SampleFormat format)
65 _sample_formats.insert (format);
67 SampleFormatPtr ptr (new SampleFormatState (format, get_sample_format_name (format)));
68 sample_format_states.push_back (ptr);
69 ptr->SelectChanged.connect_same_thread (*this, boost::bind (&HasSampleFormat::update_sample_format_selection, this, _1));
70 // BOOST SIGNALS Could this be made any uglier?
71 ptr->SelectChanged.connect_same_thread (*this,
72 boost::bind (boost::type<void> (), boost::ref (SampleFormatSelectChanged), _1, WeakSampleFormatPtr (ptr)));
73 ptr->CompatibleChanged.connect_same_thread (*this,
74 boost::bind (boost::type<void> (), boost::ref (SampleFormatCompatibleChanged), _1, WeakSampleFormatPtr (ptr)));
78 HasSampleFormat::add_dither_type (ExportFormatBase::DitherType type, string name)
80 DitherTypePtr ptr (new DitherTypeState (type, name));
81 dither_type_states.push_back (ptr);
82 ptr->SelectChanged.connect_same_thread (*this, boost::bind (&HasSampleFormat::update_dither_type_selection, this, _1));
83 // BOOST SIGNALS Could this be made any uglier?
84 ptr->SelectChanged.connect_same_thread (*this,
85 boost::bind (boost::type<void> (), boost::ref (DitherTypeSelectChanged), _1, WeakDitherTypePtr (ptr)));
86 ptr->CompatibleChanged.connect_same_thread (*this,
87 boost::bind (boost::type<void> (),boost::ref ( DitherTypeCompatibleChanged), _1, WeakDitherTypePtr (ptr)));
90 HasSampleFormat::SampleFormatPtr
91 HasSampleFormat::get_selected_sample_format ()
93 for (SampleFormatList::iterator it = sample_format_states.begin(); it != sample_format_states.end(); ++it) {
94 if ((*it)->selected()) {
99 return SampleFormatPtr();
102 HasSampleFormat::DitherTypePtr
103 HasSampleFormat::get_selected_dither_type ()
105 for (DitherTypeList::iterator it = dither_type_states.begin(); it != dither_type_states.end(); ++it) {
106 if ((*it)->selected()) {
111 return DitherTypePtr();
115 HasSampleFormat::update_sample_format_selection (bool)
117 SampleFormatPtr format = get_selected_sample_format();
122 if (format->format == ExportFormatBase::SF_24 ||
123 format->format == ExportFormatBase::SF_32 ||
124 format->format == ExportFormatBase::SF_Float ||
125 format->format == ExportFormatBase::SF_Double) {
126 for (DitherTypeList::iterator it = dither_type_states.begin(); it != dither_type_states.end(); ++it) {
127 if ((*it)->type == ExportFormatBase::D_None) {
128 (*it)->set_selected (true);
130 (*it)->set_compatible (false);
135 for (DitherTypeList::iterator it = dither_type_states.begin(); it != dither_type_states.end(); ++it) {
136 (*it)->set_compatible (true);
142 HasSampleFormat::update_dither_type_selection (bool)
144 DitherTypePtr type = get_selected_dither_type();
149 if (!type->compatible()) {
150 SampleFormatPtr format = get_selected_sample_format();
152 format->set_selected (false);
155 for (DitherTypeList::iterator it = dither_type_states.begin(); it != dither_type_states.end(); ++it) {
156 (*it)->set_compatible (true);
162 HasSampleFormat::get_sample_format_name (ExportFormatBase::SampleFormat format)
165 case ExportFormatBase::SF_8:
167 case ExportFormatBase::SF_16:
169 case ExportFormatBase::SF_24:
171 case ExportFormatBase::SF_32:
173 case ExportFormatBase::SF_Float:
175 case ExportFormatBase::SF_Double:
177 case ExportFormatBase::SF_U8:
178 return _("8-bit unsigned");
179 case ExportFormatBase::SF_Vorbis:
180 return _("Vorbis sample format");
181 case ExportFormatBase::SF_None:
182 return _("No sample format");
189 ExportFormatLinear::ExportFormatLinear (string name, FormatId format_id) :
190 HasSampleFormat (sample_formats),
191 _default_sample_format (SF_None)
194 set_format_id (format_id);
196 add_sample_rate (SR_8);
197 add_sample_rate (SR_22_05);
198 add_sample_rate (SR_44_1);
199 add_sample_rate (SR_48);
200 add_sample_rate (SR_88_2);
201 add_sample_rate (SR_96);
202 add_sample_rate (SR_176_4);
203 add_sample_rate (SR_192);
204 add_sample_rate (SR_Session);
206 add_endianness (E_FileDefault);
208 set_quality (Q_LosslessLinear);
212 ExportFormatLinear::set_compatibility_state (ExportFormatCompatibility const & compatibility)
216 bool compatible = true;
218 if (!compatibility.has_quality (Q_LosslessLinear)) {
222 if (!compatibility.has_format (get_format_id())) {
226 boost::shared_ptr<ExportFormatBase> intersection = get_intersection (compatibility);
228 if (intersection->endiannesses_empty()) {
232 if (intersection->sample_rates_empty()) {
236 if (intersection->sample_formats_empty()) {
240 set_compatible (compatible);
244 for (SampleFormatList::iterator it = sample_format_states.begin(); it != sample_format_states.end(); ++it) {
245 (*it)->set_compatible (compatibility.has_sample_format ((*it)->format));
253 ExportFormatOggVorbis::ExportFormatOggVorbis ()
255 /* Check system compatibility */
258 sf_info.channels = 2;
259 sf_info.samplerate = SR_44_1;
260 sf_info.format = F_Ogg | SF_Vorbis;
261 if (sf_format_check (&sf_info) != SF_TRUE) {
262 throw ExportFormatIncompatible();
265 set_name ("Ogg Vorbis");
266 set_format_id (F_Ogg);
267 sample_formats.insert (SF_Vorbis);
269 add_sample_rate (SR_22_05);
270 add_sample_rate (SR_44_1);
271 add_sample_rate (SR_48);
272 add_sample_rate (SR_88_2);
273 add_sample_rate (SR_96);
274 add_sample_rate (SR_176_4);
275 add_sample_rate (SR_192);
276 add_sample_rate (SR_Session);
278 /* these are 100 vorbis_encode_init_vbr() quality */
279 add_codec_quality ("Low (0)", 0);
280 add_codec_quality ("Default (4)", 40);
281 add_codec_quality ("High (6)", 60);
282 add_codec_quality ("Very High (10)", 100);
284 add_endianness (E_FileDefault);
286 set_extension ("ogg");
287 set_quality (Q_LossyCompression);
291 ExportFormatOggVorbis::set_compatibility_state (ExportFormatCompatibility const & compatibility)
293 bool compatible = compatibility.has_format (F_Ogg);
294 set_compatible (compatible);
300 ExportFormatFLAC::ExportFormatFLAC () :
301 HasSampleFormat (sample_formats)
303 /* Check system compatibility */
306 sf_info.channels = 2;
307 sf_info.samplerate = SR_44_1;
308 sf_info.format = F_FLAC | SF_16;
309 if (sf_format_check (&sf_info) != SF_TRUE) {
310 throw ExportFormatIncompatible();
314 set_format_id (F_FLAC);
316 add_sample_rate (SR_22_05);
317 add_sample_rate (SR_44_1);
318 add_sample_rate (SR_48);
319 add_sample_rate (SR_88_2);
320 add_sample_rate (SR_96);
321 add_sample_rate (SR_176_4);
322 add_sample_rate (SR_192);
323 add_sample_rate (SR_Session);
325 add_sample_format (SF_8);
326 add_sample_format (SF_16);
327 add_sample_format (SF_24);
329 add_endianness (E_FileDefault);
331 set_extension ("flac");
332 set_quality (Q_LosslessCompression);
336 ExportFormatFLAC::set_compatibility_state (ExportFormatCompatibility const & compatibility)
338 bool compatible = compatibility.has_format (F_FLAC);
339 set_compatible (compatible);
345 ExportFormatBWF::ExportFormatBWF () :
346 HasSampleFormat (sample_formats)
349 set_format_id (F_WAV);
351 add_sample_rate (SR_22_05);
352 add_sample_rate (SR_44_1);
353 add_sample_rate (SR_48);
354 add_sample_rate (SR_88_2);
355 add_sample_rate (SR_96);
356 add_sample_rate (SR_176_4);
357 add_sample_rate (SR_192);
358 add_sample_rate (SR_Session);
360 add_sample_format (SF_U8);
361 add_sample_format (SF_16);
362 add_sample_format (SF_24);
363 add_sample_format (SF_32);
364 add_sample_format (SF_Float);
365 add_sample_format (SF_Double);
367 add_endianness (E_FileDefault);
369 set_extension ("wav");
370 set_quality (Q_LosslessLinear);
374 ExportFormatBWF::set_compatibility_state (ExportFormatCompatibility const & compatibility)
376 bool compatible = compatibility.has_format (F_WAV);
377 set_compatible (compatible);
382 /*** FFMPEG Pipe ***/
384 ExportFormatFFMPEG::ExportFormatFFMPEG (std::string const& name, std::string const& ext)
387 set_format_id (F_FFMPEG);
388 sample_formats.insert (SF_Float);
390 add_sample_rate (SR_8);
391 add_sample_rate (SR_22_05);
392 add_sample_rate (SR_44_1);
393 add_sample_rate (SR_48);
394 add_sample_rate (SR_Session);
396 add_endianness (E_Little);
398 add_codec_quality ("VBR 220-260 kb/s", 0);
399 add_codec_quality ("VBR 190-250 kb/s", -1);
400 add_codec_quality ("VBR 170-210 kb/s", -2);
401 add_codec_quality ("VBR 150-195 kb/s", -3);
402 add_codec_quality ("VBR 140-185 kb/s", -4);
403 add_codec_quality ("VBR 120-150 kb/s", -5);
404 add_codec_quality ("VBR 100-130 kb/s", -6);
405 add_codec_quality ("VBR 80-120 kb/s", -7);
406 add_codec_quality ("VBR 70-105 kb/s", -8);
407 add_codec_quality ("VBR 45-85 kb/s", -9);
408 /* Available CBR options are:
409 * 8, 16, 24, 32, 40, 48, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320
411 add_codec_quality ("CBR 64 kb/s", 64);
412 add_codec_quality ("CBR 128 kb/s", 128);
413 add_codec_quality ("CBR 160 kb/s", 160);
414 add_codec_quality ("CBR 192 kb/s", 192);
415 add_codec_quality ("CBR 256 kb/s", 256);
418 set_quality (Q_LossyCompression);
422 ExportFormatFFMPEG::set_compatibility_state (ExportFormatCompatibility const & compatibility)
424 bool compatible = compatibility.has_format (F_FFMPEG);
425 set_compatible (compatible);
430 }; // namespace ARDOUR