2 * Copyright (C) 2008-2010 Sakari Bergen <sakari.bergen@beatwaves.net>
3 * Copyright (C) 2008-2016 Paul Davis <paul@linuxaudiosystems.com>
4 * Copyright (C) 2009 David Robillard <d@drobilla.net>
5 * Copyright (C) 2017-2019 Robin Gareus <robin@gareus.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "ardour/export_formats.h"
32 ExportFormat::has_sample_format ()
34 return dynamic_cast<HasSampleFormat *> (this);
38 ExportFormat::has_codec_quality ()
40 return dynamic_cast<HasCodecQuality *> (this);
45 ExportFormat::sample_format_is_compatible (SampleFormat format) const
47 return (sample_formats.find (format) != sample_formats.end());
50 /*** HasSampleFormat ***/
52 HasSampleFormat::HasSampleFormat (ExportFormatBase::SampleFormatSet & sample_formats) :
53 _sample_formats (sample_formats)
57 add_dither_type (ExportFormatBase::D_Shaped, _("Shaped Noise"));
58 add_dither_type (ExportFormatBase::D_Tri, _("Triangular"));
59 add_dither_type (ExportFormatBase::D_Rect, _("Rectangular"));
60 add_dither_type (ExportFormatBase::D_None, _("None"));
64 HasSampleFormat::add_sample_format (ExportFormatBase::SampleFormat format)
66 _sample_formats.insert (format);
68 SampleFormatPtr ptr (new SampleFormatState (format, get_sample_format_name (format)));
69 sample_format_states.push_back (ptr);
70 ptr->SelectChanged.connect_same_thread (*this, boost::bind (&HasSampleFormat::update_sample_format_selection, this, _1));
71 // BOOST SIGNALS Could this be made any uglier?
72 ptr->SelectChanged.connect_same_thread (*this,
73 boost::bind (boost::type<void> (), boost::ref (SampleFormatSelectChanged), _1, WeakSampleFormatPtr (ptr)));
74 ptr->CompatibleChanged.connect_same_thread (*this,
75 boost::bind (boost::type<void> (), boost::ref (SampleFormatCompatibleChanged), _1, WeakSampleFormatPtr (ptr)));
79 HasSampleFormat::add_dither_type (ExportFormatBase::DitherType type, string name)
81 DitherTypePtr ptr (new DitherTypeState (type, name));
82 dither_type_states.push_back (ptr);
83 ptr->SelectChanged.connect_same_thread (*this, boost::bind (&HasSampleFormat::update_dither_type_selection, this, _1));
84 // BOOST SIGNALS Could this be made any uglier?
85 ptr->SelectChanged.connect_same_thread (*this,
86 boost::bind (boost::type<void> (), boost::ref (DitherTypeSelectChanged), _1, WeakDitherTypePtr (ptr)));
87 ptr->CompatibleChanged.connect_same_thread (*this,
88 boost::bind (boost::type<void> (),boost::ref ( DitherTypeCompatibleChanged), _1, WeakDitherTypePtr (ptr)));
91 HasSampleFormat::SampleFormatPtr
92 HasSampleFormat::get_selected_sample_format ()
94 for (SampleFormatList::iterator it = sample_format_states.begin(); it != sample_format_states.end(); ++it) {
95 if ((*it)->selected()) {
100 return SampleFormatPtr();
103 HasSampleFormat::DitherTypePtr
104 HasSampleFormat::get_selected_dither_type ()
106 for (DitherTypeList::iterator it = dither_type_states.begin(); it != dither_type_states.end(); ++it) {
107 if ((*it)->selected()) {
112 return DitherTypePtr();
116 HasSampleFormat::update_sample_format_selection (bool)
118 SampleFormatPtr format = get_selected_sample_format();
123 if (format->format == ExportFormatBase::SF_24 ||
124 format->format == ExportFormatBase::SF_32 ||
125 format->format == ExportFormatBase::SF_Float ||
126 format->format == ExportFormatBase::SF_Double) {
127 for (DitherTypeList::iterator it = dither_type_states.begin(); it != dither_type_states.end(); ++it) {
128 if ((*it)->type == ExportFormatBase::D_None) {
129 (*it)->set_selected (true);
131 (*it)->set_compatible (false);
136 for (DitherTypeList::iterator it = dither_type_states.begin(); it != dither_type_states.end(); ++it) {
137 (*it)->set_compatible (true);
143 HasSampleFormat::update_dither_type_selection (bool)
145 DitherTypePtr type = get_selected_dither_type();
150 if (!type->compatible()) {
151 SampleFormatPtr format = get_selected_sample_format();
153 format->set_selected (false);
156 for (DitherTypeList::iterator it = dither_type_states.begin(); it != dither_type_states.end(); ++it) {
157 (*it)->set_compatible (true);
163 HasSampleFormat::get_sample_format_name (ExportFormatBase::SampleFormat format)
166 case ExportFormatBase::SF_8:
168 case ExportFormatBase::SF_16:
170 case ExportFormatBase::SF_24:
172 case ExportFormatBase::SF_32:
174 case ExportFormatBase::SF_Float:
176 case ExportFormatBase::SF_Double:
178 case ExportFormatBase::SF_U8:
179 return _("8-bit unsigned");
180 case ExportFormatBase::SF_Vorbis:
181 return _("Vorbis sample format");
182 case ExportFormatBase::SF_None:
183 return _("No sample format");
190 ExportFormatLinear::ExportFormatLinear (string name, FormatId format_id) :
191 HasSampleFormat (sample_formats),
192 _default_sample_format (SF_None)
195 set_format_id (format_id);
197 add_sample_rate (SR_8);
198 add_sample_rate (SR_22_05);
199 add_sample_rate (SR_44_1);
200 add_sample_rate (SR_48);
201 add_sample_rate (SR_88_2);
202 add_sample_rate (SR_96);
203 add_sample_rate (SR_176_4);
204 add_sample_rate (SR_192);
205 add_sample_rate (SR_Session);
207 add_endianness (E_FileDefault);
209 set_quality (Q_LosslessLinear);
213 ExportFormatLinear::set_compatibility_state (ExportFormatCompatibility const & compatibility)
217 bool compatible = true;
219 if (!compatibility.has_quality (Q_LosslessLinear)) {
223 if (!compatibility.has_format (get_format_id())) {
227 boost::shared_ptr<ExportFormatBase> intersection = get_intersection (compatibility);
229 if (intersection->endiannesses_empty()) {
233 if (intersection->sample_rates_empty()) {
237 if (intersection->sample_formats_empty()) {
241 set_compatible (compatible);
245 for (SampleFormatList::iterator it = sample_format_states.begin(); it != sample_format_states.end(); ++it) {
246 (*it)->set_compatible (compatibility.has_sample_format ((*it)->format));
254 ExportFormatOggVorbis::ExportFormatOggVorbis ()
256 /* Check system compatibility */
259 sf_info.channels = 2;
260 sf_info.samplerate = SR_44_1;
261 sf_info.format = F_Ogg | SF_Vorbis;
262 if (sf_format_check (&sf_info) != SF_TRUE) {
263 throw ExportFormatIncompatible();
266 set_name ("Ogg Vorbis");
267 set_format_id (F_Ogg);
268 sample_formats.insert (SF_Vorbis);
270 add_sample_rate (SR_22_05);
271 add_sample_rate (SR_44_1);
272 add_sample_rate (SR_48);
273 add_sample_rate (SR_88_2);
274 add_sample_rate (SR_96);
275 add_sample_rate (SR_176_4);
276 add_sample_rate (SR_192);
277 add_sample_rate (SR_Session);
279 /* these are 100 vorbis_encode_init_vbr() quality */
280 add_codec_quality ("Low (0)", 0);
281 add_codec_quality ("Default (4)", 40);
282 add_codec_quality ("High (6)", 60);
283 add_codec_quality ("Very High (10)", 100);
285 add_endianness (E_FileDefault);
287 set_extension ("ogg");
288 set_quality (Q_LossyCompression);
292 ExportFormatOggVorbis::set_compatibility_state (ExportFormatCompatibility const & compatibility)
294 bool compatible = compatibility.has_format (F_Ogg);
295 set_compatible (compatible);
301 ExportFormatFLAC::ExportFormatFLAC () :
302 HasSampleFormat (sample_formats)
304 /* Check system compatibility */
307 sf_info.channels = 2;
308 sf_info.samplerate = SR_44_1;
309 sf_info.format = F_FLAC | SF_16;
310 if (sf_format_check (&sf_info) != SF_TRUE) {
311 throw ExportFormatIncompatible();
315 set_format_id (F_FLAC);
317 add_sample_rate (SR_22_05);
318 add_sample_rate (SR_44_1);
319 add_sample_rate (SR_48);
320 add_sample_rate (SR_88_2);
321 add_sample_rate (SR_96);
322 add_sample_rate (SR_176_4);
323 add_sample_rate (SR_192);
324 add_sample_rate (SR_Session);
326 add_sample_format (SF_8);
327 add_sample_format (SF_16);
328 add_sample_format (SF_24);
330 add_endianness (E_FileDefault);
332 set_extension ("flac");
333 set_quality (Q_LosslessCompression);
337 ExportFormatFLAC::set_compatibility_state (ExportFormatCompatibility const & compatibility)
339 bool compatible = compatibility.has_format (F_FLAC);
340 set_compatible (compatible);
346 ExportFormatBWF::ExportFormatBWF () :
347 HasSampleFormat (sample_formats)
350 set_format_id (F_WAV);
352 add_sample_rate (SR_22_05);
353 add_sample_rate (SR_44_1);
354 add_sample_rate (SR_48);
355 add_sample_rate (SR_88_2);
356 add_sample_rate (SR_96);
357 add_sample_rate (SR_176_4);
358 add_sample_rate (SR_192);
359 add_sample_rate (SR_Session);
361 add_sample_format (SF_U8);
362 add_sample_format (SF_16);
363 add_sample_format (SF_24);
364 add_sample_format (SF_32);
365 add_sample_format (SF_Float);
366 add_sample_format (SF_Double);
368 add_endianness (E_FileDefault);
370 set_extension ("wav");
371 set_quality (Q_LosslessLinear);
375 ExportFormatBWF::set_compatibility_state (ExportFormatCompatibility const & compatibility)
377 bool compatible = compatibility.has_format (F_WAV);
378 set_compatible (compatible);
383 /*** FFMPEG Pipe ***/
385 ExportFormatFFMPEG::ExportFormatFFMPEG (std::string const& name, std::string const& ext)
388 set_format_id (F_FFMPEG);
389 sample_formats.insert (SF_Float);
391 add_sample_rate (SR_8);
392 add_sample_rate (SR_22_05);
393 add_sample_rate (SR_44_1);
394 add_sample_rate (SR_48);
395 add_sample_rate (SR_Session);
397 add_endianness (E_Little);
399 add_codec_quality ("VBR 220-260 kb/s", 0);
400 add_codec_quality ("VBR 190-250 kb/s", -1);
401 add_codec_quality ("VBR 170-210 kb/s", -2);
402 add_codec_quality ("VBR 150-195 kb/s", -3);
403 add_codec_quality ("VBR 140-185 kb/s", -4);
404 add_codec_quality ("VBR 120-150 kb/s", -5);
405 add_codec_quality ("VBR 100-130 kb/s", -6);
406 add_codec_quality ("VBR 80-120 kb/s", -7);
407 add_codec_quality ("VBR 70-105 kb/s", -8);
408 add_codec_quality ("VBR 45-85 kb/s", -9);
409 /* Available CBR options are:
410 * 8, 16, 24, 32, 40, 48, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320
412 add_codec_quality ("CBR 64 kb/s", 64);
413 add_codec_quality ("CBR 128 kb/s", 128);
414 add_codec_quality ("CBR 160 kb/s", 160);
415 add_codec_quality ("CBR 192 kb/s", 192);
416 add_codec_quality ("CBR 256 kb/s", 256);
417 add_codec_quality ("CBR 320 kb/s", 320);
420 set_quality (Q_LossyCompression);
424 ExportFormatFFMPEG::set_compatibility_state (ExportFormatCompatibility const & compatibility)
426 bool compatible = compatibility.has_format (F_FFMPEG);
427 set_compatible (compatible);
432 }; // namespace ARDOUR