Refactor TmpFile into an abstract base class
[ardour.git] / libs / ardour / ardour / export_graph_builder.h
1 /*
2     Copyright (C) 2009 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_graph_builder_h__
22 #define __ardour_export_graph_builder_h__
23
24 #include "ardour/export_handler.h"
25 #include "ardour/export_analysis.h"
26
27 #include "audiographer/utils/identity_vertex.h"
28
29 #include <boost/ptr_container/ptr_list.hpp>
30 #include <glibmm/threadpool.h>
31
32 namespace AudioGrapher {
33         class SampleRateConverter;
34         class PeakReader;
35         class LoudnessReader;
36         class Normalizer;
37         class Analyser;
38         template <typename T> class Chunker;
39         template <typename T> class SampleFormatConverter;
40         template <typename T> class Interleaver;
41         template <typename T> class SndfileWriter;
42         template <typename T> class SilenceTrimmer;
43         template <typename T> class TmpFile;
44         template <typename T> class Threader;
45         template <typename T> class AllocatingProcessContext;
46 }
47
48 namespace ARDOUR
49 {
50
51 class ExportTimespan;
52 class Session;
53
54 class LIBARDOUR_API ExportGraphBuilder
55 {
56   private:
57         typedef ExportHandler::FileSpec FileSpec;
58
59         typedef boost::shared_ptr<AudioGrapher::Sink<Sample> > FloatSinkPtr;
60         typedef boost::shared_ptr<AudioGrapher::IdentityVertex<Sample> > IdentityVertexPtr;
61         typedef boost::shared_ptr<AudioGrapher::Analyser> AnalysisPtr;
62         typedef std::map<ExportChannelPtr,  IdentityVertexPtr> ChannelMap;
63         typedef std::map<std::string, AnalysisPtr> AnalysisMap;
64
65   public:
66
67         ExportGraphBuilder (Session const & session);
68         ~ExportGraphBuilder ();
69
70         int process (framecnt_t frames, bool last_cycle);
71         bool process_normalize (); // returns true when finished
72         bool will_normalize() { return !normalizers.empty(); }
73         unsigned get_normalize_cycle_count() const;
74
75         void reset ();
76         void cleanup (bool remove_out_files = false);
77         void set_current_timespan (boost::shared_ptr<ExportTimespan> span);
78         void add_config (FileSpec const & config);
79         void get_analysis_results (AnalysisResults& results);
80
81   private:
82
83         void add_analyser (const std::string& fn, AnalysisPtr ap) {
84                 analysis_map.insert (std::make_pair (fn, ap));
85         }
86
87         void add_split_config (FileSpec const & config);
88
89         class Encoder {
90             public:
91                 template <typename T> boost::shared_ptr<AudioGrapher::Sink<T> > init (FileSpec const & new_config);
92                 void add_child (FileSpec const & new_config);
93                 void remove_children ();
94                 void destroy_writer (bool delete_out_file);
95                 bool operator== (FileSpec const & other_config) const;
96
97                 static int get_real_format (FileSpec const & config);
98
99                                                 private:
100                 typedef boost::shared_ptr<AudioGrapher::SndfileWriter<Sample> > FloatWriterPtr;
101                 typedef boost::shared_ptr<AudioGrapher::SndfileWriter<int> >    IntWriterPtr;
102                 typedef boost::shared_ptr<AudioGrapher::SndfileWriter<short> >  ShortWriterPtr;
103
104                 template<typename T> void init_writer (boost::shared_ptr<AudioGrapher::SndfileWriter<T> > & writer);
105                 void copy_files (std::string orig_path);
106
107                 FileSpec               config;
108                 std::list<ExportFilenamePtr> filenames;
109                 PBD::ScopedConnection  copy_files_connection;
110
111                 std::string writer_filename;
112
113                 // Only one of these should be available at a time
114                 FloatWriterPtr float_writer;
115                 IntWriterPtr   int_writer;
116                 ShortWriterPtr short_writer;
117         };
118
119         // sample format converter
120         class SFC {
121             public:
122                 // This constructor so that this can be constructed like a Normalizer
123                 SFC (ExportGraphBuilder &, FileSpec const & new_config, framecnt_t max_frames);
124                 FloatSinkPtr sink ();
125                 void add_child (FileSpec const & new_config);
126                 void remove_children (bool remove_out_files);
127                 bool operator== (FileSpec const & other_config) const;
128                 void set_peak (float);
129
130                                                 private:
131                 typedef boost::shared_ptr<AudioGrapher::Chunker<float> > ChunkerPtr;
132                 typedef boost::shared_ptr<AudioGrapher::SampleFormatConverter<Sample> > FloatConverterPtr;
133                 typedef boost::shared_ptr<AudioGrapher::SampleFormatConverter<int> >   IntConverterPtr;
134                 typedef boost::shared_ptr<AudioGrapher::SampleFormatConverter<short> > ShortConverterPtr;
135
136                 FileSpec           config;
137                 boost::ptr_list<Encoder> children;
138                 int                data_width;
139
140                 ChunkerPtr      chunker;
141                 AnalysisPtr     analyser;
142                 bool            _analyse;
143                 // Only one of these should be available at a time
144                 FloatConverterPtr float_converter;
145                 IntConverterPtr int_converter;
146                 ShortConverterPtr short_converter;
147         };
148
149         class Normalizer {
150                                                 public:
151                 Normalizer (ExportGraphBuilder & parent, FileSpec const & new_config, framecnt_t max_frames);
152                 FloatSinkPtr sink ();
153                 void add_child (FileSpec const & new_config);
154                 void remove_children (bool remove_out_files);
155                 bool operator== (FileSpec const & other_config) const;
156
157                 unsigned get_normalize_cycle_count() const;
158
159                 /// Returns true when finished
160                 bool process ();
161
162                                                 private:
163                 typedef boost::shared_ptr<AudioGrapher::PeakReader> PeakReaderPtr;
164                 typedef boost::shared_ptr<AudioGrapher::LoudnessReader> LoudnessReaderPtr;
165                 typedef boost::shared_ptr<AudioGrapher::Normalizer> NormalizerPtr;
166                 typedef boost::shared_ptr<AudioGrapher::TmpFile<Sample> > TmpFilePtr;
167                 typedef boost::shared_ptr<AudioGrapher::Threader<Sample> > ThreaderPtr;
168                 typedef boost::shared_ptr<AudioGrapher::AllocatingProcessContext<Sample> > BufferPtr;
169
170                 void prepare_post_processing ();
171                 void start_post_processing ();
172
173                 ExportGraphBuilder & parent;
174
175                 FileSpec        config;
176                 framecnt_t      max_frames_out;
177                 bool            use_loudness;
178                 BufferPtr       buffer;
179                 PeakReaderPtr   peak_reader;
180                 TmpFilePtr      tmp_file;
181                 NormalizerPtr   normalizer;
182                 ThreaderPtr     threader;
183                 LoudnessReaderPtr    loudness_reader;
184                 boost::ptr_list<SFC> children;
185
186                 PBD::ScopedConnectionList post_processing_connection;
187         };
188
189         // sample rate converter
190         class SRC {
191             public:
192                 SRC (ExportGraphBuilder & parent, FileSpec const & new_config, framecnt_t max_frames);
193                 FloatSinkPtr sink ();
194                 void add_child (FileSpec const & new_config);
195                 void remove_children (bool remove_out_files);
196
197                 bool operator== (FileSpec const & other_config) const;
198
199                                                 private:
200                 typedef boost::shared_ptr<AudioGrapher::SampleRateConverter> SRConverterPtr;
201
202                 template<typename T>
203                 void add_child_to_list (FileSpec const & new_config, boost::ptr_list<T> & list);
204
205                 ExportGraphBuilder &  parent;
206                 FileSpec              config;
207                 boost::ptr_list<SFC>  children;
208                 boost::ptr_list<Normalizer> normalized_children;
209                 SRConverterPtr        converter;
210                 framecnt_t            max_frames_out;
211         };
212
213         // Silence trimmer + adder
214         class SilenceHandler {
215             public:
216                 SilenceHandler (ExportGraphBuilder & parent, FileSpec const & new_config, framecnt_t max_frames);
217                 FloatSinkPtr sink ();
218                 void add_child (FileSpec const & new_config);
219                 void remove_children (bool remove_out_files);
220                 bool operator== (FileSpec const & other_config) const;
221
222                                                 private:
223                 typedef boost::shared_ptr<AudioGrapher::SilenceTrimmer<Sample> > SilenceTrimmerPtr;
224
225                 ExportGraphBuilder & parent;
226                 FileSpec             config;
227                 boost::ptr_list<SRC> children;
228                 SilenceTrimmerPtr    silence_trimmer;
229                 framecnt_t           max_frames_in;
230         };
231
232         // channel configuration
233         class ChannelConfig {
234             public:
235                 ChannelConfig (ExportGraphBuilder & parent, FileSpec const & new_config, ChannelMap & channel_map);
236                 void add_child (FileSpec const & new_config);
237                 void remove_children (bool remove_out_files);
238                 bool operator== (FileSpec const & other_config) const;
239
240                                                 private:
241                 typedef boost::shared_ptr<AudioGrapher::Interleaver<Sample> > InterleaverPtr;
242                 typedef boost::shared_ptr<AudioGrapher::Chunker<Sample> > ChunkerPtr;
243
244                 ExportGraphBuilder &      parent;
245                 FileSpec                  config;
246                 boost::ptr_list<SilenceHandler> children;
247                 InterleaverPtr            interleaver;
248                 ChunkerPtr                chunker;
249                 framecnt_t                max_frames_out;
250         };
251
252         Session const & session;
253         boost::shared_ptr<ExportTimespan> timespan;
254
255         // Roots for export processor trees
256         typedef boost::ptr_list<ChannelConfig> ChannelConfigList;
257         ChannelConfigList channel_configs;
258
259         // The sources of all data, each channel is read only once
260         ChannelMap channels;
261
262         framecnt_t process_buffer_frames;
263
264         std::list<Normalizer *> normalizers;
265
266         AnalysisMap analysis_map;
267
268         Glib::ThreadPool thread_pool;
269 };
270
271 } // namespace ARDOUR
272
273 #endif /* __ardour_export_graph_builder_h__ */