Ardour  9.0-pre0-582-g084a23a80d
export_graph_builder.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009-2012 Sakari Bergen <sakari.bergen@beatwaves.net>
3  * Copyright (C) 2010-2012 David Robillard <d@drobilla.net>
4  * Copyright (C) 2013-2017 Paul Davis <paul@linuxaudiosystems.com>
5  * Copyright (C) 2016-2019 Robin Gareus <robin@gareus.org>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21 
22 #pragma once
23 
24 #include "ardour/export_handler.h"
25 #include "ardour/export_analysis.h"
27 
29 
30 #include <boost/ptr_container/ptr_list.hpp>
31 #include <glibmm/threadpool.h>
32 
33 namespace AudioGrapher {
34  class SampleRateConverter;
35  class PeakReader;
36  class LoudnessReader;
37  class Normalizer;
38  class Limiter;
39  class Analyser;
40  class DemoNoiseAdder;
41  template <typename T> class Chunker;
42  template <typename T> class SampleFormatConverter;
43  template <typename T> class Interleaver;
44  template <typename T> class SndfileWriter;
45  template <typename T> class CmdPipeWriter;
46  template <typename T> class SilenceTrimmer;
47  template <typename T> class TmpFile;
48  template <typename T> class Threader;
49  template <typename T> class AllocatingProcessContext;
50 }
51 
52 namespace ARDOUR
53 {
54 
55 class ExportTimespan;
56 class MidiBuffer;
57 class Session;
58 
60 {
61  private:
63 
64  typedef std::shared_ptr<AudioGrapher::Sink<Sample> > FloatSinkPtr;
65  typedef std::shared_ptr<AudioGrapher::Analyser> AnalysisPtr;
66  typedef std::map<std::string, AnalysisPtr> AnalysisMap;
67 
68  struct AnyExport {
69  /* Audio export */
72  audio.add_output (output);
73  }
75  audio.process (c);
76  }
77  /* MIDI Export */
79  void process (MidiBuffer const& buf, sampleoffset_t off, samplecnt_t cnt, bool last_cycle) {
80  midi.process (buf, off, cnt, last_cycle);
81  }
82  };
83 
84  typedef std::shared_ptr<AnyExport> AnyExportPtr;
85  typedef std::map<ExportChannelPtr, AnyExportPtr> ChannelMap;
86 
87  public:
88 
91 
92  samplecnt_t process (samplecnt_t samples, bool last_cycle);
93  bool post_process (); // returns true when finished
94  bool need_postprocessing () const { return !intermediates.empty(); }
95  bool realtime() const { return _realtime; }
97 
98  void reset ();
99  void cleanup (bool remove_out_files = false);
100  void set_current_timespan (std::shared_ptr<ExportTimespan> span);
101  void add_config (FileSpec const & config, bool rt);
103 
104  std::vector<std::string> exported_files () const {
105  return _exported_files;
106  }
107 
108  private:
109 
110  void add_analyser (const std::string& fn, AnalysisPtr ap) {
111  analysis_map.insert (std::make_pair (fn, ap));
112  }
113 
114  void add_export_fn (std::string const& fn) {
115  _exported_files.push_back (fn);
116  }
117 
118  std::vector<std::string> _exported_files;
119 
120  void add_split_config (FileSpec const & config);
121 
122  class Encoder {
123  public:
125  template <typename T> std::shared_ptr<AudioGrapher::Sink<T> > init (FileSpec const & new_config);
126  void add_child (FileSpec const & new_config);
128  void destroy_writer (bool delete_out_file);
129  bool operator== (FileSpec const & other_config) const;
130 
131  static int get_real_format (FileSpec const & config);
132 
133  private:
134  typedef std::shared_ptr<AudioGrapher::SndfileWriter<Sample> > FloatWriterPtr;
135  typedef std::shared_ptr<AudioGrapher::SndfileWriter<int> > IntWriterPtr;
136  typedef std::shared_ptr<AudioGrapher::SndfileWriter<short> > ShortWriterPtr;
137 
138  typedef std::shared_ptr<AudioGrapher::CmdPipeWriter<Sample> > FloatPipePtr;
139 
140  template<typename T> void init_writer (std::shared_ptr<AudioGrapher::SndfileWriter<T> > & writer);
141  template<typename T> void init_writer (std::shared_ptr<AudioGrapher::CmdPipeWriter<T> > & writer);
142 
143  void copy_files (std::string orig_path);
144 
146  std::list<ExportFilenamePtr> filenames;
148 
149  std::string writer_filename;
150 
151  // Only one of these should be available at a time
156  };
157 
158  // sample format converter
159  class SFC {
160  public:
161  // This constructor so that this can be constructed like a Normalizer
162  SFC (ExportGraphBuilder &, FileSpec const & new_config, samplecnt_t max_samples);
164  void add_child (FileSpec const & new_config);
165  void remove_children (bool remove_out_files);
166  bool operator== (FileSpec const & other_config) const;
167 
169  void set_peak_dbfs (float, bool force = false);
171 
172  private:
173  typedef std::shared_ptr<AudioGrapher::Chunker<float> > ChunkerPtr;
174  typedef std::shared_ptr<AudioGrapher::DemoNoiseAdder> DemoNoisePtr;
175  typedef std::shared_ptr<AudioGrapher::Normalizer> NormalizerPtr;
176  typedef std::shared_ptr<AudioGrapher::Limiter> LimiterPtr;
177  typedef std::shared_ptr<AudioGrapher::SampleFormatConverter<Sample> > FloatConverterPtr;
178  typedef std::shared_ptr<AudioGrapher::SampleFormatConverter<int> > IntConverterPtr;
179  typedef std::shared_ptr<AudioGrapher::SampleFormatConverter<short> > ShortConverterPtr;
180 
183  std::list<Encoder> children;
184 
190  bool _analyse;
191  // Only one of these should be available at a time
195  };
196 
197  class Intermediate {
198  public:
199  Intermediate (ExportGraphBuilder & parent, FileSpec const & new_config, samplecnt_t max_samples);
201  void add_child (FileSpec const & new_config);
202  void remove_children (bool remove_out_files);
203  bool operator== (FileSpec const & other_config) const;
204 
206 
208  bool process ();
209 
210  private:
211  typedef std::shared_ptr<AudioGrapher::PeakReader> PeakReaderPtr;
212  typedef std::shared_ptr<AudioGrapher::LoudnessReader> LoudnessReaderPtr;
213  typedef std::shared_ptr<AudioGrapher::TmpFile<Sample> > TmpFilePtr;
214  typedef std::shared_ptr<AudioGrapher::Threader<Sample> > ThreaderPtr;
215  typedef std::shared_ptr<AudioGrapher::AllocatingProcessContext<Sample> > BufferPtr;
216 
219 
221 
225  bool use_peak;
230 
232  std::list<SFC> children;
233 
235  };
236 
237  // sample rate converter
238  class SRC {
239  public:
240  SRC (ExportGraphBuilder & parent, FileSpec const & new_config, samplecnt_t max_samples);
242  void add_child (FileSpec const & new_config);
243  void remove_children (bool remove_out_files);
244 
245  bool operator== (FileSpec const & other_config) const;
246 
247  private:
248  typedef std::shared_ptr<AudioGrapher::SampleRateConverter> SRConverterPtr;
249 
250  template<typename T>
251  void add_child_to_list (FileSpec const & new_config, boost::ptr_list<T> & list);
252 
255  boost::ptr_list<SFC> children;
256  boost::ptr_list<Intermediate> intermediate_children;
259  };
260 
261  // Silence trimmer + adder
263  public:
264  SilenceHandler (ExportGraphBuilder & parent, FileSpec const & new_config, samplecnt_t max_samples);
266  void add_child (FileSpec const & new_config);
267  void remove_children (bool remove_out_files);
268  bool operator== (FileSpec const & other_config) const;
269 
270  private:
271  typedef std::shared_ptr<AudioGrapher::SilenceTrimmer<Sample> > SilenceTrimmerPtr;
272 
275  boost::ptr_list<SRC> children;
278  };
279 
280  // channel configuration
282  public:
284  void add_child (FileSpec const & new_config);
285  void remove_children (bool remove_out_files);
286  bool operator== (FileSpec const & other_config) const;
287 
288  private:
289  typedef std::shared_ptr<AudioGrapher::Interleaver<Sample> > InterleaverPtr;
290  typedef std::shared_ptr<AudioGrapher::Chunker<Sample> > ChunkerPtr;
291 
294  boost::ptr_list<SilenceHandler> children;
298  };
299 
300  Session const & session;
301  std::shared_ptr<ExportTimespan> timespan;
302 
303  // Roots for export processor trees
304  typedef boost::ptr_list<ChannelConfig> ChannelConfigList;
306 
307  // The sources of all data, each channel is read only once
309 
311 
312  std::list<Intermediate *> intermediates;
313 
315 
316  bool _realtime;
318 
319  Glib::ThreadPool thread_pool;
320  Glib::Threads::Mutex engine_request_lock;
321 };
322 
323 } // namespace ARDOUR
324 
std::shared_ptr< AudioGrapher::Interleaver< Sample > > InterleaverPtr
void remove_children(bool remove_out_files)
ChannelConfig(ExportGraphBuilder &parent, FileSpec const &new_config, ChannelMap &channel_map)
boost::ptr_list< SilenceHandler > children
void add_child(FileSpec const &new_config)
std::shared_ptr< AudioGrapher::Chunker< Sample > > ChunkerPtr
void destroy_writer(bool delete_out_file)
std::list< ExportFilenamePtr > filenames
void copy_files(std::string orig_path)
static int get_real_format(FileSpec const &config)
std::shared_ptr< AudioGrapher::SndfileWriter< short > > ShortWriterPtr
std::shared_ptr< AudioGrapher::Sink< T > > init(FileSpec const &new_config)
void add_child(FileSpec const &new_config)
std::shared_ptr< AudioGrapher::CmdPipeWriter< Sample > > FloatPipePtr
void init_writer(std::shared_ptr< AudioGrapher::SndfileWriter< T > > &writer)
std::shared_ptr< AudioGrapher::SndfileWriter< int > > IntWriterPtr
void init_writer(std::shared_ptr< AudioGrapher::CmdPipeWriter< T > > &writer)
std::shared_ptr< AudioGrapher::SndfileWriter< Sample > > FloatWriterPtr
bool process()
Returns true when finished.
void add_child(FileSpec const &new_config)
std::shared_ptr< AudioGrapher::LoudnessReader > LoudnessReaderPtr
std::shared_ptr< AudioGrapher::Threader< Sample > > ThreaderPtr
std::shared_ptr< AudioGrapher::PeakReader > PeakReaderPtr
Intermediate(ExportGraphBuilder &parent, FileSpec const &new_config, samplecnt_t max_samples)
PBD::ScopedConnectionList post_processing_connection
std::shared_ptr< AudioGrapher::AllocatingProcessContext< Sample > > BufferPtr
std::shared_ptr< AudioGrapher::TmpFile< Sample > > TmpFilePtr
void remove_children(bool remove_out_files)
std::shared_ptr< AudioGrapher::DemoNoiseAdder > DemoNoisePtr
std::shared_ptr< AudioGrapher::Chunker< float > > ChunkerPtr
std::shared_ptr< AudioGrapher::Limiter > LimiterPtr
void set_peak_dbfs(float, bool force=false)
void add_child(FileSpec const &new_config)
std::shared_ptr< AudioGrapher::SampleFormatConverter< Sample > > FloatConverterPtr
void set_peak_lufs(AudioGrapher::LoudnessReader const &)
SFC(ExportGraphBuilder &, FileSpec const &new_config, samplecnt_t max_samples)
std::shared_ptr< AudioGrapher::SampleFormatConverter< short > > ShortConverterPtr
void set_duration(samplecnt_t)
void remove_children(bool remove_out_files)
std::shared_ptr< AudioGrapher::Normalizer > NormalizerPtr
std::shared_ptr< AudioGrapher::SampleFormatConverter< int > > IntConverterPtr
void add_child_to_list(FileSpec const &new_config, boost::ptr_list< T > &list)
SRC(ExportGraphBuilder &parent, FileSpec const &new_config, samplecnt_t max_samples)
void add_child(FileSpec const &new_config)
std::shared_ptr< AudioGrapher::SampleRateConverter > SRConverterPtr
void remove_children(bool remove_out_files)
boost::ptr_list< Intermediate > intermediate_children
std::shared_ptr< AudioGrapher::SilenceTrimmer< Sample > > SilenceTrimmerPtr
SilenceHandler(ExportGraphBuilder &parent, FileSpec const &new_config, samplecnt_t max_samples)
void add_child(FileSpec const &new_config)
void remove_children(bool remove_out_files)
void add_export_fn(std::string const &fn)
void add_config(FileSpec const &config, bool rt)
std::vector< std::string > _exported_files
boost::ptr_list< ChannelConfig > ChannelConfigList
std::shared_ptr< AudioGrapher::Sink< Sample > > FloatSinkPtr
std::map< ExportChannelPtr, AnyExportPtr > ChannelMap
void add_analyser(const std::string &fn, AnalysisPtr ap)
unsigned get_postprocessing_cycle_count() const
std::map< std::string, AnalysisPtr > AnalysisMap
Glib::Threads::Mutex engine_request_lock
void get_analysis_results(AnalysisResults &results)
ExportGraphBuilder(Session const &session)
void cleanup(bool remove_out_files=false)
samplecnt_t process(samplecnt_t samples, bool last_cycle)
std::shared_ptr< ExportTimespan > timespan
void set_current_timespan(std::shared_ptr< ExportTimespan > span)
void add_split_config(FileSpec const &config)
std::shared_ptr< AnyExport > AnyExportPtr
ExportHandler::FileSpec FileSpec
std::list< Intermediate * > intermediates
std::shared_ptr< AudioGrapher::Analyser > AnalysisPtr
std::vector< std::string > exported_files() const
void process(MidiBuffer const &, sampleoffset_t, samplecnt_t, bool)
void process(ProcessContext< T > const &c)
void add_output(typename Source< T >::SinkPtr output)
Definition: listed_source.h:19
std::shared_ptr< Sink< T > > SinkPtr
#define LIBARDOUR_API
void session(lua_State *L)
PBD::PropertyDescriptor< bool > channel_map
std::map< std::string, ExportAnalysisPtr > AnalysisResults
Temporal::samplecnt_t samplecnt_t
Temporal::sampleoffset_t sampleoffset_t
bool operator==(const ProcessorSelection &a, const ProcessorSelection &b)
void add_output(AudioGrapher::Source< Sample >::SinkPtr output)
void process(AudioGrapher::ProcessContext< Sample > const &c)
AudioGrapher::IdentityVertex< Sample > audio
void process(MidiBuffer const &buf, sampleoffset_t off, samplecnt_t cnt, bool last_cycle)