ardour
export_formats.cc
Go to the documentation of this file.
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 using namespace std;
26 
27 namespace ARDOUR
28 {
29 
30 bool
31 ExportFormat::has_sample_format ()
32 {
33  return dynamic_cast<HasSampleFormat *> (this);
34 }
35 
36 bool
37 ExportFormat::sample_format_is_compatible (SampleFormat format) const
38 {
39  return (sample_formats.find (format) != sample_formats.end());
40 }
41 
42 /*** HasSampleFormat ***/
43 
44 HasSampleFormat::HasSampleFormat (ExportFormatBase::SampleFormatSet & sample_formats) :
45  _sample_formats (sample_formats)
46 {
47  /* Dither Types */
48 
49  add_dither_type (ExportFormatBase::D_Shaped, _("Shaped Noise"));
50  add_dither_type (ExportFormatBase::D_Tri, _("Triangular"));
51  add_dither_type (ExportFormatBase::D_Rect, _("Rectangular"));
53 }
54 
55 void
57 {
58  _sample_formats.insert (format);
59 
60  SampleFormatPtr ptr (new SampleFormatState (format, get_sample_format_name (format)));
61  sample_format_states.push_back (ptr);
62  ptr->SelectChanged.connect_same_thread (*this, boost::bind (&HasSampleFormat::update_sample_format_selection, this, _1));
63  // BOOST SIGNALS Could this be made any uglier?
64  ptr->SelectChanged.connect_same_thread (*this,
65  boost::bind (boost::type<void> (), boost::ref (SampleFormatSelectChanged), _1, WeakSampleFormatPtr (ptr)));
66  ptr->CompatibleChanged.connect_same_thread (*this,
67  boost::bind (boost::type<void> (), boost::ref (SampleFormatCompatibleChanged), _1, WeakSampleFormatPtr (ptr)));
68 }
69 
70 void
72 {
73  DitherTypePtr ptr (new DitherTypeState (type, name));
74  dither_type_states.push_back (ptr);
75  ptr->SelectChanged.connect_same_thread (*this, boost::bind (&HasSampleFormat::update_dither_type_selection, this, _1));
76  // BOOST SIGNALS Could this be made any uglier?
77  ptr->SelectChanged.connect_same_thread (*this,
78  boost::bind (boost::type<void> (), boost::ref (DitherTypeSelectChanged), _1, WeakDitherTypePtr (ptr)));
79  ptr->CompatibleChanged.connect_same_thread (*this,
80  boost::bind (boost::type<void> (),boost::ref ( DitherTypeCompatibleChanged), _1, WeakDitherTypePtr (ptr)));
81 }
82 
85 {
86  for (SampleFormatList::iterator it = sample_format_states.begin(); it != sample_format_states.end(); ++it) {
87  if ((*it)->selected()) {
88  return *it;
89  }
90  }
91 
92  return SampleFormatPtr();
93 }
94 
97 {
98  for (DitherTypeList::iterator it = dither_type_states.begin(); it != dither_type_states.end(); ++it) {
99  if ((*it)->selected()) {
100  return *it;
101  }
102  }
103 
104  return DitherTypePtr();
105 }
106 
107 void
109 {
111  if (!format) {
112  return;
113  }
114 
115  if (format->format == ExportFormatBase::SF_24 ||
116  format->format == ExportFormatBase::SF_32 ||
117  format->format == ExportFormatBase::SF_Float ||
118  format->format == ExportFormatBase::SF_Double) {
119  for (DitherTypeList::iterator it = dither_type_states.begin(); it != dither_type_states.end(); ++it) {
120  if ((*it)->type == ExportFormatBase::D_None) {
121  (*it)->set_selected (true);
122  } else {
123  (*it)->set_compatible (false);
124  }
125  }
126 
127  } else {
128  for (DitherTypeList::iterator it = dither_type_states.begin(); it != dither_type_states.end(); ++it) {
129  (*it)->set_compatible (true);
130  }
131  }
132 }
133 
134 void
136 {
138  if (!type) {
139  return;
140  }
141 
142  if (!type->compatible()) {
144  if (format) {
145  format->set_selected (false);
146  }
147 
148  for (DitherTypeList::iterator it = dither_type_states.begin(); it != dither_type_states.end(); ++it) {
149  (*it)->set_compatible (true);
150  }
151  }
152 }
153 
154 string
156 {
157  switch (format) {
159  return _("8bit");
161  return _("16bit");
163  return _("24bit");
165  return _("32bit");
167  return _("float");
169  return _("double");
171  return _("8bit unsigned");
173  return _("Vorbis sample format");
175  return _("No sample format");
176  }
177  return "";
178 }
179 
180 /*** Linear ***/
181 
183  HasSampleFormat (sample_formats),
184  _default_sample_format (SF_None)
185 {
186  set_name (name);
187  set_format_id (format_id);
188 
197 
199 
201 }
202 
203 bool
205 {
206  /* Global state */
207 
208  bool compatible = true;
209 
210  if (!compatibility.has_quality (Q_LosslessLinear)) {
211  compatible = false;
212  }
213 
214  if (!compatibility.has_format (get_format_id())) {
215  compatible = false;
216  }
217 
218  boost::shared_ptr<ExportFormatBase> intersection = get_intersection (compatibility);
219 
220  if (intersection->endiannesses_empty()) {
221  compatible = false;
222  }
223 
224  if (intersection->sample_rates_empty()) {
225  compatible = false;
226  }
227 
228  if (intersection->sample_formats_empty()) {
229  compatible = false;
230  }
231 
232  set_compatible (compatible);
233 
234  /* Sample Formats */
235 
236  for (SampleFormatList::iterator it = sample_format_states.begin(); it != sample_format_states.end(); ++it) {
237  (*it)->set_compatible (compatibility.has_sample_format ((*it)->format));
238  }
239 
240  return compatible;
241 }
242 
243 /*** Ogg Vorbis ***/
244 
246 {
247  /* Check system compatibility */
248 
249  SF_INFO sf_info;
250  sf_info.channels = 2;
251  sf_info.samplerate = SR_44_1;
252  sf_info.format = F_Ogg | SF_Vorbis;
253  if (sf_format_check (&sf_info) != SF_TRUE) {
254  throw ExportFormatIncompatible();
255  }
256 
257  set_name ("Ogg Vorbis");
259  sample_formats.insert (SF_Vorbis);
260 
268 
270 
271  set_extension ("ogg");
273 }
274 
275 bool
277 {
278  bool compatible = compatibility.has_format (F_Ogg);
279  set_compatible (compatible);
280  return compatible;
281 }
282 
283 /*** FLAC ***/
284 
286  HasSampleFormat (sample_formats)
287 {
288  /* Check system compatibility */
289 
290  SF_INFO sf_info;
291  sf_info.channels = 2;
292  sf_info.samplerate = SR_44_1;
293  sf_info.format = F_FLAC | SF_16;
294  if (sf_format_check (&sf_info) != SF_TRUE) {
295  throw ExportFormatIncompatible();
296  }
297 
298  set_name ("FLAC");
300 
308 
312 
314 
315  set_extension ("flac");
317 }
318 
319 bool
321 {
322  bool compatible = compatibility.has_format (F_FLAC);
323  set_compatible (compatible);
324  return compatible;
325 }
326 
327 /*** BWF ***/
328 
330  HasSampleFormat (sample_formats)
331 {
332  set_name ("BWF");
334 
342 
349 
351 
352  set_extension ("wav");
354 }
355 
356 bool
358 {
359  bool compatible = compatibility.has_format (F_WAV);
360  set_compatible (compatible);
361  return compatible;
362 }
363 
364 }; // namespace ARDOUR
void add_dither_type(ExportFormatBase::DitherType type, std::string name)
void set_extension(std::string const &extension)
void set_format_id(FormatId id)
boost::shared_ptr< ExportFormatBase > get_intersection(ExportFormatBase const &other) const
PBD::Signal2< void, bool, WeakSampleFormatPtr > SampleFormatSelectChanged
void add_sample_format(ExportFormatBase::SampleFormat format)
bool has_quality(Quality quality) const
boost::shared_ptr< DitherTypeState > DitherTypePtr
Definition: Beats.hpp:239
void update_sample_format_selection(bool)
bool set_compatibility_state(ExportFormatCompatibility const &compatibility)
void update_dither_type_selection(bool)
bool set_compatibility_state(ExportFormatCompatibility const &compatibility)
SampleFormatList sample_format_states
#define _(Text)
Definition: i18n.h:11
PBD::Signal2< void, bool, WeakDitherTypePtr > DitherTypeSelectChanged
void set_quality(Quality value)
Definition: amp.h:29
bool set_compatibility_state(ExportFormatCompatibility const &compatibility)
Class to be inherited by export formats that have a selectable sample format.
PBD::Signal2< void, bool, WeakDitherTypePtr > DitherTypeCompatibleChanged
SampleFormatPtr get_selected_sample_format()
const char * name
ExportFormatBase::SampleFormatSet & _sample_formats
static std::string get_sample_format_name(ExportFormatBase::SampleFormat format)
FormatId get_format_id() const
void add_endianness(Endianness endianness)
PBD::Signal2< void, bool, WeakSampleFormatPtr > SampleFormatCompatibleChanged
Allows adding to all sets. A format should be able to test if it is compatible with this...
void add_sample_rate(SampleRate rate)
boost::shared_ptr< SampleFormatState > SampleFormatPtr
bool has_format(FormatId format) const
void add_endianness(Endianness endianness)
DitherTypeList dither_type_states
DitherTypePtr get_selected_dither_type()
bool set_compatibility_state(ExportFormatCompatibility const &compatibility)
bool has_sample_format(SampleFormat format) const
ExportFormatLinear(std::string name, FormatId format_id)
std::set< SampleFormat > SampleFormatSet