summaryrefslogtreecommitdiff
path: root/libs/ardour/ardour/export_profile_manager.h
blob: b0285f8ecce11733b6a2d4582ee61bce19468ab0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
/*
    Copyright (C) 2008 Paul Davis
    Author: Sakari Bergen

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#ifndef __ardour_export_profile_manager_h__
#define __ardour_export_profile_manager_h__

#include <list>
#include <vector>
#include <map>
#include <stdexcept>
#include <string>

#include <boost/shared_ptr.hpp>

#include "pbd/uuid.h"
#include "pbd/file_utils.h"
#include "pbd/xml++.h"

#include "ardour/filesystem_paths.h"
#include "ardour/location.h"
#include "ardour/libardour_visibility.h"
#include "ardour/types.h"
#include "ardour/export_handler.h"

namespace ARDOUR
{

class ExportHandler;
class Location;
class Session;

/// Manages (de)serialization of export profiles and related classes
class LIBARDOUR_API ExportProfileManager
{
  public:

	enum ExportType {
		RegularExport,
		RangeExport,
		SelectionExport,
		RegionExport,
		StemExport
	};

	ExportProfileManager (Session & s, ExportType type);
	~ExportProfileManager ();

	void load_profile ();
	void prepare_for_export ();

	ExportType type () const { return _type; }

	typedef std::list<ExportPresetPtr> PresetList;

	PresetList const & get_presets () { return preset_list; }
	bool load_preset (ExportPresetPtr preset);
	ExportPresetPtr new_preset (std::string const & name);
	ExportPresetPtr save_preset (std::string const & name);
	void remove_preset ();

  private:
	typedef boost::shared_ptr<ExportHandler> HandlerPtr;

	typedef std::pair<PBD::UUID, std::string> FilePair;
	typedef std::map<PBD::UUID, std::string> FileMap;

	ExportType  _type;
	std::string xml_node_name;
	HandlerPtr  handler;
	Session &   session;

	std::string preset_filename (std::string const & preset_name);
	void load_presets ();
	void load_preset_from_disk (std::string const & path);

	bool set_state (XMLNode const & root);
	bool set_global_state (XMLNode const & root);
	bool set_local_state (XMLNode const & root);

	void serialize_profile (XMLNode & root);
	void serialize_global_profile (XMLNode & root);
	void serialize_local_profile (XMLNode & root);

	PresetList      preset_list;
	ExportPresetPtr current_preset;
	FileMap         preset_file_map;

	std::vector<std::string> find_file (std::string const & pattern);

	std::string  export_config_dir;
	PBD::Searchpath search_path;

/* Timespans */
  public:

	typedef std::list<ExportTimespanPtr> TimespanList;
	typedef boost::shared_ptr<TimespanList> TimespanListPtr;
	typedef std::list<Location *> LocationList;

	enum TimeFormat {
		Timecode,
		BBT,
		MinSec,
		Frames,
	};

	struct TimespanState {
		TimespanListPtr timespans;
		TimeFormat      time_format;

		boost::shared_ptr<Location> selection_range;
		boost::shared_ptr<LocationList> ranges;

		TimespanState (boost::shared_ptr<Location> selection_range,
		               boost::shared_ptr<LocationList> ranges)
		  : timespans (new TimespanList ())
		  , time_format (Timecode)
		  , selection_range (selection_range)
		  , ranges (ranges)
		{}
	};

	typedef boost::shared_ptr<TimespanState> TimespanStatePtr;
	typedef std::list<TimespanStatePtr> TimespanStateList;

	void set_selection_range (framepos_t start = 0, framepos_t end = 0);
	std::string set_single_range (framepos_t start, framepos_t end, std::string name);
	TimespanStateList const & get_timespans () { return check_list (timespans); }

  private:

	TimespanStateList timespans;

	bool init_timespans (XMLNodeList nodes);

	TimespanStatePtr deserialize_timespan (XMLNode & root);
	XMLNode & serialize_timespan (TimespanStatePtr state);

	/* Locations */

	void update_ranges ();

	boost::shared_ptr<Location>     selection_range;
	boost::shared_ptr<LocationList> ranges;

	bool                            single_range_mode;
	boost::shared_ptr<Location>     single_range;

