Re-integrate export-optimization branch.
[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/ardour.h"
25 #include "ardour/export_handler.h"
26 #include "ardour/export_channel.h"
27 #include "ardour/export_format_base.h"
28
29 #include "audiographer/identity_vertex.h"
30
31 #include <glibmm/threadpool.h>
32
33 namespace AudioGrapher {
34         class SampleRateConverter;
35         class PeakReader;
36         class Normalizer;
37         template <typename T> class SampleFormatConverter;
38         template <typename T> class Interleaver;
39         template <typename T> class SndfileWriter;
40         template <typename T> class SilenceTrimmer;
41         template <typename T> class TmpFile;
42         template <typename T> class Threader;
43         template <typename T> class AllocatingProcessContext;
44 }
45
46 namespace ARDOUR
47 {
48
49 class ExportGraphBuilder
50 {
51   private:
52         typedef ExportHandler::FileSpec FileSpec;
53         typedef ExportElementFactory::FilenamePtr FilenamePtr;
54
55         typedef boost::shared_ptr<AudioGrapher::Sink<Sample> > FloatSinkPtr;
56         typedef boost::shared_ptr<AudioGrapher::IdentityVertex<Sample> > IdentityVertexPtr;
57         typedef std::map<ExportChannelPtr,  IdentityVertexPtr> ChannelMap;
58
59   public:
60         
61         ExportGraphBuilder (Session const & session);
62         ~ExportGraphBuilder ();
63         
64         int process (nframes_t frames, bool last_cycle);
65         
66         void reset ();
67         void add_config (FileSpec const & config);
68         
69   private:
70         
71         class Encoder : public sigc::trackable {
72           public:
73                 template <typename T> boost::shared_ptr<AudioGrapher::Sink<T> > init (FileSpec const & new_config);
74                 void add_child (FileSpec const & new_config);
75                 bool operator== (FileSpec const & other_config) const;
76         
77                 static int get_real_format (FileSpec const & config);
78         
79           private:
80                 typedef boost::shared_ptr<AudioGrapher::SndfileWriter<Sample> > FloatWriterPtr;
81                 typedef boost::shared_ptr<AudioGrapher::SndfileWriter<int> >    IntWriterPtr;
82                 typedef boost::shared_ptr<AudioGrapher::SndfileWriter<short> >  ShortWriterPtr;
83                   
84                 template<typename T> void init_writer (boost::shared_ptr<AudioGrapher::SndfileWriter<T> > & writer);
85                 void copy_files (std::string orig_path);
86                 
87                 FileSpec               config;
88                 std::list<FilenamePtr> filenames;
89                 
90                 // Only one of these should be available at a time
91                 FloatWriterPtr float_writer;
92                 IntWriterPtr   int_writer;
93                 ShortWriterPtr short_writer;
94         };
95         
96         // sample format converter
97         class SFC {
98           public:
99                 // This constructor so that this can be constructed like a Normalizer
100                 SFC (ExportGraphBuilder &) {}
101                 FloatSinkPtr init (FileSpec const & new_config, nframes_t max_frames);
102                 void add_child (FileSpec const & new_config);
103                 bool operator== (FileSpec const & other_config) const;
104                 
105           private:
106                 typedef boost::shared_ptr<AudioGrapher::SampleFormatConverter<Sample> > FloatConverterPtr;
107                 typedef boost::shared_ptr<AudioGrapher::SampleFormatConverter<int> >   IntConverterPtr;
108                 typedef boost::shared_ptr<AudioGrapher::SampleFormatConverter<short> > ShortConverterPtr;
109                 
110                 FileSpec           config;
111                 std::list<Encoder> children;
112                 int                data_width;
113                 
114                 // Only one of these should be available at a time
115                 FloatConverterPtr float_converter;
116                 IntConverterPtr   int_converter;
117                 ShortConverterPtr short_converter;
118         };
119         
120         class Normalizer : public sigc::trackable {
121           public:
122                 Normalizer (ExportGraphBuilder & parent) : parent (parent) {}
123                 FloatSinkPtr init (FileSpec const & new_config, nframes_t max_frames);
124                 void add_child (FileSpec const & new_config);
125                 bool operator== (FileSpec const & other_config) const;
126                 
127           private:
128                 typedef boost::shared_ptr<AudioGrapher::PeakReader> PeakReaderPtr;
129                 typedef boost::shared_ptr<AudioGrapher::Normalizer> NormalizerPtr;
130                 typedef boost::shared_ptr<AudioGrapher::TmpFile<Sample> > TmpFilePtr;
131                 typedef boost::shared_ptr<AudioGrapher::Threader<Sample> > ThreaderPtr;
132                 typedef boost::shared_ptr<AudioGrapher::AllocatingProcessContext<Sample> > BufferPtr;
133                 
134                 void start_post_processing();
135                 void do_post_processing();
136                 
137                 ExportGraphBuilder & parent;
138                 
139                 FileSpec        config;
140                 nframes_t       max_frames_out;
141                 
142                 BufferPtr       buffer;
143                 PeakReaderPtr   peak_reader;
144                 TmpFilePtr      tmp_file;
145                 NormalizerPtr   normalizer;
146                 ThreaderPtr     threader;
147                 std::list<SFC>  children;
148         };
149         
150         // sample rate converter
151         class SRC {
152           public:
153                 SRC (ExportGraphBuilder & parent) : parent (parent) {}
154                 FloatSinkPtr init (FileSpec const & new_config, nframes_t max_frames);
155                 void add_child (FileSpec const & new_config);
156                 bool operator== (FileSpec const & other_config) const;
157                 
158           private:
159                 typedef boost::shared_ptr<AudioGrapher::SampleRateConverter> SRConverterPtr;
160                 
161                 template<typename T>
162                 void add_child_to_list (FileSpec const & new_config, std::list<T> & list);
163   
164                 ExportGraphBuilder &  parent;
165                 FileSpec              config;
166                 std::list<SFC>        children;
167                 std::list<Normalizer> normalized_children;
168                 SRConverterPtr        converter;
169                 nframes_t             max_frames_out;
170         };
171         
172         // Silence trimmer + adder
173         class SilenceHandler {
174           public:
175                 SilenceHandler (ExportGraphBuilder & parent) : parent (parent) {}
176                 FloatSinkPtr init (FileSpec const & new_config, nframes_t max_frames);
177                 void add_child (FileSpec const & new_config);
178                 bool operator== (FileSpec const & other_config) const;
179                 
180           private:
181                 typedef boost::shared_ptr<AudioGrapher::SilenceTrimmer<Sample> > SilenceTrimmerPtr;
182                 
183                 ExportGraphBuilder & parent;
184                 FileSpec             config;
185                 std::list<SRC>       children;
186                 SilenceTrimmerPtr    silence_trimmer;
187                 nframes_t            max_frames_in;
188         };
189         
190         // channel configuration
191         class ChannelConfig {
192           public:
193                 ChannelConfig (ExportGraphBuilder & parent) : parent (parent) {}
194                 void init (FileSpec const & new_config, ChannelMap & channel_map);
195                 void add_child (FileSpec const & new_config);
196                 bool operator== (FileSpec const & other_config) const;
197                 
198           private:
199                 typedef boost::shared_ptr<AudioGrapher::Interleaver<Sample> > InterleaverPtr;
200                 
201                 ExportGraphBuilder &      parent;
202                 FileSpec                  config;
203                 std::list<SilenceHandler> children;
204                 InterleaverPtr            interleaver;
205                 nframes_t                 max_frames;
206         };
207
208         Session const & session;
209         
210         // Roots for export processor trees
211         typedef std::list<ChannelConfig> ChannelConfigList;
212         ChannelConfigList channel_configs;
213         
214         // The sources of all data, each channel is read only once
215         ChannelMap channels;
216         
217         Sample *  process_buffer;
218         nframes_t process_buffer_frames;
219         
220         Glib::ThreadPool thread_pool;
221 };
222
223 } // namespace ARDOUR
224
225 #endif /* __ardour_export_graph_builder_h__ */