Add stem export dialog and make all different export dialogs save their config to a different node in instant.xml

git-svn-id: svn://localhost/ardour2/branches/3.0@8465 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Sakari Bergen 2011-01-06 16:55:19 +00:00
parent 9a400114bb
commit 8e35583358
13 changed files with 222 additions and 33 deletions

View file

@ -22,6 +22,7 @@
<menuitem action='importFromSession'/> <menuitem action='importFromSession'/>
<menu name='Export' action='Export'> <menu name='Export' action='Export'>
<menuitem action='ExportAudio'/> <menuitem action='ExportAudio'/>
<menuitem action='StemExport'/>
</menu> </menu>
<menu name='Cleanup' action='Cleanup'> <menu name='Cleanup' action='Cleanup'>
<menuitem action='CleanupUnused'/> <menuitem action='CleanupUnused'/>

View file

@ -162,6 +162,9 @@ ARDOUR_UI::install_actions ()
act = ActionManager::register_action (main_actions, X_("ExportAudio"), _("Export To Audio File(s)..."), sigc::mem_fun (*editor, &PublicEditor::export_audio)); act = ActionManager::register_action (main_actions, X_("ExportAudio"), _("Export To Audio File(s)..."), sigc::mem_fun (*editor, &PublicEditor::export_audio));
ActionManager::session_sensitive_actions.push_back (act); ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (main_actions, X_("StemExport"), _("Stem export..."), sigc::mem_fun (*editor, &PublicEditor::stem_export));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (main_actions, X_("Export"), _("Export")); act = ActionManager::register_action (main_actions, X_("Export"), _("Export"));
ActionManager::session_sensitive_actions.push_back (act); ActionManager::session_sensitive_actions.push_back (act);

View file

@ -291,6 +291,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
/* export */ /* export */
void export_audio (); void export_audio ();
void stem_export ();
void export_selection (); void export_selection ();
void export_range (); void export_range ();
void export_region (); void export_region ();

View file

@ -59,7 +59,15 @@ using namespace Gtk;
void void
Editor::export_audio () Editor::export_audio ()
{ {
ExportDialog dialog (*this, _("Export")); ExportDialog dialog (*this, _("Export"), X_("ExportProfile"));
dialog.set_session (_session);
dialog.run();
}
void
Editor::stem_export ()
{
StemExportDialog dialog (*this);
dialog.set_session (_session); dialog.set_session (_session);
dialog.run(); dialog.run();
} }

View file

@ -502,3 +502,96 @@ RegionExportChannelSelector::handle_selection ()
CriticalSelectionChanged (); CriticalSelectionChanged ();
} }
TrackExportChannelSelector::TrackExportChannelSelector (ARDOUR::Session * session, ProfileManagerPtr manager)
: ExportChannelSelector(session, manager)
{
track_scroller.add (track_view);
track_scroller.set_size_request (-1, 130);
track_scroller.set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
pack_start(track_scroller);
// Track list
track_list = Gtk::ListStore::create (track_cols);
track_view.set_model (track_list);
track_view.set_headers_visible (true);
track_view.append_column_editable (_("Track"), track_cols.selected);
Gtk::CellRendererToggle *toggle = dynamic_cast<Gtk::CellRendererToggle *>(track_view.get_column_cell_renderer (0));
toggle->signal_toggled().connect (sigc::hide (sigc::mem_fun (*this, &TrackExportChannelSelector::update_config)));
Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
text_renderer->property_editable() = false;
Gtk::TreeView::Column* column = track_view.get_column (0);
column->pack_start (*text_renderer);
column->add_attribute (text_renderer->property_text(), track_cols.label);
fill_list();
show_all_children ();
}
void
TrackExportChannelSelector::sync_with_manager ()
{
// TODO implement properly
update_config();
}
void
TrackExportChannelSelector::fill_list()
{
track_list->clear();
RouteList routes = *_session->get_routes();
for (RouteList::iterator it = routes.begin(); it != routes.end(); ++it) {
Route * route = it->get();
if(dynamic_cast<AudioTrack *>(route)) {
add_track(route->output().get());
}
}
}
void
TrackExportChannelSelector::add_track(IO * io)
{
Gtk::TreeModel::iterator iter = track_list->append();
Gtk::TreeModel::Row row = *iter;
row[track_cols.selected] = true;
row[track_cols.label] = io->name();
row[track_cols.track] = io;
}
void
TrackExportChannelSelector::update_config()
{
manager->clear_channel_configs();
for (Gtk::ListStore::Children::iterator it = track_list->children().begin(); it != track_list->children().end(); ++it) {
Gtk::TreeModel::Row row = *it;
if (!row[track_cols.selected]) {
continue;
}
ExportProfileManager::ChannelConfigStatePtr state = manager->add_channel_config();
IO * track = row[track_cols.track];
uint32_t outs = track->n_ports().n_audio();
for (uint32_t i = 0; i < outs; ++i) {
AudioPort * port = track->audio (i);
if(port) {
ExportChannelPtr channel (new PortExportChannel ());
PortExportChannel * pec = static_cast<PortExportChannel *> (channel.get());
pec->add_port(port);
state->config->register_channel(channel);
}
}
state->config->set_name(track->name());
}
CriticalSelectionChanged ();
}

