add 0.5 second sleep after closing JACK connection so that next startup/connect is...
[ardour.git] / libs / ardour / ardour / export_profile_manager.h
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 #ifndef __ardour_export_profile_manager_h__
22 #define __ardour_export_profile_manager_h__
23
24 #include <list>
25 #include <vector>
26 #include <map>
27 #include <stdexcept>
28 #include <string>
29
30 #include <boost/shared_ptr.hpp>
31
32 #include "pbd/uuid.h"
33 #include "pbd/file_utils.h"
34 #include "pbd/xml++.h"
35
36 #include "ardour/filesystem_paths.h"
37 #include "ardour/location.h"
38 #include "ardour/types.h"
39 #include "ardour/export_handler.h"
40
41 namespace ARDOUR
42 {
43
44 class ExportHandler;
45 class Location;
46 class Session;
47
48 /// Manages (de)serialization of export profiles and related classes
49 class ExportProfileManager
50 {
51   public:
52
53         enum ExportType {
54                 RegularExport,
55                 RangeExport,
56                 SelectionExport,
57                 RegionExport,
58                 StemExport
59         };
60
61         ExportProfileManager (Session & s, ExportType type);
62         ~ExportProfileManager ();
63
64         void load_profile ();
65         void prepare_for_export ();
66
67         typedef std::list<ExportPresetPtr> PresetList;
68
69         PresetList const & get_presets () { return preset_list; }
70         bool load_preset (ExportPresetPtr preset);
71         ExportPresetPtr new_preset (std::string const & name);
72         ExportPresetPtr save_preset (std::string const & name);
73         void remove_preset ();
74
75   private:
76         typedef boost::shared_ptr<ExportHandler> HandlerPtr;
77
78         typedef std::pair<PBD::UUID, std::string> FilePair;
79         typedef std::map<PBD::UUID, std::string> FileMap;
80
81         ExportType type;
82         std::string xml_node_name;
83         HandlerPtr  handler;
84         Session &   session;
85
86         std::string preset_filename (std::string const & preset_name);
87         void load_presets ();
88         void load_preset_from_disk (std::string const & path);
89
90         bool set_state (XMLNode const & root);
91         bool set_global_state (XMLNode const & root);
92         bool set_local_state (XMLNode const & root);
93
94         void serialize_profile (XMLNode & root);
95         void serialize_global_profile (XMLNode & root);
96         void serialize_local_profile (XMLNode & root);
97
98         PresetList      preset_list;
99         ExportPresetPtr current_preset;
100         FileMap         preset_file_map;
101
102         std::vector<std::string> find_file (std::string const & pattern);
103
104         std::string  export_config_dir;
105         PBD::SearchPath search_path;
106
107 /* Timespans */
108   public:
109
110         typedef std::list<ExportTimespanPtr> TimespanList;
111         typedef boost::shared_ptr<TimespanList> TimespanListPtr;
112         typedef std::list<Location *> LocationList;
113
114         enum TimeFormat {
115                 Timecode,
116                 BBT,
117                 MinSec,
118                 Frames,
119         };
120
121         struct TimespanState {
122                 TimespanListPtr timespans;
123                 TimeFormat      time_format;
124
125                 boost::shared_ptr<Location> selection_range;
126                 boost::shared_ptr<LocationList> ranges;
127
128                 TimespanState (boost::shared_ptr<Location> selection_range,
129                                boost::shared_ptr<LocationList> ranges)
130                   : timespans (new TimespanList ())
131                   , time_format (Timecode)
132                   , selection_range (selection_range)
133                   , ranges (ranges)
134                 {}
135         };
136
137         typedef boost::shared_ptr<TimespanState> TimespanStatePtr;
138         typedef std::list<TimespanStatePtr> TimespanStateList;
139
140         void set_selection_range (framepos_t start = 0, framepos_t end = 0);
141         std::string set_single_range (framepos_t start, framepos_t end, std::string name);
142         TimespanStateList const & get_timespans () { return check_list (timespans); }
143
144   private:
145
146         TimespanStateList timespans;
147
148         bool init_timespans (XMLNodeList nodes);
149
150         TimespanStatePtr deserialize_timespan (XMLNode & root);
151         XMLNode & serialize_timespan (TimespanStatePtr state);
152
153         /* Locations */
154
155         void update_ranges ();
156
157         boost::shared_ptr<Location>     selection_range;
158         boost::shared_ptr<LocationList> ranges;
159
160         bool                            single_range_mode;
161         boost::shared_ptr<Location>     single_range;
162
163 /* Channel Configs */
164   public:
165
166         struct ChannelConfigState {
167                 ExportChannelConfigPtr config;
168
169                 ChannelConfigState (ExportChannelConfigPtr ptr) : config (ptr) {}
170         };
171         typedef boost::shared_ptr<ChannelConfigState> ChannelConfigStatePtr;
172         typedef std::list<ChannelConfigStatePtr> ChannelConfigStateList;
173
174         ChannelConfigStateList const & get_channel_configs () { return check_list (channel_configs); }
175         void clear_channel_configs () { channel_configs.clear(); }
176         ChannelConfigStatePtr add_channel_config ();
177
178   private:
179
180         ChannelConfigStateList channel_configs;
181
182         bool init_channel_configs (XMLNodeList nodes);
183
184 /* Formats */
185   public:
186
187         typedef std::list<ExportFormatSpecPtr> FormatList;
188
189         struct FormatState {
190                 boost::shared_ptr<FormatList const> list;
191                 ExportFormatSpecPtr                     format;
192
193                 FormatState (boost::shared_ptr<FormatList const> list, ExportFormatSpecPtr format) :
194                   list (list), format (format) {}
195         };
196         typedef boost::shared_ptr<FormatState> FormatStatePtr;
197         typedef std::list<FormatStatePtr> FormatStateList;
198
199         FormatStateList const & get_formats () { return check_list (formats); }
200         FormatStatePtr duplicate_format_state (FormatStatePtr state);
201         void remove_format_state (FormatStatePtr state);
202
203         std::string save_format_to_disk (ExportFormatSpecPtr format);
204         void remove_format_profile (ExportFormatSpecPtr format);
205         ExportFormatSpecPtr get_new_format (ExportFormatSpecPtr original);
206
207         PBD::Signal0<void> FormatListChanged;
208
209   private:
210
211         FormatStateList formats;
212
213         bool init_formats (XMLNodeList nodes);
214         FormatStatePtr deserialize_format (XMLNode & root);
215         XMLNode & serialize_format (FormatStatePtr state);
216
217         void load_formats ();
218
219         ExportFormatSpecPtr load_format (XMLNode & node);
220         void load_format_from_disk (std::string const & path);
221
222         boost::shared_ptr<FormatList> format_list;
223         FileMap                       format_file_map;
224
225 /* Filenames */
226   public:
227
228         struct FilenameState {
229                 ExportFilenamePtr  filename;
230
231                 FilenameState (ExportFilenamePtr ptr) : filename (ptr) {}
232         };
233         typedef boost::shared_ptr<FilenameState> FilenameStatePtr;
234         typedef std::list<FilenameStatePtr> FilenameStateList;
235
236         FilenameStateList const & get_filenames () { return check_list (filenames); }
237         FilenameStatePtr duplicate_filename_state (FilenameStatePtr state);
238         void remove_filename_state (FilenameStatePtr state);
239
240         std::string get_sample_filename_for_format (ExportFilenamePtr filename, ExportFormatSpecPtr format);
241
242   private:
243
244         FilenameStateList filenames;
245
246         bool init_filenames (XMLNodeList nodes);
247         ExportFilenamePtr load_filename (XMLNode & node);
248
249 /* Warnings */
250   public:
251         struct Warnings {
252                 std::list<std::string> errors;
253                 std::list<std::string> warnings;
254                 std::list<std::string> conflicting_filenames;
255         };
256
257         boost::shared_ptr<Warnings> get_warnings ();
258
259   private:
260         void check_config (boost::shared_ptr<Warnings> warnings,
261                            TimespanStatePtr timespan_state,
262                            ChannelConfigStatePtr channel_config_state,
263                            FormatStatePtr format_state,
264                            FilenameStatePtr filename_state);
265
266         bool check_format (ExportFormatSpecPtr format, uint32_t channels);
267         bool check_sndfile_format (ExportFormatSpecPtr format, unsigned int channels);
268
269  /* Utilities */
270
271         void build_filenames(std::list<std::string> & result, ExportFilenamePtr filename,
272                              TimespanListPtr timespans, ExportChannelConfigPtr channel_config,
273                              ExportFormatSpecPtr format);
274
275         /* Element state lists should never be empty, this is used to check them */
276         template<typename T>
277         std::list<T> const &
278         check_list (std::list<T> const & list)
279         {
280                 if (list.empty()) {
281                         throw std::runtime_error ("Programming error: Uninitialized list in ExportProfileManager");
282                 }
283                 return list;
284         }
285
286 };
287
288
289 } // namespace ARDOUR
290
291 #endif /* __ardour_export_profile_manager_h__ */