Handle mutiple export files with the same extension but different format.
[ardour.git] / libs / ardour / ardour / export_handler.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_handler_h__
22 #define __ardour_export_handler_h__
23
24 #include <map>
25 #include <fstream>
26
27 #include <boost/operators.hpp>
28 #include <boost/shared_ptr.hpp>
29
30 #include "ardour/export_pointers.h"
31 #include "ardour/session.h"
32 #include "ardour/types.h"
33
34 namespace AudioGrapher {
35         class BroadcastInfo;
36 }
37
38 namespace ARDOUR
39 {
40
41 class ExportTimespan;
42 class ExportChannelConfiguration;
43 class ExportFormatSpecification;
44 class ExportFilename;
45 class ExportGraphBuilder;
46 class Location;
47
48 class ExportElementFactory
49 {
50   public:
51
52         ExportElementFactory (Session & session);
53         ~ExportElementFactory ();
54
55         ExportTimespanPtr add_timespan ();
56
57         ExportChannelConfigPtr add_channel_config ();
58
59         ExportFormatSpecPtr    add_format ();
60         ExportFormatSpecPtr    add_format (XMLNode const & state);
61         ExportFormatSpecPtr    add_format_copy (ExportFormatSpecPtr other);
62
63         ExportFilenamePtr      add_filename ();
64         ExportFilenamePtr      add_filename_copy (ExportFilenamePtr other);
65
66   private:
67         Session & session;
68 };
69
70 class ExportHandler : public ExportElementFactory
71 {
72   public:
73         struct FileSpec {
74                 FileSpec() {}
75                 FileSpec (ExportChannelConfigPtr channel_config, ExportFormatSpecPtr format,
76                           ExportFilenamePtr filename, BroadcastInfoPtr broadcast_info)
77                   : channel_config (channel_config)
78                   , format (format)
79                   , filename (filename)
80                   , broadcast_info (broadcast_info)
81                         {}
82
83                 ExportChannelConfigPtr channel_config;
84                 ExportFormatSpecPtr    format;
85                 ExportFilenamePtr      filename;
86                 BroadcastInfoPtr       broadcast_info;
87         };
88
89   private:
90         /* Session::get_export_handler() should be used to obtain an export handler
91          * This ensures that it doesn't go out of scope before finalize_audio_export is called
92          */
93
94         friend boost::shared_ptr<ExportHandler> Session::get_export_handler();
95         ExportHandler (Session & session);
96
97   public:
98         ~ExportHandler ();
99
100         bool add_export_config (ExportTimespanPtr timespan, ExportChannelConfigPtr channel_config,
101                                 ExportFormatSpecPtr format, ExportFilenamePtr filename,
102                                 BroadcastInfoPtr broadcast_info);
103         void do_export ();
104
105         std::string get_cd_marker_filename(std::string filename, CDMarkerFormat format);
106
107   private:
108
109         void handle_duplicate_format_extensions();
110         int process (framecnt_t frames);
111
112         Session &          session;
113         boost::shared_ptr<ExportGraphBuilder> graph_builder;
114         ExportStatusPtr    export_status;
115
116         /* The timespan and corresponding file specifications that we are exporting;
117            there can be multiple FileSpecs for each ExportTimespan.
118         */
119         typedef std::multimap<ExportTimespanPtr, FileSpec> ConfigMap;
120         ConfigMap          config_map;
121
122         bool               normalizing;
123
124         /* Timespan management */
125
126         void start_timespan ();
127         int  process_timespan (framecnt_t frames);
128         int  process_normalize ();
129         void finish_timespan ();
130
131         typedef std::pair<ConfigMap::iterator, ConfigMap::iterator> TimespanBounds;
132         ExportTimespanPtr     current_timespan;
133         TimespanBounds        timespan_bounds;
134
135         PBD::ScopedConnection process_connection;
136         framepos_t             process_position;
137
138         /* CD Marker stuff */
139
140         struct CDMarkerStatus {
141                 CDMarkerStatus (std::string out_file, ExportTimespanPtr timespan,
142                                 ExportFormatSpecPtr format, std::string filename)
143                   : out (out_file.c_str()), timespan (timespan), format (format), filename (filename), marker(0)
144                   , track_number (1), track_position (0), track_duration (0), track_start_frame (0)
145                   , index_number (1), index_position (0)
146                   {}
147
148                 /* General info */
149                 std::ofstream  out;
150                 ExportTimespanPtr   timespan;
151                 ExportFormatSpecPtr format;
152                 std::string         filename;
153                 Location *          marker;
154
155                 /* Track info */
156                 uint32_t        track_number;
157                 framepos_t      track_position;
158                 framepos_t      track_duration;
159                 framepos_t      track_start_frame;
160
161                 /* Index info */
162                 uint32_t       index_number;
163                 framepos_t      index_position;
164         };
165
166
167         void export_cd_marker_file (ExportTimespanPtr timespan, ExportFormatSpecPtr file_format,
168                                     std::string filename, CDMarkerFormat format);
169
170         void write_cue_header (CDMarkerStatus & status);
171         void write_toc_header (CDMarkerStatus & status);
172
173         void write_track_info_cue (CDMarkerStatus & status);
174         void write_track_info_toc (CDMarkerStatus & status);
175
176         void write_index_info_cue (CDMarkerStatus & status);
177         void write_index_info_toc (CDMarkerStatus & status);
178
179         void frames_to_cd_frames_string (char* buf, framepos_t when);
180         std::string toc_escape_cdtext (const std::string&);
181         std::string toc_escape_filename (const std::string&);
182         std::string cue_escape_cdtext (const std::string& txt);
183
184         int cue_tracknum;
185         int cue_indexnum;
186 };
187
188 } // namespace ARDOUR
189
190 #endif /* __ardour_export_handler_h__ */