diff options
author | Robin Gareus <robin@gareus.org> | 2016-02-10 03:01:05 +0100 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2016-02-10 03:01:05 +0100 |
commit | c1642fead82c58e7ca546b375aaf95459a803d96 (patch) | |
tree | 0e7fe62415b6183bc887990e6815f3cd8772f955 /libs/ardour | |
parent | 883a6a3d4e0481d1145e62c995ed937e69245a94 (diff) |
Post-export Analysis
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/export_analysis.h | 60 | ||||
-rw-r--r-- | libs/ardour/ardour/export_graph_builder.h | 12 | ||||
-rw-r--r-- | libs/ardour/ardour/export_status.h | 3 | ||||
-rw-r--r-- | libs/ardour/export_graph_builder.cc | 28 | ||||
-rw-r--r-- | libs/ardour/export_handler.cc | 15 | ||||
-rw-r--r-- | libs/ardour/export_status.cc | 1 |
6 files changed, 105 insertions, 14 deletions
diff --git a/libs/ardour/ardour/export_analysis.h b/libs/ardour/ardour/export_analysis.h new file mode 100644 index 0000000000..bab79bba4e --- /dev/null +++ b/libs/ardour/ardour/export_analysis.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2016 Robin Gareus <robin@gareus.org> + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ardour_export_analysis_h__ +#define __ardour_export_analysis_h__ + +#include <map> +#include <cstring> +#include <boost/shared_ptr.hpp> + +#include "ardour/types.h" + +namespace ARDOUR { + struct ExportAnalysis { + public: + ExportAnalysis () + : loudness (0) + , loudness_range (0) + , have_loudness (false) + { + memset (_peaks, 0, sizeof(_peaks)); + memset (_spectrum, 0, sizeof(_spectrum)); + } + + ExportAnalysis (const ExportAnalysis& other) + : loudness (other.loudness) + , loudness_range (other.loudness_range) + , have_loudness (other.have_loudness) + { + memcpy (_peaks, other._peaks, sizeof(_peaks)); + memcpy (_spectrum, other._spectrum, sizeof(_spectrum)); + } + + float loudness; + float loudness_range; + bool have_loudness; + PeakData _peaks[800]; + float _spectrum[800][256]; + }; + + typedef boost::shared_ptr<ExportAnalysis> ExportAnalysisPtr; + typedef std::map<std::string, ExportAnalysisPtr> AnalysisResults; + +} // namespace ARDOUR +#endif diff --git a/libs/ardour/ardour/export_graph_builder.h b/libs/ardour/ardour/export_graph_builder.h index 3e9fb58a15..d14a00997a 100644 --- a/libs/ardour/ardour/export_graph_builder.h +++ b/libs/ardour/ardour/export_graph_builder.h @@ -22,6 +22,7 @@ #define __ardour_export_graph_builder_h__ #include "ardour/export_handler.h" +#include "ardour/export_analysis.h" #include "audiographer/utils/identity_vertex.h" @@ -32,6 +33,7 @@ namespace AudioGrapher { class SampleRateConverter; class PeakReader; class Normalizer; + class Analyser; template <typename T> class Chunker; template <typename T> class SampleFormatConverter; template <typename T> class Interleaver; @@ -55,7 +57,9 @@ class LIBARDOUR_API ExportGraphBuilder typedef boost::shared_ptr<AudioGrapher::Sink<Sample> > FloatSinkPtr; typedef boost::shared_ptr<AudioGrapher::IdentityVertex<Sample> > IdentityVertexPtr; + typedef boost::shared_ptr<AudioGrapher::Analyser> AnalysisPtr; typedef std::map<ExportChannelPtr, IdentityVertexPtr> ChannelMap; + typedef std::map<std::string, AnalysisPtr> AnalysisMap; public: @@ -71,9 +75,14 @@ class LIBARDOUR_API ExportGraphBuilder void cleanup (bool remove_out_files = false); void set_current_timespan (boost::shared_ptr<ExportTimespan> span); void add_config (FileSpec const & config); + 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 { @@ -125,6 +134,7 @@ class LIBARDOUR_API ExportGraphBuilder boost::ptr_list<Encoder> children; int data_width; + AnalysisPtr analyser; // Only one of these should be available at a time FloatConverterPtr float_converter; IntConverterPtr int_converter; @@ -245,6 +255,8 @@ class LIBARDOUR_API ExportGraphBuilder std::list<Normalizer *> normalizers; + AnalysisMap analysis_map; + Glib::ThreadPool thread_pool; }; diff --git a/libs/ardour/ardour/export_status.h b/libs/ardour/ardour/export_status.h index 95921629c7..f250ae0dc6 100644 --- a/libs/ardour/ardour/export_status.h +++ b/libs/ardour/ardour/export_status.h @@ -24,6 +24,7 @@ #include <stdint.h> #include "ardour/libardour_visibility.h" +#include "ardour/export_analysis.h" #include "ardour/types.h" #include "pbd/signals.h" @@ -79,6 +80,8 @@ class LIBARDOUR_API ExportStatus { volatile uint32_t total_normalize_cycles; volatile uint32_t current_normalize_cycle; + AnalysisResults result_map; + private: volatile bool _aborted; volatile bool _errors; diff --git a/libs/ardour/export_graph_builder.cc b/libs/ardour/export_graph_builder.cc index c054d85242..685db817d4 100644 --- a/libs/ardour/export_graph_builder.cc +++ b/libs/ardour/export_graph_builder.cc @@ -28,6 +28,7 @@ #include "audiographer/general/chunker.h" #include "audiographer/general/interleaver.h" #include "audiographer/general/normalizer.h" +#include "audiographer/general/analyser.h" #include "audiographer/general/peak_reader.h" #include "audiographer/general/sample_format_converter.h" #include "audiographer/general/sr_converter.h" @@ -110,6 +111,7 @@ ExportGraphBuilder::reset () channel_configs.clear (); channels.clear (); normalizers.clear (); + analysis_map.clear(); } void @@ -174,6 +176,16 @@ ExportGraphBuilder::add_config (FileSpec const & config) } void +ExportGraphBuilder::get_analysis_results (AnalysisResults& results) { + for (AnalysisMap::iterator i = analysis_map.begin(); i != analysis_map.end(); ++i) { + ExportAnalysisPtr p = i->second->result (); + if (p) { + results.insert (std::make_pair (i->first, p)); + } + } +} + +void ExportGraphBuilder::add_split_config (FileSpec const & config) { for (ChannelConfigList::iterator it = channel_configs.begin(); it != channel_configs.end(); ++it) { @@ -287,39 +299,39 @@ ExportGraphBuilder::Encoder::copy_files (std::string orig_path) /* SFC */ -ExportGraphBuilder::SFC::SFC (ExportGraphBuilder &, FileSpec const & new_config, framecnt_t max_frames) +ExportGraphBuilder::SFC::SFC (ExportGraphBuilder &parent, FileSpec const & new_config, framecnt_t max_frames) : data_width(0) { config = new_config; data_width = sndfile_data_width (Encoder::get_real_format (config)); unsigned channels = new_config.channel_config->get_n_chans(); + analyser.reset (new Analyser (config.format->sample_rate(), channels, max_frames, + (framecnt_t) ceil (parent.timespan->get_length () * config.format->sample_rate () / (double) parent.session.nominal_frame_rate ()))); + parent.add_analyser (config.filename->get_path (config.format), analyser); if (data_width == 8 || data_width == 16) { short_converter = ShortConverterPtr (new SampleFormatConverter<short> (channels)); short_converter->init (max_frames, config.format->dither_type(), data_width); add_child (config); + analyser->add_output (short_converter); } else if (data_width == 24 || data_width == 32) { int_converter = IntConverterPtr (new SampleFormatConverter<int> (channels)); int_converter->init (max_frames, config.format->dither_type(), data_width); add_child (config); + analyser->add_output (int_converter); } else { int actual_data_width = 8 * sizeof(Sample); float_converter = FloatConverterPtr (new SampleFormatConverter<Sample> (channels)); float_converter->init (max_frames, config.format->dither_type(), actual_data_width); add_child (config); + analyser->add_output (float_converter); } } ExportGraphBuilder::FloatSinkPtr ExportGraphBuilder::SFC::sink () { - if (data_width == 8 || data_width == 16) { - return short_converter; - } else if (data_width == 24 || data_width == 32) { - return int_converter; - } else { - return float_converter; - } + return analyser; } void diff --git a/libs/ardour/export_handler.cc b/libs/ardour/export_handler.cc index 70c807b7de..6b59afec89 100644 --- a/libs/ardour/export_handler.cc +++ b/libs/ardour/export_handler.cc @@ -295,11 +295,12 @@ ExportHandler::command_output(std::string output, size_t size) void ExportHandler::finish_timespan () { + graph_builder->get_analysis_results (export_status->result_map); + while (config_map.begin() != timespan_bounds.second) { ExportFormatSpecPtr fmt = config_map.begin()->second.format; std::string filename = config_map.begin()->second.filename->get_path(fmt); - if (fmt->with_cue()) { export_cd_marker_file (current_timespan, fmt, filename, CDMarkerCUE); } @@ -312,15 +313,17 @@ ExportHandler::finish_timespan () export_cd_marker_file (current_timespan, fmt, filename, MP4Chaps); } + /* close file first, otherwise TagLib enounters an ERROR_SHARING_VIOLATION + * The process cannot access the file because it is being used. + * ditto for post-export and upload. + */ + graph_builder->reset (); + if (fmt->tag()) { - /* close file first, otherwise TagLib enounters an ERROR_SHARING_VIOLATION - * The process cannot access the file because it is being used. - * - * TODO: check Umlauts and encoding in filename. + /* TODO: check Umlauts and encoding in filename. * TagLib eventually calls CreateFileA(), */ export_status->active_job = ExportStatus::Tagging; - graph_builder->reset (); AudiofileTagger::tag_file(filename, *SessionMetadata::Metadata()); } diff --git a/libs/ardour/export_status.cc b/libs/ardour/export_status.cc index 4b48a8edd7..170073974b 100644 --- a/libs/ardour/export_status.cc +++ b/libs/ardour/export_status.cc @@ -52,6 +52,7 @@ ExportStatus::init () total_normalize_cycles = 0; current_normalize_cycle = 0; + result_map.clear(); } void |