summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/export_graph_builder.h7
-rw-r--r--libs/ardour/ardour/export_handler.h6
-rw-r--r--libs/ardour/ardour/session.h3
-rw-r--r--libs/ardour/export_graph_builder.cc34
-rw-r--r--libs/ardour/export_handler.cc38
-rw-r--r--libs/ardour/session_export.cc63
-rw-r--r--libs/ardour/session_state.cc1
7 files changed, 85 insertions, 67 deletions
diff --git a/libs/ardour/ardour/export_graph_builder.h b/libs/ardour/ardour/export_graph_builder.h
index 1244afd647..2f57aaf583 100644
--- a/libs/ardour/ardour/export_graph_builder.h
+++ b/libs/ardour/ardour/export_graph_builder.h
@@ -62,6 +62,7 @@ class ExportGraphBuilder
~ExportGraphBuilder ();
int process (nframes_t frames, bool last_cycle);
+ bool process_normalize (); // returns true when finished
void reset ();
void add_config (FileSpec const & config);
@@ -124,6 +125,9 @@ class ExportGraphBuilder
void add_child (FileSpec const & new_config);
bool operator== (FileSpec const & other_config) const;
+ /// Returns true when finished
+ bool process ();
+
private:
typedef boost::shared_ptr<AudioGrapher::PeakReader> PeakReaderPtr;
typedef boost::shared_ptr<AudioGrapher::Normalizer> NormalizerPtr;
@@ -132,7 +136,6 @@ class ExportGraphBuilder
typedef boost::shared_ptr<AudioGrapher::AllocatingProcessContext<Sample> > BufferPtr;
void start_post_processing();
- void do_post_processing();
ExportGraphBuilder & parent;
@@ -217,6 +220,8 @@ class ExportGraphBuilder
Sample * process_buffer;
nframes_t process_buffer_frames;
+ std::list<Normalizer *> normalizers;
+
Glib::ThreadPool thread_pool;
};
diff --git a/libs/ardour/ardour/export_handler.h b/libs/ardour/ardour/export_handler.h
index f7f3b863b9..971c0c4940 100644
--- a/libs/ardour/ardour/export_handler.h
+++ b/libs/ardour/ardour/export_handler.h
@@ -112,17 +112,21 @@ class ExportHandler : public ExportElementFactory
private:
+ int process (nframes_t frames);
+
Session & session;
GraphBuilderPtr graph_builder;
StatusPtr export_status;
ConfigMap config_map;
bool realtime;
+ bool normalizing;
/* Timespan management */
void start_timespan ();
int process_timespan (nframes_t frames);
+ int process_normalize ();
void finish_timespan ();
typedef std::pair<ConfigMap::iterator, ConfigMap::iterator> TimespanBounds;
@@ -131,8 +135,6 @@ class ExportHandler : public ExportElementFactory
PBD::ScopedConnection process_connection;
sframes_t process_position;
-
- PBD::ScopedConnection export_read_finished_connection;
/* CD Marker stuff */
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index ae9c1f58a5..b72822bd1c 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -530,7 +530,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
int start_audio_export (nframes_t position, bool realtime);
PBD::Signal1<int,nframes_t> ProcessExport;
- PBD::Signal0<void> ExportReadFinished;
static PBD::Signal2<void,std::string, std::string> Exported;
void add_source (boost::shared_ptr<Source>);
@@ -934,7 +933,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
nframes_t post_export_position;
bool _exporting;
- bool _exporting_realtime;
+ bool _export_rolling;
boost::shared_ptr<ExportHandler> export_handler;
boost::shared_ptr<ExportStatus> export_status;
diff --git a/libs/ardour/export_graph_builder.cc b/libs/ardour/export_graph_builder.cc
index 5b5ec16b36..3b1d1e3838 100644
--- a/libs/ardour/export_graph_builder.cc
+++ b/libs/ardour/export_graph_builder.cc
@@ -56,11 +56,26 @@ ExportGraphBuilder::process (nframes_t frames, bool last_cycle)
return 0;
}
+bool
+ExportGraphBuilder::process_normalize ()
+{
+ for (std::list<Normalizer *>::iterator it = normalizers.begin(); it != normalizers.end(); /* ++ in loop */) {
+ if ((*it)->process()) {
+ it = normalizers.erase (it);
+ } else {
+ ++it;
+ }
+ }
+
+ return normalizers.empty();
+}
+
void
ExportGraphBuilder::reset ()
{
channel_configs.clear ();
channels.clear ();
+ normalizers.clear ();
}
void
@@ -252,20 +267,21 @@ ExportGraphBuilder::Normalizer::operator== (FileSpec const & other_config) const
config.format->normalize_target() == other_config.format->normalize_target();
}
-void
-ExportGraphBuilder::Normalizer::start_post_processing()
+bool
+ExportGraphBuilder::Normalizer::process()
{
- normalizer->set_peak (peak_reader->get_peak());
- tmp_file->seek (0, SndfileReader<Sample>::SeekBeginning);
- parent.thread_pool.push (sigc::mem_fun (*this, &Normalizer::do_post_processing));
+ ProcessContext<Sample> buffer_copy (*buffer);
+ tmp_file->read (buffer_copy);
+ normalizer->process (buffer_copy);
+ return buffer_copy.frames() != buffer->frames();
}
void
-ExportGraphBuilder::Normalizer::do_post_processing()
+ExportGraphBuilder::Normalizer::start_post_processing()
{
- while (tmp_file->read (*buffer) == buffer->frames()) {
- normalizer->process (*buffer);
- }
+ normalizer->set_peak (peak_reader->get_peak());
+ tmp_file->seek (0, SndfileReader<Sample>::SeekBeginning);
+ parent.normalizers.push_back (this);
}
/* SRC */
diff --git a/libs/ardour/export_handler.cc b/libs/ardour/export_handler.cc
index 3ce07cf44d..a9335add37 100644
--- a/libs/ardour/export_handler.cc
+++ b/libs/ardour/export_handler.cc
@@ -119,7 +119,7 @@ ExportHandler::add_export_config (TimespanPtr timespan, ChannelConfigPtr channel
FileSpec spec (channel_config, format, filename);
ConfigPair pair (timespan, spec);
config_map.insert (pair);
-
+
return true;
}
@@ -138,8 +138,6 @@ ExportHandler::do_export (bool rt)
/* Start export */
realtime = rt;
-
- session.ExportReadFinished.connect_same_thread (export_read_finished_connection, boost::bind (&ExportHandler::finish_timespan, this));
start_timespan ();
}
@@ -149,6 +147,7 @@ ExportHandler::start_timespan ()
export_status->timespan++;
if (config_map.empty()) {
+ // freewheeling has to be stopped from outside the process cycle
export_status->running = false;
return;
}
@@ -160,17 +159,33 @@ ExportHandler::start_timespan ()
timespan_bounds = config_map.equal_range (current_timespan);
graph_builder->reset ();
for (ConfigMap::iterator it = timespan_bounds.first; it != timespan_bounds.second; ++it) {
- graph_builder->add_config (it->second);
+ // Filenames can be shared across timespans
+ FileSpec & spec = it->second;
+ spec.filename->set_timespan (it->first);
+ graph_builder->add_config (spec);
}
/* start export */
- session.ProcessExport.connect_same_thread (process_connection, boost::bind (&ExportHandler::process_timespan, this, _1));
+ normalizing = false;
+ session.ProcessExport.connect_same_thread (process_connection, boost::bind (&ExportHandler::process, this, _1));
process_position = current_timespan->get_start();
session.start_audio_export (process_position, realtime);
}
int
+ExportHandler::process (nframes_t frames)
+{
+ if (!export_status->running) {
+ return 0;
+ } else if (normalizing) {
+ return process_normalize ();
+ } else {
+ return process_timespan (frames);
+ }
+}
+
+int
ExportHandler::process_timespan (nframes_t frames)
{
/* update position */
@@ -184,6 +199,7 @@ ExportHandler::process_timespan (nframes_t frames)
if (last_cycle) {
frames_to_read = end - process_position;
export_status->stop = true;
+ normalizing = true;
} else {
frames_to_read = frames;
}
@@ -196,11 +212,19 @@ ExportHandler::process_timespan (nframes_t frames)
return graph_builder->process (frames_to_read, last_cycle);
}
+int
+ExportHandler::process_normalize ()
+{
+ if (graph_builder->process_normalize ()) {
+ finish_timespan ();
+ }
+
+ return 0;
+}
+
void
ExportHandler::finish_timespan ()
{
- process_connection.disconnect ();
-
while (config_map.begin() != timespan_bounds.second) {
config_map.erase (config_map.begin());
}
diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc
index 86a6250ffd..9a277f5655 100644
--- a/libs/ardour/session_export.cc
+++ b/libs/ardour/session_export.cc
@@ -123,8 +123,6 @@ Session::start_audio_export (nframes_t position, bool realtime)
*/
_transport_frame = position;
-
- _exporting_realtime = realtime;
export_status->stop = false;
/* get transport ready. note how this is calling butler functions
@@ -144,39 +142,30 @@ Session::start_audio_export (nframes_t position, bool realtime)
return -1;
}
- if (realtime) {
- last_process_function = process_function;
- process_function = &Session::process_export;
- } else {
- _engine.Freewheel.connect_same_thread (export_freewheel_connection, boost::bind (&Session::process_export_fw, this, _1));
- return _engine.freewheel (true);
- }
-
- return 0;
+ _engine.Freewheel.connect_same_thread (export_freewheel_connection, boost::bind (&Session::process_export_fw, this, _1));
+ _export_rolling = true;
+ return _engine.freewheel (true);
}
void
Session::process_export (nframes_t nframes)
{
- try {
-
- if (export_status->stop) {
- stop_audio_export ();
- return;
- }
-
- if (!_exporting_realtime) {
- /* make sure we've caught up with disk i/o, since
- we're running faster than realtime c/o JACK.
- */
+ if (_export_rolling && export_status->stop) {
+ stop_audio_export ();
+ }
- _butler->wait_until_finished ();
- }
+ if (_export_rolling) {
+ /* make sure we've caught up with disk i/o, since
+ we're running faster than realtime c/o JACK.
+ */
+ _butler->wait_until_finished ();
/* do the usual stuff */
process_without_events (nframes);
-
+ }
+
+ try {
/* handle export - XXX what about error handling? */
ProcessExport (nframes);
@@ -197,23 +186,16 @@ Session::process_export_fw (nframes_t nframes)
int
Session::stop_audio_export ()
{
- if (_exporting_realtime) {
- process_function = last_process_function;
- } else {
- export_freewheel_connection.disconnect();
- }
-
/* can't use stop_transport() here because we need
an immediate halt and don't require all the declick
stuff that stop_transport() implements.
*/
realtime_stop (true, true);
+ _export_rolling = false;
_butler->schedule_transport_work ();
- if (!export_status->aborted()) {
- ExportReadFinished ();
- } else {
+ if (export_status->aborted()) {
finalize_audio_export ();
}
@@ -225,20 +207,11 @@ void
Session::finalize_audio_export ()
{
_exporting = false;
- export_status->running = false;
-
- if (!_exporting_realtime) {
- _engine.freewheel (false);
- _exporting_realtime = false;
- }
+ _export_rolling = false;
/* Clean up */
- /* BOOST SIGNAL are these necessary?
- ProcessExport.clear();
- ExportReadFinished.clear();
- */
-
+ _engine.freewheel (false);
export_freewheel_connection.disconnect();
export_handler.reset();
export_status.reset();
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 13b9112866..9394cd7bec 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -209,7 +209,6 @@ Session::first_stage_init (string fullpath, string snapshot_name)
g_atomic_int_set (&_capture_load_min, 100);
_play_range = false;
_exporting = false;
- _exporting_realtime = false;
_gain_automation_buffer = 0;
_pan_automation_buffer = 0;
_npan_buffers = 0;