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