Show proper progress information for export while normalizing
authorSakari Bergen <sakari.bergen@beatwaves.net>
Tue, 24 Jan 2012 20:21:54 +0000 (20:21 +0000)
committerSakari Bergen <sakari.bergen@beatwaves.net>
Tue, 24 Jan 2012 20:21:54 +0000 (20:21 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@11337 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ardour/export_graph_builder.h
libs/ardour/ardour/export_status.h
libs/ardour/export_graph_builder.cc
libs/ardour/export_handler.cc
libs/audiographer/audiographer/sndfile/sndfile_writer.h

index b4ef0a1d94a6f95d5bb16169485fcfd030b9ba90..18aa8db5198c56db566178c2fb053a065c90f219 100644 (file)
@@ -64,6 +64,7 @@ class ExportGraphBuilder
        int process (framecnt_t frames, bool last_cycle);
        bool process_normalize (); // returns true when finished
        bool will_normalize() { return !normalizers.empty(); }
+       unsigned get_normalize_cycle_count() const;
 
        void reset ();
        void set_current_timespan (boost::shared_ptr<ExportTimespan> span);
@@ -130,6 +131,8 @@ class ExportGraphBuilder
                void add_child (FileSpec const & new_config);
                bool operator== (FileSpec const & other_config) const;
 
+               unsigned get_normalize_cycle_count() const;
+
                /// Returns true when finished
                bool process ();
 
index a42327c8aae0d421ceccabcbb0890d53de863648..5a50777f946e088bef948af23934729c5459340b 100644 (file)
@@ -61,6 +61,9 @@ struct ExportStatus {
        volatile framecnt_t     total_frames;
        volatile framecnt_t     processed_frames;
 
+       volatile uint32_t       total_normalize_cycles;
+       volatile uint32_t       current_normalize_cycle;
+
   private:
        volatile bool          _aborted;
        volatile bool          _errors;
index f01b5e090474726df860ae75f6a488044b210a10..9b35e16530dac5c784b152165db8a5f943af067c 100644 (file)
@@ -68,6 +68,16 @@ ExportGraphBuilder::process_normalize ()
        return normalizers.empty();
 }
 
+unsigned
+ExportGraphBuilder::get_normalize_cycle_count() const
+{
+       unsigned max = 0;
+       for (std::list<Normalizer *>::const_iterator it = normalizers.begin(); it != normalizers.end(); ++it) {
+               max = std::max(max, (*it)->get_normalize_cycle_count());
+       }
+       return max;
+}
+
 void
 ExportGraphBuilder::reset ()
 {
@@ -296,7 +306,8 @@ ExportGraphBuilder::Normalizer::Normalizer (ExportGraphBuilder & parent, FileSpe
        int format = ExportFormatBase::F_RAW | ExportFormatBase::SF_Float;
        tmp_file.reset (new TmpFile<float> (format, config.channel_config->get_n_chans(),
                                            config.format->sample_rate()));
-       tmp_file->FileWritten.connect_same_thread (post_processing_connection, boost::bind (&Normalizer::start_post_processing, this));
+       tmp_file->FileWritten.connect_same_thread (post_processing_connection,
+                                                  boost::bind (&Normalizer::start_post_processing, this));
 
        add_child (new_config);
 
@@ -330,6 +341,13 @@ ExportGraphBuilder::Normalizer::operator== (FileSpec const & other_config) const
               config.format->normalize_target() == other_config.format->normalize_target();
 }
 
+unsigned
+ExportGraphBuilder::Normalizer::get_normalize_cycle_count() const
+{
+       return static_cast<unsigned>(std::ceil(static_cast<float>(tmp_file->get_frames_written()) /
+                                              max_frames_out));
+}
+
 bool
 ExportGraphBuilder::Normalizer::process()
 {
index 305df0d28ac9d05b556e03a9f799473841cac2d2..42d5c8901c149825eb64408fd6b004a367fbd6dc 100644 (file)
@@ -138,8 +138,10 @@ ExportHandler::do_export (bool rt)
        export_status->init();
        std::set<ExportTimespanPtr> timespan_set;
        for (ConfigMap::iterator it = config_map.begin(); it != config_map.end(); ++it) {
-               timespan_set.insert (it->first);
-               export_status->total_frames += it->first->get_length();
+               bool new_timespan = timespan_set.insert (it->first).second;
+               if (new_timespan) {
+                       export_status->total_frames += it->first->get_length();
+               }
        }
        export_status->total_timespans = timespan_set.size();
 
@@ -207,18 +209,31 @@ ExportHandler::process_timespan (framecnt_t frames)
        if (last_cycle) {
                frames_to_read = end - process_position;
                export_status->stop = true;
-               normalizing = true;
        } else {
                frames_to_read = frames;
        }
 
        process_position += frames_to_read;
        export_status->processed_frames += frames_to_read;
-       export_status->progress = (float) export_status->processed_frames / export_status->total_frames;
+       export_status->progress = (float) export_status->processed_frames /
+                                         export_status->total_frames;
 
        /* Do actual processing */
+       int ret = graph_builder->process (frames_to_read, last_cycle);
 
-       return graph_builder->process (frames_to_read, last_cycle);
+       /* Start normalizing if necessary */
+       if (last_cycle) {
+               normalizing = graph_builder->will_normalize();
+               if (normalizing) {
+                       export_status->total_normalize_cycles = graph_builder->get_normalize_cycle_count();
+                       export_status->current_normalize_cycle = 0;
+               } else {
+                       finish_timespan ();
+                       return 0;
+               }
+       }
+
+       return ret;
 }
 
 int
@@ -231,6 +246,10 @@ ExportHandler::process_normalize ()
                export_status->normalizing = true;
        }
 
+       export_status->progress = (float) export_status->current_normalize_cycle /
+                                         export_status->total_normalize_cycles;
+       export_status->current_normalize_cycle++;
+
        return 0;
 }
 
