/* Copyright (C) 2009 Paul Davis Author: Sakari Bergen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __ardour_export_graph_builder_h__ #define __ardour_export_graph_builder_h__ #include "ardour/export_handler.h" #include "ardour/export_analysis.h" #include "audiographer/utils/identity_vertex.h" #include #include namespace AudioGrapher { class SampleRateConverter; class PeakReader; class LoudnessReader; class Normalizer; class Analyser; template class Chunker; template class SampleFormatConverter; template class Interleaver; template class SndfileWriter; template class SilenceTrimmer; template class TmpFile; template class Threader; template class AllocatingProcessContext; } namespace ARDOUR { class ExportTimespan; class Session; class LIBARDOUR_API ExportGraphBuilder { private: typedef ExportHandler::FileSpec FileSpec; typedef boost::shared_ptr > FloatSinkPtr; typedef boost::shared_ptr > IdentityVertexPtr; typedef boost::shared_ptr AnalysisPtr; typedef std::map ChannelMap; typedef std::map AnalysisMap; public: ExportGraphBuilder (Session const & session); ~ExportGraphBuilder (); int process (samplecnt_t samples, bool last_cycle); bool post_process (); // returns true when finished bool need_postprocessing () const { return !intermediates.empty(); } bool realtime() const { return _realtime; } unsigned get_postprocessing_cycle_count() const; void reset (); void cleanup (bool remove_out_files = false); void set_current_timespan (boost::shared_ptr span); void add_config (FileSpec const & config, bool rt); void get_analysis_results (AnalysisResults& results); private: void add_analyser (const std::string& fn, AnalysisPtr ap) { analysis_map.insert (std::make_pair (fn, ap)); } void add_split_config (FileSpec const & config); class Encoder { public: template boost::shared_ptr > init (FileSpec const & new_config); void add_child (FileSpec const & new_config); void remove_children (); void destroy_writer (bool delete_out_file); bool operator== (FileSpec const & other_config) const; static int get_real_format (FileSpec const & config); private: typedef boost::shared_ptr > FloatWriterPtr; typedef boost::shared_ptr > IntWriterPtr; typedef boost::shared_ptr > ShortWriterPtr; template void init_writer (boost::shared_ptr > & writer); void copy_files (std::string orig_path); FileSpec config; std::list filenames; PBD::ScopedConnection copy_files_connection; std::string writer_filename; // Only one of these should be available at a time FloatWriterPtr float_writer; IntWriterPtr int_writer; ShortWriterPtr short_writer; }; // sample format converter class SFC { public: // This constructor so that this can be constructed like a Normalizer SFC (ExportGraphBuilder &, FileSpec const & new_config, samplecnt_t max_samples); FloatSinkPtr sink (); void add_child (FileSpec const & new_config); void remove_children (bool remove_out_files); bool operator== (FileSpec const & other_config) const; void set_peak (float); private: typedef boost::shared_ptr > ChunkerPtr; typedef boost::shared_ptr > FloatConverterPtr; typedef boost::shared_ptr > IntConverterPtr; typedef boost::shared_ptr > ShortConverterPtr; FileSpec config; boost::ptr_list children; int data_width; ChunkerPtr chunker; AnalysisPtr analyser; bool _analyse; // Only one of these should be available at a time FloatConverterPtr float_converter; IntConverterPtr int_converter; ShortConverterPtr short_converter; }; class Intermediate { public: Intermediate (ExportGraphBuilder & parent, FileSpec const & new_config, samplecnt_t max_samples); FloatSinkPtr sink (); void add_child (FileSpec const & new_config); void remove_children (bool remove_out_files); bool operator== (FileSpec const & other_config) const; unsigned get_postprocessing_cycle_count() const; /// Returns true when finished bool process (); private: typedef boost::shared_ptr PeakReaderPtr; typedef boost::shared_ptr LoudnessReaderPtr; typedef boost::shared_ptr NormalizerPtr; typedef boost::shared_ptr > TmpFilePtr; typedef boost::shared_ptr > ThreaderPtr; typedef boost::shared_ptr > BufferPtr; void prepare_post_processing (); void start_post_processing (); ExportGraphBuilder & parent; FileSpec config; samplecnt_t max_samples_out; bool use_loudness; bool use_peak; BufferPtr buffer; PeakReaderPtr peak_reader; TmpFilePtr tmp_file; NormalizerPtr normalizer; ThreaderPtr threader; LoudnessReaderPtr loudness_reader; boost::ptr_list children; PBD::ScopedConnectionList post_processing_connection; }; // sample rate converter class SRC { public: SRC (ExportGraphBuilder & parent, FileSpec const & new_config, samplecnt_t max_samples); FloatSinkPtr sink (); void add_child (FileSpec const & new_config); void remove_children (bool remove_out_files); bool operator== (FileSpec const & other_config) const; private: typedef boost::shared_ptr SRConverterPtr; template void add_child_to_list (FileSpec const & new_config, boost::ptr_list & list); ExportGraphBuilder & parent; FileSpec config; boost::ptr_list children; boost::ptr_list intermediate_children; SRConverterPtr converter; samplecnt_t max_samples_out; }; // Silence trimmer + adder class SilenceHandler { public: SilenceHandler (ExportGraphBuilder & parent, FileSpec const & new_config, samplecnt_t max_samples); FloatSinkPtr sink (); void add_child (FileSpec const & new_config); void remove_children (bool remove_out_files); bool operator== (FileSpec const & other_config) const; private: typedef boost::shared_ptr > SilenceTrimmerPtr; ExportGraphBuilder & parent; FileSpec config; boost::ptr_list children; SilenceTrimmerPtr silence_trimmer; samplecnt_t max_samples_in; }; // channel configuration class ChannelConfig { public: ChannelConfig (ExportGraphBuilder & parent, FileSpec const & new_config, ChannelMap & channel_map); void add_child (FileSpec const & new_config); void remove_children (bool remove_out_files); bool operator== (FileSpec const & other_config) const; private: typedef boost::shared_ptr > InterleaverPtr; typedef boost::shared_ptr > ChunkerPtr; ExportGraphBuilder & parent; FileSpec config; boost::ptr_list children; InterleaverPtr interleaver; ChunkerPtr chunker; samplecnt_t max_samples_out; }; Session const & session; boost::shared_ptr timespan; // Roots for export processor trees typedef boost::ptr_list ChannelConfigList; ChannelConfigList channel_configs; // The sources of all data, each channel is read only once ChannelMap channels; samplecnt_t process_buffer_samples; std::list intermediates; AnalysisMap analysis_map; bool _realtime; Glib::ThreadPool thread_pool; }; } // namespace ARDOUR #endif /* __ardour_export_graph_builder_h__ */