X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fexport_channel_configuration.cc;h=eb3b2838c64e68cf3bd117d873359f9fbf5db444;hb=b2bf4eee3d9ca63a34415c75e877b8c97d6b5f13;hp=a092af88c1d57a78f49892a9c3920aea209ab92d;hpb=89e4d352445e9394073804f78fbd6845e6820f20;p=ardour.git diff --git a/libs/ardour/export_channel_configuration.cc b/libs/ardour/export_channel_configuration.cc index a092af88c1..eb3b2838c6 100644 --- a/libs/ardour/export_channel_configuration.cc +++ b/libs/ardour/export_channel_configuration.cc @@ -18,82 +18,55 @@ */ -#include +#include "ardour/export_channel_configuration.h" -#include -#include -#include -#include +#include "ardour/export_handler.h" +#include "ardour/export_filename.h" +#include "ardour/export_timespan.h" -#include -#include -#include -#include -#include +#include "ardour/audio_port.h" +#include "ardour/export_failed.h" +#include "ardour/midi_port.h" +#include "ardour/session.h" +#include "ardour/audioengine.h" -#include -#include +#include "pbd/convert.h" +#include "pbd/pthread_utils.h" -namespace ARDOUR -{ +using namespace PBD; -/* ExportChannel */ - -void -ExportChannel::read_ports (float * data, nframes_t frames) const +namespace ARDOUR { - memset (data, 0, frames * sizeof (float)); - - for (iterator it = begin(); it != end(); ++it) { - if (*it != 0) { - Sample* port_buffer = (*it)->get_audio_buffer( frames, 0).data(); - - for (uint32_t i = 0; i < frames; ++i) { - data[i] += (float) port_buffer[i]; - } - } - } -} /* ExportChannelConfiguration */ ExportChannelConfiguration::ExportChannelConfiguration (Session & session) : session (session), - writer_thread (*this), - status (session.get_export_status ()), - files_written (false), split (false) { } - XMLNode & ExportChannelConfiguration::get_state () { XMLNode * root = new XMLNode ("ExportChannelConfiguration"); XMLNode * channel; - XMLNode * port_node; - + root->add_property ("split", get_split() ? "true" : "false"); root->add_property ("channels", to_string (get_n_chans(), std::dec)); - + uint32_t i = 1; for (ExportChannelConfiguration::ChannelList::const_iterator c_it = channels.begin(); c_it != channels.end(); ++c_it) { channel = root->add_child ("Channel"); if (!channel) { continue; } - + channel->add_property ("number", to_string (i, std::dec)); - - for (ExportChannel::const_iterator p_it = (*c_it)->begin(); p_it != (*c_it)->end(); ++p_it) { - if ((port_node = channel->add_child ("Port"))) { - port_node->add_property ("name", (*p_it)->name()); - } - } - + (*c_it)->get_state (channel); + ++i; } - + return *root; } @@ -101,22 +74,15 @@ int ExportChannelConfiguration::set_state (const XMLNode & root) { XMLProperty const * prop; - + if ((prop = root.property ("split"))) { set_split (!prop->value().compare ("true")); } XMLNodeList channels = root.children ("Channel"); for (XMLNodeList::iterator it = channels.begin(); it != channels.end(); ++it) { - boost::shared_ptr channel (new ExportChannel ()); - - XMLNodeList ports = (*it)->children ("Port"); - for (XMLNodeList::iterator p_it = ports.begin(); p_it != ports.end(); ++p_it) { - if ((prop = (*p_it)->property ("name"))) { - channel->add_port (dynamic_cast (session.engine().get_port_by_name (prop->value()))); - } - } - + ExportChannelPtr channel (new PortExportChannel ()); + channel->set_state (*it, session); register_channel (channel); } @@ -124,131 +90,31 @@ ExportChannelConfiguration::set_state (const XMLNode & root) } bool -ExportChannelConfiguration::all_channels_have_ports () +ExportChannelConfiguration::all_channels_have_ports () const { - for (ChannelList::iterator it = channels.begin(); it != channels.end(); ++it) { + for (ChannelList::const_iterator it = channels.begin(); it != channels.end(); ++it) { if ((*it)->empty ()) { return false; } } - - return true; -} - -bool -ExportChannelConfiguration::write_files (boost::shared_ptr new_processor) -{ - if (files_written || writer_thread.running) { - return false; - } - - files_written = true; - if (!timespan) { - throw ExportFailed (X_("Programming error: No timespan registered to channel configuration when requesting files to be written")); - } - - /* Take a local copy of the processor to be used in the thread that is created below */ - - processor.reset (new_processor->copy()); - - /* Create new thread for post processing */ - - pthread_create (&writer_thread.thread, 0, _write_files, &writer_thread); - writer_thread.running = true; - pthread_detach (writer_thread.thread); - return true; } void -ExportChannelConfiguration::write_file () +ExportChannelConfiguration::configurations_for_files (std::list > & configs) { - timespan->rewind (); - nframes_t progress = 0; - nframes_t timespan_length = timespan->get_length(); - - nframes_t frames = 2048; // TODO good block size ? - nframes_t frames_read = 0; - - float * channel_buffer = new float [frames]; - float * file_buffer = new float [channels.size() * frames]; - uint32_t channel_count = channels.size(); - uint32_t channel; - - do { - if (status->aborted()) { break; } - - channel = 0; - for (ChannelList::iterator it = channels.begin(); it != channels.end(); ++it) { - - /* Get channel data */ - - frames_read = timespan->get_data (channel_buffer, frames, **it); - - /* Interleave into file buffer */ - - for (uint32_t i = 0; i < frames_read; ++i) { - file_buffer[channel + (channel_count * i)] = channel_buffer[i]; - } - - ++channel; - } - - progress += frames_read; - status->progress = (float) progress / timespan_length; - - } while (processor->process (file_buffer, frames_read) > 0); + configs.clear (); - delete [] channel_buffer; - delete [] file_buffer; -} - -void * -ExportChannelConfiguration::_write_files (void *arg) -{ - - PBD::ThreadCreated (pthread_self(), "Export post-processing"); - - // cc can be trated like 'this' - WriterThread & cc (*((WriterThread *) arg)); - - try { - for (FileConfigList::iterator it = cc->file_configs.begin(); it != cc->file_configs.end(); ++it) { - if (cc->status->aborted()) { - break; - } - cc->processor->prepare (it->first, it->second, cc->channels.size(), cc->split, cc->timespan->get_start()); - cc->write_file (); // Writes tempfile - cc->processor->prepare_post_processors (); - cc->processor->write_files(); - } - } catch (ExportFailed & e) { - cc->status->abort (true); + if (!split) { + configs.push_back (shared_from_this ()); + return; } - cc.running = false; - cc->files_written = true; - cc->FilesWritten(); - - return 0; // avoid compiler warnings -} - -void -ExportChannelConfiguration::register_with_timespan (TimespanPtr new_timespan) -{ - timespan = new_timespan; - - for (ChannelList::iterator it = channels.begin(); it != channels.end(); ++it) { - timespan->register_channel (**it); + for (ChannelList::const_iterator it = channels.begin (); it != channels.end (); ++it) { + boost::shared_ptr config (new ExportChannelConfiguration (session)); + config->set_name (_name); + config->register_channel (*it); + configs.push_back (config); } } -void -ExportChannelConfiguration::unregister_all () -{ - timespan.reset(); - processor.reset(); - file_configs.clear(); - files_written = false; -} - } // namespace ARDOUR