1 /*
2  * Copyright (C) 2008-2010 Sakari Bergen <sakari.bergen@beatwaves.net>
3  * Copyright (C) 2008-2015 Paul Davis <paul@linuxaudiosystems.com>
4  * Copyright (C) 2009-2011 David Robillard <d@drobilla.net>
5  * Copyright (C) 2018-2019 Robin Gareus <robin@gareus.org>
6  *
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.
11  *
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.
16  *
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.
20  */
21 
22 #ifndef __ardour_export_formats_h__
23 #define __ardour_export_formats_h__
24 
25 #include <boost/weak_ptr.hpp>
26 #include <list>
27 
28 #include "pbd/failed_constructor.h"
29 #include "pbd/signals.h"
30 
31 #include "ardour/export_format_base.h"
32 #include "ardour/export_format_compatibility.h"
33 
34 namespace ARDOUR {
35 
36 class LIBARDOUR_API ExportFormatIncompatible : public failed_constructor
37 {
38 public:
what()39 	virtual const char* what () const throw ()
40 	{
41 		return "Export format constructor failed: Format incompatible with system";
42 	}
43 };
44 
45 /// Base class for formats
46 class LIBARDOUR_API ExportFormat : public ExportFormatBase, public ExportFormatBase::SelectableCompatible
47 {
48 public:
ExportFormat()49 	ExportFormat (){};
~ExportFormat()50 	~ExportFormat (){};
51 
52 	virtual bool set_compatibility_state (ExportFormatCompatibility const& compatibility) = 0;
53 
54 	virtual Type get_type () const = 0;
55 
get_format_id()56 	FormatId get_format_id () const
57 	{
58 		return *format_ids.begin ();
59 	}
60 
get_quality()61 	Quality get_quality () const
62 	{
63 		return *qualities.begin ();
64 	}
65 
66 	bool has_sample_format ();
67 	bool has_codec_quality ();
68 
69 	bool sample_format_is_compatible (SampleFormat format) const;
70 
71 	/* If the format has a specific sample format, this function should be overridden
72 	 * if the format has a selectable sample format, do not override this!
73 	 */
get_explicit_sample_format()74 	virtual SampleFormat get_explicit_sample_format () const
75 	{
76 		return SF_None;
77 	}
78 
79 	/* If the above is not overridden, this one should be */
default_sample_format()80 	virtual ExportFormat::SampleFormat default_sample_format () const
81 	{
82 		return SF_None;
83 	}
84 
85 	/* If the format has a channel count limit, override this */
get_channel_limit()86 	virtual uint32_t get_channel_limit () const
87 	{
88 		return 256;
89 	}
90 
91 	/* If the format can be tagged with metadata override this */
supports_tagging()92 	virtual bool supports_tagging () const
93 	{
94 		return false;
95 	}
96 
97 	/* If the format contains broadcast info override this */
has_broadcast_info()98 	virtual bool has_broadcast_info () const
99 	{
100 		return false;
101 	}
102 
103 protected:
add_sample_rate(SampleRate rate)104 	void add_sample_rate (SampleRate rate)
105 	{
106 		sample_rates.insert (rate);
107 	}
108 
add_endianness(Endianness endianness)109 	void add_endianness (Endianness endianness)
110 	{
111 		endiannesses.insert (endianness);
112 	}
113 
set_format_id(FormatId id)114 	void set_format_id (FormatId id)
115 	{
116 		format_ids.clear ();
117 		format_ids.insert (id);
118 	}
119 
set_quality(Quality value)120 	void set_quality (Quality value)
121 	{
122 		qualities.clear ();
123 		qualities.insert (value);
124 	}
125 };
126 
127 class LIBARDOUR_API HasCodecQuality
128 {
129 public:
130 	struct CodecQuality {
CodecQualityCodecQuality131 		CodecQuality (std::string const& n, int q)
132 			: name (n)
133 			, quality (q)
134 		{}
135 
136 		std::string name;
137 		int         quality;
138 	};
139 
140 	typedef boost::shared_ptr<CodecQuality> CodecQualityPtr;
141 	typedef std::list<CodecQualityPtr>      CodecQualityList;
142 
~HasCodecQuality()143 	virtual ~HasCodecQuality () {}
144 
add_codec_quality(std::string const & name,int q)145 	void add_codec_quality (std::string const& name, int q)
146 	{
147 		CodecQualityPtr ptr (new CodecQuality (name, q));
148 		_codec_qualties.push_back (ptr);
149 	}
150 
get_codec_qualities()151 	CodecQualityList const& get_codec_qualities () const
152 	{
153 		return _codec_qualties;
154 	}
155 
156 	virtual int default_codec_quality () const = 0;
157 
158 protected:
159 	CodecQualityList _codec_qualties;
160 };
161 
162 /// Class to be inherited by export formats that have a selectable sample format
163 class LIBARDOUR_API HasSampleFormat : public PBD::ScopedConnectionList
164 {
165 public:
166 	class SampleFormatState : public ExportFormatBase::SelectableCompatible
167 	{
168 	public:
SampleFormatState(ExportFormatBase::SampleFormat format,std::string name)169 		SampleFormatState (ExportFormatBase::SampleFormat format, std::string name)
170 			: format (format)
171 		{
172 			set_name (name);
173 		}
174 
175 		ExportFormatBase::SampleFormat format;
176 	};
177 
178 	class DitherTypeState : public ExportFormatBase::SelectableCompatible
179 	{
180 	public:
DitherTypeState(ExportFormatBase::DitherType type,Glib::ustring name)181 		DitherTypeState (ExportFormatBase::DitherType type, Glib::ustring name)
182 			: type (type)
183 		{
184 			set_name (name);
185 		}
186 
187 		ExportFormatBase::DitherType type;
188 	};
189 
190 	typedef boost::shared_ptr<SampleFormatState> SampleFormatPtr;
191 	typedef boost::weak_ptr<SampleFormatState>   WeakSampleFormatPtr;
192 	typedef std::list<SampleFormatPtr>           SampleFormatList;
193 
194 	typedef boost::shared_ptr<DitherTypeState> DitherTypePtr;
195 	typedef boost::weak_ptr<DitherTypeState>   WeakDitherTypePtr;
196 	typedef std::list<DitherTypePtr>           DitherTypeList;
197 
198 public:
199 	HasSampleFormat (ExportFormatBase::SampleFormatSet& sample_formats);
~HasSampleFormat()200 	virtual ~HasSampleFormat (){};
201 
202 	void add_sample_format (ExportFormatBase::SampleFormat format);
203 
get_sample_formats()204 	SampleFormatList const& get_sample_formats () const
205 	{
206 		return sample_format_states;
207 	}
208 
get_dither_types()209 	DitherTypeList const& get_dither_types () const
210 	{
211 		return dither_type_states;
212 	}
213 
214 	SampleFormatPtr get_selected_sample_format ();
215 	DitherTypePtr   get_selected_dither_type ();
216 
217 	/* Proxies for signals from sample formats and dither types */
218 	PBD::Signal2<void, bool, WeakSampleFormatPtr> SampleFormatSelectChanged;
219 	PBD::Signal2<void, bool, WeakSampleFormatPtr> SampleFormatCompatibleChanged;
220 
221 	PBD::Signal2<void, bool, WeakDitherTypePtr> DitherTypeSelectChanged;
222 	PBD::Signal2<void, bool, WeakDitherTypePtr> DitherTypeCompatibleChanged;
223 
224 	static std::string get_sample_format_name (ExportFormatBase::SampleFormat format);
225 
226 protected:
227 	/* State lists */
228 	DitherTypeList   dither_type_states;
229 	SampleFormatList sample_format_states;
230 
231 private:
232 	/* Connected to signals */
233 	void add_dither_type (ExportFormatBase::DitherType type, std::string name);
234 	void update_sample_format_selection (bool);
235 	void update_dither_type_selection (bool);
236 
237 	/* Reference to ExportFormatBase::sample_formats */
238 	ExportFormatBase::SampleFormatSet& _sample_formats;
239 };
240 
241 class LIBARDOUR_API ExportFormatLinear : public ExportFormat, public HasSampleFormat
242 {
243 public:
244 	ExportFormatLinear (std::string name, FormatId format_id);
~ExportFormatLinear()245 	~ExportFormatLinear (){};
246 
247 	bool set_compatibility_state (ExportFormatCompatibility const& compatibility);
get_type()248 	Type get_type () const
249 	{
250 		return T_Sndfile;
251 	}
252 
add_endianness(Endianness endianness)253 	void add_endianness (Endianness endianness)
254 	{
255 		endiannesses.insert (endianness);
256 	}
257 
set_default_sample_format(SampleFormat sf)258 	void set_default_sample_format (SampleFormat sf)
259 	{
260 		_default_sample_format = sf;
261 	}
262 
default_sample_format()263 	SampleFormat default_sample_format () const
264 	{
265 		return _default_sample_format;
266 	}
267 
268 protected:
269 	SampleFormat _default_sample_format;
270 };
271 
272 class LIBARDOUR_API ExportFormatTaggedLinear : public ExportFormatLinear
273 {
274 public:
ExportFormatTaggedLinear(std::string name,FormatId format_id)275 	ExportFormatTaggedLinear (std::string name, FormatId format_id)
276 		: ExportFormatLinear (name, format_id)
277 	{
278 	}
279 
supports_tagging()280 	virtual bool supports_tagging () const
281 	{
282 		return true;
283 	}
284 };
285 
286 class LIBARDOUR_API ExportFormatOggVorbis : public ExportFormat, public HasCodecQuality
287 {
288 public:
289 	ExportFormatOggVorbis ();
~ExportFormatOggVorbis()290 	~ExportFormatOggVorbis (){};
291 
292 	bool set_compatibility_state (ExportFormatCompatibility const& compatibility);
get_type()293 	Type get_type () const
294 	{
295 		return T_Sndfile;
296 	}
get_explicit_sample_format()297 	SampleFormat get_explicit_sample_format () const
298 	{
299 		return SF_Vorbis;
300 	}
supports_tagging()301 	virtual bool supports_tagging () const
302 	{
303 		return true;
304 	}
default_codec_quality()305 	int default_codec_quality () const
306 	{
307 		return 40;
308 	}
309 };
310 
311 class LIBARDOUR_API ExportFormatFLAC : public ExportFormat, public HasSampleFormat
312 {
313 public:
314 	ExportFormatFLAC ();
~ExportFormatFLAC()315 	~ExportFormatFLAC (){};
316 
317 	bool set_compatibility_state (ExportFormatCompatibility const& compatibility);
get_type()318 	Type get_type () const
319 	{
320 		return T_Sndfile;
321 	}
get_channel_limit()322 	uint32_t get_channel_limit () const
323 	{
324 		return 8;
325 	}
default_sample_format()326 	SampleFormat default_sample_format () const
327 	{
328 		return SF_16;
329 	}
supports_tagging()330 	virtual bool supports_tagging () const
331 	{
332 		return true;
333 	}
334 };
335 
336 class LIBARDOUR_API ExportFormatBWF : public ExportFormat, public HasSampleFormat
337 {
338 public:
339 	ExportFormatBWF ();
~ExportFormatBWF()340 	~ExportFormatBWF (){};
341 
342 	bool set_compatibility_state (ExportFormatCompatibility const& compatibility);
343 
get_type()344 	Type get_type () const
345 	{
346 		return T_Sndfile;
347 	}
default_sample_format()348 	SampleFormat default_sample_format () const
349 	{
350 		return SF_16;
351 	}
has_broadcast_info()352 	virtual bool has_broadcast_info () const
353 	{
354 		return true;
355 	}
356 };
357 
358 class LIBARDOUR_API ExportFormatFFMPEG : public ExportFormat, public HasCodecQuality
359 {
360 public:
361 	ExportFormatFFMPEG (std::string const& name, std::string const& ext);
~ExportFormatFFMPEG()362 	~ExportFormatFFMPEG (){};
363 
364 	bool set_compatibility_state (ExportFormatCompatibility const& compatibility);
365 
get_type()366 	Type get_type () const
367 	{
368 		return T_FFMPEG;
369 	}
get_explicit_sample_format()370 	SampleFormat get_explicit_sample_format () const
371 	{
372 		return SF_Float;
373 	}
default_codec_quality()374 	int default_codec_quality () const
375 	{
376 		return -2;
377 	}
supports_tagging()378 	virtual bool supports_tagging () const
379 	{
380 		return true;
381 	}
382 };
383 
384 } // namespace ARDOUR
385 
386 #endif /* __ardour_export_formats__ */
387