signed VCA numbers
[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 start_post_processing();
171
172                 ExportGraphBuilder & parent;
173
174                 FileSpec        config;
175                 framecnt_t      max_frames_out;
176                 bool            use_loudness;
177                 BufferPtr       buffer;
178                 PeakReaderPtr   peak_reader;
179                 TmpFilePtr      tmp_file;
180                 NormalizerPtr   normalizer;
181                 ThreaderPtr     threader;
182                 LoudnessReaderPtr    loudness_reader;
183                 boost::ptr_list<SFC> children;
184
185                 PBD::ScopedConnection post_processing_connection;
186         };
187
188         // sample rate converter
189         class SRC {
190             public:
191                 SRC (ExportGraphBuilder & parent, FileSpec const & new_config, framecnt_t max_frames);
192                 FloatSinkPtr sink ();
193                 void add_child (FileSpec const & new_config);
194                 void remove_children (bool remove_out_files);
195
196                 bool operator== (FileSpec const & other_config) const;
197
198                                                 private:
199                 typedef boost::shared_ptr<AudioGrapher::SampleRateConverter> SRConverterPtr;
200
201                 template<typename T>
202                 void add_child_to_list (FileSpec const & new_config, boost::ptr_list<T> & list);
203
204                 ExportGraphBuilder &  parent;
205                 FileSpec              config;
206                 boost::ptr_list<SFC>  children;
207                 boost::ptr_list<Normalizer> normalized_children;
208                 SRConverterPtr        converter;
209                 framecnt_t            max_frames_out;
210         };
211
212         // Silence trimmer + adder
213         class SilenceHandler {
214             public:
215                 SilenceHandler (ExportGraphBuilder & parent, FileSpec const & new_config, framecnt_t max_frames);
216                 FloatSinkPtr sink ();
217                 void add_child (FileSpec const & new_config);
218                 void remove_children (bool remove_out_files);
219                 bool operator== (FileSpec const & other_config) const;
220
221                                                 private:
222                 typedef boost::shared_ptr<AudioGrapher::SilenceTrimmer<Sample> > SilenceTrimmerPtr;
223
224                 ExportGraphBuilder & parent;
225                 FileSpec             config;
226                 boost::ptr_list<SRC> children;
227                 SilenceTrimmerPtr    silence_trimmer;
228                 framecnt_t           max_frames_in;
229         };
230
231         // channel configuration
232         class ChannelConfig {
233             public:
234                 ChannelConfig (ExportGraphBuilder & parent, FileSpec const & new_config, ChannelMap & channel_map);
235                 void add_child (FileSpec const & new_config);
236                 void remove_children (bool remove_out_files);
237                 bool operator== (FileSpec const & other_config) const;
238
239                                                 private:
240                 typedef boost::shared_ptr<AudioGrapher::Interleaver<Sample> > InterleaverPtr;
241                 typedef boost::shared_ptr<AudioGrapher::Chunker<Sample> > ChunkerPtr;
242
243                 ExportGraphBuilder &      parent;
244                 FileSpec                  config;
245                 boost::ptr_list<SilenceHandler> children;
246                 InterleaverPtr            interleaver;
247                 ChunkerPtr                chunker;
248                 framecnt_t                max_frames_out;
249         };
250
251         Session const & session;
252         boost::shared_ptr<ExportTimespan> timespan;
253
254         // Roots for export processor trees
255         typedef boost::ptr_list<ChannelConfig> ChannelConfigList;
256         ChannelConfigList channel_configs;
257
258         // The sources of all data, each channel is read only once
259         ChannelMap channels;
260
261         framecnt_t process_buffer_frames;
262
263         std::list<Normalizer *> normalizers;
264
265         AnalysisMap analysis_map;
266
267         Glib::ThreadPool thread_pool;
268 };
269
270 } // namespace ARDOUR
271
272 #endif /* __ardour_export_graph_builder_h__ */