View file

@ -47,6 +47,7 @@ class ExportChannelSelector : public Gtk::HBox, public ARDOUR::SessionHandlePtr
{ {
protected: protected:
typedef boost::shared_ptr<ARDOUR::ExportChannelConfiguration> ChannelConfigPtr; typedef boost::shared_ptr<ARDOUR::ExportChannelConfiguration> ChannelConfigPtr;
typedef std::list<ChannelConfigPtr> ChannelConfigList;
typedef boost::shared_ptr<ARDOUR::ExportProfileManager> ProfileManagerPtr; typedef boost::shared_ptr<ARDOUR::ExportProfileManager> ProfileManagerPtr;
ProfileManagerPtr manager; ProfileManagerPtr manager;
@ -225,4 +226,37 @@ class RegionExportChannelSelector : public ExportChannelSelector
Gtk::RadioButton processed_button; Gtk::RadioButton processed_button;
}; };
class TrackExportChannelSelector : public ExportChannelSelector
{
public:
TrackExportChannelSelector (ARDOUR::Session * session, ProfileManagerPtr manager);
virtual void sync_with_manager ();
private:
void fill_list();
void add_track(ARDOUR::IO * io);
void update_config();
ChannelConfigList configs;
struct TrackCols : public Gtk::TreeModelColumnRecord
{
public:
Gtk::TreeModelColumn<ARDOUR::IO *> track;
Gtk::TreeModelColumn<std::string> label;
Gtk::TreeModelColumn<bool> selected;
TrackCols () { add (track); add(label); add(selected); }
};
TrackCols track_cols;
Glib::RefPtr<Gtk::ListStore> track_list;
Gtk::TreeView track_view;
Gtk::ScrolledWindow track_scroller;
};
#endif /* __export_channel_selector_h__ */ #endif /* __export_channel_selector_h__ */

View file

@ -36,13 +36,14 @@ using namespace ARDOUR;
using namespace PBD; using namespace PBD;
using std::string; using std::string;
ExportDialog::ExportDialog (PublicEditor & editor, std::string title) : ExportDialog::ExportDialog (PublicEditor & editor, std::string title, std::string xml_node_name)
ArdourDialog (title), : ArdourDialog (title)
editor (editor), , xml_node_name (xml_node_name)
, editor (editor)
warn_label ("", Gtk::ALIGN_LEFT), , warn_label ("", Gtk::ALIGN_LEFT)
list_files_label (_("<span color=\"#ffa755\">Some already existing files will be overwritten.</span>"), Gtk::ALIGN_RIGHT), , list_files_label (_("<span color=\"#ffa755\">Some already existing files will be overwritten.</span>"), Gtk::ALIGN_RIGHT)
list_files_button (_("List files")) , list_files_button (_("List files"))
{ } { }
ExportDialog::~ExportDialog () ExportDialog::~ExportDialog ()
@ -61,7 +62,7 @@ ExportDialog::set_session (ARDOUR::Session* s)
handler = _session->get_export_handler (); handler = _session->get_export_handler ();
status = _session->get_export_status (); status = _session->get_export_status ();
profile_manager.reset (new ExportProfileManager (*_session)); profile_manager.reset (new ExportProfileManager (*_session, xml_node_name));
/* Possibly init stuff in derived classes */ /* Possibly init stuff in derived classes */
@ -381,7 +382,7 @@ ExportDialog::add_warning (string const & text)
/*** Dialog specializations ***/ /*** Dialog specializations ***/
ExportRangeDialog::ExportRangeDialog (PublicEditor & editor, string range_id) : ExportRangeDialog::ExportRangeDialog (PublicEditor & editor, string range_id) :
ExportDialog (editor, _("Export Range")), ExportDialog (editor, _("Export Range"), X_("RangeExportProfile")),
range_id (range_id) range_id (range_id)
{} {}
@ -395,7 +396,7 @@ ExportRangeDialog::init_components ()
} }
ExportSelectionDialog::ExportSelectionDialog (PublicEditor & editor) : ExportSelectionDialog::ExportSelectionDialog (PublicEditor & editor) :
ExportDialog (editor, _("Export Selection")) ExportDialog (editor, _("Export Selection"), X_("SelectionExportProfile"))
{} {}
void void
@ -408,7 +409,7 @@ ExportSelectionDialog::init_components ()
} }
ExportRegionDialog::ExportRegionDialog (PublicEditor & editor, ARDOUR::AudioRegion const & region, ARDOUR::AudioTrack & track) : ExportRegionDialog::ExportRegionDialog (PublicEditor & editor, ARDOUR::AudioRegion const & region, ARDOUR::AudioTrack & track) :
ExportDialog (editor, _("Export Region")), ExportDialog (editor, _("Export Region"), X_("RegionExportProfile")),
region (region), region (region),
track (track) track (track)
{} {}
@ -431,3 +432,19 @@ ExportRegionDialog::init_components ()
channel_selector.reset (new RegionExportChannelSelector (_session, profile_manager, region, track)); channel_selector.reset (new RegionExportChannelSelector (_session, profile_manager, region, track));
file_notebook.reset (new ExportFileNotebook ()); file_notebook.reset (new ExportFileNotebook ());
} }
StemExportDialog::StemExportDialog (PublicEditor & editor)
: ExportDialog(editor, _("Stem Export"), X_("StemExportProfile"))
{
}
void
StemExportDialog::init_components ()
{
preset_selector.reset (new ExportPresetSelector ());
timespan_selector.reset (new ExportTimespanSelectorMultiple (_session, profile_manager));
channel_selector.reset (new TrackExportChannelSelector (_session, profile_manager));
file_notebook.reset (new ExportFileNotebook ());
}

