mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 07:45:00 +01:00
Region export dialog: Make export channel and -selector polymorphic, add the region related classes and a dialog specialization
git-svn-id: svn://localhost/ardour2/branches/3.0@3915 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
01b1790c98
commit
98389f7da4
14 changed files with 537 additions and 115 deletions
|
|
@ -91,17 +91,25 @@ Editor::export_range ()
|
||||||
void
|
void
|
||||||
Editor::export_region ()
|
Editor::export_region ()
|
||||||
{
|
{
|
||||||
// if (selection->regions.empty()) {
|
if (selection->regions.empty()) {
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// boost::shared_ptr<Region> r = selection->regions.front()->region();
|
try {
|
||||||
//
|
boost::shared_ptr<Region> r = selection->regions.front()->region();
|
||||||
// ExportDialog* dialog = new ExportRegionDialog (*this, r);
|
AudioRegion & region (dynamic_cast<AudioRegion &> (*r));
|
||||||
//
|
|
||||||
// dialog->connect_to_session (session);
|
RouteTimeAxisView & rtv (dynamic_cast<RouteTimeAxisView &> (selection->regions.front()->get_time_axis_view()));
|
||||||
// dialog->set_range (clicked_regionview->region()->first_frame(), clicked_regionview->region()->last_frame());
|
AudioTrack & track (dynamic_cast<AudioTrack &> (*rtv.route()));
|
||||||
// dialog->start_export();
|
|
||||||
|
ExportRegionDialog dialog (*this, region, track);
|
||||||
|
dialog.set_session (session);
|
||||||
|
dialog.run();
|
||||||
|
|
||||||
|
} catch (std::bad_cast & e) {
|
||||||
|
error << "Exporting Region failed!" << endmsg;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
using namespace ARDOUR;
|
using namespace ARDOUR;
|
||||||
using namespace PBD;
|
using namespace PBD;
|
||||||
|
|
||||||
ExportChannelSelector::ExportChannelSelector () :
|
PortExportChannelSelector::PortExportChannelSelector () :
|
||||||
channels_label (_("Channels:"), Gtk::ALIGN_LEFT),
|
channels_label (_("Channels:"), Gtk::ALIGN_LEFT),
|
||||||
split_checkbox (_("Split to mono files")),
|
split_checkbox (_("Split to mono files")),
|
||||||
max_channels (20),
|
max_channels (20),
|
||||||
|
|
@ -68,11 +68,11 @@ ExportChannelSelector::ExportChannelSelector () :
|
||||||
channels_spinbutton.set_range (1, max_channels);
|
channels_spinbutton.set_range (1, max_channels);
|
||||||
channels_spinbutton.set_value (2);
|
channels_spinbutton.set_value (2);
|
||||||
|
|
||||||
channels_spinbutton.signal_value_changed().connect (sigc::mem_fun (*this, &ExportChannelSelector::update_channel_count));
|
channels_spinbutton.signal_value_changed().connect (sigc::mem_fun (*this, &PortExportChannelSelector::update_channel_count));
|
||||||
|
|
||||||
/* Other signals */
|
/* Other signals */
|
||||||
|
|
||||||
split_checkbox.signal_toggled().connect (sigc::mem_fun (*this, &ExportChannelSelector::update_split_state));
|
split_checkbox.signal_toggled().connect (sigc::mem_fun (*this, &PortExportChannelSelector::update_split_state));
|
||||||
channel_view.CriticalSelectionChanged.connect (CriticalSelectionChanged.make_slot());
|
channel_view.CriticalSelectionChanged.connect (CriticalSelectionChanged.make_slot());
|
||||||
|
|
||||||
/* Finalize */
|
/* Finalize */
|
||||||
|
|
@ -81,7 +81,7 @@ ExportChannelSelector::ExportChannelSelector () :
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ExportChannelSelector::~ExportChannelSelector ()
|
PortExportChannelSelector::~PortExportChannelSelector ()
|
||||||
{
|
{
|
||||||
// if (session) {
|
// if (session) {
|
||||||
// session->add_instant_xml (get_state(), false);
|
// session->add_instant_xml (get_state(), false);
|
||||||
|
|
@ -89,7 +89,7 @@ ExportChannelSelector::~ExportChannelSelector ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ExportChannelSelector::set_state (ARDOUR::ExportProfileManager::ChannelConfigStatePtr const state_, ARDOUR::Session * session_)
|
PortExportChannelSelector::set_state (ARDOUR::ExportProfileManager::ChannelConfigStatePtr const state_, ARDOUR::Session * session_)
|
||||||
{
|
{
|
||||||
state = state_;
|
state = state_;
|
||||||
session = session_;
|
session = session_;
|
||||||
|
|
@ -102,7 +102,7 @@ ExportChannelSelector::set_state (ARDOUR::ExportProfileManager::ChannelConfigSta
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ExportChannelSelector::fill_route_list ()
|
PortExportChannelSelector::fill_route_list ()
|
||||||
{
|
{
|
||||||
channel_view.clear_routes ();
|
channel_view.clear_routes ();
|
||||||
Session::RouteList routes = *session->get_routes();
|
Session::RouteList routes = *session->get_routes();
|
||||||
|
|
@ -123,7 +123,7 @@ ExportChannelSelector::fill_route_list ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ExportChannelSelector::update_channel_count ()
|
PortExportChannelSelector::update_channel_count ()
|
||||||
{
|
{
|
||||||
uint32_t chans = static_cast<uint32_t> (channels_spinbutton.get_value());
|
uint32_t chans = static_cast<uint32_t> (channels_spinbutton.get_value());
|
||||||
channel_view.set_channel_count (chans);
|
channel_view.set_channel_count (chans);
|
||||||
|
|
@ -131,14 +131,14 @@ ExportChannelSelector::update_channel_count ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ExportChannelSelector::update_split_state ()
|
PortExportChannelSelector::update_split_state ()
|
||||||
{
|
{
|
||||||
state->config->set_split (split_checkbox.get_active());
|
state->config->set_split (split_checkbox.get_active());
|
||||||
CriticalSelectionChanged();
|
CriticalSelectionChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ExportChannelSelector::RouteCols::add_channels (uint32_t chans)
|
PortExportChannelSelector::RouteCols::add_channels (uint32_t chans)
|
||||||
{
|
{
|
||||||
while (chans > 0) {
|
while (chans > 0) {
|
||||||
channels.push_back (Channel (*this));
|
channels.push_back (Channel (*this));
|
||||||
|
|
@ -147,8 +147,8 @@ ExportChannelSelector::RouteCols::add_channels (uint32_t chans)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExportChannelSelector::RouteCols::Channel &
|
PortExportChannelSelector::RouteCols::Channel &
|
||||||
ExportChannelSelector::RouteCols::get_channel (uint32_t channel)
|
PortExportChannelSelector::RouteCols::get_channel (uint32_t channel)
|
||||||
{
|
{
|
||||||
if (channel > n_channels) {
|
if (channel > n_channels) {
|
||||||
std::cout << "Invalid channel cout for get_channel!" << std::endl;
|
std::cout << "Invalid channel cout for get_channel!" << std::endl;
|
||||||
|
|
@ -164,7 +164,7 @@ ExportChannelSelector::RouteCols::get_channel (uint32_t channel)
|
||||||
return *it;
|
return *it;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExportChannelSelector::ChannelTreeView::ChannelTreeView (uint32_t max_channels) :
|
PortExportChannelSelector::ChannelTreeView::ChannelTreeView (uint32_t max_channels) :
|
||||||
n_channels (0)
|
n_channels (0)
|
||||||
{
|
{
|
||||||
/* Main columns */
|
/* Main columns */
|
||||||
|
|
@ -186,13 +186,13 @@ ExportChannelSelector::ChannelTreeView::ChannelTreeView (uint32_t max_channels)
|
||||||
column->add_attribute (text_renderer->property_text(), route_cols.name);
|
column->add_attribute (text_renderer->property_text(), route_cols.name);
|
||||||
|
|
||||||
Gtk::CellRendererToggle *toggle = dynamic_cast<Gtk::CellRendererToggle *>(get_column_cell_renderer (0));
|
Gtk::CellRendererToggle *toggle = dynamic_cast<Gtk::CellRendererToggle *>(get_column_cell_renderer (0));
|
||||||
toggle->signal_toggled().connect (mem_fun (*this, &ExportChannelSelector::ChannelTreeView::update_toggle_selection));
|
toggle->signal_toggled().connect (mem_fun (*this, &PortExportChannelSelector::ChannelTreeView::update_toggle_selection));
|
||||||
|
|
||||||
static_columns = get_columns().size();
|
static_columns = get_columns().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ExportChannelSelector::ChannelTreeView::set_config (ChannelConfigPtr c)
|
PortExportChannelSelector::ChannelTreeView::set_config (ChannelConfigPtr c)
|
||||||
{
|
{
|
||||||
/* TODO Without the following line, the state might get reset.
|
/* TODO Without the following line, the state might get reset.
|
||||||
* Pointing to the same address does not mean the state of the configuration hasn't changed.
|
* Pointing to the same address does not mean the state of the configuration hasn't changed.
|
||||||
|
|
@ -208,6 +208,11 @@ ExportChannelSelector::ChannelTreeView::set_config (ChannelConfigPtr c)
|
||||||
|
|
||||||
for (Gtk::ListStore::Children::iterator r_it = route_list->children().begin(); r_it != route_list->children().end(); ++r_it) {
|
for (Gtk::ListStore::Children::iterator r_it = route_list->children().begin(); r_it != route_list->children().end(); ++r_it) {
|
||||||
|
|
||||||
|
ARDOUR::PortExportChannel * pec;
|
||||||
|
if (!(pec = dynamic_cast<ARDOUR::PortExportChannel *> (c_it->get()))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Glib::RefPtr<Gtk::ListStore> port_list = r_it->get_value (route_cols.port_list_col);
|
Glib::RefPtr<Gtk::ListStore> port_list = r_it->get_value (route_cols.port_list_col);
|
||||||
std::set<AudioPort *> route_ports;
|
std::set<AudioPort *> route_ports;
|
||||||
std::set<AudioPort *> intersection;
|
std::set<AudioPort *> intersection;
|
||||||
|
|
@ -219,7 +224,7 @@ ExportChannelSelector::ChannelTreeView::set_config (ChannelConfigPtr c)
|
||||||
(*p_it)->get_value (route_cols.port_cols.label)));
|
(*p_it)->get_value (route_cols.port_cols.label)));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set_intersection ((*c_it)->begin(), (*c_it)->end(),
|
std::set_intersection (pec->get_ports().begin(), pec->get_ports().end(),
|
||||||
route_ports.begin(), route_ports.end(),
|
route_ports.begin(), route_ports.end(),
|
||||||
std::insert_iterator<std::set<AudioPort *> > (intersection, intersection.begin()));
|
std::insert_iterator<std::set<AudioPort *> > (intersection, intersection.begin()));
|
||||||
|
|
||||||
|
|
@ -253,7 +258,7 @@ ExportChannelSelector::ChannelTreeView::set_config (ChannelConfigPtr c)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ExportChannelSelector::ChannelTreeView::add_route (ARDOUR::IO * route)
|
PortExportChannelSelector::ChannelTreeView::add_route (ARDOUR::IO * route)
|
||||||
{
|
{
|
||||||
Gtk::TreeModel::iterator iter = route_list->append();
|
Gtk::TreeModel::iterator iter = route_list->append();
|
||||||
Gtk::TreeModel::Row row = *iter;
|
Gtk::TreeModel::Row row = *iter;
|
||||||
|
|
@ -291,7 +296,7 @@ ExportChannelSelector::ChannelTreeView::add_route (ARDOUR::IO * route)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ExportChannelSelector::ChannelTreeView::set_channel_count (uint32_t channels)
|
PortExportChannelSelector::ChannelTreeView::set_channel_count (uint32_t channels)
|
||||||
{
|
{
|
||||||
int offset = channels - n_channels;
|
int offset = channels - n_channels;
|
||||||
|
|
||||||
|
|
@ -315,7 +320,7 @@ ExportChannelSelector::ChannelTreeView::set_channel_count (uint32_t channels)
|
||||||
column->add_attribute (combo_renderer->property_model(), route_cols.port_list_col);
|
column->add_attribute (combo_renderer->property_model(), route_cols.port_list_col);
|
||||||
column->add_attribute (combo_renderer->property_editable(), route_cols.selected);
|
column->add_attribute (combo_renderer->property_editable(), route_cols.selected);
|
||||||
|
|
||||||
combo_renderer->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &ExportChannelSelector::ChannelTreeView::update_selection_text), n_channels));
|
combo_renderer->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &PortExportChannelSelector::ChannelTreeView::update_selection_text), n_channels));
|
||||||
|
|
||||||
/* put data into view */
|
/* put data into view */
|
||||||
|
|
||||||
|
|
@ -344,7 +349,7 @@ ExportChannelSelector::ChannelTreeView::set_channel_count (uint32_t channels)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ExportChannelSelector::ChannelTreeView::update_config ()
|
PortExportChannelSelector::ChannelTreeView::update_config ()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!config) { return; }
|
if (!config) { return; }
|
||||||
|
|
@ -353,7 +358,8 @@ ExportChannelSelector::ChannelTreeView::update_config ()
|
||||||
|
|
||||||
for (uint32_t i = 1; i <= n_channels; ++i) {
|
for (uint32_t i = 1; i <= n_channels; ++i) {
|
||||||
|
|
||||||
boost::shared_ptr<ExportChannel> channel (new ExportChannel ());
|
ExportChannelPtr channel (new PortExportChannel ());
|
||||||
|
PortExportChannel * pec = static_cast<PortExportChannel *> (channel.get());
|
||||||
|
|
||||||
for (Gtk::ListStore::Children::iterator it = route_list->children().begin(); it != route_list->children().end(); ++it) {
|
for (Gtk::ListStore::Children::iterator it = route_list->children().begin(); it != route_list->children().end(); ++it) {
|
||||||
Gtk::TreeModel::Row row = *it;
|
Gtk::TreeModel::Row row = *it;
|
||||||
|
|
@ -364,7 +370,7 @@ ExportChannelSelector::ChannelTreeView::update_config ()
|
||||||
|
|
||||||
AudioPort * port = row[route_cols.get_channel (i).port];
|
AudioPort * port = row[route_cols.get_channel (i).port];
|
||||||
if (port) {
|
if (port) {
|
||||||
channel->add_port (port);
|
pec->add_port (port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -375,7 +381,7 @@ ExportChannelSelector::ChannelTreeView::update_config ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ExportChannelSelector::ChannelTreeView::update_toggle_selection (Glib::ustring const & path)
|
PortExportChannelSelector::ChannelTreeView::update_toggle_selection (Glib::ustring const & path)
|
||||||
{
|
{
|
||||||
Gtk::TreeModel::iterator iter = get_model ()->get_iter (path);
|
Gtk::TreeModel::iterator iter = get_model ()->get_iter (path);
|
||||||
bool selected = iter->get_value (route_cols.selected);
|
bool selected = iter->get_value (route_cols.selected);
|
||||||
|
|
@ -408,7 +414,7 @@ ExportChannelSelector::ChannelTreeView::update_toggle_selection (Glib::ustring c
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ExportChannelSelector::ChannelTreeView::update_selection_text (Glib::ustring const & path, Glib::ustring const & new_text, uint32_t channel)
|
PortExportChannelSelector::ChannelTreeView::update_selection_text (Glib::ustring const & path, Glib::ustring const & new_text, uint32_t channel)
|
||||||
{
|
{
|
||||||
Gtk::TreeModel::iterator iter = get_model ()->get_iter (path);
|
Gtk::TreeModel::iterator iter = get_model ()->get_iter (path);
|
||||||
iter->set_value (route_cols.get_channel (channel).label, new_text);
|
iter->set_value (route_cols.get_channel (channel).label, new_text);
|
||||||
|
|
@ -425,3 +431,66 @@ ExportChannelSelector::ChannelTreeView::update_selection_text (Glib::ustring con
|
||||||
|
|
||||||
update_config ();
|
update_config ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RegionExportChannelSelector::RegionExportChannelSelector (ARDOUR::AudioRegion const & region, ARDOUR::AudioTrack & track) :
|
||||||
|
session (0),
|
||||||
|
region (region),
|
||||||
|
track (track),
|
||||||
|
region_chans (region.n_channels()),
|
||||||
|
track_chans (track.n_outputs().n_audio()),
|
||||||
|
|
||||||
|
raw_button (type_group),
|
||||||
|
processed_button (type_group)
|
||||||
|
{
|
||||||
|
pack_start (vbox);
|
||||||
|
|
||||||
|
raw_button.set_label (string_compose (_("Raw region export, no fades or plugins (%1 channels)"), region_chans));
|
||||||
|
raw_button.signal_toggled ().connect (sigc::mem_fun (*this, &RegionExportChannelSelector::handle_selection));
|
||||||
|
vbox.pack_start (raw_button);
|
||||||
|
|
||||||
|
processed_button.set_label (string_compose (_("Processed region export with fades and plugins applied (%1 channels)"), track_chans));
|
||||||
|
processed_button.signal_toggled ().connect (sigc::mem_fun (*this, &RegionExportChannelSelector::handle_selection));
|
||||||
|
vbox.pack_start (processed_button);
|
||||||
|
|
||||||
|
vbox.show_all_children ();
|
||||||
|
show_all_children ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RegionExportChannelSelector::set_state (ARDOUR::ExportProfileManager::ChannelConfigStatePtr const state_, ARDOUR::Session * session_)
|
||||||
|
{
|
||||||
|
state = state_;
|
||||||
|
session = session_;
|
||||||
|
|
||||||
|
handle_selection ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RegionExportChannelSelector::handle_selection ()
|
||||||
|
{
|
||||||
|
if (!state) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
state->config->clear_channels ();
|
||||||
|
|
||||||
|
if (raw_button.get_active ()) {
|
||||||
|
|
||||||
|
factory.reset (new RegionExportChannelFactory (session, region, track, RegionExportChannelFactory::Raw));
|
||||||
|
|
||||||
|
for (size_t chan = 0; chan < region_chans; ++chan) {
|
||||||
|
state->config->register_channel (factory->create (chan));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (processed_button.get_active ()) {
|
||||||
|
|
||||||
|
factory.reset (new RegionExportChannelFactory(session, region, track, RegionExportChannelFactory::Processed));
|
||||||
|
|
||||||
|
for (size_t chan = 0; chan < region_chans; ++chan) {
|
||||||
|
state->config->register_channel (factory->create (chan));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CriticalSelectionChanged ();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include <ardour/export_profile_manager.h>
|
#include <ardour/export_profile_manager.h>
|
||||||
|
#include <ardour/export_channel.h>
|
||||||
|
|
||||||
#include <gtkmm.h>
|
#include <gtkmm.h>
|
||||||
#include <sigc++/signal.h>
|
#include <sigc++/signal.h>
|
||||||
|
|
@ -31,40 +32,47 @@
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
class Session;
|
class Session;
|
||||||
class ExportChannel;
|
|
||||||
class ExportChannelConfiguration;
|
class ExportChannelConfiguration;
|
||||||
|
class RegionExportChannelFactory;
|
||||||
class ExportHandler;
|
class ExportHandler;
|
||||||
class AudioPort;
|
class AudioPort;
|
||||||
class IO;
|
class IO;
|
||||||
|
class AudioRegion;
|
||||||
|
class AudioTrack;
|
||||||
}
|
}
|
||||||
|
|
||||||
class XMLNode;
|
class XMLNode;
|
||||||
|
|
||||||
///
|
class ExportChannelSelector : public Gtk::HBox
|
||||||
class ExportChannelSelector : public Gtk::HBox {
|
{
|
||||||
private:
|
protected:
|
||||||
|
|
||||||
typedef boost::shared_ptr<ARDOUR::ExportChannelConfiguration> ChannelConfigPtr;
|
typedef boost::shared_ptr<ARDOUR::ExportChannelConfiguration> ChannelConfigPtr;
|
||||||
|
|
||||||
typedef boost::shared_ptr<ARDOUR::ExportHandler> HandlerPtr;
|
typedef boost::shared_ptr<ARDOUR::ExportHandler> HandlerPtr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
virtual ~ExportChannelSelector () {}
|
||||||
|
|
||||||
ExportChannelSelector ();
|
virtual void set_state (ARDOUR::ExportProfileManager::ChannelConfigStatePtr const state_, ARDOUR::Session * session_) = 0;
|
||||||
~ExportChannelSelector ();
|
sigc::signal<void> CriticalSelectionChanged;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PortExportChannelSelector : public ExportChannelSelector
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
PortExportChannelSelector ();
|
||||||
|
~PortExportChannelSelector ();
|
||||||
|
|
||||||
void set_state (ARDOUR::ExportProfileManager::ChannelConfigStatePtr const state_, ARDOUR::Session * session_);
|
void set_state (ARDOUR::ExportProfileManager::ChannelConfigStatePtr const state_, ARDOUR::Session * session_);
|
||||||
|
|
||||||
sigc::signal<void> CriticalSelectionChanged;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void fill_route_list ();
|
void fill_route_list ();
|
||||||
void update_channel_count ();
|
void update_channel_count ();
|
||||||
void update_split_state ();
|
void update_split_state ();
|
||||||
|
|
||||||
typedef boost::shared_ptr<ARDOUR::ExportChannel> ChannelPtr;
|
typedef std::list<ARDOUR::ExportChannelPtr> CahnnelList;
|
||||||
typedef std::list<ChannelPtr> CahnnelList;
|
|
||||||
|
|
||||||
ARDOUR::Session * session;
|
ARDOUR::Session * session;
|
||||||
ARDOUR::ExportProfileManager::ChannelConfigStatePtr state;
|
ARDOUR::ExportProfileManager::ChannelConfigStatePtr state;
|
||||||
|
|
@ -178,4 +186,33 @@ class ExportChannelSelector : public Gtk::HBox {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RegionExportChannelSelector : public ExportChannelSelector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RegionExportChannelSelector (ARDOUR::AudioRegion const & region, ARDOUR::AudioTrack & track);
|
||||||
|
|
||||||
|
virtual void set_state (ARDOUR::ExportProfileManager::ChannelConfigStatePtr const state_, ARDOUR::Session * session_);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void handle_selection ();
|
||||||
|
|
||||||
|
ARDOUR::Session * session;
|
||||||
|
ARDOUR::ExportProfileManager::ChannelConfigStatePtr state;
|
||||||
|
boost::shared_ptr<ARDOUR::RegionExportChannelFactory> factory;
|
||||||
|
ARDOUR::AudioRegion const & region;
|
||||||
|
ARDOUR::AudioTrack & track;
|
||||||
|
|
||||||
|
uint32_t region_chans;
|
||||||
|
uint32_t track_chans;
|
||||||
|
|
||||||
|
/*** GUI components ***/
|
||||||
|
|
||||||
|
Gtk::VBox vbox;
|
||||||
|
|
||||||
|
Gtk::RadioButtonGroup type_group;
|
||||||
|
Gtk::RadioButton raw_button;
|
||||||
|
Gtk::RadioButton processed_button;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* __export_channel_selector_h__ */
|
#endif /* __export_channel_selector_h__ */
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,6 @@ ExportDialog::~ExportDialog ()
|
||||||
void
|
void
|
||||||
ExportDialog::set_session (ARDOUR::Session* s)
|
ExportDialog::set_session (ARDOUR::Session* s)
|
||||||
{
|
{
|
||||||
init ();
|
|
||||||
|
|
||||||
session = s;
|
session = s;
|
||||||
|
|
||||||
/* Init handler and profile manager */
|
/* Init handler and profile manager */
|
||||||
|
|
@ -55,6 +53,12 @@ ExportDialog::set_session (ARDOUR::Session* s)
|
||||||
status = session->get_export_status ();
|
status = session->get_export_status ();
|
||||||
profile_manager.reset (new ExportProfileManager (*session));
|
profile_manager.reset (new ExportProfileManager (*session));
|
||||||
|
|
||||||
|
/* Possibly init stuff in derived classes */
|
||||||
|
|
||||||
|
init ();
|
||||||
|
|
||||||
|
/* Rest of session related initialization */
|
||||||
|
|
||||||
preset_selector->set_manager (profile_manager);
|
preset_selector->set_manager (profile_manager);
|
||||||
file_notebook->set_session_and_manager (session, profile_manager);
|
file_notebook->set_session_and_manager (session, profile_manager);
|
||||||
|
|
||||||
|
|
@ -163,7 +167,7 @@ ExportDialog::init_components ()
|
||||||
{
|
{
|
||||||
preset_selector.reset (new ExportPresetSelector ());
|
preset_selector.reset (new ExportPresetSelector ());
|
||||||
timespan_selector.reset (new ExportTimespanSelectorMultiple ());
|
timespan_selector.reset (new ExportTimespanSelectorMultiple ());
|
||||||
channel_selector.reset (new ExportChannelSelector ());
|
channel_selector.reset (new PortExportChannelSelector ());
|
||||||
file_notebook.reset (new ExportFileNotebook ());
|
file_notebook.reset (new ExportFileNotebook ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -358,7 +362,7 @@ ExportRangeDialog::init_components ()
|
||||||
{
|
{
|
||||||
preset_selector.reset (new ExportPresetSelector ());
|
preset_selector.reset (new ExportPresetSelector ());
|
||||||
timespan_selector.reset (new ExportTimespanSelectorSingle (range_id));
|
timespan_selector.reset (new ExportTimespanSelectorSingle (range_id));
|
||||||
channel_selector.reset (new ExportChannelSelector ());
|
channel_selector.reset (new PortExportChannelSelector ());
|
||||||
file_notebook.reset (new ExportFileNotebook ());
|
file_notebook.reset (new ExportFileNotebook ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -371,6 +375,23 @@ ExportSelectionDialog::init_components ()
|
||||||
{
|
{
|
||||||
preset_selector.reset (new ExportPresetSelector ());
|
preset_selector.reset (new ExportPresetSelector ());
|
||||||
timespan_selector.reset (new ExportTimespanSelectorSingle (X_("selection")));
|
timespan_selector.reset (new ExportTimespanSelectorSingle (X_("selection")));
|
||||||
channel_selector.reset (new ExportChannelSelector ());
|
channel_selector.reset (new PortExportChannelSelector ());
|
||||||
|
file_notebook.reset (new ExportFileNotebook ());
|
||||||
|
}
|
||||||
|
|
||||||
|
ExportRegionDialog::ExportRegionDialog (PublicEditor & editor, ARDOUR::AudioRegion const & region, ARDOUR::AudioTrack & track) :
|
||||||
|
ExportDialog (editor, _("Export Region")),
|
||||||
|
region (region),
|
||||||
|
track (track)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExportRegionDialog::init_components ()
|
||||||
|
{
|
||||||
|
Glib::ustring loc_id = profile_manager->set_single_range (region.position(), region.position() + region.length(), region.name());
|
||||||
|
|
||||||
|
preset_selector.reset (new ExportPresetSelector ());
|
||||||
|
timespan_selector.reset (new ExportTimespanSelectorSingle (loc_id));
|
||||||
|
channel_selector.reset (new RegionExportChannelSelector (region, track));
|
||||||
file_notebook.reset (new ExportFileNotebook ());
|
file_notebook.reset (new ExportFileNotebook ());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,12 @@ class ExportDialog : public ArdourDialog {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
typedef boost::shared_ptr<ARDOUR::ExportHandler> HandlerPtr;
|
||||||
|
typedef boost::shared_ptr<ARDOUR::ExportProfileManager> ManagerPtr;
|
||||||
|
|
||||||
|
HandlerPtr handler;
|
||||||
|
ManagerPtr profile_manager;
|
||||||
|
|
||||||
// initializes GUI layout
|
// initializes GUI layout
|
||||||
virtual void init_gui ();
|
virtual void init_gui ();
|
||||||
|
|
||||||
|
|
@ -94,13 +100,9 @@ class ExportDialog : public ArdourDialog {
|
||||||
void show_progress ();
|
void show_progress ();
|
||||||
gint progress_timeout ();
|
gint progress_timeout ();
|
||||||
|
|
||||||
typedef boost::shared_ptr<ARDOUR::ExportHandler> HandlerPtr;
|
|
||||||
typedef boost::shared_ptr<ARDOUR::ExportProfileManager> ManagerPtr;
|
|
||||||
typedef boost::shared_ptr<ARDOUR::ExportStatus> StatusPtr;
|
typedef boost::shared_ptr<ARDOUR::ExportStatus> StatusPtr;
|
||||||
|
|
||||||
PublicEditor & editor;
|
PublicEditor & editor;
|
||||||
HandlerPtr handler;
|
|
||||||
ManagerPtr profile_manager;
|
|
||||||
StatusPtr status;
|
StatusPtr status;
|
||||||
|
|
||||||
/*** GUI components ***/
|
/*** GUI components ***/
|
||||||
|
|
@ -153,4 +155,16 @@ class ExportSelectionDialog : public ExportDialog
|
||||||
void init_components ();
|
void init_components ();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ExportRegionDialog : public ExportDialog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ExportRegionDialog (PublicEditor & editor, ARDOUR::AudioRegion const & region, ARDOUR::AudioTrack & track);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void init_components ();
|
||||||
|
|
||||||
|
ARDOUR::AudioRegion const & region;
|
||||||
|
ARDOUR::AudioTrack & track;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* __ardour_export_dialog_h__ */
|
#endif /* __ardour_export_dialog_h__ */
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ element_importer.cc
|
||||||
element_import_handler.cc
|
element_import_handler.cc
|
||||||
enums.cc
|
enums.cc
|
||||||
event_type_map.cc
|
event_type_map.cc
|
||||||
|
export_channel.cc
|
||||||
export_channel_configuration.cc
|
export_channel_configuration.cc
|
||||||
export_file_io.cc
|
export_file_io.cc
|
||||||
export_filename.cc
|
export_filename.cc
|
||||||
|
|
|
||||||
144
libs/ardour/ardour/export_channel.h
Normal file
144
libs/ardour/ardour/export_channel.h
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2008 Paul Davis
|
||||||
|
Author: Sakari Bergen
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ardour_export_channel_h__
|
||||||
|
#define __ardour_export_channel_h__
|
||||||
|
|
||||||
|
#include <ardour/audioregion.h>
|
||||||
|
#include <ardour/audio_track.h>
|
||||||
|
#include <ardour/buffer_set.h>
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <sigc++/signal.h>
|
||||||
|
|
||||||
|
namespace ARDOUR {
|
||||||
|
|
||||||
|
class Session;
|
||||||
|
|
||||||
|
/// Export channel base class interface for different source types
|
||||||
|
class ExportChannel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void read (Sample * data, nframes_t frames) const = 0;
|
||||||
|
virtual bool empty () const = 0;
|
||||||
|
|
||||||
|
/// Adds state to node passed
|
||||||
|
virtual void get_state (XMLNode * node) const = 0;
|
||||||
|
|
||||||
|
/// Sets state from node passed
|
||||||
|
virtual void set_state (XMLNode * node, Session & session) = 0;
|
||||||
|
|
||||||
|
// Operator< must be defined for usage in e.g. std::map or std::set to disallow duplicates when necessary
|
||||||
|
virtual bool operator< (ExportChannel const & other) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Safe pointer for storing ExportChannels in ordered STL containers
|
||||||
|
class ExportChannelPtr : public boost::shared_ptr<ExportChannel>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ExportChannelPtr () {}
|
||||||
|
template<typename Y> explicit ExportChannelPtr (Y * ptr) : boost::shared_ptr<ExportChannel> (ptr) {}
|
||||||
|
|
||||||
|
bool operator< (ExportChannelPtr const & other) const { return **this < *other; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Basic export channel that reads from AudioPorts
|
||||||
|
class PortExportChannel : public ExportChannel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::set<AudioPort *> PortSet;
|
||||||
|
|
||||||
|
PortExportChannel () {}
|
||||||
|
|
||||||
|
virtual void read (Sample * data, nframes_t frames) const;
|
||||||
|
virtual bool empty () const { return ports.empty(); }
|
||||||
|
|
||||||
|
virtual void get_state (XMLNode * node) const;
|
||||||
|
virtual void set_state (XMLNode * node, Session & session);
|
||||||
|
|
||||||
|
virtual bool operator< (ExportChannel const & other) const;
|
||||||
|
|
||||||
|
void add_port (AudioPort * port) { ports.insert (port); }
|
||||||
|
PortSet const & get_ports () { return ports; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
PortSet ports;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Handles RegionExportChannels and does actual reading from region
|
||||||
|
class RegionExportChannelFactory : public sigc::trackable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
Raw,
|
||||||
|
Processed
|
||||||
|
};
|
||||||
|
|
||||||
|
RegionExportChannelFactory (Session * session, AudioRegion const & region, AudioTrack & track, Type type);
|
||||||
|
|
||||||
|
ExportChannelPtr create (uint32_t channel);
|
||||||
|
void read (uint32_t channel, Sample * data, nframes_t frames_to_read);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int new_cycle_started () { buffers_up_to_date = false; return 0; }
|
||||||
|
void update_buffers (nframes_t frames);
|
||||||
|
|
||||||
|
AudioRegion const & region;
|
||||||
|
AudioTrack & track;
|
||||||
|
Type type;
|
||||||
|
|
||||||
|
nframes_t frames_per_cycle;
|
||||||
|
size_t n_channels;
|
||||||
|
BufferSet buffers;
|
||||||
|
bool buffers_up_to_date;
|
||||||
|
nframes_t region_start;
|
||||||
|
nframes_t position;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Export channel that reads from region channel
|
||||||
|
class RegionExportChannel : public ExportChannel
|
||||||
|
{
|
||||||
|
friend class RegionExportChannelFactory;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void read (Sample * data, nframes_t frames_to_read) const { factory.read (channel, data, frames_to_read); }
|
||||||
|
virtual void get_state (XMLNode * node) const {};
|
||||||
|
virtual void set_state (XMLNode * node, Session & session) {};
|
||||||
|
virtual bool empty () const { return false; }
|
||||||
|
// Region export should never have duplicate channels, so there need not be any semantics here
|
||||||
|
virtual bool operator< (ExportChannel const & other) const { return this < &other; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
RegionExportChannel (RegionExportChannelFactory & factory, uint32_t channel) :
|
||||||
|
factory (factory),
|
||||||
|
channel (channel)
|
||||||
|
{}
|
||||||
|
|
||||||
|
RegionExportChannelFactory & factory;
|
||||||
|
uint32_t channel;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ARDOUR
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -21,12 +21,12 @@
|
||||||
#ifndef __ardour_export_channel_configuration_h__
|
#ifndef __ardour_export_channel_configuration_h__
|
||||||
#define __ardour_export_channel_configuration_h__
|
#define __ardour_export_channel_configuration_h__
|
||||||
|
|
||||||
#include <set>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include <glibmm/ustring.h>
|
#include <glibmm/ustring.h>
|
||||||
#include <sigc++/signal.h>
|
#include <sigc++/signal.h>
|
||||||
|
|
||||||
|
#include <ardour/export_channel.h>
|
||||||
#include <ardour/export_status.h>
|
#include <ardour/export_status.h>
|
||||||
#include <ardour/ardour.h>
|
#include <ardour/ardour.h>
|
||||||
|
|
||||||
|
|
@ -46,13 +46,6 @@ class ExportProcessor;
|
||||||
class ExportTimespan;
|
class ExportTimespan;
|
||||||
class Session;
|
class Session;
|
||||||
|
|
||||||
class ExportChannel : public std::set<AudioPort *>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void add_port (AudioPort * port) { if (port) { insert (port); } }
|
|
||||||
void read_ports (float * data, nframes_t frames) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ExportChannelConfiguration
|
class ExportChannelConfiguration
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
@ -86,20 +79,19 @@ class ExportChannelConfiguration
|
||||||
XMLNode & get_state ();
|
XMLNode & get_state ();
|
||||||
int set_state (const XMLNode &);
|
int set_state (const XMLNode &);
|
||||||
|
|
||||||
typedef boost::shared_ptr<ExportChannel const> ChannelPtr;
|
typedef std::list<ExportChannelPtr> ChannelList;
|
||||||
typedef std::list<ChannelPtr> ChannelList;
|
|
||||||
|
|
||||||
ChannelList const & get_channels () { return channels; }
|
ChannelList const & get_channels () const { return channels; }
|
||||||
bool all_channels_have_ports ();
|
bool all_channels_have_ports () const;
|
||||||
|
|
||||||
ustring name () const { return _name; }
|
ustring name () const { return _name; }
|
||||||
void set_name (ustring name) { _name = name; }
|
void set_name (ustring name) { _name = name; }
|
||||||
void set_split (bool value) { split = value; }
|
void set_split (bool value) { split = value; }
|
||||||
|
|
||||||
bool get_split () { return split; }
|
bool get_split () const { return split; }
|
||||||
uint32_t get_n_chans () { return channels.size(); }
|
uint32_t get_n_chans () const { return channels.size(); }
|
||||||
|
|
||||||
void register_channel (ChannelPtr channel) { channels.push_back (channel); }
|
void register_channel (ExportChannelPtr channel) { channels.push_back (channel); }
|
||||||
void register_file_config (FormatPtr format, FilenamePtr filename) { file_configs.push_back (FileConfig (format, filename)); }
|
void register_file_config (FormatPtr format, FilenamePtr filename) { file_configs.push_back (FileConfig (format, filename)); }
|
||||||
|
|
||||||
void clear_channels () { channels.clear (); }
|
void clear_channels () { channels.clear (); }
|
||||||
|
|
|
||||||
|
|
@ -144,6 +144,7 @@ class ExportProfileManager
|
||||||
typedef std::list<TimespanStatePtr> TimespanStateList;
|
typedef std::list<TimespanStatePtr> TimespanStateList;
|
||||||
|
|
||||||
void set_selection_range (nframes_t start = 0, nframes_t end = 0);
|
void set_selection_range (nframes_t start = 0, nframes_t end = 0);
|
||||||
|
std::string set_single_range (nframes_t start, nframes_t end, Glib::ustring name);
|
||||||
TimespanStateList const & get_timespans () { return check_list (timespans); }
|
TimespanStateList const & get_timespans () { return check_list (timespans); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -163,6 +164,9 @@ class ExportProfileManager
|
||||||
boost::shared_ptr<Location> selection_range;
|
boost::shared_ptr<Location> selection_range;
|
||||||
boost::shared_ptr<LocationList> ranges;
|
boost::shared_ptr<LocationList> ranges;
|
||||||
|
|
||||||
|
bool single_range_mode;
|
||||||
|
boost::shared_ptr<Location> single_range;
|
||||||
|
|
||||||
/* Channel Configs */
|
/* Channel Configs */
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
#include <glibmm/ustring.h>
|
#include <glibmm/ustring.h>
|
||||||
|
|
||||||
#include <ardour/export_status.h>
|
#include <ardour/export_status.h>
|
||||||
|
#include <ardour/export_channel.h>
|
||||||
#include <ardour/ardour.h>
|
#include <ardour/ardour.h>
|
||||||
|
|
||||||
using Glib::ustring;
|
using Glib::ustring;
|
||||||
|
|
@ -41,8 +42,8 @@ class ExportTimespan : public sigc::trackable
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef boost::shared_ptr<ExportTempFile> TempFilePtr;
|
typedef boost::shared_ptr<ExportTempFile> TempFilePtr;
|
||||||
typedef std::pair<ExportChannel const, TempFilePtr> ChannelFilePair;
|
typedef std::pair<ExportChannelPtr, TempFilePtr> ChannelFilePair;
|
||||||
typedef std::map<ExportChannel const, TempFilePtr> TempFileMap;
|
typedef std::map<ExportChannelPtr, TempFilePtr> TempFileMap;
|
||||||
typedef boost::shared_ptr<ExportStatus> ExportStatusPtr;
|
typedef boost::shared_ptr<ExportStatus> ExportStatusPtr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -59,13 +60,13 @@ class ExportTimespan : public sigc::trackable
|
||||||
void set_range_id (ustring range_id) { _range_id = range_id; }
|
void set_range_id (ustring range_id) { _range_id = range_id; }
|
||||||
|
|
||||||
/// Registers a channel to be read when export starts rolling
|
/// Registers a channel to be read when export starts rolling
|
||||||
void register_channel (ExportChannel const & channel);
|
void register_channel (ExportChannelPtr channel);
|
||||||
|
|
||||||
/// "Rewinds" the tempfiles to start reading the beginnings again
|
/// "Rewinds" the tempfiles to start reading the beginnings again
|
||||||
void rewind ();
|
void rewind ();
|
||||||
|
|
||||||
/// Reads data from the tempfile belonging to channel into data
|
/// Reads data from the tempfile belonging to channel into data
|
||||||
nframes_t get_data (float * data, nframes_t frames, ExportChannel const & channel);
|
nframes_t get_data (float * data, nframes_t frames, ExportChannelPtr channel);
|
||||||
|
|
||||||
/// Reads data from each channel and writes to tempfile
|
/// Reads data from each channel and writes to tempfile
|
||||||
int process (nframes_t frames);
|
int process (nframes_t frames);
|
||||||
|
|
|
||||||
142
libs/ardour/export_channel.cc
Normal file
142
libs/ardour/export_channel.cc
Normal file
|
|
@ -0,0 +1,142 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2008 Paul Davis
|
||||||
|
Author: Sakari Bergen
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ardour/export_channel.h>
|
||||||
|
|
||||||
|
#include <ardour/export_failed.h>
|
||||||
|
#include <ardour/audioengine.h>
|
||||||
|
|
||||||
|
using namespace ARDOUR;
|
||||||
|
|
||||||
|
bool
|
||||||
|
PortExportChannel::operator< (ExportChannel const & other) const
|
||||||
|
{
|
||||||
|
PortExportChannel const * pec;
|
||||||
|
if (!(pec = dynamic_cast<PortExportChannel const *> (&other))) {
|
||||||
|
return this < &other;
|
||||||
|
}
|
||||||
|
return ports < pec->ports;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PortExportChannel::read (Sample * data, nframes_t frames) const
|
||||||
|
{
|
||||||
|
memset (data, 0, frames * sizeof (float));
|
||||||
|
|
||||||
|
for (PortSet::const_iterator it = ports.begin(); it != ports.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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PortExportChannel::get_state (XMLNode * node) const
|
||||||
|
{
|
||||||
|
XMLNode * port_node;
|
||||||
|
for (PortSet::const_iterator it = ports.begin(); it != ports.end(); ++it) {
|
||||||
|
if ((port_node = node->add_child ("Port"))) {
|
||||||
|
port_node->add_property ("name", (*it)->name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PortExportChannel::set_state (XMLNode * node, Session & session)
|
||||||
|
{
|
||||||
|
XMLProperty * prop;
|
||||||
|
XMLNodeList xml_ports = node->children ("Port");
|
||||||
|
for (XMLNodeList::iterator it = xml_ports.begin(); it != xml_ports.end(); ++it) {
|
||||||
|
if ((prop = (*it)->property ("name"))) {
|
||||||
|
ports.insert (dynamic_cast<AudioPort *> (session.engine().get_port_by_name (prop->value())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionExportChannelFactory::RegionExportChannelFactory (Session * session, AudioRegion const & region, AudioTrack & track, Type type) :
|
||||||
|
region (region),
|
||||||
|
track (track),
|
||||||
|
type (type),
|
||||||
|
frames_per_cycle (session->engine().frames_per_cycle ()),
|
||||||
|
buffers_up_to_date (false),
|
||||||
|
region_start (region.position()),
|
||||||
|
position (region_start)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case Raw:
|
||||||
|
n_channels = region.n_channels();
|
||||||
|
break;
|
||||||
|
case Processed:
|
||||||
|
n_channels = track.n_outputs().n_audio();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw ExportFailed ("Unhandled type in ExportChannelFactory constructor");
|
||||||
|
}
|
||||||
|
|
||||||
|
session->ProcessExport.connect (sigc::hide (sigc::mem_fun (*this, &RegionExportChannelFactory::new_cycle_started)));
|
||||||
|
|
||||||
|
buffers.set_count (ChanCount (DataType::AUDIO, n_channels));
|
||||||
|
buffers.ensure_buffers (DataType::AUDIO, n_channels, frames_per_cycle);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExportChannelPtr
|
||||||
|
RegionExportChannelFactory::create (uint32_t channel)
|
||||||
|
{
|
||||||
|
assert (channel < n_channels);
|
||||||
|
return ExportChannelPtr (new RegionExportChannel (*this, channel));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RegionExportChannelFactory::read (uint32_t channel, Sample * data, nframes_t frames_to_read)
|
||||||
|
{
|
||||||
|
assert (channel < n_channels);
|
||||||
|
assert (frames_to_read <= frames_per_cycle);
|
||||||
|
|
||||||
|
if (!buffers_up_to_date) {
|
||||||
|
update_buffers(frames_to_read);
|
||||||
|
buffers_up_to_date = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (data, buffers.get_audio (channel).data(), frames_to_read * sizeof (Sample));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RegionExportChannelFactory::update_buffers (nframes_t frames)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case Raw:
|
||||||
|
for (size_t channel = 0; channel < n_channels; ++channel) {
|
||||||
|
region.read (buffers.get_audio (channel).data(), position - region_start, frames, channel);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Processed:
|
||||||
|
std::cout << "exporting " << frames << " frames from position " << position << std::endl;
|
||||||
|
track.export_stuff (buffers, position, frames);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw ExportFailed ("Unhandled type in ExportChannelFactory::update_buffers");
|
||||||
|
}
|
||||||
|
|
||||||
|
position += frames;
|
||||||
|
}
|
||||||
|
|
@ -37,24 +37,6 @@
|
||||||
namespace ARDOUR
|
namespace ARDOUR
|
||||||
{
|
{
|
||||||
|
|
||||||
/* ExportChannel */
|
|
||||||
|
|
||||||
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( frames, 0).data();
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < frames; ++i) {
|
|
||||||
data[i] += (float) port_buffer[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ExportChannelConfiguration */
|
/* ExportChannelConfiguration */
|
||||||
|
|
||||||
ExportChannelConfiguration::ExportChannelConfiguration (Session & session) :
|
ExportChannelConfiguration::ExportChannelConfiguration (Session & session) :
|
||||||
|
|
@ -73,7 +55,6 @@ ExportChannelConfiguration::get_state ()
|
||||||
{
|
{
|
||||||
XMLNode * root = new XMLNode ("ExportChannelConfiguration");
|
XMLNode * root = new XMLNode ("ExportChannelConfiguration");
|
||||||
XMLNode * channel;
|
XMLNode * channel;
|
||||||
XMLNode * port_node;
|
|
||||||
|
|
||||||
root->add_property ("split", get_split() ? "true" : "false");
|
root->add_property ("split", get_split() ? "true" : "false");
|
||||||
root->add_property ("channels", to_string (get_n_chans(), std::dec));
|
root->add_property ("channels", to_string (get_n_chans(), std::dec));
|
||||||
|
|
@ -84,12 +65,7 @@ ExportChannelConfiguration::get_state ()
|
||||||
if (!channel) { continue; }
|
if (!channel) { continue; }
|
||||||
|
|
||||||
channel->add_property ("number", to_string (i, std::dec));
|
channel->add_property ("number", to_string (i, std::dec));
|
||||||
|
(*c_it)->get_state (channel);
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
@ -108,15 +84,8 @@ ExportChannelConfiguration::set_state (const XMLNode & root)
|
||||||
|
|
||||||
XMLNodeList channels = root.children ("Channel");
|
XMLNodeList channels = root.children ("Channel");
|
||||||
for (XMLNodeList::iterator it = channels.begin(); it != channels.end(); ++it) {
|
for (XMLNodeList::iterator it = channels.begin(); it != channels.end(); ++it) {
|
||||||
boost::shared_ptr<ExportChannel> channel (new ExportChannel ());
|
ExportChannelPtr channel (new PortExportChannel ());
|
||||||
|
channel->set_state (*it, session);
|
||||||
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<AudioPort *> (session.engine().get_port_by_name (prop->value())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register_channel (channel);
|
register_channel (channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,9 +93,9 @@ ExportChannelConfiguration::set_state (const XMLNode & root)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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; }
|
if ((*it)->empty ()) { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -182,7 +151,7 @@ ExportChannelConfiguration::write_file ()
|
||||||
|
|
||||||
/* Get channel data */
|
/* 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 */
|
/* Interleave into file buffer */
|
||||||
|
|
||||||
|
|
@ -238,7 +207,7 @@ ExportChannelConfiguration::register_with_timespan (TimespanPtr new_timespan)
|
||||||
timespan = new_timespan;
|
timespan = new_timespan;
|
||||||
|
|
||||||
for (ChannelList::iterator it = channels.begin(); it != channels.end(); ++it) {
|
for (ChannelList::iterator it = channels.begin(); it != channels.end(); ++it) {
|
||||||
timespan->register_channel (**it);
|
timespan->register_channel (*it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ ExportProfileManager::ExportProfileManager (Session & s) :
|
||||||
|
|
||||||
session_range (new Location ()),
|
session_range (new Location ()),
|
||||||
ranges (new LocationList ()),
|
ranges (new LocationList ()),
|
||||||
|
single_range_mode (false),
|
||||||
|
|
||||||
format_list (new FormatList ())
|
format_list (new FormatList ())
|
||||||
{
|
{
|
||||||
|
|
@ -299,6 +300,20 @@ ExportProfileManager::set_selection_range (nframes_t start, nframes_t end)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
ExportProfileManager::set_single_range (nframes_t start, nframes_t end, Glib::ustring name)
|
||||||
|
{
|
||||||
|
single_range_mode = true;
|
||||||
|
|
||||||
|
single_range.reset (new Location());
|
||||||
|
single_range->set_name (name);
|
||||||
|
single_range->set (start, end);
|
||||||
|
|
||||||
|
update_ranges ();
|
||||||
|
|
||||||
|
return single_range->id().to_s();
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ExportProfileManager::init_timespans (XMLNodeList nodes)
|
ExportProfileManager::init_timespans (XMLNodeList nodes)
|
||||||
{
|
{
|
||||||
|
|
@ -378,6 +393,11 @@ void
|
||||||
ExportProfileManager::update_ranges () {
|
ExportProfileManager::update_ranges () {
|
||||||
ranges->clear();
|
ranges->clear();
|
||||||
|
|
||||||
|
if (single_range_mode) {
|
||||||
|
ranges->push_back (single_range.get());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Session */
|
/* Session */
|
||||||
|
|
||||||
session_range->set_name (_("Session"));
|
session_range->set_name (_("Session"));
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ ExportTimespan::~ExportTimespan ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ExportTimespan::register_channel (ExportChannel const & channel)
|
ExportTimespan::register_channel (ExportChannelPtr channel)
|
||||||
{
|
{
|
||||||
TempFilePtr ptr (new ExportTempFile (1, frame_rate));
|
TempFilePtr ptr (new ExportTempFile (1, frame_rate));
|
||||||
ChannelFilePair pair (channel, ptr);
|
ChannelFilePair pair (channel, ptr);
|
||||||
|
|
@ -58,7 +58,7 @@ ExportTimespan::rewind ()
|
||||||
}
|
}
|
||||||
|
|
||||||
nframes_t
|
nframes_t
|
||||||
ExportTimespan::get_data (float * data, nframes_t frames, ExportChannel const & channel)
|
ExportTimespan::get_data (float * data, nframes_t frames, ExportChannelPtr channel)
|
||||||
{
|
{
|
||||||
TempFileMap::iterator it = filemap.find (channel);
|
TempFileMap::iterator it = filemap.find (channel);
|
||||||
if (it == filemap.end()) {
|
if (it == filemap.end()) {
|
||||||
|
|
@ -100,7 +100,7 @@ ExportTimespan::process (nframes_t frames)
|
||||||
float * data = new float[frames_to_read];
|
float * data = new float[frames_to_read];
|
||||||
|
|
||||||
for (TempFileMap::iterator it = filemap.begin(); it != filemap.end(); ++it) {
|
for (TempFileMap::iterator it = filemap.begin(); it != filemap.end(); ++it) {
|
||||||
it->first.read_ports (data, frames_to_read);
|
it->first->read (data, frames_to_read);
|
||||||
it->second->write (data, frames_to_read);
|
it->second->write (data, frames_to_read);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue