f3c8f7197c31e0c4c225c48496af94f32a103f00
[ardour.git] / libs / ardour / export_formats.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_formats.h>
22
23 #include "i18n.h"
24
25 namespace ARDOUR
26 {
27
28 bool
29 ExportFormat::has_sample_format ()
30 {
31         return dynamic_cast<HasSampleFormat *> (this);
32 }
33
34 bool
35 ExportFormat::sample_format_is_compatible (SampleFormat format) const
36 {
37         return (sample_formats.find (format) != sample_formats.end());
38 }
39
40 /*** HasSampleFormat ***/
41
42 HasSampleFormat::HasSampleFormat (ExportFormatBase::SampleFormatSet & sample_formats) :
43   _sample_formats (sample_formats)
44 {
45         /* Dither Types */
46         
47         add_dither_type (ExportFormatBase::D_Shaped, _("Shaped Noise"));
48         add_dither_type (ExportFormatBase::D_Tri, _("Triangular"));
49         add_dither_type (ExportFormatBase::D_Rect, _("Rectangular"));
50         add_dither_type (ExportFormatBase::D_None,  _("None"));
51 }
52
53 void
54 HasSampleFormat::add_sample_format (ExportFormatBase::SampleFormat format)
55 {
56         _sample_formats.insert (format);
57         
58         SampleFormatPtr ptr (new SampleFormatState (format, get_sample_format_name (format)));
59         sample_format_states.push_back (ptr);
60         ptr->SelectChanged.connect (sigc::bind (SampleFormatSelectChanged.make_slot(), WeakSampleFormatPtr (ptr)));
61         ptr->SelectChanged.connect (sigc::mem_fun (*this, &HasSampleFormat::update_sample_format_selection));
62         ptr->CompatibleChanged.connect (sigc::bind (SampleFormatCompatibleChanged.make_slot(), WeakSampleFormatPtr (ptr)));
63 }
64
65 void
66 HasSampleFormat::add_dither_type (ExportFormatBase::DitherType type, Glib::ustring name)
67 {
68         DitherTypePtr ptr (new DitherTypeState (type, name));
69         dither_type_states.push_back (ptr);
70         ptr->SelectChanged.connect (sigc::bind (DitherTypeSelectChanged.make_slot(), WeakDitherTypePtr (ptr)));
71         ptr->SelectChanged.connect (sigc::mem_fun (*this, &HasSampleFormat::update_dither_type_selection));
72         ptr->CompatibleChanged.connect (sigc::bind (DitherTypeCompatibleChanged.make_slot(), WeakDitherTypePtr (ptr)));
73 }
74
75 HasSampleFormat::SampleFormatPtr
76 HasSampleFormat::get_selected_sample_format ()
77 {
78         for (SampleFormatList::iterator it = sample_format_states.begin(); it != sample_format_states.end(); ++it) {
79                 if ((*it)->selected()) {
80                         return *it;
81                 }
82         }
83         
84         return SampleFormatPtr();
85 }
86
87 HasSampleFormat::DitherTypePtr
88 HasSampleFormat::get_selected_dither_type ()
89 {
90         for (DitherTypeList::iterator it = dither_type_states.begin(); it != dither_type_states.end(); ++it) {
91                 if ((*it)->selected()) {
92                         return *it;
93                 }
94         }
95         
96         return DitherTypePtr();
97 }
98
99 void
100 HasSampleFormat::update_sample_format_selection (bool)
101 {
102         SampleFormatPtr format = get_selected_sample_format();
103         if (!format) {
104                 return;
105         }
106         
107         if (format->format == ExportFormatBase::SF_24 ||
108             format->format == ExportFormatBase::SF_32 ||
109             format->format == ExportFormatBase::SF_Float ||
110             format->format == ExportFormatBase::SF_Double) {
111                 for (DitherTypeList::iterator it = dither_type_states.begin(); it != dither_type_states.end(); ++it) {
112                         if ((*it)->type == ExportFormatBase::D_None) {
113                                 (*it)->set_selected (true);
114                         } else {
115                                 (*it)->set_compatible (false);
116                         }
117                 }
118
119         } else {
120                 for (DitherTypeList::iterator it = dither_type_states.begin(); it != dither_type_states.end(); ++it) {
121                         (*it)->set_compatible (true);
122                 }
123         }
124 }
125
126 void
127 HasSampleFormat::update_dither_type_selection (bool)
128 {
129         DitherTypePtr type = get_selected_dither_type();
130         if (!type) {
131                 return;
132         }
133         
134         if (!type->compatible()) {
135                 SampleFormatPtr format = get_selected_sample_format();
136                 if (format) {
137                         format->set_selected (false);
138                 }
139                 
140                 for (DitherTypeList::iterator it = dither_type_states.begin(); it != dither_type_states.end(); ++it) {
141                         (*it)->set_compatible (true);
142                 }
143         }
144 }
145
146 string
147 HasSampleFormat::get_sample_format_name (ExportFormatBase::SampleFormat format)
148 {
149         switch (format) {
150           case ExportFormatBase::SF_8:
151                 return _("8bit");
152           case ExportFormatBase::SF_16:
153                 return _("16bit");
154           case ExportFormatBase::SF_24:
155                 return _("24bit");
156           case ExportFormatBase::SF_32:
157                 return _("32bit");
158           case ExportFormatBase::SF_Float:
159                 return _("float");
160           case ExportFormatBase::SF_Double:
161                 return _("double");
162           case ExportFormatBase::SF_U8:
163                 return _("8bit unsigned");
164           case ExportFormatBase::SF_Vorbis:
165                 return _("Vorbis sample format");
166           case ExportFormatBase::SF_None:
167                 return _("No sample format");
168         }
169         return "";
170 }
171
172 /*** Linear ***/
173
174 ExportFormatLinear::ExportFormatLinear (Glib::ustring name, FormatId format_id) :
175   HasSampleFormat (sample_formats),
176   _default_sample_format (SF_None)
177 {
178         set_name (name);
179         set_format_id (format_id);
180         
181         add_sample_rate (SR_22_05);
182         add_sample_rate (SR_44_1);
183         add_sample_rate (SR_48);
184         add_sample_rate (SR_88_2);
185         add_sample_rate (SR_96);
186         add_sample_rate (SR_192);
187         
188         add_endianness (E_FileDefault);
189         
190         set_quality (Q_LosslessLinear);
191 }
192
193 bool
194 ExportFormatLinear::set_compatibility_state (ExportFormatCompatibility const & compatibility)
195 {
196         /* Global state */
197
198         bool compatible = true;
199
200         if (!compatibility.has_quality (Q_LosslessLinear)) {
201                 compatible = false;
202         }
203         
204         if (!compatibility.has_format (get_format_id())) {
205                 compatible = false;
206         }
207
208         boost::shared_ptr<ExportFormatBase> intersection = get_intersection (compatibility);
209         
210         if (intersection->endiannesses_empty()) {
211                 compatible = false;
212         }
213         
214         if (intersection->sample_rates_empty()) {
215                 compatible = false;
216         }
217         
218         if (intersection->sample_formats_empty()) {
219                 compatible = false;
220         }
221         
222         set_compatible (compatible);
223
224         /* Sample Formats */
225         
226         for (SampleFormatList::iterator it = sample_format_states.begin(); it != sample_format_states.end(); ++it) {
227                 (*it)->set_compatible (compatibility.has_sample_format ((*it)->format));
228         }
229
230         return compatible;
231 }
232
233 /*** Ogg Vorbis ***/
234
235 ExportFormatOggVorbis::ExportFormatOggVorbis ()
236 {
237         set_name ("Ogg Vorbis");
238         set_format_id (F_Ogg);
239         sample_formats.insert (SF_Vorbis);
240         
241         add_sample_rate (SR_22_05);
242         add_sample_rate (SR_44_1);
243         add_sample_rate (SR_48);
244         add_sample_rate (SR_88_2);
245         add_sample_rate (SR_96);
246         add_sample_rate (SR_192);
247         
248         add_endianness (E_FileDefault);
249         
250         set_extension ("ogg");
251         set_quality (Q_LossyCompression);
252 }
253
254 bool
255 ExportFormatOggVorbis::check_system_compatibility ()
256 {
257         SF_INFO sf_info;
258         sf_info.channels = 2;
259         sf_info.samplerate = SR_44_1;
260         sf_info.format = F_Ogg | SF_Vorbis;
261
262         return (sf_format_check (&sf_info) == SF_TRUE ? true : false);
263 }
264
265 bool
266 ExportFormatOggVorbis::set_compatibility_state (ExportFormatCompatibility const & compatibility)
267 {
268         bool compatible = compatibility.has_format (F_Ogg);
269         set_compatible (compatible);
270         return compatible;
271 }
272
273 /*** FLAC ***/
274
275 ExportFormatFLAC::ExportFormatFLAC () :
276   HasSampleFormat (sample_formats)
277 {
278         set_name ("FLAC");
279         set_format_id (F_FLAC);
280         
281         add_sample_rate (SR_22_05);
282         add_sample_rate (SR_44_1);
283         add_sample_rate (SR_48);
284         add_sample_rate (SR_88_2);
285         add_sample_rate (SR_96);
286         add_sample_rate (SR_192);
287         
288         add_sample_format (SF_8);
289         add_sample_format (SF_16);
290         add_sample_format (SF_24);
291         
292         add_endianness (E_FileDefault);
293         
294         set_extension ("flac");
295         set_quality (Q_LosslessCompression);
296 }
297
298 bool
299 ExportFormatFLAC::check_system_compatibility ()
300 {
301         SF_INFO sf_info;
302         sf_info.channels = 2;
303         sf_info.samplerate = SR_44_1;
304         sf_info.format = F_FLAC | SF_16;
305
306         return (sf_format_check (&sf_info) == SF_TRUE ? true : false);
307 }
308
309 bool
310 ExportFormatFLAC::set_compatibility_state (ExportFormatCompatibility const & compatibility)
311 {
312         bool compatible = compatibility.has_format (F_FLAC);
313         set_compatible (compatible);
314         return compatible;
315 }
316
317 /*** BWF ***/
318
319 ExportFormatBWF::ExportFormatBWF () :
320   HasSampleFormat (sample_formats)
321 {
322         set_name ("BWF");
323         set_format_id (F_WAV);
324         
325         add_sample_rate (SR_22_05);
326         add_sample_rate (SR_44_1);
327         add_sample_rate (SR_48);
328         add_sample_rate (SR_88_2);
329         add_sample_rate (SR_96);
330         add_sample_rate (SR_192);
331
332         add_sample_format (SF_U8);
333         add_sample_format (SF_16);
334         add_sample_format (SF_24);
335         add_sample_format (SF_32);
336         add_sample_format (SF_Float);
337         add_sample_format (SF_Double);
338         
339         add_endianness (E_FileDefault);
340         
341         set_extension ("wav");
342         set_quality (Q_LosslessLinear);
343 }
344
345 bool
346 ExportFormatBWF::set_compatibility_state (ExportFormatCompatibility const & compatibility)
347 {
348         bool compatible = compatibility.has_format (F_WAV);
349         set_compatible (compatible);
350         return compatible;
351 }
352
353 }; // namespace ARDOUR