summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2006-11-09 20:38:39 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2006-11-09 20:38:39 +0000
commit0c4c6e031a3624cfc74c2eef6e79527b7c49eca8 (patch)
treef2f9e7c1184723073075ff1ad4a3f023b1c51399
parentf7ccc404b38946c89d74e9776226b8ab4f0f6a05 (diff)
first pass on track mode switch; fixes to dangling region refs after capture; destroy region menu item removed; small fix to SConstruct for missing C++ case; playlist selection mechanism modified ; new Selection operation added (Add); handle crashing situation with align style change handling caused by recursion
git-svn-id: svn://localhost/ardour2/trunk@1099 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--SConstruct2
-rw-r--r--gtk2_ardour/ardour_ui.cc2
-rw-r--r--gtk2_ardour/editor.cc34
-rw-r--r--gtk2_ardour/editor.h6
-rw-r--r--gtk2_ardour/editor_ops.cc14
-rw-r--r--gtk2_ardour/editor_region_list.cc15
-rw-r--r--gtk2_ardour/keyboard.cc2
-rw-r--r--gtk2_ardour/redirect_box.cc2
-rw-r--r--gtk2_ardour/region_selection.cc12
-rw-r--r--gtk2_ardour/region_view.cc2
-rw-r--r--gtk2_ardour/route_time_axis.cc165
-rw-r--r--gtk2_ardour/route_time_axis.h10
-rw-r--r--gtk2_ardour/selection.h1
-rw-r--r--gtk2_ardour/time_axis_view.cc2
-rw-r--r--gtk2_ardour/utils.cc2
-rw-r--r--libs/ardour/SConscript1
-rw-r--r--libs/ardour/ardour/audio_diskstream.h3
-rw-r--r--libs/ardour/ardour/audio_track.h2
-rw-r--r--libs/ardour/ardour/audioregion.h2
-rw-r--r--libs/ardour/ardour/diskstream.h5
-rw-r--r--libs/ardour/ardour/playlist.h17
-rw-r--r--libs/ardour/ardour/region.h5
-rw-r--r--libs/ardour/ardour/session.h5
-rw-r--r--libs/ardour/ardour/source.h12
-rw-r--r--libs/ardour/ardour/track.h8
-rw-r--r--libs/ardour/audio_diskstream.cc71
-rw-r--r--libs/ardour/audio_playlist.cc21
-rw-r--r--libs/ardour/audio_track.cc17
-rw-r--r--libs/ardour/audioregion.cc41
-rw-r--r--libs/ardour/diskstream.cc16
-rw-r--r--libs/ardour/playlist.cc28
-rw-r--r--libs/ardour/region_factory.cc3
-rw-r--r--libs/ardour/session.cc54
-rw-r--r--libs/ardour/session_state.cc3
-rw-r--r--libs/ardour/sndfilesource.cc6
-rw-r--r--libs/ardour/source.cc24
-rw-r--r--libs/ardour/track.cc12
-rw-r--r--libs/gtkmm2ext/barcontroller.cc1
38 files changed, 479 insertions, 149 deletions
diff --git a/SConstruct b/SConstruct
index 6b278ea3c4..6f4f1bdde1 100644
--- a/SConstruct
+++ b/SConstruct
@@ -703,7 +703,7 @@ config_prefix = '$DESTDIR' + final_config_prefix
conf = Configure (env)
-have_cxx = conf.TryAction (Action (env['CXX'] + ' --version'))
+have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
if have_cxx[0] != 1:
print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
sys.exit (1)
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index 873c3849c2..df2848a88e 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -1946,7 +1946,7 @@ ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* l
_("No audio files were ready for cleanup"),
true,
Gtk::MESSAGE_INFO,
- (Gtk::ButtonsType)(Gtk::BUTTONS_CLOSE) );
+ (Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
msgd.set_secondary_text (_("If this seems suprising, \n\
check for any existing snapshots.\n\
These may still include regions that\n\
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index a9f4b4b7dc..d0b8f757f1 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -62,6 +62,7 @@
#include "selection.h"
#include "audio_streamview.h"
#include "time_axis_view.h"
+#include "audio_time_axis.h"
#include "utils.h"
#include "crossfade_view.h"
#include "editing.h"
@@ -1695,7 +1696,7 @@ Editor::add_region_context_items (AudioStreamView* sv, boost::shared_ptr<Region>
become selected.
*/
- region_menu->signal_map_event().connect (bind (mem_fun(*this, &Editor::set_selected_regionview_from_map_event), sv, boost::weak_ptr<Region>(region)));
+ // region_menu->signal_map_event().connect (bind (mem_fun(*this, &Editor::set_selected_regionview_from_map_event), sv, boost::weak_ptr<Region>(region)));
items.push_back (MenuElem (_("Popup region editor"), mem_fun(*this, &Editor::edit_region)));
items.push_back (MenuElem (_("Raise to top layer"), mem_fun(*this, &Editor::raise_region_to_top)));
@@ -1793,8 +1794,6 @@ Editor::add_region_context_items (AudioStreamView* sv, boost::shared_ptr<Region>
items.push_back (MenuElem (_("Fill Track"), (mem_fun(*this, &Editor::region_fill_track))));
items.push_back (SeparatorElem());
items.push_back (MenuElem (_("Remove"), mem_fun(*this, &Editor::remove_clicked_region)));
- items.push_back (SeparatorElem());
- items.push_back (MenuElem (_("Destroy"), mem_fun(*this, &Editor::destroy_clicked_region)));
/* OK, stick the region submenu at the top of the list, and then add
the standard items.
@@ -2847,6 +2846,13 @@ Editor::set_selected_track (TimeAxisView& view, Selection::Operation op, bool no
}
break;
+ case Selection::Add:
+ if (!selection->selected (&view)) {
+ selection->add (&view);
+ commit = true;
+ }
+ break;
+
case Selection::Set:
if (selection->selected (&view) && selection->tracks.size() == 1) {
/* no commit necessary */
@@ -2894,7 +2900,7 @@ Editor::set_selected_control_point_from_click (Selection::Operation op, bool no_
}
void
-Editor::get_relevant_audio_tracks (AudioTimeAxisView& base, set<AudioTimeAxisView*>& relevant_tracks)
+Editor::get_relevant_audio_tracks (set<AudioTimeAxisView*>& relevant_tracks)
{
/* step one: get all selected tracks and all tracks in the relevant edit groups */
@@ -2923,14 +2929,9 @@ Editor::get_relevant_audio_tracks (AudioTimeAxisView& base, set<AudioTimeAxisVie
}
}
}
-
} else {
-
- /* no active group, or no group */
-
- relevant_tracks.insert (&base);
+ relevant_tracks.insert (atv);
}
-
}
}
@@ -2939,14 +2940,10 @@ Editor::mapover_audio_tracks (slot<void,AudioTimeAxisView&,uint32_t> sl)
{
set<AudioTimeAxisView*> relevant_tracks;
- if (!clicked_audio_trackview) {
- return;
- }
-
- get_relevant_audio_tracks (*clicked_audio_trackview, relevant_tracks);
+ get_relevant_audio_tracks (relevant_tracks);
uint32_t sz = relevant_tracks.size();
-
+
for (set<AudioTimeAxisView*>::iterator ati = relevant_tracks.begin(); ati != relevant_tracks.end(); ++ati) {
sl (**ati, sz);
}
@@ -3134,7 +3131,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
set<AudioTimeAxisView*> relevant_tracks;
- get_relevant_audio_tracks (*clicked_audio_trackview, relevant_tracks);
+ get_relevant_audio_tracks (relevant_tracks);
for (set<AudioTimeAxisView*>::iterator t = relevant_tracks.begin(); t != relevant_tracks.end(); ++t) {
(*t)->get_selectables (first_frame, last_frame, -1.0, -1.0, results);
@@ -3209,6 +3206,9 @@ Editor::set_selected_regionview_from_region_list (boost::shared_ptr<Region> regi
case Selection::Extend:
selection->add (all_equivalent_regions);
break;
+ case Selection::Add:
+ selection->add (all_equivalent_regions);
+ break;
}
commit_reversible_command () ;
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 10747735b5..bbf5e8ad01 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -412,7 +412,7 @@ class Editor : public PublicEditor
CrossfadeView* clicked_crossfadeview;
ControlPoint* clicked_control_point;
- void get_relevant_audio_tracks (AudioTimeAxisView& base, std::set<AudioTimeAxisView*>& relevant_tracks);
+ void get_relevant_audio_tracks (std::set<AudioTimeAxisView*>& relevant_tracks);
void mapover_audio_tracks (sigc::slot<void,AudioTimeAxisView&,uint32_t> sl);
/* functions to be passed to mapover_audio_tracks(), possibly with sigc::bind()-supplied arguments */
@@ -814,8 +814,8 @@ class Editor : public PublicEditor
int ensure_cursor (nframes_t* pos);
- void handle_new_audio_region (boost::shared_ptr<ARDOUR::AudioRegion>);
- void handle_audio_region_removed (boost::shared_ptr<ARDOUR::AudioRegion>);
+ void handle_new_audio_region (boost::weak_ptr<ARDOUR::AudioRegion>);
+ void handle_audio_region_removed (boost::weak_ptr<ARDOUR::AudioRegion>);
void add_audio_region_to_region_display (boost::shared_ptr<ARDOUR::AudioRegion>);
void region_hidden (boost::shared_ptr<ARDOUR::Region>);
void redisplay_regions ();
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 6d006f94bf..a29d00fd5a 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -162,9 +162,9 @@ Editor::remove_clicked_region ()
void
Editor::destroy_clicked_region ()
{
- int32_t selected = selection->regions.size();
+ uint32_t selected = selection->regions.size();
- if (!session || clicked_regionview == 0 && selected == 0) {
+ if (!session || !selected) {
return;
}
@@ -191,7 +191,7 @@ Do you really want to destroy %1 ?"),
return;
}
- if (selected > 0) {
+ if (selected) {
list<boost::shared_ptr<Region> > r;
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
@@ -199,9 +199,6 @@ Do you really want to destroy %1 ?"),
}
session->destroy_regions (r);
-
- } else if (clicked_regionview) {
- session->destroy_region (clicked_regionview->region());
}
}
@@ -1275,6 +1272,9 @@ Editor::select_all_in_track (Selection::Operation op)
case Selection::Extend:
/* not defined yet */
break;
+ case Selection::Add:
+ selection->add (touched);
+ break;
}
}
@@ -1291,6 +1291,7 @@ Editor::select_all (Selection::Operation op)
}
begin_reversible_command (_("select all"));
switch (op) {
+ case Selection::Add:
case Selection::Toggle:
selection->add (touched);
break;
@@ -1348,6 +1349,7 @@ Editor::select_all_within (nframes_t start, nframes_t end, double top, double bo
begin_reversible_command (_("select all within"));
switch (op) {
+ case Selection::Add:
case Selection::Toggle:
cerr << "toggle\n";
selection->add (touched);
diff --git a/gtk2_ardour/editor_region_list.cc b/gtk2_ardour/editor_region_list.cc
index 397c401e0c..1ebf59fecd 100644
--- a/gtk2_ardour/editor_region_list.cc
+++ b/gtk2_ardour/editor_region_list.cc
@@ -48,22 +48,27 @@ using namespace Glib;
using namespace Editing;
void
-Editor::handle_audio_region_removed (boost::shared_ptr<AudioRegion> region)
+Editor::handle_audio_region_removed (boost::weak_ptr<AudioRegion> wregion)
{
- ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::handle_audio_region_removed), region));
+ ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::handle_audio_region_removed), wregion));
redisplay_regions ();
}
void
-Editor::handle_new_audio_region (boost::shared_ptr<AudioRegion> region)
+Editor::handle_new_audio_region (boost::weak_ptr<AudioRegion> wregion)
{
- ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::handle_new_audio_region), region));
+ ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::handle_new_audio_region), wregion));
/* don't copy region - the one we are being notified
about belongs to the session, and so it will
never be edited.
*/
- add_audio_region_to_region_display (region);
+
+ boost::shared_ptr<AudioRegion> region (wregion.lock());
+
+ if (region) {
+ add_audio_region_to_region_display (region);
+ }
}
void
diff --git a/gtk2_ardour/keyboard.cc b/gtk2_ardour/keyboard.cc
index 17390b8b4d..a6a14ad55b 100644
--- a/gtk2_ardour/keyboard.cc
+++ b/gtk2_ardour/keyboard.cc
@@ -796,6 +796,8 @@ Keyboard::modifier_state_equals (guint state, ModifierMask mask)
Selection::Operation
Keyboard::selection_type (guint state)
{
+ /* note that there is no modifier for "Add" */
+
if (modifier_state_equals (state, Shift)) {
return Selection::Extend;
} else if (modifier_state_equals (state, Control)) {
diff --git a/gtk2_ardour/redirect_box.cc b/gtk2_ardour/redirect_box.cc
index 6153d093f3..b7eb117703 100644
--- a/gtk2_ardour/redirect_box.cc
+++ b/gtk2_ardour/redirect_box.cc
@@ -968,11 +968,13 @@ RedirectBox::edit_redirect (boost::shared_ptr<Redirect> redirect)
if (plugin_insert->get_gui() == 0) {
plugin_ui = new PluginUIWindow (plugin_insert);
+
if (_owner_is_mixer) {
ARDOUR_UI::instance()->the_mixer()->ensure_float (*plugin_ui);
} else {
ARDOUR_UI::instance()->the_editor().ensure_float (*plugin_ui);
}
+
plugin_ui->set_title (generate_redirect_title (plugin_insert));
plugin_insert->set_gui (plugin_ui);
diff --git a/gtk2_ardour/region_selection.cc b/gtk2_ardour/region_selection.cc
index d887021a42..a418b1de23 100644
--- a/gtk2_ardour/region_selection.cc
+++ b/gtk2_ardour/region_selection.cc
@@ -79,23 +79,19 @@ RegionSelection::clear_all()
{
clear();
_bylayer.clear();
+ _current_start = 0;
+ _current_end = 0;
}
bool RegionSelection::contains (RegionView* rv)
{
- if (this->find (rv) != end()) {
- return true;
- }
- else {
- return false;
- }
-
+ return this->find (rv) != end();
}
void
RegionSelection::add (RegionView* rv, bool dosort)
{
- if (this->find (rv) != end()) {
+ if (contains (rv)) {
/* we already have it */
return;
}
diff --git a/gtk2_ardour/region_view.cc b/gtk2_ardour/region_view.cc
index db2726e515..634c29f767 100644
--- a/gtk2_ardour/region_view.cc
+++ b/gtk2_ardour/region_view.cc
@@ -149,8 +149,6 @@ RegionView::~RegionView ()
{
in_destructor = true;
- RegionViewGoingAway (this); /* EMIT_SIGNAL */
-
for (vector<GhostRegion*>::iterator g = ghosts.begin(); g != ghosts.end(); ++g) {
delete *g;
}
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
index f5f0f1dd10..ab8ebb32b5 100644
--- a/gtk2_ardour/route_time_axis.cc
+++ b/gtk2_ardour/route_time_axis.cc
@@ -40,6 +40,7 @@
#include <gtkmm2ext/utils.h>
#include <ardour/playlist.h>
+#include <ardour/audioplaylist.h>
#include <ardour/diskstream.h>
#include <ardour/insert.h>
#include <ardour/ladspa_plugin.h>
@@ -182,6 +183,7 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
if (is_track()) {
+ track()->TrackModeChanged.connect (mem_fun(*this, &RouteTimeAxisView::track_mode_changed));
track()->FreezeChange.connect (mem_fun(*this, &RouteTimeAxisView::map_frozen));
track()->DiskstreamChanged.connect (mem_fun(*this, &RouteTimeAxisView::diskstream_changed));
get_diskstream()->SpeedChanged.connect (mem_fun(*this, &RouteTimeAxisView::speed_changed));
@@ -276,8 +278,6 @@ RouteTimeAxisView::add_edit_group_menu_item (RouteGroup *eg, RadioMenuItem::Grou
MenuList &items = edit_group_menu.items();
- cerr << "adding edit group " << eg->name() << endl;
-
items.push_back (RadioMenuElem (*group, eg->name(), bind (mem_fun(*this, &RouteTimeAxisView::set_edit_group_from_menu), eg)));
if (_route->edit_group() == eg) {
static_cast<RadioMenuItem*>(&items.back())->set_active ();
@@ -286,19 +286,11 @@ RouteTimeAxisView::add_edit_group_menu_item (RouteGroup *eg, RadioMenuItem::Grou
void
RouteTimeAxisView::set_edit_group_from_menu (RouteGroup *eg)
-
{
_route->set_edit_group (eg, this);
}
void
-RouteTimeAxisView::playlist_state_changed (Change ignored)
-{
- // ENSURE_GUI_THREAD (bind (mem_fun(*this, &RouteTimeAxisView::playlist_state_changed), ignored));
- // why are we here ?
-}
-
-void
RouteTimeAxisView::playlist_changed ()
{
@@ -342,13 +334,15 @@ RouteTimeAxisView::playlist_click ()
{
// always build a new action menu
- if (playlist_action_menu == 0) {
- playlist_action_menu = new Menu;
- playlist_action_menu->set_name ("ArdourContextMenu");
- }
-
- build_playlist_menu(playlist_action_menu);
+ if (playlist_action_menu != 0) {
+ delete playlist_action_menu;
+ }
+ playlist_action_menu = new Menu;
+ playlist_action_menu->set_name ("ArdourContextMenu");
+
+ build_playlist_menu (playlist_action_menu);
+ editor.set_selected_track (*this, Selection::Add);
playlist_action_menu->popup (1, 0);
}
@@ -361,6 +355,7 @@ RouteTimeAxisView::automation_click ()
*/
build_display_menu ();
}
+ editor.set_selected_track (*this, Selection::Add);
automation_action_menu->popup (1, 0);
}
@@ -443,6 +438,24 @@ RouteTimeAxisView::build_display_menu ()
get_diskstream()->AlignmentStyleChanged.connect (
mem_fun(*this, &RouteTimeAxisView::align_style_changed));
+
+ RadioMenuItem::Group mode_group;
+ items.push_back (RadioMenuElem (mode_group, _("Normal mode"),
+ bind (mem_fun (*this, &RouteTimeAxisView::set_track_mode), ARDOUR::Normal)));
+ normal_track_mode_item = dynamic_cast<RadioMenuItem*>(&items.back());
+ items.push_back (RadioMenuElem (mode_group, _("Tape mode"),
+ bind (mem_fun (*this, &RouteTimeAxisView::set_track_mode), ARDOUR::Destructive)));
+ destructive_track_mode_item = dynamic_cast<RadioMenuItem*>(&items.back());
+
+
+ switch (track()->mode()) {
+ case ARDOUR::Destructive:
+ destructive_track_mode_item->set_active ();
+ break;
+ case ARDOUR::Normal:
+ normal_track_mode_item->set_active ();
+ break;
+ }
}
items.push_back (SeparatorElem());
@@ -454,6 +467,63 @@ RouteTimeAxisView::build_display_menu ()
items.push_back (MenuElem (_("Remove"), mem_fun(*this, &RouteUI::remove_this_route)));
}
+static bool __reset_item (RadioMenuItem* item)
+{
+ cerr << "reset item to true\n";
+ item->set_active ();
+ return false;
+}
+
+void
+RouteTimeAxisView::set_track_mode (TrackMode mode)
+{
+ RadioMenuItem* item;
+ RadioMenuItem* other_item;
+
+ cerr << "STM, mode = " << mode;
+
+ switch (mode) {
+ case ARDOUR::Normal:
+ item = normal_track_mode_item;
+ other_item = destructive_track_mode_item;
+ break;
+ case ARDOUR::Destructive:
+ item = destructive_track_mode_item;
+ other_item = normal_track_mode_item;
+ break;
+ default:
+ fatal << string_compose (_("programming error: %1 %2"), "illegal track mode in RouteTimeAxisView::set_track_mode", mode) << endmsg;
+ /*NOTREACHED*/
+ return;
+ }
+
+ if (item->get_active () && track()->mode() != mode) {
+ if (track()->set_mode (mode)) {
+ Glib::signal_idle().connect (bind (sigc::ptr_fun (__reset_item), other_item));
+ }
+ }
+}
+
+void
+RouteTimeAxisView::track_mode_changed ()
+{
+ RadioMenuItem* item;
+
+ switch (track()->mode()) {
+ case ARDOUR::Normal:
+ item = normal_track_mode_item;
+ break;
+ case ARDOUR::Destructive:
+ item = destructive_track_mode_item;
+ break;
+ default:
+ fatal << string_compose (_("programming error: %1 %2"), "illegal track mode in RouteTimeAxisView::set_track_mode", track()->mode()) << endmsg;
+ /*NOTREACHED*/
+ return;
+ }
+
+ item->set_active ();
+}
void
RouteTimeAxisView::show_timestretch (nframes_t start, nframes_t end)
@@ -700,7 +770,24 @@ RouteTimeAxisView::align_style_changed ()
void
RouteTimeAxisView::set_align_style (AlignStyle style)
{
- get_diskstream()->set_align_style (style);
+ RadioMenuItem* item;
+
+ switch (style) {
+ case ExistingMaterial:
+ item = align_existing_item;
+ break;
+ case CaptureTime:
+ item = align_capture_item;
+ break;
+ default:
+ fatal << string_compose (_("programming error: %1 %2"), "illegal align style in RouteTimeAxisView::set_align_style", style) << endmsg;
+ /*NOTREACHED*/
+ return;
+ }
+
+ if (item->get_active()) {
+ get_diskstream()->set_align_style (style);
+ }
}
void
@@ -772,7 +859,7 @@ RouteTimeAxisView::use_copy_playlist (bool prompt)
if (name.length()) {
ds->use_copy_playlist ();
- pl->set_name (name);
+ ds->playlist()->set_name (name);
}
}
@@ -799,7 +886,7 @@ RouteTimeAxisView::use_new_playlist (bool prompt)
prompter.set_initial_text (name);
prompter.add_button (Gtk::Stock::NEW, Gtk::RESPONSE_ACCEPT);
prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
-
+
switch (prompter.run ()) {
case Gtk::RESPONSE_ACCEPT:
prompter.get_result (name);
@@ -812,7 +899,7 @@ RouteTimeAxisView::use_new_playlist (bool prompt)
if (name.length()) {
ds->use_new_playlist ();
- pl->set_name (name);
+ ds->playlist()->set_name (name);
}
}
@@ -869,6 +956,10 @@ RouteTimeAxisView::selection_click (GdkEventButton* ev)
case Selection::Extend:
/* not defined yet */
break;
+
+ case Selection::Add:
+ editor.get_selection().add (*tracks);
+ break;
}
delete tracks;
@@ -1114,12 +1205,28 @@ RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
if (playlist_menu) {
delete playlist_menu;
}
+
playlist_menu = new Menu;
playlist_menu->set_name ("ArdourContextMenu");
- playlist_items.push_back (MenuElem (string_compose (_("Current: %1"), get_diskstream()->playlist()->name())));
- playlist_items.push_back (SeparatorElem());
+ vector<Playlist*> playlists;
+ boost::shared_ptr<Diskstream> ds = get_diskstream();
+ RadioMenuItem::Group playlist_group;
+
+ _session.get_playlists (playlists);
+ for (vector<Playlist*>::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+
+ if ((*i)->get_orig_diskstream_id() == ds->id()) {
+ playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name(), bind (mem_fun (*this, &RouteTimeAxisView::use_playlist), (*i))));
+
+ if (ds->playlist()->id() == (*i)->id()) {
+ static_cast<RadioMenuItem*>(&playlist_items.back())->set_active();
+ }
+ }
+ }
+
+ playlist_items.push_back (SeparatorElem());
playlist_items.push_back (MenuElem (_("Rename"), mem_fun(*this, &RouteTimeAxisView::rename_current_playlist)));
playlist_items.push_back (SeparatorElem());
@@ -1128,8 +1235,20 @@ RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
playlist_items.push_back (SeparatorElem());
playlist_items.push_back (MenuElem (_("Clear Current"), mem_fun(editor, &PublicEditor::clear_playlists)));
playlist_items.push_back (SeparatorElem());
- playlist_items.push_back (MenuElem(_("Select"), mem_fun(*this, &RouteTimeAxisView::show_playlist_selector)));
+ playlist_items.push_back (MenuElem(_("Select from all ..."), mem_fun(*this, &RouteTimeAxisView::show_playlist_selector)));
+}
+
+void
+RouteTimeAxisView::use_playlist (Playlist* pl)
+{
+ AudioPlaylist* apl = dynamic_cast<AudioPlaylist*> (pl);
+
+ assert (is_track());
+
+ if (apl) {
+ get_diskstream()->use_playlist (apl);
+ }
}
void
diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h
index 54fb387fcd..4a6f89e0af 100644
--- a/gtk2_ardour/route_time_axis.h
+++ b/gtk2_ardour/route_time_axis.h
@@ -180,7 +180,6 @@ protected:
void playlist_click ();
void show_playlist_selector ();
void playlist_changed ();
- void playlist_state_changed (ARDOUR::Change);
void playlist_modified ();
void rename_current_playlist ();
@@ -224,12 +223,19 @@ protected:
Gtk::Menu edit_group_menu;
Gtk::RadioMenuItem* align_existing_item;
Gtk::RadioMenuItem* align_capture_item;
+ Gtk::RadioMenuItem* normal_track_mode_item;
+ Gtk::RadioMenuItem* destructive_track_mode_item;
Gtk::Menu* playlist_menu;
Gtk::Menu* playlist_action_menu;
Gtk::MenuItem* playlist_item;
+ void use_playlist (ARDOUR::Playlist*);
+
ArdourCanvas::SimpleRect* timestretch_rect;
-
+
+ void set_track_mode (ARDOUR::TrackMode);
+ void track_mode_changed ();
+
list<RedirectAutomationInfo*> redirect_automation;
vector<RedirectAutomationLine*> redirect_automation_curves;
diff --git a/gtk2_ardour/selection.h b/gtk2_ardour/selection.h
index a1b1ae0da3..c4336fba21 100644
--- a/gtk2_ardour/selection.h
+++ b/gtk2_ardour/selection.h
@@ -56,6 +56,7 @@ class Selection : public sigc::trackable
enum Operation {
Set,
+ Add,
Toggle,
Extend
};
diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc
index 3a9ea7b4de..783a41e0a1 100644
--- a/gtk2_ardour/time_axis_view.cc
+++ b/gtk2_ardour/time_axis_view.cc
@@ -475,12 +475,14 @@ TimeAxisView::popup_display_menu (guint32 when)
if (display_menu == 0) {
build_display_menu ();
}
+ editor.set_selected_track (*this, Selection::Add);
display_menu->popup (1, when);
}
gint
TimeAxisView::size_click (GdkEventButton *ev)
{
+ editor.set_selected_track (*this, Selection::Add);
popup_size_menu (ev->time);
return TRUE;
}
diff --git a/gtk2_ardour/utils.cc b/gtk2_ardour/utils.cc
index 76b237713a..433fdd647a 100644
--- a/gtk2_ardour/utils.cc
+++ b/gtk2_ardour/utils.cc
@@ -362,7 +362,7 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
if (focus) {
if (GTK_IS_ENTRY(focus)) {
special_handling_of_unmodified_accelerators = true;
- }
+ }
}
/* This exists to allow us to override the way GTK handles
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript
index 8c6bd36c2d..7d1520a98c 100644
--- a/libs/ardour/SConscript
+++ b/libs/ardour/SConscript
@@ -274,7 +274,6 @@ if env['NLS']:
env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libardour))
-env.AlwaysBuild ('version.cc')
env.Alias('version', ardour.VersionBuild(['version.cc', 'ardour/version.h'], 'SConscript'))
env.Alias('tarball', env.Distribute (env['DISTTREE'],
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h
index 4dee5e9b00..74c804e5bb 100644
--- a/libs/ardour/ardour/audio_diskstream.h
+++ b/libs/ardour/ardour/audio_diskstream.h
@@ -77,6 +77,7 @@ class AudioDiskstream : public Diskstream
}
void set_record_enabled (bool yn);
+ int set_destructive (bool yn);
float peak_power(uint32_t n=0) {
float x = channels[n].peak_power;
@@ -251,6 +252,8 @@ class AudioDiskstream : public Diskstream
typedef vector<ChannelInfo> ChannelList;
ChannelList channels;
+
+ bool can_become_destructive () const;
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h
index 66fcd16a56..ae299dae4a 100644
--- a/libs/ardour/ardour/audio_track.h
+++ b/libs/ardour/ardour/audio_track.h
@@ -37,6 +37,8 @@ class AudioTrack : public Track
AudioTrack (Session&, const XMLNode&);
~AudioTrack ();
+ int set_mode (TrackMode m);
+
int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
nframes_t offset, int declick, bool can_record, bool rec_monitors_input);
diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h
index 4be5d27a6b..b739935d96 100644
--- a/libs/ardour/ardour/audioregion.h
+++ b/libs/ardour/ardour/audioregion.h
@@ -136,6 +136,8 @@ class AudioRegion : public Region
void resume_fade_in ();
void resume_fade_out ();
+ void set_playlist (Playlist *);
+
private:
friend class RegionFactory;
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
index 0afed75348..4cee6d1268 100644
--- a/libs/ardour/ardour/diskstream.h
+++ b/libs/ardour/ardour/diskstream.h
@@ -90,7 +90,7 @@ class IO;
virtual void set_record_enabled (bool yn) = 0;
bool destructive() const { return _flags & Destructive; }
- virtual void set_destructive (bool yn);
+ virtual int set_destructive (bool yn) { return -1; }
bool hidden() const { return _flags & Hidden; }
bool recordable() const { return _flags & Recordable; }
@@ -138,6 +138,8 @@ class IO;
void handle_input_change (IOChange, void *src);
+ void remove_region_from_last_capture (boost::weak_ptr<Region> wregion);
+
sigc::signal<void> RecordEnableChanged;
sigc::signal<void> SpeedChanged;
sigc::signal<void> ReverseChanged;
@@ -224,6 +226,7 @@ class IO;
virtual bool realtime_set_speed (double, bool global_change);
std::list<boost::shared_ptr<Region> > _last_capture_regions;
+
virtual int use_pending_capture_data (XMLNode& node) = 0;
virtual void get_input_sources () = 0;
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index 9cc3f86f0b..7b9ae718bc 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -62,14 +62,15 @@ class Playlist : public PBD::StatefulDestructible {
void unref();
uint32_t refcnt() const { return _refcnt; }
- const string& name() const { return _name; }
- void set_name (const string& str);
+ std::string name() const { return _name; }
+ void set_name (std::string str);
bool frozen() const { return _frozen; }
void set_frozen (bool yn);
bool hidden() const { return _hidden; }
bool empty() const;
+ uint32_t n_regions() const;
nframes_t get_maximum_extent () const;
layer_t top_layer() const;
@@ -88,19 +89,15 @@ class Playlist : public PBD::StatefulDestructible {
void duplicate (boost::shared_ptr<Region>, nframes_t position, float times);
void nudge_after (nframes_t start, nframes_t distance, bool forwards);
- boost::shared_ptr<Region> find_region (const PBD::ID&) const;
-
Playlist* cut (list<AudioRange>&, bool result_is_hidden = true);
Playlist* copy (list<AudioRange>&, bool result_is_hidden = true);
int paste (Playlist&, nframes_t position, float times);
- uint32_t read_data_count() { return _read_data_count; }
-
- RegionList* regions_at (nframes_t frame);
- RegionList* regions_touched (nframes_t start, nframes_t end);
+ RegionList* regions_at (nframes_t frame);
+ RegionList* regions_touched (nframes_t start, nframes_t end);
+ boost::shared_ptr<Region> find_region (const PBD::ID&) const;
boost::shared_ptr<Region> top_region_at (nframes_t frame);
-
- boost::shared_ptr<Region> find_next_region (nframes_t frame, RegionPoint point, int dir);
+ boost::shared_ptr<Region> find_next_region (nframes_t frame, RegionPoint point, int dir);
template<class T> void foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>, void *), void *arg);
template<class T> void foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>));
diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h
index 67e00d0ee8..7f511c4dd4 100644
--- a/libs/ardour/ardour/region.h
+++ b/libs/ardour/ardour/region.h
@@ -163,10 +163,7 @@ class Region : public PBD::StatefulDestructible, public boost::enable_shared_fro
ARDOUR::Playlist* playlist() const { return _playlist; }
- void set_playlist (ARDOUR::Playlist*);
-
- virtual void lock_sources () {}
- virtual void unlock_sources () {}
+ virtual void set_playlist (ARDOUR::Playlist*);
/* serialization */
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 85c0ef508c..93c093ec85 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -542,8 +542,8 @@ class Session : public PBD::StatefulDestructible
/* region info */
- sigc::signal<void,boost::shared_ptr<AudioRegion> > AudioRegionAdded;
- sigc::signal<void,boost::shared_ptr<AudioRegion> > AudioRegionRemoved;
+ sigc::signal<void,boost::weak_ptr<AudioRegion> > AudioRegionAdded;
+ sigc::signal<void,boost::weak_ptr<AudioRegion> > AudioRegionRemoved;
int region_name (string& result, string base = string(""), bool newlevel = false) const;
string new_region_name (string);
@@ -630,6 +630,7 @@ class Session : public PBD::StatefulDestructible
uint32_t n_playlists() const;
template<class T> void foreach_playlist (T *obj, void (T::*func)(Playlist *));
+ void get_playlists (std::vector<Playlist*>&);
/* named selections */
diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h
index 7e05e628ac..15e814e946 100644
--- a/libs/ardour/ardour/source.h
+++ b/libs/ardour/ardour/source.h
@@ -22,6 +22,7 @@
#define __ardour_source_h__
#include <string>
+#include <set>
#include <sigc++/signal.h>
@@ -32,6 +33,7 @@
namespace ARDOUR {
class Session;
+class Playlist;
class Source : public PBD::StatefulDestructible
{
@@ -49,13 +51,23 @@ class Source : public PBD::StatefulDestructible
XMLNode& get_state ();
int set_state (const XMLNode&);
+ void use () { _in_use++; }
+ void disuse () { if (_in_use) { _in_use--; } }
+
+ void add_playlist (ARDOUR::Playlist*);
+ void remove_playlist (ARDOUR::Playlist*);
+
+ uint32_t used() const;
protected:
Session& _session;
string _name;
time_t _timestamp;
+ std::set<ARDOUR::Playlist*> _playlists;
+
private:
+ uint32_t _in_use;
};
}
diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h
index cf380de153..a24b614157 100644
--- a/libs/ardour/ardour/track.h
+++ b/libs/ardour/ardour/track.h
@@ -39,6 +39,10 @@ class Track : public Route
int set_name (string str, void *src);
+ TrackMode mode () const { return _mode; }
+ virtual int set_mode (TrackMode m) { return false; }
+ sigc::signal<void> TrackModeChanged;
+
virtual int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
nframes_t offset, int declick, bool can_record, bool rec_monitors_input) = 0;
@@ -57,9 +61,6 @@ class Track : public Route
virtual int use_diskstream (string name) = 0;
virtual int use_diskstream (const PBD::ID& id) = 0;
- TrackMode mode() const { return _mode; }
- void set_mode (TrackMode m);
-
nframes_t update_total_latency();
void set_latency_delay (nframes_t);
@@ -88,7 +89,6 @@ class Track : public Route
void set_meter_point (MeterPoint, void* src);
- sigc::signal<void> ModeChanged;
sigc::signal<void> DiskstreamChanged;
sigc::signal<void> FreezeChange;
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index ad9fec2d41..7e753fa601 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -381,7 +381,7 @@ AudioDiskstream::setup_destructive_playlist ()
void
AudioDiskstream::use_destructive_playlist ()
{
- /* this is called from the XML-based constructor. when its done,
+ /* this is called from the XML-based constructor or ::set_destructive. when called,
we already have a playlist and a region, but we need to
set up our sources for write. we use the sources associated
with the (presumed single, full-extent) region.
@@ -400,6 +400,10 @@ AudioDiskstream::use_destructive_playlist ()
throw failed_constructor();
}
+ /* be sure to stretch the region out to the maximum length */
+
+ region->set_length (max_frames - region->position(), this);
+
uint32_t n;
ChannelList::iterator chan;
@@ -407,6 +411,10 @@ AudioDiskstream::use_destructive_playlist ()
(*chan).write_source = boost::dynamic_pointer_cast<AudioFileSource>(region->source (n));
assert((*chan).write_source);
(*chan).write_source->set_allow_remove_if_empty (false);
+
+ /* this might be false if we switched modes, so force it */
+
+ (*chan).write_source->set_destructive (true);
}
/* the source list will never be reset for a destructive track */
@@ -1584,9 +1592,9 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
continue; /* XXX is this OK? */
}
- _last_capture_regions.push_back (region);
+ region->GoingAway.connect (bind (mem_fun (*this, &Diskstream::remove_region_from_last_capture), boost::weak_ptr<Region>(region)));
- // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
+ _last_capture_regions.push_back (region);
i_am_the_modifier++;
_playlist->add_region (region, (*ci)->start);
@@ -2228,3 +2236,60 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
return 0;
}
+
+int
+AudioDiskstream::set_destructive (bool yn)
+{
+ if (yn != destructive()) {
+
+ if (yn) {
+ if (!can_become_destructive ()) {
+ return -1;
+ }
+ _flags |= Destructive;
+ use_destructive_playlist ();
+ } else {
+ _flags &= ~Destructive;
+ reset_write_sources (true, true);
+ }
+ }
+
+ return 0;
+}
+
+bool
+AudioDiskstream::can_become_destructive () const
+{
+ if (!_playlist) {
+ return false;
+ }
+
+ /* is there only one region ? */
+
+ if (_playlist->n_regions() != 1) {
+ return false;
+ }
+
+ boost::shared_ptr<Region> first = _playlist->find_next_region (_session.current_start_frame(), Start, 1);
+ assert (first);
+
+ /* do the source(s) for the region cover the session start position ? */
+
+ if (first->position() != _session.current_start_frame()) {
+ if (first->start() > _session.current_start_frame()) {
+ return false;
+ }
+ }
+
+ /* is the source used by only 1 playlist ? */
+
+ boost::shared_ptr<AudioRegion> afirst = boost::dynamic_pointer_cast<AudioRegion> (first);
+
+ assert (afirst);
+
+ if (afirst->source()->used() > 1) {
+ return false;
+ }
+
+ return true;
+}
diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc
index 290907746b..5118aab684 100644
--- a/libs/ardour/audio_playlist.cc
+++ b/libs/ardour/audio_playlist.cc
@@ -624,12 +624,10 @@ AudioPlaylist::destroy_region (boost::shared_ptr<Region> region)
{
RegionLock rlock (this);
- RegionList::iterator i;
- RegionList::iterator tmp;
- for (i = regions.begin(); i != regions.end(); ) {
+ for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
- tmp = i;
+ RegionList::iterator tmp = i;
++tmp;
if ((*i) == region) {
@@ -639,6 +637,21 @@ AudioPlaylist::destroy_region (boost::shared_ptr<Region> region)
i = tmp;
}
+
+ for (set<boost::shared_ptr<Region> >::iterator x = all_regions.begin(); x != all_regions.end(); ) {
+
+ set<boost::shared_ptr<Region> >::iterator xtmp = x;
+ ++xtmp;
+
+ if ((*x) == region) {
+ all_regions.erase (x);
+ changed = true;
+ }
+
+ x = xtmp;
+ }
+
+ region->set_playlist (0);
}
for (c = _crossfades.begin(); c != _crossfades.end(); ) {
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index 23ece02fa8..9c5020e9aa 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -73,6 +73,23 @@ AudioTrack::~AudioTrack ()
}
int
+AudioTrack::set_mode (TrackMode m)
+{
+ if (m != _mode) {
+
+ if (_diskstream->set_destructive (m == Destructive)) {
+ return -1;
+ }
+
+ _mode = m;
+
+ TrackModeChanged (); /* EMIT SIGNAL */
+ }
+
+ return 0;
+}
+
+int
AudioTrack::deprecated_use_diskstream_connections ()
{
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 2f0ae03f2d..a3ba886e38 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -306,6 +306,12 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
AudioRegion::~AudioRegion ()
{
+ if (_playlist) {
+ for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
+ (*i)->remove_playlist (_playlist);
+ }
+ }
+
notify_callbacks ();
GoingAway (); /* EMIT SIGNAL */
}
@@ -1145,8 +1151,6 @@ AudioRegion::exportme (Session& session, AudioExportSpecification& spec)
boost::shared_ptr<Region>
AudioRegion::get_parent()
{
- boost::shared_ptr<Region> r;
-
if (_playlist) {
boost::shared_ptr<AudioRegion> ar;
boost::shared_ptr<AudioRegion> grrr2 = boost::dynamic_pointer_cast<AudioRegion> (shared_from_this());
@@ -1156,7 +1160,7 @@ AudioRegion::get_parent()
}
}
- return r;
+ return boost::shared_ptr<Region>();
}
void
@@ -1305,6 +1309,37 @@ AudioRegion::source_offset_changed ()
}
}
+void
+AudioRegion::set_playlist (Playlist* pl)
+{
+ if (pl == _playlist) {
+ return;
+ }
+
+ Playlist* old_playlist = _playlist;
+
+ Region::set_playlist (pl);
+
+ if (pl) {
+ if (old_playlist) {
+ for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
+ (*i)->remove_playlist (old_playlist);
+ (*i)->add_playlist (_playlist);
+ }
+ } else {
+ for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
+ (*i)->add_playlist (_playlist);
+ }
+ }
+ } else {
+ if (old_playlist) {
+ for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
+ (*i)->remove_playlist (old_playlist);
+ }
+ }
+ }
+}
+
extern "C" {
int region_read_peaks_from_c (void *arg, uint32_t npeaks, uint32_t start, uint32_t cnt, intptr_t data, uint32_t n_chan, double samples_per_unit)
diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc
index 9e83c5e21a..7b3db9aab4 100644
--- a/libs/ardour/diskstream.cc
+++ b/libs/ardour/diskstream.cc
@@ -392,14 +392,14 @@ Diskstream::set_name (string str)
}
void
-Diskstream::set_destructive (bool yn)
+Diskstream::remove_region_from_last_capture (boost::weak_ptr<Region> wregion)
{
- if (yn != destructive()) {
- reset_write_sources (true, true);
- if (yn) {
- _flags |= Destructive;
- } else {
- _flags &= ~Destructive;
- }
+ boost::shared_ptr<Region> region (wregion.lock());
+
+ if (!region) {
+ return;
}
+
+ _last_capture_regions.remove (region);
}
+
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 713558f15e..a06fe2b5fd 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -85,10 +85,8 @@ Playlist::Playlist (Session& sess, const XMLNode& node, bool hide)
{
init (hide);
_name = "unnamed"; /* reset by set_state */
-
- if (set_state (node)) {
- throw failed_constructor();
- }
+
+ /* derived class calls set_state() */
}
Playlist::Playlist (const Playlist& other, string namestr, bool hide)
@@ -257,11 +255,19 @@ Playlist::Playlist (Playlist& pl)
Playlist::~Playlist ()
{
+ {
+ RegionLock rl (this);
+
+ for (set<boost::shared_ptr<Region> >::iterator i = all_regions.begin(); i != all_regions.end(); ++i) {
+ (*i)->set_playlist (0);
+ }
+ }
+
/* GoingAway must be emitted by derived classes */
}
void
-Playlist::set_name (const string& str)
+Playlist::set_name (string str)
{
/* in a typical situation, a playlist is being used
by one diskstream and also is referenced by the
@@ -1442,13 +1448,21 @@ Playlist::state (bool full_state)
bool
Playlist::empty() const
{
+ RegionLock rlock (const_cast<Playlist *>(this), false);
return regions.empty();
}
+uint32_t
+Playlist::n_regions() const
+{
+ RegionLock rlock (const_cast<Playlist *>(this), false);
+ return regions.size();
+}
+
nframes_t
Playlist::get_maximum_extent () const
{
- RegionLock rlock (const_cast<Playlist *>(this));
+ RegionLock rlock (const_cast<Playlist *>(this), false);
return _get_maximum_extent ();
}
@@ -1475,7 +1489,7 @@ Playlist::bump_name (string name, Session &session)
do {
newname = Playlist::bump_name_once (newname);
- } while (session.playlist_by_name(newname)!=NULL);
+ } while (session.playlist_by_name (newname)!=NULL);
return newname;
}
diff --git a/libs/ardour/region_factory.cc b/libs/ardour/region_factory.cc
index 313bb31f2a..5bcbdb8b80 100644
--- a/libs/ardour/region_factory.cc
+++ b/libs/ardour/region_factory.cc
@@ -93,8 +93,7 @@ RegionFactory::create (Session& session, XMLNode& node, bool yn)
boost::shared_ptr<Region>
RegionFactory::create (SourceList& srcs, nframes_t start, nframes_t length, const string& name, layer_t layer, Region::Flag flags, bool announce)
{
- AudioRegion* ar = new AudioRegion (srcs, start, length, name, layer, flags);
- boost::shared_ptr<AudioRegion> arp (ar);
+ boost::shared_ptr<AudioRegion> arp (new AudioRegion (srcs, start, length, name, layer, flags));
boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp));
if (announce) {
CheckNewRegion (ret);
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index b2705c2cbd..a4def58bb4 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -2535,7 +2535,7 @@ Session::remove_region (boost::weak_ptr<Region> weak_region)
set_dirty();
if (removed) {
- AudioRegionRemoved(ar); /* EMIT SIGNAL */
+ AudioRegionRemoved (ar); /* EMIT SIGNAL */
}
}
@@ -2571,32 +2571,38 @@ Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vec
int
Session::destroy_region (boost::shared_ptr<Region> region)
{
- boost::shared_ptr<AudioRegion> aregion;
-
- if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
- return 0;
- }
-
- if (aregion->playlist()) {
- aregion->playlist()->destroy_region (region);
- }
-
vector<boost::shared_ptr<Source> > srcs;
-
- for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
- srcs.push_back (aregion->source (n));
+
+ {
+ boost::shared_ptr<AudioRegion> aregion;
+
+ if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
+ return 0;
+ }
+
+ if (aregion->playlist()) {
+ aregion->playlist()->destroy_region (region);
+ }
+
+ for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
+ srcs.push_back (aregion->source (n));
+ }
}
+ region->drop_references ();
+
for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
-
- if ((*i).use_count() == 1) {
- boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
+ if (!(*i)->used()) {
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
+
if (afs) {
(afs)->mark_for_remove ();
}
(*i)->drop_references ();
+
+ cerr << "source was not used by any playlist\n";
}
}
@@ -2989,6 +2995,20 @@ Session::add_playlist (Playlist* playlist)
}
void
+Session::get_playlists (vector<Playlist*>& s)
+{
+ {
+ Glib::Mutex::Lock lm (playlist_lock);
+ for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+ s.push_back (*i);
+ }
+ for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
+ s.push_back (*i);
+ }
+ }
+}
+
+void
Session::track_playlist (Playlist* pl, bool inuse)
{
PlaylistList::iterator x;
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 763f8b9c01..f80c9e9a82 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -520,7 +520,6 @@ Session::create (bool& new_session, string* mix_template, nframes_t initial_leng
_state_of_the_state = Clean;
if (save_state (_current_snapshot_name)) {
- save_history (_current_snapshot_name);
return -1;
}
@@ -2456,6 +2455,8 @@ Session::cleanup_sources (Session::cleanup_report& rep)
capture files.
*/
+ cerr << "checking out source " << i->second->name() << " use_count = " << i->second.use_count() << endl;
+
if (i->second.use_count() == 1 && i->second->length() > 0) {
dead_sources.push_back (i->second);
diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc
index 3c3798c8ab..4b9c7ff33b 100644
--- a/libs/ardour/sndfilesource.cc
+++ b/libs/ardour/sndfilesource.cc
@@ -212,7 +212,7 @@ SndFileSource::init (string idstr)
_capture_end = false;
file_pos = 0;
- if (destructive()) {
+ if (destructive()) {
xfade_buf = new Sample[xfade_frames];
timeline_position = header_position_offset;
}
@@ -680,11 +680,15 @@ SndFileSource::set_destructive (bool yn)
{
if (yn) {
_flags = Flag (_flags | Destructive);
+ if (!xfade_buf) {
+ xfade_buf = new Sample[xfade_frames];
+ }
clear_capture_marks ();
timeline_position = header_position_offset;
} else {
_flags = Flag (_flags & ~Destructive);
timeline_position = 0;
+ /* leave xfade buf alone in case we need it again later */
}
return true;
diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc
index 7ade8a8573..74ca0afcd4 100644
--- a/libs/ardour/source.cc
+++ b/libs/ardour/source.cc
@@ -34,6 +34,7 @@
#include <pbd/pthread_utils.h>
#include <ardour/source.h>
+#include <ardour/playlist.h>
#include "i18n.h"
@@ -47,12 +48,14 @@ Source::Source (Session& s, string name)
{
_name = name;
_timestamp = 0;
+ _in_use = 0;
}
Source::Source (Session& s, const XMLNode& node)
: _session (s)
{
_timestamp = 0;
+ _in_use = 0;
if (set_state (node)) {
throw failed_constructor();
@@ -106,3 +109,24 @@ Source::set_state (const XMLNode& node)
return 0;
}
+void
+Source::add_playlist (Playlist* pl)
+{
+ _playlists.insert (pl);
+}
+
+void
+Source::remove_playlist (Playlist* pl)
+{
+ std::set<Playlist*>::iterator x;
+
+ if ((x = _playlists.find (pl)) != _playlists.end()) {
+ _playlists.erase (x);
+ }
+}
+
+uint32_t
+Source::used () const
+{
+ return _playlists.size();
+}
diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc
index 2c3d7c9151..95e21e6735 100644
--- a/libs/ardour/track.cc
+++ b/libs/ardour/track.cc
@@ -183,18 +183,6 @@ Track::set_record_enable (bool yn, void *src)
_rec_enable_control.Changed ();
}
-void
-Track::set_mode (TrackMode m)
-{
- if (_diskstream) {
- if (_mode != m) {
- _mode = m;
- _diskstream->set_destructive (m == Destructive);
- ModeChanged();
- }
- }
-}
-
int
Track::set_name (string str, void *src)
{
diff --git a/libs/gtkmm2ext/barcontroller.cc b/libs/gtkmm2ext/barcontroller.cc
index eefe6ca843..734c4b77e2 100644
--- a/libs/gtkmm2ext/barcontroller.cc
+++ b/libs/gtkmm2ext/barcontroller.cc
@@ -423,6 +423,7 @@ BarController::switch_to_spinner ()
remove ();
add (spinner);
spinner.show ();
+ spinner.select_region (0, spinner.get_text_length());
spinner.grab_focus ();
switching = false;