index 6e8ecc2567df3f01201ee8e2c4835cbc0b86f4a7..984ec01d4126bfa180b83bfc3e4779241d2e7d81 100644 (file)
@@ -31,7 +31,7 @@ class SndfileWriter
          : SndfileHandle (path, Write, format, channels, samplerate)
          , path (path)
        {
-               add_supported_flag (ProcessContext<T>::EndOfInput);
+               init();
 
                if (broadcast_info) {
                        broadcast_info->write_to_file (this);
@@ -40,8 +40,16 @@ class SndfileWriter
        
        virtual ~SndfileWriter () {}
        
-       SndfileWriter (SndfileWriter const & other) : SndfileHandle (other) {}
+       SndfileWriter (SndfileWriter const & other)
+               : SndfileHandle (other)
+       {
+               init();
+       }
+
        using SndfileHandle::operator=;
+
+       framecnt_t get_frames_written() const { return frames_written; }
+       void       reset_frames_written_count() { frames_written = 0; }
        
        /// Writes data to file
        void process (ProcessContext<T> const & c)
@@ -55,6 +63,8 @@ class SndfileWriter
                }
                
                framecnt_t const written = write (c.data(), c.frames());
+               frames_written += written;
+
                if (throw_level (ThrowProcess) && written != c.frames()) {
                        throw Exception (*this, boost::str (boost::format
                                ("Could not write data to output file (%1%)")
@@ -75,11 +85,18 @@ class SndfileWriter
        /// SndfileHandle has to be constructed directly by deriving classes
        SndfileWriter ()
        {
+               init();
+       }
+
+       void init()
+       {
+               frames_written = 0;
                add_supported_flag (ProcessContext<T>::EndOfInput);
        }
-       
+
   protected:
        std::string path;
+       framecnt_t frames_written;
 };
 
 } // namespace