/* Channel Configs */
  public:

	struct ChannelConfigState {
		ExportChannelConfigPtr config;

		ChannelConfigState (ExportChannelConfigPtr ptr) : config (ptr) {}
	};
	typedef boost::shared_ptr<ChannelConfigState> ChannelConfigStatePtr;
	typedef std::list<ChannelConfigStatePtr> ChannelConfigStateList;

	ChannelConfigStateList const & get_channel_configs () { return check_list (channel_configs); }
	void clear_channel_configs () { channel_configs.clear(); }
	ChannelConfigStatePtr add_channel_config ();

  private:

	ChannelConfigStateList channel_configs;

	bool init_channel_configs (XMLNodeList nodes);

/* Formats */
  public:

	typedef std::list<ExportFormatSpecPtr> FormatList;

	struct FormatState {
		boost::shared_ptr<FormatList const> list;
		ExportFormatSpecPtr                     format;

		FormatState (boost::shared_ptr<FormatList const> list, ExportFormatSpecPtr format) :
		  list (list), format (format) {}
	};
	typedef boost::shared_ptr<FormatState> FormatStatePtr;
	typedef std::list<FormatStatePtr> FormatStateList;

	FormatStateList const & get_formats () { return check_list (formats); }
	FormatStatePtr duplicate_format_state (FormatStatePtr state);
	void remove_format_state (FormatStatePtr state);

	std::string save_format_to_disk (ExportFormatSpecPtr format);
	void remove_format_profile (ExportFormatSpecPtr format);
	ExportFormatSpecPtr get_new_format (ExportFormatSpecPtr original);

	PBD::Signal0<void> FormatListChanged;

  private:

	FormatStateList formats;

	bool init_formats (XMLNodeList nodes);
	FormatStatePtr deserialize_format (XMLNode & root);
	XMLNode & serialize_format (FormatStatePtr state);

	void load_formats ();

	ExportFormatSpecPtr load_format (XMLNode & node);
	void load_format_from_disk (std::string const & path);

	boost::shared_ptr<FormatList> format_list;
	FileMap                       format_file_map;

/* Filenames */
  public:

	struct FilenameState {
		ExportFilenamePtr  filename;

		FilenameState (ExportFilenamePtr ptr) : filename (ptr) {}
	};
	typedef boost::shared_ptr<FilenameState> FilenameStatePtr;
	typedef std::list<FilenameStatePtr> FilenameStateList;

	FilenameStateList const & get_filenames () { return check_list (filenames); }
	FilenameStatePtr duplicate_filename_state (FilenameStatePtr state);
	void remove_filename_state (FilenameStatePtr state);

	std::string get_sample_filename_for_format (ExportFilenamePtr filename, ExportFormatSpecPtr format);

  private:

	FilenameStateList filenames;

	bool init_filenames (XMLNodeList nodes);
	ExportFilenamePtr load_filename (XMLNode & node);

/* Warnings */
  public:
	struct Warnings {
		std::list<std::string> errors;
		std::list<std::string> warnings;
		std::list<std::string> conflicting_filenames;
	};

	boost::shared_ptr<Warnings> get_warnings ();

  private:
	void check_config (boost::shared_ptr<Warnings> warnings,
	                   TimespanStatePtr timespan_state,
	                   ChannelConfigStatePtr channel_config_state,
	                   FormatStatePtr format_state,
	                   FilenameStatePtr filename_state);

	bool check_format (ExportFormatSpecPtr format, uint32_t channels);
	bool check_sndfile_format (ExportFormatSpecPtr format, unsigned int channels);

 /* Utilities */

	void build_filenames(std::list<std::string> & result, ExportFilenamePtr filename,
	                     TimespanListPtr timespans, ExportChannelConfigPtr channel_config,
	                     ExportFormatSpecPtr format);

	/* Element state lists should never be empty, this is used to check them */
	template<typename T>
	std::list<T> const &
	check_list (std::list<T> const & list)
	{
		if (list.empty()) {
			throw std::runtime_error ("Programming error: Uninitialized list in ExportProfileManager");
		}
		return list;
	}

};


} // namespace ARDOUR

#endif /* __ardour_export_profile_manager_h__ */