Move is_embedded calculation to a single place.
[ardour.git] / libs / ardour / export_channel_configuration.cc
index cd29a4e5787e7cd7c2451b982d93e6d6a3c3ae20..47bbbd276cb5f7a233c84debf3fa3b67bc780879 100644 (file)
 
 */
 
-#include <ardour/export_channel_configuration.h>
+#include "ardour/export_channel_configuration.h"
 
-#include <ardour/export_handler.h>
-#include <ardour/export_filename.h>
-#include <ardour/export_processor.h>
-#include <ardour/export_timespan.h>
+#include "ardour/export_handler.h"
+#include "ardour/export_filename.h"
+#include "ardour/export_processor.h"
+#include "ardour/export_timespan.h"
 
-#include <ardour/audio_port.h>
-#include <ardour/export_failed.h>
-#include <ardour/midi_port.h>
-#include <pbd/pthread_utils.h>
+#include "ardour/audio_port.h"
+#include "ardour/export_failed.h"
+#include "ardour/midi_port.h"
+#include "ardour/session.h"
+#include "ardour/audioengine.h"
+
+#include "pbd/convert.h"
+#include "pbd/pthread_utils.h"
+
+using namespace PBD;
 
 namespace ARDOUR
 {
 
-/* ExportChannel */
+/* ExportChannelConfiguration */
 
-ExportChannel::ExportChannel ()
+ExportChannelConfiguration::ExportChannelConfiguration (Session & session) :
+  session (session),
+  writer_thread (*this),
+  status (session.get_export_status ()),
+  files_written (false),
+  split (false)
 {
 
 }
 
-ExportChannel::~ExportChannel ()
+
+XMLNode &
+ExportChannelConfiguration::get_state ()
 {
+       XMLNode * root = new XMLNode ("ExportChannelConfiguration");
+       XMLNode * channel;
 
-}
+       root->add_property ("split", get_split() ? "true" : "false");
+       root->add_property ("channels", to_string (get_n_chans(), std::dec));
 
-void
-ExportChannel::read_ports (float * data, nframes_t frames) const
-{
-       memset (data, 0, frames * sizeof (float));
-
-       for (iterator it = begin(); it != end(); ++it) {
-               if (*it != 0) {
-                       Sample* port_buffer = (*it)->get_audio_buffer().data();
-                       
-                       for (uint32_t i = 0; i < frames; ++i) {
-                               data[i] += (float) port_buffer[i];
-                       }
-               }
-       }
-}
+       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; }
 
-/* ExportChannelConfiguration */
+               channel->add_property ("number", to_string (i, std::dec));
+               (*c_it)->get_state (channel);
 
-ExportChannelConfiguration::ExportChannelConfiguration (ExportStatus & status) :
-  writer_thread (*this),
-  status (status),
-  files_written (false),
-  split (false)
-{
+               ++i;
+       }
 
+       return *root;
 }
 
-ExportChannelConfiguration::~ExportChannelConfiguration ()
+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) {
+               ExportChannelPtr channel (new PortExportChannel ());
+               channel->set_state (*it, session);
+               register_channel (channel);
+       }
 
+       return 0;
 }
 
 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;
 }
 
@@ -93,23 +110,23 @@ ExportChannelConfiguration::write_files (boost::shared_ptr<ExportProcessor> new_
        if (files_written || writer_thread.running) {
                return false;
        }
-       
+
        files_written = true;
 
        if (!timespan) {
-               throw ExportFailed (_("Export failed due to a programming error"), _("No timespan registered to channel configuration when requesting files to be written"));
+               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;
 }
 
@@ -122,36 +139,36 @@ ExportChannelConfiguration::write_file ()
 
        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; }
-       
+               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);
-                       
+
+                       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;
-               
+               status->progress = (float) progress / timespan_length;
+
        } while (processor->process (file_buffer, frames_read) > 0);
-       
+
        delete [] channel_buffer;
        delete [] file_buffer;
 }
@@ -159,26 +176,29 @@ ExportChannelConfiguration::write_file ()
 void *
 ExportChannelConfiguration::_write_files (void *arg)
 {
+       notify_gui_about_thread_creation (pthread_self(), "Export post-processing");
 
-       PBD::ThreadCreated (pthread_self(), "Export post-processing");
-       
        // cc can be trated like 'this'
        WriterThread & cc (*((WriterThread *) arg));
-       
-       for (FileConfigList::iterator it = cc->file_configs.begin(); it != cc->file_configs.end(); ++it) {
-               if (cc->status.aborted()) {
-                       break;
+
+       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();
                }
-               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);
        }
-       
+
        cc.running = false;
        cc->files_written = true;
        cc->FilesWritten();
-       
+
        return 0; // avoid compiler warnings
 }
 
@@ -186,9 +206,9 @@ 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);
+               timespan->register_channel (*it);
        }
 }