View file

@ -47,7 +47,7 @@ class ExportDialog : public ArdourDialog {
public: public:
explicit ExportDialog (PublicEditor & editor, std::string title); ExportDialog (PublicEditor & editor, std::string title, std::string xml_node_name);
~ExportDialog (); ~ExportDialog ();
void set_session (ARDOUR::Session* s); void set_session (ARDOUR::Session* s);
@ -65,6 +65,7 @@ class ExportDialog : public ArdourDialog {
typedef boost::shared_ptr<ARDOUR::ExportHandler> HandlerPtr; typedef boost::shared_ptr<ARDOUR::ExportHandler> HandlerPtr;
typedef boost::shared_ptr<ARDOUR::ExportProfileManager> ManagerPtr; typedef boost::shared_ptr<ARDOUR::ExportProfileManager> ManagerPtr;
std::string xml_node_name;
HandlerPtr handler; HandlerPtr handler;
ManagerPtr profile_manager; ManagerPtr profile_manager;
@ -171,4 +172,13 @@ class ExportRegionDialog : public ExportDialog
ARDOUR::AudioTrack & track; ARDOUR::AudioTrack & track;
}; };
class StemExportDialog : public ExportDialog
{
public:
StemExportDialog (PublicEditor & editor);
private:
void init_components ();
};
#endif /* __ardour_export_dialog_h__ */ #endif /* __ardour_export_dialog_h__ */

View file

@ -211,6 +211,9 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible {
/** Open main export dialog */ /** Open main export dialog */
virtual void export_audio () = 0; virtual void export_audio () = 0;
/** Open stem export dialog */
virtual void stem_export () = 0;
/** Open export dialog with current selection pre-selected */ /** Open export dialog with current selection pre-selected */
virtual void export_selection () = 0; virtual void export_selection () = 0;

View file

@ -55,7 +55,7 @@ class ExportProfileManager
{ {
public: public:
ExportProfileManager (Session & s); ExportProfileManager (Session & s, std::string xml_node_name);
~ExportProfileManager (); ~ExportProfileManager ();
void load_profile (); void load_profile ();
@ -75,6 +75,7 @@ class ExportProfileManager
typedef std::pair<PBD::UUID, PBD::sys::path> FilePair; typedef std::pair<PBD::UUID, PBD::sys::path> FilePair;
typedef std::map<PBD::UUID, PBD::sys::path> FileMap; typedef std::map<PBD::UUID, PBD::sys::path> FileMap;
std::string const xml_node_name;
HandlerPtr handler; HandlerPtr handler;
Session & session; Session & session;
@ -174,6 +175,8 @@ class ExportProfileManager
typedef std::list<ChannelConfigStatePtr> ChannelConfigStateList; typedef std::list<ChannelConfigStatePtr> ChannelConfigStateList;
ChannelConfigStateList const & get_channel_configs () { return check_list (channel_configs); } ChannelConfigStateList const & get_channel_configs () { return check_list (channel_configs); }
void clear_channel_configs () { channel_configs.clear(); }
ChannelConfigStatePtr add_channel_config ();
private: private:

View file

@ -187,6 +187,7 @@ ExportGraphBuilder::Encoder::init_writer (boost::shared_ptr<AudioGrapher::Sndfil
{ {
unsigned channels = config.channel_config->get_n_chans(); unsigned channels = config.channel_config->get_n_chans();
int format = get_real_format (config); int format = get_real_format (config);
config.filename->set_channel_config(config.channel_config);
string filename = config.filename->get_path (config.format); string filename = config.filename->get_path (config.format);
writer.reset (new AudioGrapher::SndfileWriter<T> (filename, format, channels, config.format->sample_rate(), config.broadcast_info)); writer.reset (new AudioGrapher::SndfileWriter<T> (filename, format, channels, config.format->sample_rate(), config.broadcast_info));

View file

@ -49,15 +49,16 @@ using namespace PBD;
namespace ARDOUR namespace ARDOUR
{ {
ExportProfileManager::ExportProfileManager (Session & s) : ExportProfileManager::ExportProfileManager (Session & s, std::string xml_node_name)
handler (s.get_export_handler()), : xml_node_name (xml_node_name)
session (s), , handler (s.get_export_handler())
, session (s)
session_range (new Location (s)), , session_range (new Location (s))
ranges (new LocationList ()), , ranges (new LocationList ())
single_range_mode (false), , single_range_mode (false)
format_list (new FormatList ()) , format_list (new FormatList ())
{ {
/* Initialize path variables */ /* Initialize path variables */
@ -98,7 +99,7 @@ ExportProfileManager::~ExportProfileManager ()
{ {
if (single_range_mode) { return; } if (single_range_mode) { return; }
XMLNode * instant_xml (new XMLNode ("ExportProfile")); XMLNode * instant_xml (new XMLNode (xml_node_name));
serialize_profile (*instant_xml); serialize_profile (*instant_xml);
session.add_instant_xml (*instant_xml, false); session.add_instant_xml (*instant_xml, false);
} }
@ -106,11 +107,11 @@ ExportProfileManager::~ExportProfileManager ()
void void
ExportProfileManager::load_profile () ExportProfileManager::load_profile ()
{ {
XMLNode * instant_node = session.instant_xml ("ExportProfile"); XMLNode * instant_node = session.instant_xml (xml_node_name);
if (instant_node) { if (instant_node) {
set_state (*instant_node); set_state (*instant_node);
} else { } else {
XMLNode empty_node ("ExportProfile"); XMLNode empty_node (xml_node_name);
set_state (empty_node); set_state (empty_node);
} }
} }
@ -118,17 +119,19 @@ ExportProfileManager::load_profile ()
void void
ExportProfileManager::prepare_for_export () ExportProfileManager::prepare_for_export ()
{ {
ChannelConfigPtr channel_config = channel_configs.front()->config;
TimespanListPtr ts_list = timespans.front()->timespans; TimespanListPtr ts_list = timespans.front()->timespans;
FormatStateList::const_iterator format_it; FormatStateList::const_iterator format_it;
FilenameStateList::const_iterator filename_it; FilenameStateList::const_iterator filename_it;
// For each timespan
for (TimespanList::iterator ts_it = ts_list->begin(); ts_it != ts_list->end(); ++ts_it) { for (TimespanList::iterator ts_it = ts_list->begin(); ts_it != ts_list->end(); ++ts_it) {
// ..., each format-filename pair
for (format_it = formats.begin(), filename_it = filenames.begin(); for (format_it = formats.begin(), filename_it = filenames.begin();
format_it != formats.end() && filename_it != filenames.end(); format_it != formats.end() && filename_it != filenames.end();
++format_it, ++filename_it) { ++format_it, ++filename_it) {
FilenamePtr filename = (*filename_it)->filename;
// filename->include_timespan = (ts_list->size() > 1); Disabled for now... // filename->include_timespan = (ts_list->size() > 1); Disabled for now...
boost::shared_ptr<BroadcastInfo> b; boost::shared_ptr<BroadcastInfo> b;
@ -137,7 +140,11 @@ ExportProfileManager::prepare_for_export ()
b->set_from_session (session, (*ts_it)->get_start()); b->set_from_session (session, (*ts_it)->get_start());
} }
handler->add_export_config (*ts_it, channel_config, (*format_it)->format, (*filename_it)->filename, b); // ...and each channel config
filename->include_channel_config = (channel_configs.size() > 1);
for(ChannelConfigStateList::iterator cc_it = channel_configs.begin(); cc_it != channel_configs.end(); ++cc_it) {
handler->add_export_config (*ts_it, (*cc_it)->config, (*format_it)->format, filename, b);
}
} }
} }
} }
@ -440,6 +447,14 @@ ExportProfileManager::update_ranges () {
} }
} }
ExportProfileManager::ChannelConfigStatePtr
ExportProfileManager::add_channel_config ()
{
ChannelConfigStatePtr ptr(new ChannelConfigState(handler->add_channel_config()));
channel_configs.push_back(ptr);
return ptr;
}
bool bool
ExportProfileManager::init_channel_configs (XMLNodeList nodes) ExportProfileManager::init_channel_configs (XMLNodeList nodes)
{ {