summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2007-09-02 15:17:13 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2007-09-02 15:17:13 +0000
commitf2a2e9c00281c9bfe5ff7df31cdc8860129b282c (patch)
treee45988a790da04e1e72e917d2b0f7935526fe8a2
parent6c2728f9815bcdbf1cbd702f271344e295ddb074 (diff)
limited history depth (no GUI yet); more work on import dialog and semantics
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2361 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/audio_streamview.cc6
-rw-r--r--gtk2_ardour/editing_syms.h7
-rw-r--r--gtk2_ardour/editor.h17
-rw-r--r--gtk2_ardour/editor_audio_import.cc132
-rw-r--r--gtk2_ardour/editor_canvas.cc5
-rw-r--r--gtk2_ardour/editor_region_list.cc2
-rw-r--r--gtk2_ardour/mixer_strip.cc4
-rw-r--r--gtk2_ardour/mixer_ui.cc2
-rw-r--r--gtk2_ardour/playlist_selector.cc2
-rw-r--r--gtk2_ardour/route_time_axis.cc2
-rw-r--r--gtk2_ardour/route_time_axis.h2
-rw-r--r--gtk2_ardour/route_ui.cc12
-rw-r--r--gtk2_ardour/route_ui.h9
-rw-r--r--gtk2_ardour/sfdb_ui.cc256
-rw-r--r--gtk2_ardour/sfdb_ui.h17
-rw-r--r--gtk2_ardour/streamview.cc4
-rw-r--r--libs/ardour/ardour/configuration_vars.h3
-rw-r--r--libs/ardour/ardour/session.h1
-rw-r--r--libs/ardour/session_state.cc14
-rw-r--r--libs/pbd/pbd/undo.h10
-rw-r--r--libs/pbd/undo.cc16
21 files changed, 349 insertions, 174 deletions
diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc
index d80207fad9..abfecce046 100644
--- a/gtk2_ardour/audio_streamview.cc
+++ b/gtk2_ardour/audio_streamview.cc
@@ -513,16 +513,14 @@ AudioStreamView::setup_rec_box ()
/* start a new rec box */
- AudioTrack* at;
-
- at = _trackview.audio_track(); /* we know what it is already */
+ boost::shared_ptr<AudioTrack> at = _trackview.audio_track ();
boost::shared_ptr<AudioDiskstream> ds = at->audio_diskstream();
nframes_t frame_pos = ds->current_capture_start ();
gdouble xstart = _trackview.editor.frame_to_pixel (frame_pos);
gdouble xend;
uint32_t fill_color;
- switch (_trackview.audio_track()->mode()) {
+ switch (at->mode()) {
case Normal:
xend = xstart;
fill_color = ARDOUR_UI::config()->canvasvar_RecordingRect.get();
diff --git a/gtk2_ardour/editing_syms.h b/gtk2_ardour/editing_syms.h
index 8971f79995..116588a1ce 100644
--- a/gtk2_ardour/editing_syms.h
+++ b/gtk2_ardour/editing_syms.h
@@ -86,7 +86,8 @@ IMPORTPOSITION(ImportAtPlayhead=2)
IMPORTPOSITION(ImportAtStart=3)
// if this is changed, remember to update the string table in sfdb_ui.cc
-IMPORTCHANNEL(ImportThingPerFile=0)
-IMPORTCHANNEL(ImportThingPerChannel=1)
-IMPORTCHANNEL(ImportThingForAll=2)
+IMPORTCHANNEL(ImportDistinctFiles=0)
+IMPORTCHANNEL(ImportMergeFiles=1)
+IMPORTCHANNEL(ImportSerializeFiles=2)
+IMPORTCHANNEL(ImportDistinctChannels=3)
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 715ca04b41..c79bb317b0 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -965,17 +965,18 @@ class Editor : public PublicEditor
void external_audio_dialog ();
bool check_multichannel_status (const std::vector<Glib::ustring>& paths);
- void bring_in_external_audio (Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes64_t& pos);
- void do_import (vector<Glib::ustring> paths, Editing::ImportChannel, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes64_t&);
+ void bring_in_external_audio (Editing::ImportMode mode, nframes64_t& pos);
+ void do_import (vector<Glib::ustring> paths, Editing::ImportChannel, Editing::ImportMode mode, nframes64_t&);
- void _do_embed (vector<Glib::ustring> paths, Editing::ImportChannel, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes64_t&);
- void do_embed (vector<Glib::ustring> paths, Editing::ImportChannel, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes64_t&);
- bool idle_do_embed (vector<Glib::ustring> paths, Editing::ImportChannel, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes64_t&);
+ void _do_embed (vector<Glib::ustring> paths, Editing::ImportChannel, Editing::ImportMode mode, nframes64_t&);
+ void do_embed (vector<Glib::ustring> paths, Editing::ImportChannel, Editing::ImportMode mode, nframes64_t&);
+ bool idle_do_embed (vector<Glib::ustring> paths, Editing::ImportChannel, Editing::ImportMode mode, nframes64_t&);
- int import_sndfile (vector<Glib::ustring> paths, Editing::ImportMode mode, ARDOUR::AudioTrack* track, nframes64_t& pos);
+ int import_sndfile (vector<Glib::ustring> paths, Editing::ImportMode mode, nframes64_t& pos);
int embed_sndfile (vector<Glib::ustring> paths, Editing::ImportChannel, bool multiple_files, bool& check_sample_rate, Editing::ImportMode mode,
- ARDOUR::AudioTrack* track, nframes64_t& pos);
- int finish_bringing_in_audio (boost::shared_ptr<ARDOUR::AudioRegion> region, uint32_t, uint32_t, ARDOUR::AudioTrack* track, nframes64_t& pos, Editing::ImportMode mode);
+ nframes64_t& pos);
+ int finish_bringing_in_audio (boost::shared_ptr<ARDOUR::AudioRegion> region, uint32_t, uint32_t, nframes64_t& pos, Editing::ImportMode mode,
+ boost::shared_ptr<ARDOUR::AudioTrack>& existing_track, int nth);
/* generic interthread progress window */
diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc
index 0f05b27449..d2bbfa1113 100644
--- a/gtk2_ardour/editor_audio_import.cc
+++ b/gtk2_ardour/editor_audio_import.cc
@@ -97,14 +97,6 @@ Editor::external_audio_dialog ()
/* lets do it */
- AudioTrack* track = 0;
-
- if (!selection->tracks.empty()) {
- AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(selection->tracks.front());
- if (atv) {
- track = atv->audio_track();
- }
- }
paths = browser.get_paths ();
ImportPosition pos = browser.get_position ();
@@ -128,24 +120,24 @@ Editor::external_audio_dialog ()
}
if (browser.import.get_active()) {
- do_import (paths, chns, mode, track, where);
+ do_import (paths, chns, mode, where);
} else {
- do_embed (paths, chns, mode, track, where);
+ do_embed (paths, chns, mode, where);
}
}
void
-Editor::do_import (vector<ustring> paths, ImportChannel chns, ImportMode mode, AudioTrack* track, nframes64_t& pos)
+Editor::do_import (vector<ustring> paths, ImportChannel chns, ImportMode mode, nframes64_t& pos)
{
switch (chns) {
- case Editing::ImportThingPerFile:
- case Editing::ImportThingForAll:
- import_status.multichan = true;
+ case Editing::ImportDistinctChannels:
+ import_status.multichan = false;
break;
- case Editing::ImportThingPerChannel:
- import_status.multichan = false;
+ default:
+ import_status.multichan = true;
break;
+
}
if (interthread_progress_window == 0) {
@@ -159,31 +151,31 @@ Editor::do_import (vector<ustring> paths, ImportChannel chns, ImportMode mode, A
to_import.clear ();
to_import.push_back (*a);
- import_sndfile (to_import, mode, track, pos);
+ import_sndfile (to_import, mode, pos);
}
interthread_progress_window->hide_all ();
}
bool
-Editor::idle_do_embed (vector<ustring> paths, ImportChannel chns, ImportMode mode, AudioTrack* track, nframes64_t& pos)
+Editor::idle_do_embed (vector<ustring> paths, ImportChannel chns, ImportMode mode, nframes64_t& pos)
{
- _do_embed (paths, chns, mode, track, pos);
+ _do_embed (paths, chns, mode, pos);
return false;
}
void
-Editor::do_embed (vector<ustring> paths, ImportChannel chns, ImportMode mode, AudioTrack* track, nframes64_t& pos)
+Editor::do_embed (vector<ustring> paths, ImportChannel chns, ImportMode mode, nframes64_t& pos)
{
#ifdef GTKOSX
- Glib::signal_idle().connect (bind (mem_fun (*this, &Editor::idle_do_embed), paths, chns, mode, track, pos));
+ Glib::signal_idle().connect (bind (mem_fun (*this, &Editor::idle_do_embed), paths, chns, mode, pos));
#else
- _do_embed (paths, chns, mode, track, pos);
+ _do_embed (paths, chns, mode, pos);
#endif
}
void
-Editor::_do_embed (vector<ustring> paths, ImportChannel chns, ImportMode mode, AudioTrack* track, nframes64_t& pos)
+Editor::_do_embed (vector<ustring> paths, ImportChannel chns, ImportMode mode, nframes64_t& pos)
{
bool multiple_files = paths.size() > 1;
bool check_sample_rate = true;
@@ -192,21 +184,22 @@ Editor::_do_embed (vector<ustring> paths, ImportChannel chns, ImportMode mode, A
switch (chns) {
- case Editing::ImportThingPerFile:
- case Editing::ImportThingPerChannel:
+ case Editing::ImportDistinctFiles:
+ case Editing::ImportDistinctChannels:
for (vector<ustring>::iterator a = paths.begin(); a != paths.end(); ++a) {
to_embed.clear ();
to_embed.push_back (*a);
- if (embed_sndfile (to_embed, chns, multiple_files, check_sample_rate, mode, track, pos) < -1) {
+ if (embed_sndfile (to_embed, chns, multiple_files, check_sample_rate, mode, pos) < -1) {
goto out;
}
}
break;
- case Editing::ImportThingForAll:
- if (embed_sndfile (paths, chns, multiple_files, check_sample_rate, mode, track, pos) < -1) {
+ case Editing::ImportSerializeFiles:
+ case Editing::ImportMergeFiles:
+ if (embed_sndfile (paths, chns, multiple_files, check_sample_rate, mode, pos) < -1) {
goto out;
}
break;
@@ -221,7 +214,7 @@ Editor::_do_embed (vector<ustring> paths, ImportChannel chns, ImportMode mode, A
}
int
-Editor::import_sndfile (vector<ustring> paths, ImportMode mode, AudioTrack* track, nframes64_t& pos)
+Editor::import_sndfile (vector<ustring> paths, ImportMode mode, nframes64_t& pos)
{
WindowTitle title = string_compose (_("importing %1"), paths.front());
@@ -261,10 +254,12 @@ Editor::import_sndfile (vector<ustring> paths, ImportMode mode, AudioTrack* trac
interthread_progress_connection.disconnect ();
/* import thread finished - see if we should build a new track */
+
+ boost::shared_ptr<AudioTrack> track;
if (!import_status.new_regions.empty()) {
boost::shared_ptr<AudioRegion> region (import_status.new_regions.front());
- finish_bringing_in_audio (region, region->n_channels(), region->n_channels(), track, pos, mode);
+ finish_bringing_in_audio (region, region->n_channels(), region->n_channels(), pos, mode, track, 0);
}
track_canvas.get_window()->set_cursor (*current_canvas_cursor);
@@ -272,9 +267,9 @@ Editor::import_sndfile (vector<ustring> paths, ImportMode mode, AudioTrack* trac
}
int
-Editor::embed_sndfile (vector<Glib::ustring> paths, Editing::ImportChannel chns, bool multiple_files, bool& check_sample_rate, ImportMode mode,
- AudioTrack* track, nframes64_t& pos)
+Editor::embed_sndfile (vector<Glib::ustring> paths, Editing::ImportChannel chns, bool multiple_files, bool& check_sample_rate, ImportMode mode, nframes64_t& pos)
{
+ boost::shared_ptr<AudioTrack> track;
boost::shared_ptr<AudioFileSource> source;
SourceList sources;
boost::shared_ptr<AudioRegion> region;
@@ -437,7 +432,7 @@ Editor::embed_sndfile (vector<Glib::ustring> paths, Editing::ImportChannel chns,
}
}
- if (chns == Editing::ImportThingPerFile || chns == Editing::ImportThingForAll) {
+ if (chns == Editing::ImportMergeFiles) {
/* take all the sources we have and package them up as a region */
@@ -452,9 +447,9 @@ Editor::embed_sndfile (vector<Glib::ustring> paths, Editing::ImportChannel chns,
output_chan = input_chan;
}
- finish_bringing_in_audio (region, input_chan, output_chan, track, pos, mode);
+ finish_bringing_in_audio (region, input_chan, output_chan, pos, mode, track, 0);
- } else {
+ } else { // SerializeFiles, DistinctFiles, DistinctChannels
/* take each source and create a region for each one */
@@ -462,8 +457,9 @@ Editor::embed_sndfile (vector<Glib::ustring> paths, Editing::ImportChannel chns,
SourceList::iterator x;
vector<Glib::ustring>::iterator p = paths.begin();
vector<Glib::ustring>::iterator next_path;
-
- for (x = sources.begin(); x != sources.end(); ++x) {
+ int nth;
+
+ for (nth = 0, x = sources.begin(); x != sources.end(); ++x, ++nth) {
just_one.clear ();
just_one.push_back (*x);
@@ -479,7 +475,16 @@ Editor::embed_sndfile (vector<Glib::ustring> paths, Editing::ImportChannel chns,
output_chan = input_chan;
}
- finish_bringing_in_audio (region, 1, output_chan, track, pos, mode);
+ finish_bringing_in_audio (region, 1, output_chan, pos, mode, track, nth);
+
+ if (chns == ImportSerializeFiles) {
+ pos += region->length();
+ }
+
+ if (chns == ImportDistinctChannels || chns == ImportDistinctFiles) {
+ /* make a new track for the next region */
+ track.reset ();
+ }
/* don't run out of paths */
@@ -499,39 +504,56 @@ Editor::embed_sndfile (vector<Glib::ustring> paths, Editing::ImportChannel chns,
}
int
-Editor::finish_bringing_in_audio (boost::shared_ptr<AudioRegion> region, uint32_t in_chans, uint32_t out_chans, AudioTrack* track, nframes64_t& pos, ImportMode mode)
+Editor::finish_bringing_in_audio (boost::shared_ptr<AudioRegion> region, uint32_t in_chans, uint32_t out_chans, nframes64_t& pos,
+ ImportMode mode, boost::shared_ptr<AudioTrack>& existing_track, int nth)
{
+ boost::shared_ptr<AudioTrack> track;
+
switch (mode) {
case ImportAsRegion:
/* relax, its been done */
break;
case ImportToTrack:
- if (track) {
- boost::shared_ptr<Playlist> playlist = track->diskstream()->playlist();
-
- boost::shared_ptr<AudioRegion> copy (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region)));
- begin_reversible_command (_("insert sndfile"));
- XMLNode &before = playlist->get_state();
- playlist->add_region (copy, pos);
- session->add_command (new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
- commit_reversible_command ();
+ {
+ if (selection->tracks.empty()) {
+ return -1;
+ }
- pos += region->length();
+ AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(selection->tracks.front());
+
+ if (!atv) {
+ return -1;
}
- break;
+
+ track = atv->audio_track();
+ boost::shared_ptr<Playlist> playlist = track->diskstream()->playlist();
+ boost::shared_ptr<AudioRegion> copy (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region)));
+ begin_reversible_command (_("insert sndfile"));
+ XMLNode &before = playlist->get_state();
+ playlist->add_region (copy, pos);
+ session->add_command (new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
+ commit_reversible_command ();
+ break;
+ }
+
case ImportAsTrack:
{
- list<boost::shared_ptr<AudioTrack> > at (session->new_audio_track (in_chans, out_chans, Normal, 1));
- if (!at.empty()) {
- boost::shared_ptr<AudioRegion> copy (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region)));
- at.front()->set_name (basename_nosuffix (copy->name()), this);
- at.front()->diskstream()->playlist()->add_region (copy, pos);
+ if (!existing_track) {
+ list<boost::shared_ptr<AudioTrack> > at (session->new_audio_track (in_chans, out_chans, Normal, 1));
+ if (at.empty()) {
+ return -1;
+ }
+ existing_track = at.front();
+ existing_track->set_name (basename_nosuffix (region->name()), this);
}
+ boost::shared_ptr<AudioRegion> copy (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region)));
+ existing_track->diskstream()->playlist()->add_region (copy, pos);
break;
}
+
case ImportAsTapeTrack:
{
list<boost::shared_ptr<AudioTrack> > at (session->new_audio_track (in_chans, out_chans, Destructive));
diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc
index 0e381921e1..3a6a6d8e0a 100644
--- a/gtk2_ardour/editor_canvas.cc
+++ b/gtk2_ardour/editor_canvas.cc
@@ -465,14 +465,15 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context,
frame = 0;
- do_embed (paths, Editing::ImportThingPerFile, ImportAsTrack, 0, frame);
+ do_embed (paths, Editing::ImportDistinctFiles, ImportAsTrack, frame);
} else if ((tv = dynamic_cast<AudioTimeAxisView*>(tvp)) != 0) {
/* check that its an audio track, not a bus */
if (tv->get_diskstream()) {
- do_embed (paths, Editing::ImportThingPerFile, ImportToTrack, tv->audio_track(), frame);
+ // XXX NEED A WAY TO DROP INTO THIS SPECIFIC TRACK: tv->audio_track()
+ do_embed (paths, Editing::ImportDistinctFiles, ImportToTrack, frame);
}
}
diff --git a/gtk2_ardour/editor_region_list.cc b/gtk2_ardour/editor_region_list.cc
index 87c006c339..55e668eb00 100644
--- a/gtk2_ardour/editor_region_list.cc
+++ b/gtk2_ardour/editor_region_list.cc
@@ -621,7 +621,7 @@ Editor::region_list_display_drag_data_received (const RefPtr<Gdk::DragContext>&
if (convert_drop_to_paths (paths, context, x, y, data, info, time) == 0) {
nframes64_t pos = 0;
- do_embed (paths, Editing::ImportThingPerFile, ImportAsRegion, 0, pos);
+ do_embed (paths, Editing::ImportDistinctFiles, ImportAsRegion, pos);
context->drag_finish (true, false, time);
}
}
diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc
index b6d24c0871..cd382c41e6 100644
--- a/gtk2_ardour/mixer_strip.cc
+++ b/gtk2_ardour/mixer_strip.cc
@@ -185,7 +185,7 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, boost::shared_ptr<Route> rt
rec_enable_button->set_name ("MixerRecordEnableButton");
- AudioTrack* at = audio_track();
+ boost::shared_ptr<AudioTrack> at = audio_track();
at->FreezeChange.connect (mem_fun(*this, &MixerStrip::map_frozen));
@@ -1130,7 +1130,7 @@ MixerStrip::map_frozen ()
{
ENSURE_GUI_THREAD (mem_fun(*this, &MixerStrip::map_frozen));
- AudioTrack* at = audio_track();
+ boost::shared_ptr<AudioTrack> at = audio_track();
if (at) {
switch (at->freeze_state()) {
diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc
index de888ff9ab..b40ace3766 100644
--- a/gtk2_ardour/mixer_ui.cc
+++ b/gtk2_ardour/mixer_ui.cc
@@ -509,7 +509,7 @@ Mixer_UI::set_all_audio_visibility (int tracks, bool yn)
continue;
}
- AudioTrack* at = strip->audio_track();
+ boost::shared_ptr<AudioTrack> at = strip->audio_track();
switch (tracks) {
case 0:
diff --git a/gtk2_ardour/playlist_selector.cc b/gtk2_ardour/playlist_selector.cc
index 40f837eb5e..39abfe3dc1 100644
--- a/gtk2_ardour/playlist_selector.cc
+++ b/gtk2_ardour/playlist_selector.cc
@@ -245,7 +245,7 @@ PlaylistSelector::selection_changed ()
if ((playlist = ((*iter)[columns.playlist])) != 0) {
- AudioTrack* at;
+ boost::shared_ptr<AudioTrack> at;
boost::shared_ptr<AudioPlaylist> apl;
if ((at = rui->audio_track()) == 0) {
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
index 237a39bba3..e198397307 100644
--- a/gtk2_ardour/route_time_axis.cc
+++ b/gtk2_ardour/route_time_axis.cc
@@ -503,7 +503,7 @@ RouteTimeAxisView::set_track_mode (TrackMode mode)
}
void
-RouteTimeAxisView::_set_track_mode (Track* track, TrackMode mode, RadioMenuItem* reset_item)
+RouteTimeAxisView::_set_track_mode (boost::shared_ptr<Track> track, TrackMode mode, RadioMenuItem* reset_item)
{
bool needs_bounce;
diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h
index ae425cf9b3..a2ccc5d7c8 100644
--- a/gtk2_ardour/route_time_axis.h
+++ b/gtk2_ardour/route_time_axis.h
@@ -234,7 +234,7 @@ protected:
ArdourCanvas::SimpleRect* timestretch_rect;
void set_track_mode (ARDOUR::TrackMode);
- void _set_track_mode (ARDOUR::Track* track, ARDOUR::TrackMode mode, Gtk::RadioMenuItem* reset_item);
+ void _set_track_mode (boost::shared_ptr<ARDOUR::Track> track, ARDOUR::TrackMode mode, Gtk::RadioMenuItem* reset_item);
void track_mode_changed ();
list<RedirectAutomationInfo*> redirect_automation;
diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc
index 240072eeb1..6eb5499f23 100644
--- a/gtk2_ardour/route_ui.cc
+++ b/gtk2_ardour/route_ui.cc
@@ -968,25 +968,25 @@ RouteUI::disconnect_output ()
bool
RouteUI::is_track () const
{
- return dynamic_cast<Track*>(_route.get()) != 0;
+ return boost::dynamic_pointer_cast<Track>(_route) != 0;
}
-Track*
+boost::shared_ptr<Track>
RouteUI::track() const
{
- return dynamic_cast<Track*>(_route.get());
+ return boost::dynamic_pointer_cast<Track>(_route);
}
bool
RouteUI::is_audio_track () const
{
- return dynamic_cast<AudioTrack*>(_route.get()) != 0;
+ return boost::dynamic_pointer_cast<AudioTrack>(_route) != 0;
}
-AudioTrack*
+boost::shared_ptr<AudioTrack>
RouteUI::audio_track() const
{
- return dynamic_cast<AudioTrack*>(_route.get());
+ return boost::dynamic_pointer_cast<AudioTrack>(_route);
}
boost::shared_ptr<Diskstream>
diff --git a/gtk2_ardour/route_ui.h b/gtk2_ardour/route_ui.h
index 1c442afcae..1a6a6ecc73 100644
--- a/gtk2_ardour/route_ui.h
+++ b/gtk2_ardour/route_ui.h
@@ -50,12 +50,9 @@ class RouteUI : public virtual AxisView
bool is_track() const;
bool is_audio_track() const;
- boost::shared_ptr<ARDOUR::Route> route() const { return _route; }
-
- // FIXME: make these return shared_ptr
- ARDOUR::Track* track() const;
- ARDOUR::AudioTrack* audio_track() const;
-
+ boost::shared_ptr<ARDOUR::Route> route() const { return _route; }
+ boost::shared_ptr<ARDOUR::Track> track() const;
+ boost::shared_ptr<ARDOUR::AudioTrack> audio_track() const;
boost::shared_ptr<ARDOUR::Diskstream> get_diskstream() const;
string name() const;
diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc
index 819d13aa5b..0abb810bc2 100644
--- a/gtk2_ardour/sfdb_ui.cc
+++ b/gtk2_ardour/sfdb_ui.cc
@@ -295,7 +295,6 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
found_list_view (found_list),
import (rgroup2, _("Copy to Ardour-native files")),
embed (rgroup2, _("Use file without copying")),
- mode (ImportAsTrack),
found_search_btn (_("Search")),
selected_track_cnt (selected_tracks)
{
@@ -303,8 +302,9 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
VBox* vbox;
HBox* hbox;
HBox* hpacker;
-
+
set_session (s);
+ resetting_ourselves = false;
vpacker = manage (new VBox);
vpacker->pack_start (preview, true, true);
@@ -320,6 +320,25 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
options.set_spacing (12);
+ vector<string> action_strings;
+ vector<string> where_strings;
+
+ action_strings.push_back (_("as new tracks"));
+ if (selected_track_cnt > 0) {
+ action_strings.push_back (_("to selected tracks"));
+ }
+ action_strings.push_back (_("to the region list"));
+ action_strings.push_back (_("as new tape tracks"));
+ set_popdown_strings (action_combo, action_strings);
+ action_combo.set_active_text (action_strings.front());
+
+ where_strings.push_back (_("use file timestamp"));
+ where_strings.push_back (_("at edit cursor"));
+ where_strings.push_back (_("at playhead"));
+ where_strings.push_back (_("at session start"));
+ set_popdown_strings (where_combo, where_strings);
+ where_combo.set_active_text (where_strings.front());
+
Label* l = manage (new Label);
l->set_text (_("Add files:"));
@@ -358,6 +377,8 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
options.pack_start (*vbox, false, false);
reset_options ();
+
+ action_combo.signal_changed().connect (mem_fun (*this, &SoundFileBrowser::reset_options_noret));
block_four.pack_start (import, false, false);
block_four.pack_start (embed, false, false);
@@ -394,6 +415,7 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
chooser.add_filter (matchall_filter);
chooser.set_select_multiple (true);
chooser.signal_update_preview().connect(mem_fun(*this, &SoundFileBrowser::update_preview));
+ chooser.signal_selection_changed().connect (mem_fun (*this, &SoundFileBrowser::file_selection_changed));
chooser.signal_file_activated().connect (mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
if (!persistent_folder.empty()) {
@@ -405,10 +427,19 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
found_search_btn.signal_clicked().connect(mem_fun(*this, &SoundFileBrowser::found_search_clicked));
found_entry.signal_activate().connect(mem_fun(*this, &SoundFileBrowser::found_search_clicked));
- add_button (Stock::OK, RESPONSE_OK);
add_button (Stock::CANCEL, RESPONSE_CANCEL);
+ add_button (Stock::OK, RESPONSE_OK);
+
+ /* setup disposition map */
- set_response_sensitive (RESPONSE_OK, false);
+ disposition_map.insert (pair<Glib::ustring,ImportChannel>(_("one track per file"), ImportDistinctFiles));
+ disposition_map.insert (pair<Glib::ustring,ImportChannel>(_("one track per channel"), ImportDistinctChannels));
+ disposition_map.insert (pair<Glib::ustring,ImportChannel>(_("merge files"), ImportMergeFiles));
+ disposition_map.insert (pair<Glib::ustring,ImportChannel>(_("sequence files"), ImportSerializeFiles));
+
+ disposition_map.insert (pair<Glib::ustring,ImportChannel>(_("one region per file"), ImportDistinctFiles));
+ disposition_map.insert (pair<Glib::ustring,ImportChannel>(_("one region per channel"), ImportDistinctChannels));
+ disposition_map.insert (pair<Glib::ustring,ImportChannel>(_("all files in one region"), ImportMergeFiles));
}
SoundFileBrowser::~SoundFileBrowser ()
@@ -417,6 +448,24 @@ SoundFileBrowser::~SoundFileBrowser ()
}
void
+SoundFileBrowser::file_selection_changed ()
+{
+ if (resetting_ourselves) {
+ return;
+ }
+
+ if (!reset_options ()) {
+ set_response_sensitive (RESPONSE_OK, false);
+ } else {
+ if (chooser.get_filenames().size() > 0) {
+ set_response_sensitive (RESPONSE_OK, true);
+ } else {
+ set_response_sensitive (RESPONSE_OK, false);
+ }
+ }
+}
+
+void
SoundFileBrowser::chooser_file_activated ()
{
preview.audition ();
@@ -438,32 +487,36 @@ SoundFileBrowser::set_session (Session* s)
bool
SoundFileBrowser::on_custom (const FileFilter::Info& filter_info)
{
- return AudioFileSource::safe_file_extension(filter_info.filename);
+ return AudioFileSource::safe_file_extension (filter_info.filename);
}
void
SoundFileBrowser::update_preview ()
{
preview.setup_labels (chooser.get_filename());
- set_response_sensitive (RESPONSE_OK, true);
- reset_options ();
}
void
SoundFileBrowser::found_list_view_selected ()
{
- Glib::ustring file;
-
- TreeView::Selection::ListHandle_Path rows = found_list_view.get_selection()->get_selected_rows ();
-
- if (!rows.empty()) {
- TreeIter iter = found_list->get_iter(*rows.begin());
- file = (*iter)[found_list_columns.pathname];
- chooser.set_filename (file);
+ if (!reset_options ()) {
+ set_response_sensitive (RESPONSE_OK, false);
+ } else {
+ Glib::ustring file;
+
+ TreeView::Selection::ListHandle_Path rows = found_list_view.get_selection()->get_selected_rows ();
+
+ if (!rows.empty()) {
+ TreeIter iter = found_list->get_iter(*rows.begin());
+ file = (*iter)[found_list_columns.pathname];
+ chooser.set_filename (file);
+ set_response_sensitive (RESPONSE_OK, true);
+ } else {
+ set_response_sensitive (RESPONSE_OK, false);
+ }
+
+ preview.setup_labels (file);
}
- preview.setup_labels (file);
- set_response_sensitive (RESPONSE_OK, true);
- reset_options ();
}
void
@@ -524,95 +577,155 @@ SoundFileBrowser::get_paths ()
}
void
+SoundFileBrowser::reset_options_noret ()
+{
+ (void) reset_options ();
+}
+
+bool
SoundFileBrowser::reset_options ()
{
vector<Glib::ustring> paths = get_paths ();
- bool selection_includes_multichannel = check_multichannel_status (paths);
- bool selection_can_be_embedded_with_links = check_link_status (*session, paths);
- vector<string> action_strings;
- vector<string> where_strings;
- vector<string> channel_strings;
+ if (paths.empty()) {
- action_strings.push_back (_("as new tracks"));
- if (selected_track_cnt > 0) {
- action_strings.push_back (_("to selected tracks"));
- }
- action_strings.push_back (_("to the region list"));
- action_strings.push_back (_("as new tape tracks"));
+ channel_combo.set_sensitive (false);
+ action_combo.set_sensitive (false);
+ where_combo.set_sensitive (false);
+ import.set_sensitive (false);
+ embed.set_sensitive (false);
+ return false;
- set_popdown_strings (action_combo, action_strings);
- action_combo.set_active_text (action_strings.front());
+ } else {
- where_strings.push_back (_("use file timestamp"));
- where_strings.push_back (_("at edit cursor"));
- where_strings.push_back (_("at playhead"));
- where_strings.push_back (_("at session start"));
-
- set_popdown_strings (where_combo, where_strings);
- where_combo.set_active_text (where_strings.front());
+ channel_combo.set_sensitive (true);
+ action_combo.set_sensitive (true);
+ where_combo.set_sensitive (true);
+ import.set_sensitive (true);
+ embed.set_sensitive (true);
+
+ }
- if (mode == ImportAsTrack) {
- channel_strings.push_back (_("one file per track"));
+ bool same_size;
+ bool err;
+ bool selection_includes_multichannel = check_multichannel_status (paths, same_size, err);
+ bool selection_can_be_embedded_with_links = check_link_status (*session, paths);
+ ImportMode mode;
+
+ if (err) {
+ Glib::signal_idle().connect (mem_fun (*this, &SoundFileBrowser::bad_file_message));
+ return false;
+ }
+
+ if ((mode = get_mode()) == ImportAsRegion) {
+ where_combo.set_sensitive (false);
+ } else {
+ where_combo.set_sensitive (true);
+ }
+
+ vector<string> channel_strings;
+
+ if (mode == ImportAsTrack || mode == ImportAsTapeTrack || mode == ImportToTrack) {
+ channel_strings.push_back (_("one track per file"));
if (selection_includes_multichannel) {
- channel_strings.push_back (_("one channel per track"));
+ channel_strings.push_back (_("one track per channel"));
}
+
if (paths.size() > 1) {
- channel_strings.push_back (_("all files in one track"));
+ /* tape tracks are a single region per track, so we cannot
+ sequence multiple files.
+ */
+ if (mode != ImportAsTapeTrack) {
+ channel_strings.push_back (_("sequence files"));
+ }
+ if (same_size) {
+ channel_strings.push_back (_("all files in one track"));
+ }
+
}
- channel_combo.show();
+
} else {
- channel_combo.hide();
+ channel_strings.push_back (_("one region per file"));
+
+ if (selection_includes_multichannel) {
+ channel_strings.push_back (_("one region per channel"));
+ }
+
+ if (paths.size() > 1) {
+ if (same_size) {
+ channel_strings.push_back (_("all files in one region"));
+ }
+ }
}
set_popdown_strings (channel_combo, channel_strings);
channel_combo.set_active_text (channel_strings.front());
-
+
if (Profile->get_sae()) {
if (selection_can_be_embedded_with_links) {
- block_four.show ();
+ embed.set_sensitive (true);
} else {
- block_four.hide ();
+ embed.set_sensitive (false);
}
} else {
- block_four.show ();
- }
-
- if ((mode == ImportAsTrack || mode == ImportAsTapeTrack) && paths.size() == 2) {
- merge_stereo.set_sensitive (true);
- } else {
- merge_stereo.set_sensitive (false);
+ embed.set_sensitive (true);
}
- if (selection_includes_multichannel) {
- split_files.set_sensitive (true);
- } else {
- split_files.set_sensitive (false);
- }
+ return true;
}
bool
-SoundFileBrowser::check_multichannel_status (const vector<Glib::ustring>& paths)
+SoundFileBrowser::bad_file_message()
+{
+ MessageDialog msg (*this,
+ _("One or more of the selected files\ncannot be used by Ardour"),
+ true,
+ Gtk::MESSAGE_INFO,
+ Gtk::BUTTONS_OK);
+ msg.run ();
+ resetting_ourselves = true;
+ chooser.unselect_uri (chooser.get_preview_uri());
+ resetting_ourselves = false;
+}
+
+bool
+SoundFileBrowser::check_multichannel_status (const vector<Glib::ustring>& paths, bool& same_size, bool& err)
{
SNDFILE* sf;
SF_INFO info;
-
+ nframes64_t sz = 0;
+ bool some_mult = false;
+
+ same_size = true;
+ err = false;
+
for (vector<Glib::ustring>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
info.format = 0; // libsndfile says to clear this before sf_open().
if ((sf = sf_open ((char*) (*i).c_str(), SFM_READ, &info)) != 0) {
sf_close (sf);
+
if (info.channels > 1) {
- return true;
+ some_mult = true;
}
+
+ if (sz == 0) {
+ sz = info.frames;
+ } else {
+ if (sz != info.frames) {
+ same_size = false;
+ }
+ }
+ } else {
+ err = true;
}
}
- return false;
+ return some_mult;
}
bool
@@ -720,13 +833,18 @@ SoundFileBrowser::get_position() const
ImportChannel
SoundFileBrowser::get_channel_disposition () const
{
+ /* we use a map here because the channel combo can contain different strings
+ depending on the state of the other combos. the map contains all possible strings
+ and the ImportDisposition enum that corresponds to it.
+ */
+
Glib::ustring str = channel_combo.get_active_text();
+ DispositionMap::const_iterator x = disposition_map.find (str);
- if (str == _("one file per track")) {
- return ImportThingPerFile;
- } else if (str == _("one channel per track")) {
- return ImportThingPerChannel;
- } else {
- return ImportThingForAll;
+ if (x == disposition_map.end()) {
+ fatal << string_compose (_("programming error: %1"), "unknown string for import disposition") << endmsg;
+ /*NOTREACHED*/
}
+
+ return x->second;
}
diff --git a/gtk2_ardour/sfdb_ui.h b/gtk2_ardour/sfdb_ui.h
index de1e9d617b..89e756ce73 100644
--- a/gtk2_ardour/sfdb_ui.h
+++ b/gtk2_ardour/sfdb_ui.h
@@ -22,6 +22,7 @@
#include <string>
#include <vector>
+#include <map>
#include <glibmm/ustring.h>
#include <sigc++/signal.h>
@@ -117,9 +118,6 @@ class SoundFileBrowser : public ArdourDialog
Gtk::FileChooserWidget chooser;
Gtk::TreeView found_list_view;
- Gtk::CheckButton split_files;
- Gtk::CheckButton merge_stereo;
-
Gtk::ComboBoxText action_combo;
Gtk::ComboBoxText where_combo;
Gtk::ComboBoxText channel_combo;
@@ -132,7 +130,6 @@ class SoundFileBrowser : public ArdourDialog
Editing::ImportChannel get_channel_disposition() const;
protected:
- Editing::ImportMode mode;
Gtk::FileFilter custom_filter;
Gtk::FileFilter matchall_filter;
SoundFileBox preview;
@@ -151,18 +148,26 @@ class SoundFileBrowser : public ArdourDialog
void chooser_file_activated ();
bool on_custom (const Gtk::FileFilter::Info& filter_info);
+ void file_selection_changed ();
int selected_track_cnt;
+ typedef std::map<Glib::ustring,Editing::ImportChannel> DispositionMap;
+ DispositionMap disposition_map;
+
+ bool resetting_ourselves;
+
Gtk::HBox options;
Gtk::VBox block_two;
Gtk::VBox block_three;
Gtk::VBox block_four;
- static bool check_multichannel_status (const std::vector<Glib::ustring>& paths);
+ static bool check_multichannel_status (const std::vector<Glib::ustring>& paths, bool& same_size, bool& err);
static bool check_link_status (const ARDOUR::Session&, const std::vector<Glib::ustring>& paths);
- void reset_options ();
+ bool reset_options ();
+ void reset_options_noret ();
+ bool bad_file_message ();
};
class SoundFileChooser : public SoundFileBrowser
diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc
index 55311135fb..24dc8750f9 100644
--- a/gtk2_ardour/streamview.cc
+++ b/gtk2_ardour/streamview.cc
@@ -247,9 +247,9 @@ StreamView::playlist_changed (boost::weak_ptr<Diskstream> wptr)
void
StreamView::diskstream_changed ()
{
- Track *t;
+ boost::shared_ptr<Track> t = _trackview.track();
- if ((t = _trackview.track()) != 0) {
+ if (t) {
Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun (*this, &StreamView::display_diskstream), boost::weak_ptr<Diskstream> (t->diskstream())));
} else {
Gtkmm2ext::UI::instance()->call_slot (mem_fun (*this, &StreamView::undisplay_diskstream));
diff --git a/libs/ardour/ardour/configuration_vars.h b/libs/ardour/ardour/configuration_vars.h
index 8c3cb38ebe..d3e2ac5159 100644
--- a/libs/ardour/ardour/configuration_vars.h
+++ b/libs/ardour/ardour/configuration_vars.h
@@ -138,7 +138,8 @@ CONFIG_VARIABLE (bool, verify_remove_last_capture, "verify-remove-last-capture",
CONFIG_VARIABLE (bool, no_new_session_dialog, "no-new-session-dialog", false)
CONFIG_VARIABLE (bool, use_vst, "use-vst", true)
CONFIG_VARIABLE (uint32_t, subframes_per_frame, "subframes-per-frame", 100)
-CONFIG_VARIABLE (uint32_t, saved_history_depth, "save-history-depth", 100)
+CONFIG_VARIABLE (uint32_t, saved_history_depth, "save-history-depth", 20)
+CONFIG_VARIABLE (uint32_t, history_depth, "history-depth", 20)
CONFIG_VARIABLE (bool, use_overlap_equivalency, "use-overlap-equivalency", false)
CONFIG_VARIABLE (bool, periodic_safety_backups, "periodic-safety-backups", true)
CONFIG_VARIABLE (uint32_t, periodic_safety_backup_interval, "periodic-safety-backup-interval", 120)
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 19db991d04..6e8650fc61 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -1717,6 +1717,7 @@ class Session : public PBD::StatefulDestructible
XMLNode& get_control_protocol_state ();
+ void set_history_depth (uint32_t depth);
};
} // namespace ARDOUR
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index e39ebf72f2..c21bae5cc9 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -117,6 +117,9 @@ Session::first_stage_init (string fullpath, string snapshot_name)
_path += '/';
}
+ set_history_depth (Config->get_history_depth());
+
+
/* these two are just provisional settings. set_state()
will likely override them.
*/
@@ -2979,7 +2982,6 @@ Session::add_instant_xml (XMLNode& node, const std::string& dir)
Config->add_instant_xml (node, get_user_ardour_path());
}
-
int
Session::save_history (string snapshot_name)
{
@@ -3284,8 +3286,10 @@ Session::config_changed (const char* parameter_name)
set_slave_source (Config->get_slave_source());
} else if (PARAM_IS ("remote-model")) {
set_remote_control_ids ();
- } else if (PARAM_IS ("denormal-model")) {
+ } else if (PARAM_IS ("denormal-model")) {
setup_fpu ();
+ } else if (PARAM_IS ("history-depth")) {
+ set_history_depth (Config->get_history_depth());
}
set_dirty ();
@@ -3293,3 +3297,9 @@ Session::config_changed (const char* parameter_name)
#undef PARAM_IS
}
+
+void
+Session::set_history_depth (uint32_t d)
+{
+ _history.set_depth (d);
+}
diff --git a/libs/pbd/pbd/undo.h b/libs/pbd/pbd/undo.h
index 9539d8b41d..3f4a1c5e9d 100644
--- a/libs/pbd/pbd/undo.h
+++ b/libs/pbd/pbd/undo.h
@@ -86,8 +86,8 @@ class UndoHistory : public sigc::trackable
unsigned long undo_depth() const { return UndoList.size(); }
unsigned long redo_depth() const { return RedoList.size(); }
- std::string next_undo() const { return (UndoList.empty() ? std::string("") : UndoList.back()->name()); }
- std::string next_redo() const { return (RedoList.empty() ? std::string("") : RedoList.back()->name()); }
+ std::string next_undo() const { return (UndoList.empty() ? std::string() : UndoList.back()->name()); }
+ std::string next_redo() const { return (RedoList.empty() ? std::string() : RedoList.back()->name()); }
void clear ();
void clear_undo ();
@@ -96,10 +96,14 @@ class UndoHistory : public sigc::trackable
XMLNode &get_state(uint32_t depth = 0);
void save_state();
- sigc::signal<void> Changed;
+ void set_depth (uint32_t);
+ uint32_t get_depth() const { return _depth; }
+ sigc::signal<void> Changed;
+
private:
bool _clearing;
+ uint32_t _depth;
std::list<UndoTransaction*> UndoList;
std::list<UndoTransaction*> RedoList;
diff --git a/libs/pbd/undo.cc b/libs/pbd/undo.cc
index 4719d0968e..d54c6b0fff 100644
--- a/libs/pbd/undo.cc
+++ b/libs/pbd/undo.cc
@@ -148,12 +148,28 @@ XMLNode &UndoTransaction::get_state()
UndoHistory::UndoHistory ()
{
_clearing = false;
+ _depth = 0;
+}
+
+void
+UndoHistory::set_depth (uint32_t d)
+{
+ _depth = d;
+
+ while (_depth > 0 && UndoList.size() > _depth) {
+ UndoList.pop_front ();
+ }
}
void
UndoHistory::add (UndoTransaction* const ut)
{
ut->GoingAway.connect (bind (mem_fun (*this, &UndoHistory::remove), ut));
+
+ while (_depth > 0 && UndoList.size() > _depth) {
+ UndoList.pop_front ();
+ }
+
UndoList.push_back (ut);
/* we are now owners of the transaction */