diff --git a/gtk2_ardour/ardour3_ui_default.conf b/gtk2_ardour/ardour3_ui_default.conf
index 0cdf195798..663c153c4f 100644
--- a/gtk2_ardour/ardour3_ui_default.conf
+++ b/gtk2_ardour/ardour3_ui_default.conf
@@ -48,8 +48,8 @@
-
-
+
+
diff --git a/gtk2_ardour/ardour3_ui_light.rc.in b/gtk2_ardour/ardour3_ui_light.rc.in
index 5d1f89dba8..907ef38f5d 100644
--- a/gtk2_ardour/ardour3_ui_light.rc.in
+++ b/gtk2_ardour/ardour3_ui_light.rc.in
@@ -298,7 +298,7 @@ style "treeview_display" = "small_bold_text"
base[SELECTED] = { 0, 0.75, 0.75 }
# row text when in normal state and not a parent
- text[NORMAL] = { 0.80, 0.80, 0.80 }
+ text[NORMAL] = { 0.20, 0.20, 0.20 }
# selected row text with window focus
text[SELECTED] = { 1.0, 1.0, 1.0 }
diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc
index 6e837b1626..c3fc279991 100644
--- a/gtk2_ardour/audio_region_view.cc
+++ b/gtk2_ardour/audio_region_view.cc
@@ -83,9 +83,9 @@ AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView
, end_xfade_out (0)
, end_xfade_rect (0)
, _amplitude_above_axis(1.0)
- , _flags(0)
, fade_color(0)
{
+ Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&AudioRegionView::parameter_changed, this, _1), gui_context());
}
AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr r, double spu,
@@ -104,9 +104,9 @@ AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView
, end_xfade_out (0)
, end_xfade_rect (0)
, _amplitude_above_axis(1.0)
- , _flags(0)
, fade_color(0)
{
+ Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&AudioRegionView::parameter_changed, this, _1), gui_context());
}
AudioRegionView::AudioRegionView (const AudioRegionView& other, boost::shared_ptr other_region)
@@ -123,7 +123,6 @@ AudioRegionView::AudioRegionView (const AudioRegionView& other, boost::shared_pt
, end_xfade_out (0)
, end_xfade_rect (0)
, _amplitude_above_axis (other._amplitude_above_axis)
- , _flags (other._flags)
, fade_color(0)
{
Gdk::Color c;
@@ -133,6 +132,8 @@ AudioRegionView::AudioRegionView (const AudioRegionView& other, boost::shared_pt
c.set_rgb_p (r/255.0, g/255.0, b/255.0);
init (c, true);
+
+ Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&AudioRegionView::parameter_changed, this, _1), gui_context());
}
void
@@ -143,17 +144,7 @@ AudioRegionView::init (Gdk::Color const & basic_color, bool wfd)
RegionView::init (basic_color, wfd);
- XMLNode *node;
-
_amplitude_above_axis = 1.0;
- _flags = 0;
-
- if ((node = _region->extra_xml ("GUI")) != 0) {
- set_flags (node);
- } else {
- _flags = WaveformVisible;
- store_flags ();
- }
compute_colors (basic_color);
@@ -230,6 +221,10 @@ AudioRegionView::init (Gdk::Color const & basic_color, bool wfd)
set_colors ();
+ setup_waveform_visibility ();
+ setup_waveform_shape ();
+ setup_waveform_scale ();
+
/* XXX sync mark drag? */
}
@@ -765,8 +760,8 @@ AudioRegionView::set_samples_per_unit (gdouble spu)
{
RegionView::set_samples_per_unit (spu);
- if (_flags & WaveformVisible) {
- for (uint32_t n=0; n < waves.size(); ++n) {
+ if (Config->get_show_waveforms ()) {
+ for (uint32_t n = 0; n < waves.size(); ++n) {
waves[n]->property_samples_per_unit() = spu;
}
}
@@ -818,25 +813,20 @@ AudioRegionView::set_colors ()
}
void
-AudioRegionView::set_waveform_visible (bool yn)
+AudioRegionView::setup_waveform_visibility ()
{
- if (((_flags & WaveformVisible) != yn)) {
- if (yn) {
- for (uint32_t n=0; n < waves.size(); ++n) {
- /* make sure the zoom level is correct, since we don't update
- this when waveforms are hidden.
- */
- waves[n]->property_samples_per_unit() = samples_per_unit;
- waves[n]->show();
- }
- _flags |= WaveformVisible;
- } else {
- for (uint32_t n=0; n < waves.size(); ++n) {
- waves[n]->hide();
- }
- _flags &= ~WaveformVisible;
+ if (Config->get_show_waveforms ()) {
+ for (uint32_t n = 0; n < waves.size(); ++n) {
+ /* make sure the zoom level is correct, since we don't update
+ this when waveforms are hidden.
+ */
+ waves[n]->property_samples_per_unit() = samples_per_unit;
+ waves[n]->show();
+ }
+ } else {
+ for (uint32_t n = 0; n < waves.size(); ++n) {
+ waves[n]->hide();
}
- store_flags ();
}
}
@@ -971,10 +961,10 @@ AudioRegionView::create_one_wave (uint32_t which, bool /*direct*/)
wave->property_zero_color() = ARDOUR_UI::config()->canvasvar_ZeroLine.get();
wave->property_zero_line() = true;
wave->property_region_start() = _region->start();
- wave->property_rectified() = (bool) (_flags & WaveformRectified);
- wave->property_logscaled() = (bool) (_flags & WaveformLogScaled);
+ wave->property_rectified() = Config->get_waveform_shape() == Rectified;
+ wave->property_logscaled() = Config->get_waveform_scale() == Logarithmic;
- if (!(_flags & WaveformVisible)) {
+ if (!Config->get_show_waveforms ()) {
wave->hide();
}
@@ -1079,90 +1069,18 @@ AudioRegionView::remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent */*
}
void
-AudioRegionView::store_flags()
+AudioRegionView::setup_waveform_shape ()
{
- XMLNode *node = new XMLNode ("GUI");
-
- node->add_property ("waveform-visible", (_flags & WaveformVisible) ? "yes" : "no");
- node->add_property ("waveform-rectified", (_flags & WaveformRectified) ? "yes" : "no");
- node->add_property ("waveform-logscaled", (_flags & WaveformLogScaled) ? "yes" : "no");
-
- _region->add_extra_xml (*node);
-}
-
-void
-AudioRegionView::set_flags (XMLNode* node)
-{
- XMLProperty *prop;
-
- if ((prop = node->property ("waveform-visible")) != 0) {
- if (string_is_affirmative (prop->value())) {
- _flags |= WaveformVisible;
- }
- }
-
- if ((prop = node->property ("waveform-rectified")) != 0) {
- if (string_is_affirmative (prop->value())) {
- _flags |= WaveformRectified;
- }
- }
-
- if ((prop = node->property ("waveform-logscaled")) != 0) {
- if (string_is_affirmative (prop->value())) {
- _flags |= WaveformLogScaled;
- }
+ for (vector::iterator wave = waves.begin(); wave != waves.end() ; ++wave) {
+ (*wave)->property_rectified() = Config->get_waveform_shape() == Rectified;
}
}
void
-AudioRegionView::set_waveform_shape (WaveformShape shape)
+AudioRegionView::setup_waveform_scale ()
{
- bool yn;
-
- /* this slightly odd approach is to leave the door open to
- other "shapes" such as spectral displays, etc.
- */
-
- switch (shape) {
- case Rectified:
- yn = true;
- break;
-
- default:
- yn = false;
- break;
- }
-
- if (yn != (bool) (_flags & WaveformRectified)) {
- for (vector::iterator wave = waves.begin(); wave != waves.end() ; ++wave) {
- (*wave)->property_rectified() = yn;
- }
-
- if (yn) {
- _flags |= WaveformRectified;
- } else {
- _flags &= ~WaveformRectified;
- }
- store_flags ();
- }
-}
-
-void
-AudioRegionView::set_waveform_scale (WaveformScale scale)
-{
- bool yn = (scale == Logarithmic);
-
- if (yn != (bool) (_flags & WaveformLogScaled)) {
- for (vector::iterator wave = waves.begin(); wave != waves.end() ; ++wave) {
- (*wave)->property_logscaled() = yn;
- }
-
- if (yn) {
- _flags |= WaveformLogScaled;
- } else {
- _flags &= ~WaveformLogScaled;
- }
- store_flags ();
+ for (vector::iterator wave = waves.begin(); wave != waves.end() ; ++wave) {
+ (*wave)->property_logscaled() = Config->get_waveform_scale() == Logarithmic;
}
}
@@ -1794,7 +1712,7 @@ AudioRegionView::drag_start ()
AudioStreamView* av = atav->audio_view();
if (av) {
/* this will hide our xfades too */
- av->hide_xfades_with (audio_region());
+ _hidden_xfades = av->hide_xfades_with (audio_region());
}
}
}
@@ -1803,5 +1721,22 @@ void
AudioRegionView::drag_end ()
{
TimeAxisViewItem::drag_end ();
- /* fades will be redrawn if they changed */
+
+ for (list::iterator i = _hidden_xfades.begin(); i != _hidden_xfades.end(); ++i) {
+ (*i)->show_xfades ();
+ }
+
+ _hidden_xfades.clear ();
+}
+
+void
+AudioRegionView::parameter_changed (string const & p)
+{
+ if (p == "show-waveforms") {
+ setup_waveform_visibility ();
+ } else if (p == "waveform-scale") {
+ setup_waveform_scale ();
+ } else if (p == "waveform-shape") {
+ setup_waveform_shape ();
+ }
}
diff --git a/gtk2_ardour/audio_region_view.h b/gtk2_ardour/audio_region_view.h
index 773e136952..ee03fdbc80 100644
--- a/gtk2_ardour/audio_region_view.h
+++ b/gtk2_ardour/audio_region_view.h
@@ -80,13 +80,6 @@ class AudioRegionView : public RegionView
void unhide_envelope (); ///< Dangerous!
void update_envelope_visibility ();
- void set_waveform_visible (bool yn);
- void set_waveform_shape (ARDOUR::WaveformShape);
- void set_waveform_scale (ARDOUR::WaveformScale);
-
- bool waveform_rectified() const { return _flags & WaveformRectified; }
- bool waveform_logscaled() const { return _flags & WaveformLogScaled; }
- bool waveform_visible() const { return _flags & WaveformVisible; }
void add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event);
void remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event);
@@ -165,7 +158,6 @@ class AudioRegionView : public RegionView
double _amplitude_above_axis;
- uint32_t _flags;
uint32_t fade_color;
void reset_fade_shapes ();
@@ -183,8 +175,6 @@ class AudioRegionView : public RegionView
void create_one_wave (uint32_t, bool);
void peaks_ready_handler (uint32_t);
- void set_flags (XMLNode *);
- void store_flags ();
void set_colors ();
void compute_colors (Gdk::Color const &);
@@ -203,10 +193,18 @@ class AudioRegionView : public RegionView
private:
void setup_fade_handle_positions ();
+ void parameter_changed (std::string const &);
+ void setup_waveform_visibility ();
+ void setup_waveform_shape ();
+ void setup_waveform_scale ();
+
/** A ScopedConnection for each PeaksReady callback (one per channel). Each member
* may be 0 if no connection exists.
*/
std::vector _data_ready_connections;
+
+ /** RegionViews that we hid the xfades for at the start of the current drag */
+ std::list _hidden_xfades;
};
#endif /* __gtk_ardour_audio_region_view_h__ */
diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc
index 22e07c0ec9..80ed198ab1 100644
--- a/gtk2_ardour/audio_streamview.cc
+++ b/gtk2_ardour/audio_streamview.cc
@@ -60,8 +60,6 @@ AudioStreamView::AudioStreamView (AudioTimeAxisView& tv)
{
color_handler ();
_amplitude_above_axis = 1.0;
-
- Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&AudioStreamView::parameter_changed, this, _1), gui_context());
}
int
@@ -132,10 +130,6 @@ AudioStreamView::create_region_view (boost::shared_ptr r, bool wait_for_
region_view->set_sensitive (false);
}
- region_view->set_waveform_scale (Config->get_waveform_scale ());
- region_view->set_waveform_shape (Config->get_waveform_shape ());
- region_view->set_waveform_visible (Config->get_show_waveforms ());
-
return region_view;
}
@@ -208,38 +202,6 @@ AudioStreamView::redisplay_track ()
layer_regions();
}
-void
-AudioStreamView::set_show_waveforms (bool yn)
-{
- for (list::iterator i = region_views.begin(); i != region_views.end(); ++i) {
- AudioRegionView* const arv = dynamic_cast(*i);
- if (arv) {
- arv->set_waveform_visible (yn);
- }
- }
-}
-
-void
-AudioStreamView::set_waveform_shape (WaveformShape shape)
-{
- for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
- AudioRegionView* const arv = dynamic_cast(*i);
- if (arv)
- arv->set_waveform_shape (shape);
- }
-}
-
-void
-AudioStreamView::set_waveform_scale (WaveformScale scale)
-{
- for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
- AudioRegionView* const arv = dynamic_cast(*i);
- if (arv) {
- arv->set_waveform_scale (scale);
- }
- }
-}
-
void
AudioStreamView::setup_rec_box ()
{
@@ -530,9 +492,14 @@ AudioStreamView::hide_all_fades ()
}
}
-void
+/** Hide xfades for regions that overlap ar.
+ * @return AudioRegionViews that xfades were hidden for.
+ */
+list
AudioStreamView::hide_xfades_with (boost::shared_ptr ar)
{
+ list hidden;
+
for (list::iterator i = region_views.begin(); i != region_views.end(); ++i) {
AudioRegionView* const arv = dynamic_cast(*i);
if (arv) {
@@ -541,10 +508,13 @@ AudioStreamView::hide_xfades_with (boost::shared_ptr ar)
break;
default:
arv->hide_xfades ();
+ hidden.push_back (arv);
break;
}
}
}
+
+ return hidden;
}
void
@@ -564,16 +534,3 @@ AudioStreamView::color_handler ()
}
}
}
-
-void
-AudioStreamView::parameter_changed (string const & p)
-{
- if (p == "show-waveforms") {
- set_show_waveforms (Config->get_show_waveforms ());
- } else if (p == "waveform-scale") {
- set_waveform_scale (Config->get_waveform_scale ());
- } else if (p == "waveform-shape") {
- set_waveform_shape (Config->get_waveform_shape ());
- }
-}
-
diff --git a/gtk2_ardour/audio_streamview.h b/gtk2_ardour/audio_streamview.h
index 5ef83b7adc..a36c57b552 100644
--- a/gtk2_ardour/audio_streamview.h
+++ b/gtk2_ardour/audio_streamview.h
@@ -56,12 +56,10 @@ class AudioStreamView : public StreamView
int set_amplitude_above_axis (gdouble app);
gdouble get_amplitude_above_axis () { return _amplitude_above_axis; }
- void set_show_waveforms (bool yn);
-
void show_all_fades ();
void hide_all_fades ();
- void hide_xfades_with (boost::shared_ptr ar);
+ std::list hide_xfades_with (boost::shared_ptr ar);
RegionView* create_region_view (boost::shared_ptr, bool, bool);
@@ -77,10 +75,6 @@ class AudioStreamView : public StreamView
void color_handler ();
- void parameter_changed (std::string const &);
- void set_waveform_shape (ARDOUR::WaveformShape);
- void set_waveform_scale (ARDOUR::WaveformScale);
-
double _amplitude_above_axis;
std::map, bool> rec_data_ready_map;
diff --git a/gtk2_ardour/canvas-flag.cc b/gtk2_ardour/canvas-flag.cc
index d77de07359..75be80fb3f 100644
--- a/gtk2_ardour/canvas-flag.cc
+++ b/gtk2_ardour/canvas-flag.cc
@@ -5,6 +5,7 @@
#include "ardour_ui.h"
#include "canvas-flag.h"
+#include "canvas-noevent-pixbuf.h"
#include "time_axis_view_item.h"
#include "utils.h"
@@ -28,7 +29,6 @@ CanvasFlag::CanvasFlag (MidiRegionView& region,
, _line(0)
, _rect(0)
{
- signal_event().connect (sigc::mem_fun (*this, &CanvasFlag::on_event));
}
void
@@ -49,7 +49,7 @@ CanvasFlag::set_text (const string& text)
{
delete_allocated_objects();
- _name_pixbuf = new ArdourCanvas::Pixbuf (*this);
+ _name_pixbuf = new ArdourCanvas::NoEventPixbuf (*this);
name_pixbuf_width = Gtkmm2ext::pixel_width (text, TimeAxisViewItem::NAME_FONT) + 2;
Gdk::Color c;
set_color (c, _outline_color_rgba);
@@ -75,15 +75,6 @@ CanvasFlag::~CanvasFlag()
delete_allocated_objects();
}
-bool
-CanvasFlag::on_event(GdkEvent* /*ev*/)
-{
- /* XXX if you change this function to actually do anything, be sure
- to fix the connections commented out elsewhere in this file.
- */
- return false;
-}
-
void
CanvasFlag::set_height (double h)
{
diff --git a/gtk2_ardour/canvas-flag.h b/gtk2_ardour/canvas-flag.h
index 17edc19880..4ad41ec883 100644
--- a/gtk2_ardour/canvas-flag.h
+++ b/gtk2_ardour/canvas-flag.h
@@ -28,8 +28,6 @@ public:
virtual ~CanvasFlag();
- virtual bool on_event(GdkEvent* ev);
-
virtual void set_text(const std::string& a_text);
virtual void set_height (double);
diff --git a/gtk2_ardour/canvas-noevent-pixbuf.h b/gtk2_ardour/canvas-noevent-pixbuf.h
new file mode 100644
index 0000000000..4424a9087e
--- /dev/null
+++ b/gtk2_ardour/canvas-noevent-pixbuf.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2009 Paul Davis
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __gtk2_ardour_canvas_noevent_pixbuf_h__
+#define __gtk2_ardour_canvas_noevent_pixbuf_h__
+
+#include
+
+namespace Gnome { namespace Canvas {
+
+class NoEventPixbuf : public Pixbuf
+{
+ public:
+ NoEventPixbuf(Group& parent) : Pixbuf (parent) {}
+
+ double point_vfunc(double, double, int, int, GnomeCanvasItem**) {
+ /* return a huge value to tell the canvas that we're never the item for an event */
+ return 9999999999999.0;
+ }
+};
+
+} } /* namespaces */
+
+#endif /* __gtk2_ardour_canvas_noevent_pixbuf_h__ */
diff --git a/gtk2_ardour/canvas_patch_change.cc b/gtk2_ardour/canvas_patch_change.cc
index ff28295c6e..29e30e332d 100644
--- a/gtk2_ardour/canvas_patch_change.cc
+++ b/gtk2_ardour/canvas_patch_change.cc
@@ -21,6 +21,8 @@
#include
+#include "pbd/stacktrace.h"
+
#include "gtkmm2ext/keyboard.h"
#include "ardour/instrument_info.h"
@@ -81,41 +83,60 @@ CanvasPatchChange::initialize_popup_menus()
const ChannelNameSet::PatchBanks& patch_banks = channel_name_set->patch_banks();
- // fill popup menu:
- Gtk::Menu::MenuList& patch_bank_menus = _popup.items();
-
- for (ChannelNameSet::PatchBanks::const_iterator bank = patch_banks.begin();
- bank != patch_banks.end();
- ++bank) {
- Gtk::Menu& patch_bank_menu = *manage(new Gtk::Menu());
-
- const PatchBank::PatchNameList& patches = (*bank)->patch_name_list();
- Gtk::Menu::MenuList& patch_menus = patch_bank_menu.items();
+ if (patch_banks.size() > 1) {
+ // fill popup menu:
+ Gtk::Menu::MenuList& patch_bank_menus = _popup.items();
+
+ for (ChannelNameSet::PatchBanks::const_iterator bank = patch_banks.begin();
+ bank != patch_banks.end();
+ ++bank) {
+ Gtk::Menu& patch_bank_menu = *manage(new Gtk::Menu());
+
+ const PatchBank::PatchNameList& patches = (*bank)->patch_name_list();
+ Gtk::Menu::MenuList& patch_menus = patch_bank_menu.items();
+
+ for (PatchBank::PatchNameList::const_iterator patch = patches.begin();
+ patch != patches.end();
+ ++patch) {
+ std::string name = (*patch)->name();
+ boost::replace_all (name, "_", " ");
+
+ patch_menus.push_back(
+ Gtk::Menu_Helpers::MenuElem(
+ name,
+ sigc::bind(
+ sigc::mem_fun(*this, &CanvasPatchChange::on_patch_menu_selected),
+ (*patch)->patch_primary_key())) );
+ }
+
+ std::string name = (*bank)->name();
+ boost::replace_all (name, "_", " ");
+
+ patch_bank_menus.push_back(
+ Gtk::Menu_Helpers::MenuElem(
+ name,
+ patch_bank_menu) );
+ }
+ } else {
+ /* only one patch bank, so make it the initial menu */
+ const PatchBank::PatchNameList& patches = patch_banks.front()->patch_name_list();
+ Gtk::Menu::MenuList& patch_menus = _popup.items();
+
for (PatchBank::PatchNameList::const_iterator patch = patches.begin();
patch != patches.end();
++patch) {
std::string name = (*patch)->name();
boost::replace_all (name, "_", " ");
-
- patch_menus.push_back(
- Gtk::Menu_Helpers::MenuElem(
- name,
- sigc::bind(
- sigc::mem_fun(*this, &CanvasPatchChange::on_patch_menu_selected),
- (*patch)->patch_primary_key())) );
+
+ patch_menus.push_back (Gtk::Menu_Helpers::MenuElem (name,
+ sigc::bind (
+ sigc::mem_fun(*this, &CanvasPatchChange::on_patch_menu_selected),
+ (*patch)->patch_primary_key())));
}
-
- std::string name = (*bank)->name();
- boost::replace_all (name, "_", " ");
-
- patch_bank_menus.push_back(
- Gtk::Menu_Helpers::MenuElem(
- name,
- patch_bank_menu) );
}
}
-
+
void
CanvasPatchChange::on_patch_menu_selected(const PatchPrimaryKey& key)
{
@@ -125,11 +146,12 @@ CanvasPatchChange::on_patch_menu_selected(const PatchPrimaryKey& key)
bool
CanvasPatchChange::on_event (GdkEvent* ev)
{
+ Editor* e;
+
switch (ev->type) {
case GDK_BUTTON_PRESS:
- {
/* XXX: icky dcast */
- Editor* e = dynamic_cast (&_region.get_time_axis_view().editor());
+ e = dynamic_cast (&_region.get_time_axis_view().editor());
if (e->current_mouse_mode() == Editing::MouseObject && e->internal_editing()) {
if (Gtkmm2ext::Keyboard::is_delete_event (&ev->button)) {
@@ -159,7 +181,6 @@ CanvasPatchChange::on_event (GdkEvent* ev)
return true;
}
break;
- }
case GDK_KEY_PRESS:
switch (ev->key.keyval) {
@@ -181,15 +202,18 @@ CanvasPatchChange::on_event (GdkEvent* ev)
_region.next_patch (*this);
}
break;
+ case GDK_Delete:
+ case GDK_BackSpace:
+ _region.delete_patch_change (this);
+ break;
default:
break;
}
break;
case GDK_SCROLL:
- {
/* XXX: icky dcast */
- Editor* e = dynamic_cast (&_region.get_time_axis_view().editor());
+ e = dynamic_cast (&_region.get_time_axis_view().editor());
if (e->current_mouse_mode() == Editing::MouseObject && e->internal_editing()) {
if (ev->scroll.direction == GDK_SCROLL_UP) {
if (Keyboard::modifier_state_contains (ev->scroll.state, Keyboard::PrimaryModifier)) {
@@ -197,25 +221,26 @@ CanvasPatchChange::on_event (GdkEvent* ev)
} else {
_region.previous_patch (*this);
}
- return true;
} else if (ev->scroll.direction == GDK_SCROLL_DOWN) {
if (Keyboard::modifier_state_contains (ev->scroll.state, Keyboard::PrimaryModifier)) {
_region.next_bank (*this);
} else {
_region.next_patch (*this);
}
- return true;
}
+ return true;
break;
}
- }
+ break;
case GDK_ENTER_NOTIFY:
_region.patch_entered (this);
+ return true;
break;
case GDK_LEAVE_NOTIFY:
_region.patch_left (this);
+ return true;
break;
default:
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index 939c05b1e8..e3e00cf340 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -282,6 +282,7 @@ Editor::Editor ()
, _region_selection_change_updates_region_list (true)
, _following_mixer_selection (false)
, _control_point_toggled_on_press (false)
+ , _stepping_axis_view (0)
{
constructed = false;
@@ -696,6 +697,8 @@ Editor::Editor ()
signal_configure_event().connect (sigc::mem_fun (*ARDOUR_UI::instance(), &ARDOUR_UI::configure_handler));
signal_delete_event().connect (sigc::mem_fun (*ARDOUR_UI::instance(), &ARDOUR_UI::exit_on_main_window_close));
+ Gtkmm2ext::Keyboard::the_keyboard().ShiftReleased.connect (sigc::mem_fun (*this, &Editor::shift_key_released));
+
/* allow external control surfaces/protocols to do various things */
ControlProtocol::ZoomToSession.connect (*this, invalidator (*this), boost::bind (&Editor::temporal_zoom_session, this), gui_context());
@@ -5473,3 +5476,8 @@ Editor::popup_control_point_context_menu (ArdourCanvas::Item* item, GdkEvent* ev
_control_point_context_menu.popup (event->button.button, event->button.time);
}
+void
+Editor::shift_key_released ()
+{
+ _stepping_axis_view = 0;
+}
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 5134b6a7a1..3fd38ec609 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -470,6 +470,14 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void get_pointer_position (double &, double &) const;
+ TimeAxisView* stepping_axis_view () {
+ return _stepping_axis_view;
+ }
+
+ void set_stepping_axis_view (TimeAxisView* v) {
+ _stepping_axis_view = v;
+ }
+
protected:
void map_transport_state ();
void map_position_change (framepos_t);
@@ -624,6 +632,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void hide_marker (ArdourCanvas::Item*, GdkEvent*);
void clear_marker_display ();
void mouse_add_new_marker (framepos_t where, bool is_cd=false, bool is_xrun=false);
+ void mouse_add_new_range (framepos_t);
bool choose_new_marker_name(std::string &name);
void update_cd_marker_display ();
void ensure_cd_marker_updated (LocationMarkers * lam, ARDOUR::Location * location);
@@ -2102,6 +2111,17 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
/** Flag for a bit of a hack wrt control point selection; see set_selected_control_point_from_click */
bool _control_point_toggled_on_press;
+ /** This is used by TimeAxisView to keep a track of the TimeAxisView that is currently being
+ stepped in height using Shift-Scrollwheel. When a scroll event occurs, we do the step on
+ this _stepping_axis_view if it is non-0 (and we set up this _stepping_axis_view with the
+ TimeAxisView underneath the mouse if it is 0). Then Editor resets _stepping_axis_view when
+ the shift key is released. In this (hacky) way, pushing shift and moving the scroll wheel
+ will operate on the same track until shift is released (rather than skipping about to whatever
+ happens to be underneath the mouse at the time).
+ */
+ TimeAxisView* _stepping_axis_view;
+ void shift_key_released ();
+
friend class Drag;
friend class RegionDrag;
friend class RegionMoveDrag;
diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc
index 9e43fcc35c..3e7aad2a1b 100644
--- a/gtk2_ardour/editor_canvas.cc
+++ b/gtk2_ardour/editor_canvas.cc
@@ -501,6 +501,10 @@ Editor::autoscroll_fudge_threshold () const
void
Editor::maybe_autoscroll (bool allow_horiz, bool allow_vert, bool moving_left, bool moving_up)
{
+ if (!Config->get_autoscroll_editor ()) {
+ return;
+ }
+
bool startit = false;
/* Work out the distance between the right hand edge of the trackview and the edge of
diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc
index e5eb7630c0..ae3795f7fa 100644
--- a/gtk2_ardour/editor_drag.cc
+++ b/gtk2_ardour/editor_drag.cc
@@ -1823,6 +1823,10 @@ TrimDrag::finished (GdkEvent* event, bool movement_occurred)
_editor->motion_frozen_playlists.clear ();
_editor->commit_reversible_command();
+ for (list::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ i->view->drag_end ();
+ }
+
} else {
/* no mouse movement */
_editor->point_trim (event, adjusted_current_frame (event));
diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc
index 46f4a0ddd5..28706ac7bc 100644
--- a/gtk2_ardour/editor_markers.cc
+++ b/gtk2_ardour/editor_markers.cc
@@ -661,6 +661,31 @@ Editor::mouse_add_new_marker (framepos_t where, bool is_cd, bool is_xrun)
}
}
+void
+Editor::mouse_add_new_range (framepos_t where)
+{
+ if (!_session) {
+ return;
+ }
+
+ /* Make this marker 1/8th of the visible area of the session so that
+ it's reasonably easy to manipulate after creation.
+ */
+
+ framepos_t const end = where + current_page_frames() / 8;
+
+ string name;
+ _session->locations()->next_available_name (name, _("range"));
+ Location* loc = new Location (*_session, where, end, name, Location::IsRangeMarker);
+
+ begin_reversible_command (_("new range marker"));
+ XMLNode& before = _session->locations()->get_state ();
+ _session->locations()->add (loc, true);
+ XMLNode& after = _session->locations()->get_state ();
+ _session->add_command (new MementoCommand (*_session->locations(), &before, &after));
+ commit_reversible_command ();
+}
+
void
Editor::remove_marker (ArdourCanvas::Item& item, GdkEvent*)
{
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 05ecc23c32..eacf0c51bd 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -3393,7 +3393,6 @@ Editor::freeze_thread ()
/* create event pool because we may need to talk to the session */
SessionEvent::create_per_thread_pool ("freeze events", 64);
/* create per-thread buffers for process() tree to use */
- current_interthread_info->process_thread.init ();
current_interthread_info->process_thread.get_buffers ();
clicked_routeview->audio_track()->freeze_me (*current_interthread_info);
current_interthread_info->done = true;
diff --git a/gtk2_ardour/editor_rulers.cc b/gtk2_ardour/editor_rulers.cc
index ea5622e4c9..ac771c42f0 100644
--- a/gtk2_ardour/editor_rulers.cc
+++ b/gtk2_ardour/editor_rulers.cc
@@ -342,7 +342,7 @@ Editor::popup_ruler_menu (framepos_t where, ItemType t)
ruler_items.push_back (SeparatorElem ());
break;
case RangeMarkerBarItem:
- //ruler_items.push_back (MenuElem (_("New Range")));
+ ruler_items.push_back (MenuElem (_("New range"), sigc::bind (sigc::mem_fun (*this, &Editor::mouse_add_new_range), where)));
ruler_items.push_back (MenuElem (_("Clear all ranges"), sigc::mem_fun(*this, &Editor::clear_ranges)));
ruler_items.push_back (MenuElem (_("Unhide ranges"), sigc::mem_fun(*this, &Editor::unhide_ranges)));
ruler_items.push_back (SeparatorElem ());
diff --git a/gtk2_ardour/location_ui.cc b/gtk2_ardour/location_ui.cc
index ea6a3f544c..9f027ea8bf 100644
--- a/gtk2_ardour/location_ui.cc
+++ b/gtk2_ardour/location_ui.cc
@@ -322,7 +322,7 @@ LocationEditRow::set_location (Location *loc)
length_clock.hide();
}
- set_clock_sensitivity ();
+ set_clock_editable_status ();
--i_am_the_modifier;
@@ -632,7 +632,7 @@ LocationEditRow::location_changed (ARDOUR::Location*)
end_clock.set (location->end());
length_clock.set (location->length());
- set_clock_sensitivity ();
+ set_clock_editable_status ();
i_am_the_modifier--;
@@ -665,7 +665,7 @@ LocationEditRow::lock_changed (ARDOUR::Location*)
lock_check_button.set_active (location->locked());
- set_clock_sensitivity ();
+ set_clock_editable_status ();
i_am_the_modifier--;
}
@@ -691,11 +691,11 @@ LocationEditRow::focus_name()
}
void
-LocationEditRow::set_clock_sensitivity ()
+LocationEditRow::set_clock_editable_status ()
{
- start_clock.set_sensitive (!location->locked());
- end_clock.set_sensitive (!location->locked());
- length_clock.set_sensitive (!location->locked());
+ start_clock.set_editable (!location->locked());
+ end_clock.set_editable (!location->locked());
+ length_clock.set_editable (!location->locked());
}
/*------------------------------------------------------------------------*/
diff --git a/gtk2_ardour/location_ui.h b/gtk2_ardour/location_ui.h
index b850b89ddd..b01b63e8e4 100644
--- a/gtk2_ardour/location_ui.h
+++ b/gtk2_ardour/location_ui.h
@@ -139,7 +139,7 @@ class LocationEditRow : public Gtk::HBox, public ARDOUR::SessionHandlePtr
void lock_changed (ARDOUR::Location *);
void position_lock_style_changed (ARDOUR::Location *);
- void set_clock_sensitivity ();
+ void set_clock_editable_status ();
PBD::ScopedConnectionList connections;
};
diff --git a/gtk2_ardour/lv2_plugin_ui.cc b/gtk2_ardour/lv2_plugin_ui.cc
index e2120e112a..7e8f827596 100644
--- a/gtk2_ardour/lv2_plugin_ui.cc
+++ b/gtk2_ardour/lv2_plugin_ui.cc
@@ -268,6 +268,7 @@ LV2PluginUI::lv2ui_instantiate(const std::string& title)
_ardour_buttons_box->pack_end (save_button, false, false);
_ardour_buttons_box->pack_end (add_button, false, false);
_ardour_buttons_box->pack_end (_preset_combo, false, false);
+ _ardour_buttons_box->pack_end (_preset_modified, false, false);
_ardour_buttons_box->show_all();
pack_start(*_ardour_buttons_box, false, false);
diff --git a/gtk2_ardour/main.cc b/gtk2_ardour/main.cc
index 0bf73ed5bf..a1562aa137 100644
--- a/gtk2_ardour/main.cc
+++ b/gtk2_ardour/main.cc
@@ -186,31 +186,24 @@ fixup_bundle_environment (int, char* [])
if (g_mkdir_with_parents (userconfigdir.c_str(), 0755) < 0) {
error << string_compose (_("cannot create user ardour folder %1 (%2)"), userconfigdir, strerror (errno))
<< endmsg;
- return;
- }
-
- path = Glib::build_filename (userconfigdir, "pango.rc");
- std::ofstream pangorc (path.c_str());
- if (!pangorc) {
- error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
} else {
- pangorc << "[Pango]\nModuleFiles="
- << Glib::build_filename (bundle_dir, "Resources/pango.modules")
- << endl;
- pangorc.close ();
-
- setenv ("PANGO_RC_FILE", path.c_str(), 1);
+
+ path = Glib::build_filename (userconfigdir, "pango.rc");
+ std::ofstream pangorc (path.c_str());
+ if (!pangorc) {
+ error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
+ } else {
+ pangorc << "[Pango]\nModuleFiles="
+ << Glib::build_filename (bundle_dir, "Resources/pango.modules")
+ << endl;
+ pangorc.close ();
+
+ setenv ("PANGO_RC_FILE", path.c_str(), 1);
+ }
}
-
- // gettext charset aliases XXX do we really need this, since the path
- // is totally wrong?
-
- setenv ("CHARSETALIASDIR", path.c_str(), 1);
-
+
+ setenv ("CHARSETALIASDIR", bundle_dir.c_str(), 1);
setenv ("FONTCONFIG_FILE", Glib::build_filename (bundle_dir, "Resources/fonts.conf").c_str(), 1);
-
- // GDK Pixbuf loader module file
-
setenv ("GDK_PIXBUF_MODULE_FILE", Glib::build_filename (bundle_dir, "Resources/gdk-pixbuf.loaders").c_str(), 1);
// Where to find soundgrid library (if it exists)
@@ -286,27 +279,33 @@ fixup_bundle_environment (int /*argc*/, char* argv[])
if (g_mkdir_with_parents (userconfigdir.c_str(), 0755) < 0) {
error << string_compose (_("cannot create user ardour folder %1 (%2)"), userconfigdir, strerror (errno))
<< endmsg;
- return;
- }
-
- path = Glib::build_filename (userconfigdir, "pango.rc");
- std::ofstream pangorc (path.c_str());
- if (!pangorc) {
- error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
} else {
- pangorc << "[Pango]\nModuleFiles="
- << Glib::build_filename (userconfigdir, "pango.modules")
- << endl;
- pangorc.close ();
+
+ path = Glib::build_filename (userconfigdir, "pango.rc");
+ std::ofstream pangorc (path.c_str());
+ if (!pangorc) {
+ error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
+ } else {
+ pangorc << "[Pango]\nModuleFiles="
+ << Glib::build_filename (userconfigdir, "pango.modules")
+ << endl;
+ pangorc.close ();
+ }
+
+ setenv ("PANGO_RC_FILE", path.c_str(), 1);
+
+ /* similar for GDK pixbuf loaders, but there's no RC file required
+ to specify where it lives.
+ */
+
+ setenv ("GDK_PIXBUF_MODULE_FILE", Glib::build_filename (userconfigdir, "gdk-pixbuf.loaders").c_str(), 1);
}
-
- setenv ("PANGO_RC_FILE", path.c_str(), 1);
- /* similar for GDK pixbuf loaders, but there's no RC file required
- to specify where it lives.
- */
-
- setenv ("GDK_PIXBUF_MODULE_FILE", Glib::build_filename (userconfigdir, "gdk-pixbuf.loaders").c_str(), 1);
+ /* this doesn't do much but setting it should prevent various parts of the GTK/GNU stack
+ from looking outside the bundle to find the charset.alias file.
+ */
+ setenv ("CHARSETALIASDIR", dir_path.c_str(), 1);
+
}
#endif
diff --git a/gtk2_ardour/midi_list_editor.cc b/gtk2_ardour/midi_list_editor.cc
index 20fc0ed433..774c6fccf7 100644
--- a/gtk2_ardour/midi_list_editor.cc
+++ b/gtk2_ardour/midi_list_editor.cc
@@ -1,19 +1,19 @@
/*
Copyright (C) 2009 Paul Davis
- 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.
+ 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
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc
index c2d706382e..ce02bf0149 100644
--- a/gtk2_ardour/midi_region_view.cc
+++ b/gtk2_ardour/midi_region_view.cc
@@ -277,8 +277,7 @@ MidiRegionView::init (Gdk::Color const & basic_color, bool wfd)
reset_width_dependent_items (_pixel_width);
group->raise_to_top();
- group->signal_event().connect(
- sigc::mem_fun(this, &MidiRegionView::canvas_event), false);
+ group->signal_event().connect (sigc::mem_fun (this, &MidiRegionView::canvas_event), false);
midi_view()->signal_channel_mode_changed().connect(
sigc::mem_fun(this, &MidiRegionView::midi_channel_mode_changed));
@@ -322,7 +321,7 @@ bool
MidiRegionView::canvas_event(GdkEvent* ev)
{
bool r;
-
+
switch (ev->type) {
case GDK_ENTER_NOTIFY:
case GDK_LEAVE_NOTIFY:
@@ -714,7 +713,11 @@ MidiRegionView::key_press (GdkEventKey* ev)
return true;
- } else if (ev->keyval == GDK_Delete && unmodified) {
+ } else if ((ev->keyval == GDK_BackSpace || ev->keyval == GDK_Delete) && unmodified) {
+
+ if (_selection.empty()) {
+ return false;
+ }
delete_selection();
return true;
@@ -925,9 +928,9 @@ MidiRegionView::create_note_at (framepos_t t, double y, double length, bool snap
}
void
-MidiRegionView::clear_events()
+MidiRegionView::clear_events (bool with_selection_signal)
{
- clear_selection();
+ clear_selection (with_selection_signal);
MidiGhostRegion* gr;
for (std::vector::iterator g = ghosts.begin(); g != ghosts.end(); ++g) {
@@ -1316,7 +1319,7 @@ MidiRegionView::~MidiRegionView ()
_selection_cleared_connection.disconnect ();
_selection.clear();
- clear_events();
+ clear_events (false);
delete _note_group;
delete _note_diff_command;
@@ -1798,7 +1801,7 @@ MidiRegionView::add_canvas_patch_change (MidiModel::PatchChangePtr patch, const
double const height = midi_stream_view()->contents_height();
boost::shared_ptr patch_change = boost::shared_ptr(
- new CanvasPatchChange(*this, *_note_group,
+ new CanvasPatchChange(*this, *group,
displaytext,
height,
x, 1.0,
@@ -3139,18 +3142,24 @@ MidiRegionView::note_left (ArdourCanvas::CanvasNoteEvent*)
}
void
-MidiRegionView::patch_entered (ArdourCanvas::CanvasPatchChange* ev)
+MidiRegionView::patch_entered (ArdourCanvas::CanvasPatchChange* p)
{
ostringstream s;
/* XXX should get patch name if we can */
- s << _("Bank:") << (ev->patch()->bank() + MIDI_BP_ZERO) << '\n' << _("Program:") << ((int) ev->patch()->program()) + MIDI_BP_ZERO << '\n' << _("Channel:") << ((int) ev->patch()->channel() + 1);
+ s << _("Bank:") << (p->patch()->bank() + MIDI_BP_ZERO) << '\n'
+ << _("Program:") << ((int) p->patch()->program()) + MIDI_BP_ZERO << '\n'
+ << _("Channel:") << ((int) p->patch()->channel() + 1);
show_verbose_cursor (s.str(), 10, 20);
+ p->grab_focus();
}
void
MidiRegionView::patch_left (ArdourCanvas::CanvasPatchChange *)
{
trackview.editor().verbose_cursor()->hide ();
+ /* focus will transfer back via the enter-notify event sent to this
+ * midi region view.
+ */
}
void
diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h
index 86600e8b8d..7674ea245f 100644
--- a/gtk2_ardour/midi_region_view.h
+++ b/gtk2_ardour/midi_region_view.h
@@ -348,7 +348,7 @@ private:
void start_playing_midi_note (boost::shared_ptr note);
void start_playing_midi_chord (std::vector > notes);
- void clear_events();
+ void clear_events (bool with_selection_signal = true);
bool canvas_event(GdkEvent* ev);
bool note_canvas_event(GdkEvent* ev);
diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc
index f182c301d6..9a4200b4af 100644
--- a/gtk2_ardour/midi_time_axis.cc
+++ b/gtk2_ardour/midi_time_axis.cc
@@ -113,7 +113,6 @@ MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session* sess, Canvas& can
, _channel_color_mode_item(0)
, _track_color_mode_item(0)
, _step_edit_item (0)
- , _midi_thru_item (0)
, controller_menu (0)
, _step_editor (0)
{
@@ -405,25 +404,9 @@ MidiTimeAxisView::append_extra_display_menu_items ()
items.push_back (MenuElem (_("Note Range"), *range_menu));
items.push_back (MenuElem (_("Note Mode"), *build_note_mode_menu()));
- items.push_back (CheckMenuElem (_("MIDI Thru"), sigc::mem_fun(*this, &MidiTimeAxisView::toggle_midi_thru)));
- _midi_thru_item = dynamic_cast(&items.back());
-
items.push_back (SeparatorElem ());
}
-void
-MidiTimeAxisView::toggle_midi_thru ()
-{
- if (!_midi_thru_item) {
- return;
- }
-
- bool view_yn = _midi_thru_item->get_active();
- if (view_yn != midi_track()->midi_thru()) {
- midi_track()->set_midi_thru (view_yn);
- }
-}
-
void
MidiTimeAxisView::build_automation_action_menu (bool for_selection)
{
diff --git a/gtk2_ardour/midi_time_axis.h b/gtk2_ardour/midi_time_axis.h
index 4da89df109..8761979947 100644
--- a/gtk2_ardour/midi_time_axis.h
+++ b/gtk2_ardour/midi_time_axis.h
@@ -136,11 +136,8 @@ class MidiTimeAxisView : public RouteTimeAxisView
Gtk::ComboBoxText _custom_device_mode_selector;
Gtk::CheckMenuItem* _step_edit_item;
- Gtk::CheckMenuItem* _midi_thru_item;
Gtk::Menu* default_channel_menu;
- void toggle_midi_thru ();
-
void change_all_channel_tracks_visibility (bool yn, Evoral::Parameter param);
void add_basic_parameter_menu_item (Gtk::Menu_Helpers::MenuList& items, const std::string& label, Evoral::Parameter param);
void add_channel_command_menu_item (Gtk::Menu_Helpers::MenuList& items, const std::string& label, ARDOUR::AutomationType auto_type, uint8_t cmd);
diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc
index ff3fd54624..adce954a91 100644
--- a/gtk2_ardour/mixer_strip.cc
+++ b/gtk2_ardour/mixer_strip.cc
@@ -611,7 +611,7 @@ MixerStrip::set_width_enum (Width w, void* owner)
solo_isolated_led->set_text (_("iso"));
solo_safe_led->set_text (_("lock"));
- Gtkmm2ext::set_size_request_to_display_given_text (name_button, "long", 2, 2);
+ Gtkmm2ext::set_size_request_to_display_given_text (name_button, longest_label.c_str(), 2, 2);
set_size_request (-1, -1);
break;
@@ -635,7 +635,7 @@ MixerStrip::set_width_enum (Width w, void* owner)
solo_isolated_led->set_text (_("i"));
solo_safe_led->set_text (_("L"));
- Gtkmm2ext::set_size_request_to_display_given_text (name_button, longest_label.c_str(), 2, 2);
+ Gtkmm2ext::set_size_request_to_display_given_text (name_button, "long", 2, 2);
set_size_request (max (50, gpm.get_gm_width()), -1);
break;
}
diff --git a/gtk2_ardour/option_editor.cc b/gtk2_ardour/option_editor.cc
index e1946002c1..a6fcc734c5 100644
--- a/gtk2_ardour/option_editor.cc
+++ b/gtk2_ardour/option_editor.cc
@@ -163,6 +163,60 @@ EntryOption::activated ()
_set (_entry->get_text ());
}
+/** Construct a BoolComboOption.
+ * @param i id
+ * @param n User-visible name.
+ * @param t Text to give for the variable being true.
+ * @param f Text to give for the variable being false.
+ * @param g Slot to get the variable's value.
+ * @param s Slot to set the variable's value.
+ */
+BoolComboOption::BoolComboOption (
+ string const & i, string const & n, string const & t, string const & f,
+ sigc::slot g, sigc::slot s
+ )
+ : Option (i, n)
+ , _get (g)
+ , _set (s)
+{
+ _label = manage (new Label (n + ":"));
+ _label->set_alignment (0, 0.5);
+ _combo = manage (new ComboBoxText);
+
+ /* option 0 is the false option */
+ _combo->append_text (f);
+ /* and option 1 is the true */
+ _combo->append_text (t);
+
+ _combo->signal_changed().connect (sigc::mem_fun (*this, &BoolComboOption::changed));
+}
+
+void
+BoolComboOption::set_state_from_config ()
+{
+ _combo->set_active (_get() ? 1 : 0);
+}
+
+void
+BoolComboOption::add_to_page (OptionEditorPage* p)
+{
+ add_widgets_to_page (p, _label, _combo);
+}
+
+void
+BoolComboOption::changed ()
+{
+ _set (_combo->get_active_row_number () == 0 ? false : true);
+}
+
+void
+BoolComboOption::set_sensitive (bool yn)
+{
+ _combo->set_sensitive (yn);
+}
+
+
+
FaderOption::FaderOption (string const & i, string const & n, sigc::slot g, sigc::slot s)
: Option (i, n)
, _db_adjustment (gain_to_slider_position_with_max (1.0, Config->get_max_gain()), 0, 1, 0.01, 0.1)
diff --git a/gtk2_ardour/option_editor.h b/gtk2_ardour/option_editor.h
index 5d6a48a024..b896411a71 100644
--- a/gtk2_ardour/option_editor.h
+++ b/gtk2_ardour/option_editor.h
@@ -192,7 +192,7 @@ private:
};
-/** Component which provides the UI to handle an enumerated option using a GTK CheckButton.
+/** Component which provides the UI to handle an enumerated option using a GTK ComboBox.
* The template parameter is the enumeration.
*/
template
@@ -273,6 +273,37 @@ private:
};
+/** Component which provides the UI to handle a boolean option which needs
+ * to be represented as a ComboBox to be clear to the user.
+ */
+class BoolComboOption : public Option
+{
+public:
+
+ BoolComboOption (
+ std::string const &,
+ std::string const &,
+ std::string const &,
+ std::string const &,
+ sigc::slot,
+ sigc::slot
+ );
+
+ void set_state_from_config ();
+ void add_to_page (OptionEditorPage *);
+ void changed ();
+ void set_sensitive (bool);
+
+private:
+
+ sigc::slot _get;
+ sigc::slot _set;
+ Gtk::Label* _label;
+ Gtk::ComboBoxText* _combo;
+};
+
+
+
/** Component which provides the UI to handle an numeric option using a GTK SpinButton */
template
class SpinOption : public Option
diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc
index 455cea1364..169928843a 100644
--- a/gtk2_ardour/plugin_ui.cc
+++ b/gtk2_ardour/plugin_ui.cc
@@ -593,6 +593,9 @@ PlugUIBase::preset_selected ()
warning << string_compose(_("Plugin preset %1 not found"),
_preset_combo.get_active_text()) << endmsg;
}
+ } else {
+ // blank selected = no preset
+ plugin->clear_preset();
}
}
@@ -745,6 +748,8 @@ PlugUIBase::update_preset_list ()
preset_labels.push_back (i->label);
}
+ preset_labels.push_back("");
+
set_popdown_strings (_preset_combo, preset_labels);
--_no_load_preset;
@@ -768,6 +773,7 @@ PlugUIBase::update_preset ()
void
PlugUIBase::update_preset_modified ()
{
+
if (plugin->last_preset().uri.empty()) {
_preset_modified.set_text ("");
return;
diff --git a/gtk2_ardour/port_matrix.cc b/gtk2_ardour/port_matrix.cc
index 7f0d9fb9f3..8465cdcd32 100644
--- a/gtk2_ardour/port_matrix.cc
+++ b/gtk2_ardour/port_matrix.cc
@@ -969,6 +969,10 @@ PortMatrix::port_connected_or_disconnected ()
void
PortMatrix::update_tab_highlighting ()
{
+ if (!_session) {
+ return;
+ }
+
for (int i = 0; i < 2; ++i) {
Gtk::Notebook* notebook = row_index() == i ? &_vnotebook : &_hnotebook;
diff --git a/gtk2_ardour/rc_option_editor.cc b/gtk2_ardour/rc_option_editor.cc
index 4d12c8e739..9ba83021d5 100644
--- a/gtk2_ardour/rc_option_editor.cc
+++ b/gtk2_ardour/rc_option_editor.cc
@@ -1063,9 +1063,11 @@ RCOptionEditor::RCOptionEditor ()
));
add_option (_("Editor"),
- new BoolOption (
+ new BoolComboOption (
"show-region-gain-envelopes",
_("Show gain envelopes in audio regions"),
+ _("in all modes"),
+ _("only in region gain mode"),
sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_region_gain),
sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_region_gain)
));
@@ -1150,6 +1152,14 @@ RCOptionEditor::RCOptionEditor ()
sigc::mem_fun (*_rc_config, &RCConfiguration::set_name_new_markers)
));
+ add_option (_("Editor"),
+ new BoolOption (
+ "autoscroll-editor",
+ _("Auto-scroll editor window when dragging near its edges"),
+ sigc::mem_fun (*_rc_config, &RCConfiguration::get_autoscroll_editor),
+ sigc::mem_fun (*_rc_config, &RCConfiguration::set_autoscroll_editor)
+ ));
+
/* AUDIO */
add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
@@ -1587,7 +1597,7 @@ RCOptionEditor::RCOptionEditor ()
add_option (S_("Visual|Interface"),
new BoolOption (
"default-narrow_ms",
- _("Use narrow mixer strips by default"),
+ _("Use narrow strips in the mixer by default"),
sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_narrow_ms),
sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_narrow_ms)
));
diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc
index da39d45db6..bff119d29d 100644
--- a/gtk2_ardour/sfdb_ui.cc
+++ b/gtk2_ardour/sfdb_ui.cc
@@ -582,6 +582,9 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
notebook.set_size_request (500, -1);
+ notebook.signal_switch_page().connect (
+ sigc::hide_return (sigc::hide (sigc::hide (sigc::mem_fun (*this, &SoundFileBrowser::reset_options))))
+ );
set_session (s);
@@ -1016,6 +1019,7 @@ SoundFileOmega::reset_options ()
channel_combo.set_sensitive (false);
action_combo.set_sensitive (false);
where_combo.set_sensitive (false);
+ copy_files_btn.set_active (true);
copy_files_btn.set_sensitive (false);
return false;
@@ -1028,7 +1032,7 @@ SoundFileOmega::reset_options ()
/* if we get through this function successfully, this may be
reset at the end, once we know if we can use hard links
- to do embedding
+ to do embedding (or if we are importing a MIDI file).
*/
if (Config->get_only_copy_imported_files()) {
@@ -1044,6 +1048,13 @@ SoundFileOmega::reset_options ()
bool selection_can_be_embedded_with_links = check_link_status (_session, paths);
ImportMode mode;
+ /* See if we are thinking about importing any MIDI files */
+ vector::iterator i = paths.begin ();
+ while (i != paths.end() && SMFSource::safe_midi_file_extension (*i) == false) {
+ ++i;
+ }
+ bool const have_a_midi_file = (i != paths.end ());
+
if (check_info (paths, same_size, src_needed, selection_includes_multichannel)) {
Glib::signal_idle().connect (sigc::mem_fun (*this, &SoundFileOmega::bad_file_message));
return false;
@@ -1194,17 +1205,26 @@ SoundFileOmega::reset_options ()
src_combo.set_sensitive (false);
}
+ /* We must copy MIDI files or those from Freesound */
+ bool const must_copy = have_a_midi_file || notebook.get_current_page() == 2;
+
if (Config->get_only_copy_imported_files()) {
- if (selection_can_be_embedded_with_links) {
+ if (selection_can_be_embedded_with_links && !must_copy) {
copy_files_btn.set_sensitive (true);
} else {
+ if (must_copy) {
+ copy_files_btn.set_active (true);
+ }
copy_files_btn.set_sensitive (false);
}
} else {
- copy_files_btn.set_sensitive (true);
+ if (must_copy) {
+ copy_files_btn.set_active (true);
+ }
+ copy_files_btn.set_sensitive (!must_copy);
}
return true;
diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc
index ddf03e968e..ee5c7c1c2a 100644
--- a/gtk2_ardour/time_axis_view.cc
+++ b/gtk2_ardour/time_axis_view.cc
@@ -48,6 +48,7 @@
#include "utils.h"
#include "streamview.h"
#include "editor_drag.h"
+#include "editor.h"
#include "i18n.h"
@@ -317,7 +318,12 @@ TimeAxisView::controls_ebox_scroll (GdkEventScroll* ev)
switch (ev->direction) {
case GDK_SCROLL_UP:
if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
- step_height (false);
+ /* See Editor::_stepping_axis_view for notes on this hack */
+ Editor& e = dynamic_cast (_editor);
+ if (!e.stepping_axis_view ()) {
+ e.set_stepping_axis_view (this);
+ }
+ e.stepping_axis_view()->step_height (false);
return true;
} else if (Keyboard::no_modifiers_active (ev->state)) {
_editor.scroll_tracks_up_line();
@@ -327,7 +333,12 @@ TimeAxisView::controls_ebox_scroll (GdkEventScroll* ev)
case GDK_SCROLL_DOWN:
if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
- step_height (true);
+ /* See Editor::_stepping_axis_view for notes on this hack */
+ Editor& e = dynamic_cast (_editor);
+ if (!e.stepping_axis_view ()) {
+ e.set_stepping_axis_view (this);
+ }
+ e.stepping_axis_view()->step_height (true);
return true;
} else if (Keyboard::no_modifiers_active (ev->state)) {
_editor.scroll_tracks_down_line();
diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h
index 5fdc0ac041..e38c98ea05 100644
--- a/libs/ardour/ardour/audioregion.h
+++ b/libs/ardour/ardour/audioregion.h
@@ -46,16 +46,11 @@ namespace Properties {
extern PBD::PropertyDescriptor fade_in_active;
extern PBD::PropertyDescriptor fade_out_active;
extern PBD::PropertyDescriptor scale_amplitude;
-
- /* the envelope and fades are not scalar items and so
- currently (2010/02) are not stored using Property.
- However, these descriptors enable us to notify
- about changes to them via PropertyChange.
- */
-
- extern PBD::PropertyDescriptor envelope;
- extern PBD::PropertyDescriptor fade_in;
- extern PBD::PropertyDescriptor fade_out;
+ extern PBD::PropertyDescriptor > fade_in;
+ extern PBD::PropertyDescriptor > inverse_fade_in;
+ extern PBD::PropertyDescriptor > fade_out;
+ extern PBD::PropertyDescriptor > inverse_fade_out;
+ extern PBD::PropertyDescriptor > envelope;
}
class Playlist;
@@ -99,11 +94,11 @@ class AudioRegion : public Region
bool fade_out_is_short() const { return _fade_out_is_short; }
void set_fade_out_is_short (bool yn);
- boost::shared_ptr fade_in() { return _fade_in; }
- boost::shared_ptr inverse_fade_in() { return _inverse_fade_in; }
- boost::shared_ptr fade_out() { return _fade_out; }
- boost::shared_ptr inverse_fade_out() { return _inverse_fade_out; }
- boost::shared_ptr envelope() { return _envelope; }
+ boost::shared_ptr fade_in() { return _fade_in.val (); }
+ boost::shared_ptr inverse_fade_in() { return _inverse_fade_in.val (); }
+ boost::shared_ptr fade_out() { return _fade_out.val (); }
+ boost::shared_ptr inverse_fade_out() { return _inverse_fade_out.val (); }
+ boost::shared_ptr envelope() { return _envelope.val (); }
Evoral::Range body_range () const;
@@ -231,15 +226,15 @@ class AudioRegion : public Region
void connect_to_analysis_changed ();
void connect_to_header_position_offset_changed ();
- Automatable _automatable;
- boost::shared_ptr _fade_in;
- boost::shared_ptr _inverse_fade_in;
- boost::shared_ptr _fade_out;
- boost::shared_ptr _inverse_fade_out;
- boost::shared_ptr _envelope;
- uint32_t _fade_in_suspended;
- uint32_t _fade_out_suspended;
+ AutomationListProperty _fade_in;
+ AutomationListProperty _inverse_fade_in;
+ AutomationListProperty _fade_out;
+ AutomationListProperty _inverse_fade_out;
+ AutomationListProperty _envelope;
+ Automatable _automatable;
+ uint32_t _fade_in_suspended;
+ uint32_t _fade_out_suspended;
boost::shared_ptr get_single_other_xfade_region (bool start) const;
diff --git a/libs/ardour/ardour/automation_list.h b/libs/ardour/ardour/automation_list.h
index 58d1fe4acf..01c9d0641a 100644
--- a/libs/ardour/ardour/automation_list.h
+++ b/libs/ardour/ardour/automation_list.h
@@ -29,6 +29,7 @@
#include "pbd/undo.h"
#include "pbd/xml++.h"
#include "pbd/statefuldestructible.h"
+#include "pbd/properties.h"
#include "ardour/ardour.h"
@@ -36,6 +37,28 @@
namespace ARDOUR {
+class AutomationList;
+
+/** A SharedStatefulProperty for AutomationLists */
+class AutomationListProperty : public PBD::SharedStatefulProperty
+{
+public:
+ AutomationListProperty (PBD::PropertyDescriptor > d, Ptr p)
+ : PBD::SharedStatefulProperty (d.property_id, p)
+ {}
+
+ AutomationListProperty (PBD::PropertyDescriptor > d, Ptr o, Ptr c)
+ : PBD::SharedStatefulProperty (d.property_id, o, c)
+ {}
+
+ PBD::PropertyBase* clone () const;
+
+private:
+ /* No copy-construction nor assignment */
+ AutomationListProperty (AutomationListProperty const &);
+ AutomationListProperty& operator= (AutomationListProperty const &);
+};
+
class AutomationList : public PBD::StatefulDestructible, public Evoral::ControlList
{
public:
@@ -82,6 +105,8 @@ class AutomationList : public PBD::StatefulDestructible, public Evoral::ControlL
XMLNode& state (bool full);
XMLNode& serialize_events ();
+ bool operator!= (const AutomationList &) const;
+
private:
void create_curve_if_necessary ();
int deserialize_events (const XMLNode&);
diff --git a/libs/ardour/ardour/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h
index 27e002ca66..baf9c959ae 100644
--- a/libs/ardour/ardour/lv2_plugin.h
+++ b/libs/ardour/ardour/lv2_plugin.h
@@ -31,6 +31,13 @@
namespace ARDOUR {
+// a callback function for lilv_state_new_from_instance(). friend of LV2Plugin
+// so we can pass an LV2Plugin* in user_data and access its private members.
+const void* lv2plugin_get_port_value(const char* port_symbol,
+ void* user_data,
+ uint32_t* size,
+ uint32_t* type);
+
class AudioEngine;
class Session;
@@ -159,6 +166,11 @@ class LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee
float* _latency_control_port; ///< Special output set by ardour
PBD::ID _insert_id;
+ friend const void* lv2plugin_get_port_value(const char* port_symbol,
+ void* user_data,
+ uint32_t* size,
+ uint32_t* type);
+
typedef enum {
PORT_INPUT = 1,
PORT_OUTPUT = 1 << 1,
diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h
index 23ae7addb0..99513734da 100644
--- a/libs/ardour/ardour/midi_diskstream.h
+++ b/libs/ardour/ardour/midi_diskstream.h
@@ -63,6 +63,7 @@ class MidiDiskstream : public Diskstream
float capture_buffer_load() const;
void get_playback (MidiBuffer& dst, framecnt_t);
+ void flush_playback (framepos_t, framepos_t);
void set_record_enabled (bool yn);
diff --git a/libs/ardour/ardour/midi_port.h b/libs/ardour/ardour/midi_port.h
index 84575ca351..5dc55398cb 100644
--- a/libs/ardour/ardour/midi_port.h
+++ b/libs/ardour/ardour/midi_port.h
@@ -45,6 +45,7 @@ class MidiPort : public Port {
void transport_stopped ();
void realtime_locate ();
void reset ();
+ void require_resolve ();
bool input_active() const { return _input_active; }
void set_input_active (bool yn);
diff --git a/libs/ardour/ardour/midi_ring_buffer.h b/libs/ardour/ardour/midi_ring_buffer.h
index 4b352b3c4d..c6756933aa 100644
--- a/libs/ardour/ardour/midi_ring_buffer.h
+++ b/libs/ardour/ardour/midi_ring_buffer.h
@@ -55,6 +55,7 @@ public:
size_t read(MidiBuffer& dst, framepos_t start, framepos_t end, framecnt_t offset=0, bool stop_on_overflow_in_destination=false);
void dump(std::ostream& dst);
+ void flush (framepos_t start, framepos_t end);
/** Set the channel filtering mode.
* @param mask If mode is FilterChannels, each bit represents a midi channel:
diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h
index bb810ff74a..934c1862b0 100644
--- a/libs/ardour/ardour/midi_track.h
+++ b/libs/ardour/ardour/midi_track.h
@@ -92,9 +92,6 @@ public:
PBD::Signal1 StepEditStatusChange;
- bool midi_thru() const { return _midi_thru; }
- void set_midi_thru (bool yn);
-
boost::shared_ptr write_source (uint32_t n = 0);
void set_channel_mode (ChannelMode, uint16_t);
ChannelMode get_channel_mode ();
@@ -116,7 +113,7 @@ protected:
void act_on_mute ();
- private:
+private:
virtual boost::shared_ptr diskstream_factory (XMLNode const &);
@@ -131,7 +128,6 @@ protected:
MidiRingBuffer _step_edit_ring_buffer;
NoteMode _note_mode;
bool _step_editing;
- bool _midi_thru;
bool _input_active;
int no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool state_changing);
diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h
index 15e5f4a9c5..bf91de903b 100644
--- a/libs/ardour/ardour/plugin.h
+++ b/libs/ardour/ardour/plugin.h
@@ -183,6 +183,7 @@ class Plugin : public PBD::StatefulDestructible, public Latent
void remove_preset (std::string);
virtual bool load_preset (PresetRecord);
+ void clear_preset ();
const PresetRecord * preset_by_label (const std::string &);
const PresetRecord * preset_by_uri (const std::string &);
diff --git a/libs/ardour/ardour/rc_configuration_vars.h b/libs/ardour/ardour/rc_configuration_vars.h
index 1f9e3c1037..37599b0ac6 100644
--- a/libs/ardour/ardour/rc_configuration_vars.h
+++ b/libs/ardour/ardour/rc_configuration_vars.h
@@ -76,6 +76,7 @@ CONFIG_VARIABLE (std::string, keyboard_layout_name, "keyboard-layout-name", "ans
CONFIG_VARIABLE (bool, automation_follows_regions, "automation-follows-regions", true)
CONFIG_VARIABLE (bool, region_boundaries_from_selected_tracks, "region-boundaries-from-selected-tracks", true)
CONFIG_VARIABLE (bool, region_boundaries_from_onscreen_tracks, "region-boundaries-from-onscreen_tracks", true)
+CONFIG_VARIABLE (bool, autoscroll_editor, "autoscroll-editor", true)
/* monitoring, mute, solo etc */
diff --git a/libs/ardour/ardour/region_factory.h b/libs/ardour/ardour/region_factory.h
index 4ba261f80c..471f172440 100644
--- a/libs/ardour/ardour/region_factory.h
+++ b/libs/ardour/ardour/region_factory.h
@@ -31,6 +31,7 @@
#include "ardour/types.h"
class XMLNode;
+class RegionNamingTest;
namespace ARDOUR {
@@ -119,6 +120,7 @@ public:
static void map_add (boost::shared_ptr);
private:
+ friend class ::RegionNamingTest;
static void region_changed (PBD::PropertyChange const &, boost::weak_ptr);
@@ -126,10 +128,15 @@ public:
static RegionMap region_map;
- static Glib::StaticMutex region_name_map_lock;
-
- static std::map region_name_map;
- static void update_region_name_map (boost::shared_ptr);
+ static Glib::StaticMutex region_name_maps_mutex;
+ /** map of partial region names and suffix numbers */
+ static std::map region_name_number_map;
+ /** map of complete region names with their region ID */
+ static std::map region_name_map;
+ static void add_to_region_name_maps (boost::shared_ptr);
+ static void rename_in_region_name_maps (boost::shared_ptr);
+ static void update_region_name_number_map (boost::shared_ptr);
+ static void remove_from_region_name_map (std::string);
static PBD::ScopedConnectionList* region_list_connections;
static CompoundAssociations _compound_associations;
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 7c3beb6c13..0f318a1b75 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -1293,9 +1293,7 @@ AudioEngine::connect_to_jack (string client_name, string session_uuid)
{
EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa ();
boost::scoped_ptr current_epa;
- jack_options_t options = JackNullOption;
jack_status_t status;
- const char *server_name = NULL;
/* revert all environment settings back to whatever they were when ardour started
*/
@@ -1311,7 +1309,7 @@ AudioEngine::connect_to_jack (string client_name, string session_uuid)
_jack = jack_client_open (jack_client_name.c_str(), JackSessionID, &status, session_uuid.c_str());
else
#endif
- _jack = jack_client_open (jack_client_name.c_str(), options, &status, server_name);
+ _jack = jack_client_open (jack_client_name.c_str(), JackNullOption, &status, 0);
if (_jack == NULL) {
// error message is not useful here
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 50a38b7bad..4c7979dbfc 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -65,6 +65,11 @@ namespace ARDOUR {
PBD::PropertyDescriptor fade_out_is_short;
PBD::PropertyDescriptor fade_in_is_xfade;
PBD::PropertyDescriptor fade_in_is_short;
+ PBD::PropertyDescriptor > fade_in;
+ PBD::PropertyDescriptor > inverse_fade_in;
+ PBD::PropertyDescriptor > fade_out;
+ PBD::PropertyDescriptor > inverse_fade_out;
+ PBD::PropertyDescriptor > envelope;
}
}
@@ -164,6 +169,16 @@ AudioRegion::make_property_quarks ()
DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for fade-in-is-xfade = %1\n", Properties::fade_in_is_xfade.property_id));
Properties::fade_in_is_short.property_id = g_quark_from_static_string (X_("fade-in-is-short"));
DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for fade-in-is-short = %1\n", Properties::fade_in_is_short.property_id));
+ Properties::fade_in.property_id = g_quark_from_static_string (X_("FadeIn"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for FadeIn = %1\n", Properties::fade_in.property_id));
+ Properties::inverse_fade_in.property_id = g_quark_from_static_string (X_("InverseFadeIn"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for InverseFadeIn = %1\n", Properties::inverse_fade_in.property_id));
+ Properties::fade_out.property_id = g_quark_from_static_string (X_("FadeOut"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for FadeOut = %1\n", Properties::fade_out.property_id));
+ Properties::inverse_fade_out.property_id = g_quark_from_static_string (X_("InverseFadeOut"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for InverseFadeOut = %1\n", Properties::inverse_fade_out.property_id));
+ Properties::envelope.property_id = g_quark_from_static_string (X_("Envelope"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for Envelope = %1\n", Properties::envelope.property_id));
}
void
@@ -181,6 +196,11 @@ AudioRegion::register_properties ()
add_property (_fade_out_is_short);
add_property (_fade_in_is_xfade);
add_property (_fade_in_is_short);
+ add_property (_fade_in);
+ add_property (_inverse_fade_in);
+ add_property (_fade_out);
+ add_property (_inverse_fade_out);
+ add_property (_envelope);
}
#define AUDIOREGION_STATE_DEFAULT \
@@ -193,7 +213,11 @@ AudioRegion::register_properties ()
, _fade_in_is_xfade (Properties::fade_in_is_xfade, false) \
, _fade_out_is_xfade (Properties::fade_out_is_xfade, false) \
, _fade_in_is_short (Properties::fade_in_is_short, false) \
- , _fade_out_is_short (Properties::fade_out_is_short, false)
+ , _fade_out_is_short (Properties::fade_out_is_short, false) \
+ , _fade_in (Properties::fade_in, boost::shared_ptr (new AutomationList (Evoral::Parameter (FadeInAutomation)))) \
+ , _inverse_fade_in (Properties::inverse_fade_in, boost::shared_ptr (new AutomationList (Evoral::Parameter (FadeInAutomation)))) \
+ , _fade_out (Properties::fade_out, boost::shared_ptr (new AutomationList (Evoral::Parameter (FadeOutAutomation)))) \
+ , _inverse_fade_out (Properties::inverse_fade_out, boost::shared_ptr (new AutomationList (Evoral::Parameter (FadeOutAutomation))))
#define AUDIOREGION_COPY_STATE(other) \
_envelope_active (Properties::envelope_active, other->_envelope_active) \
@@ -205,7 +229,11 @@ AudioRegion::register_properties ()
, _fade_in_is_xfade (Properties::fade_in_is_xfade, other->_fade_in_is_xfade) \
, _fade_out_is_xfade (Properties::fade_out_is_xfade, other->_fade_out_is_xfade) \
, _fade_in_is_short (Properties::fade_in_is_short, other->_fade_in_is_short) \
- , _fade_out_is_short (Properties::fade_out_is_short, other->_fade_out_is_short)
+ , _fade_out_is_short (Properties::fade_out_is_short, other->_fade_out_is_short) \
+ , _fade_in (Properties::fade_in, boost::shared_ptr (new AutomationList (*other->_fade_in.val()))) \
+ , _inverse_fade_in (Properties::fade_in, boost::shared_ptr (new AutomationList (*other->_inverse_fade_in.val()))) \
+ , _fade_out (Properties::fade_in, boost::shared_ptr (new AutomationList (*other->_fade_out.val()))) \
+ , _inverse_fade_out (Properties::fade_in, boost::shared_ptr (new AutomationList (*other->_inverse_fade_out.val())))
/* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
void
@@ -227,12 +255,8 @@ AudioRegion::init ()
AudioRegion::AudioRegion (Session& s, framepos_t start, framecnt_t len, std::string name)
: Region (s, start, len, name, DataType::AUDIO)
, AUDIOREGION_STATE_DEFAULT
+ , _envelope (Properties::envelope, boost::shared_ptr (new AutomationList (Evoral::Parameter(EnvelopeAutomation))))
, _automatable (s)
- , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
- , _inverse_fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
- , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
- , _inverse_fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
- , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
, _fade_in_suspended (0)
, _fade_out_suspended (0)
{
@@ -244,12 +268,8 @@ AudioRegion::AudioRegion (Session& s, framepos_t start, framecnt_t len, std::str
AudioRegion::AudioRegion (const SourceList& srcs)
: Region (srcs)
, AUDIOREGION_STATE_DEFAULT
+ , _envelope (Properties::envelope, boost::shared_ptr (new AutomationList (Evoral::Parameter(EnvelopeAutomation))))
, _automatable(srcs[0]->session())
- , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
- , _inverse_fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
- , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
- , _inverse_fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
- , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
, _fade_in_suspended (0)
, _fade_out_suspended (0)
{
@@ -260,15 +280,11 @@ AudioRegion::AudioRegion (const SourceList& srcs)
AudioRegion::AudioRegion (boost::shared_ptr other)
: Region (other)
, AUDIOREGION_COPY_STATE (other)
- , _automatable (other->session())
- , _fade_in (new AutomationList (*other->_fade_in))
- , _inverse_fade_in (new AutomationList(*other->_inverse_fade_in))
- , _fade_out (new AutomationList (*other->_fade_out))
- , _inverse_fade_out (new AutomationList (*other->_inverse_fade_out))
/* As far as I can see, the _envelope's times are relative to region position, and have nothing
to do with sources (and hence _start). So when we copy the envelope, we just use the supplied offset.
*/
- , _envelope (new AutomationList (*other->_envelope, 0, other->_length))
+ , _envelope (Properties::envelope, boost::shared_ptr (new AutomationList (*other->_envelope.val(), 0, other->_length)))
+ , _automatable (other->session())
, _fade_in_suspended (0)
, _fade_out_suspended (0)
{
@@ -286,15 +302,11 @@ AudioRegion::AudioRegion (boost::shared_ptr other)
AudioRegion::AudioRegion (boost::shared_ptr other, framecnt_t offset)
: Region (other, offset)
, AUDIOREGION_COPY_STATE (other)
- , _automatable (other->session())
- , _fade_in (new AutomationList (*other->_fade_in))
- , _inverse_fade_in (new AutomationList(*other->_inverse_fade_in))
- , _fade_out (new AutomationList (*other->_fade_out))
- , _inverse_fade_out (new AutomationList (*other->_inverse_fade_out))
/* As far as I can see, the _envelope's times are relative to region position, and have nothing
to do with sources (and hence _start). So when we copy the envelope, we just use the supplied offset.
*/
- , _envelope (new AutomationList (*other->_envelope, offset, other->_length))
+ , _envelope (Properties::envelope, boost::shared_ptr (new AutomationList (*other->_envelope.val(), offset, other->_length)))
+ , _automatable (other->session())
, _fade_in_suspended (0)
, _fade_out_suspended (0)
{
@@ -312,12 +324,8 @@ AudioRegion::AudioRegion (boost::shared_ptr other, framecnt_t
AudioRegion::AudioRegion (boost::shared_ptr other, const SourceList& srcs)
: Region (boost::static_pointer_cast(other), srcs)
, AUDIOREGION_COPY_STATE (other)
+ , _envelope (Properties::envelope, boost::shared_ptr (new AutomationList (*other->_envelope.val())))
, _automatable (other->session())
- , _fade_in (new AutomationList (*other->_fade_in))
- , _inverse_fade_in (new AutomationList(*other->_inverse_fade_in))
- , _fade_out (new AutomationList (*other->_fade_out))
- , _inverse_fade_out (new AutomationList (*other->_inverse_fade_out))
- , _envelope (new AutomationList (*other->_envelope))
, _fade_in_suspended (0)
, _fade_out_suspended (0)
{
@@ -335,12 +343,8 @@ AudioRegion::AudioRegion (boost::shared_ptr other, const Sour
AudioRegion::AudioRegion (SourceList& srcs)
: Region (srcs)
, AUDIOREGION_STATE_DEFAULT
+ , _envelope (Properties::envelope, boost::shared_ptr (new AutomationList(Evoral::Parameter(EnvelopeAutomation))))
, _automatable(srcs[0]->session())
- , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
- , _inverse_fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
- , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
- , _inverse_fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
- , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
, _fade_in_suspended (0)
, _fade_out_suspended (0)
{
@@ -756,8 +760,8 @@ AudioRegion::read_from_sources (SourceList const & srcs, framecnt_t limit, Sampl
*/
if (Config->get_replicate_missing_region_channels()) {
- /* track is N-channel, this region has less channels, so use a relevant channel
- */
+
+ /* copy an existing channel's data in for this non-existant one */
uint32_t channel = n_channels() % chan_n;
boost::shared_ptr src = boost::dynamic_pointer_cast (srcs[channel]);
@@ -765,6 +769,11 @@ AudioRegion::read_from_sources (SourceList const & srcs, framecnt_t limit, Sampl
if (src->read (buf, _start + internal_offset, to_read) != to_read) {
return 0; /* "read nothing" */
}
+
+ } else {
+
+ /* use silence */
+ memset (buf, 0, sizeof (Sample) * to_read);
}
}
@@ -988,7 +997,7 @@ void
AudioRegion::set_fade_in (boost::shared_ptr f)
{
_fade_in->freeze ();
- *_fade_in = *f;
+ *(_fade_in.val()) = *f;
_fade_in->thaw ();
_default_fade_in = false;
@@ -1010,23 +1019,23 @@ AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
case FadeLinear:
_fade_in->fast_simple_add (0.0, 0.0);
_fade_in->fast_simple_add (len, 1.0);
- reverse_curve (_inverse_fade_in, _fade_in);
+ reverse_curve (_inverse_fade_in.val(), _fade_in.val());
break;
case FadeFast:
- generate_db_fade (_fade_in, len, 10, -60);
- reverse_curve (c1, _fade_in);
+ generate_db_fade (_fade_in.val(), len, 10, -60);
+ reverse_curve (c1, _fade_in.val());
_fade_in->copy_events (*c1);
- generate_inverse_power_curve (_inverse_fade_in, _fade_in);
+ generate_inverse_power_curve (_inverse_fade_in.val(), _fade_in.val());
break;
case FadeSlow:
generate_db_fade (c1, len, 10, -1); // start off with a slow fade
generate_db_fade (c2, len, 10, -80); // end with a fast fade
- merge_curves (_fade_in, c1, c2);
- reverse_curve (c3, _fade_in);
+ merge_curves (_fade_in.val(), c1, c2);
+ reverse_curve (c3, _fade_in.val());
_fade_in->copy_events (*c3);
- generate_inverse_power_curve (_inverse_fade_in, _fade_in);
+ generate_inverse_power_curve (_inverse_fade_in.val(), _fade_in.val());
break;
case FadeConstantPower:
@@ -1035,7 +1044,7 @@ AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
_fade_in->fast_simple_add (len*dist, sin (dist*M_PI/2));
}
_fade_in->fast_simple_add (len, 1.0);
- reverse_curve (_inverse_fade_in, _fade_in);
+ reverse_curve (_inverse_fade_in.val(), _fade_in.val());
break;
case FadeSymmetric:
@@ -1053,9 +1062,9 @@ AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
_fade_in->fast_simple_add (len* (breakpoint+((1.0-breakpoint)*(double)i/(double)num_steps)), coeff);
}
_fade_in->fast_simple_add (len, VERY_SMALL_SIGNAL);
- reverse_curve (c3, _fade_in);
+ reverse_curve (c3, _fade_in.val());
_fade_in->copy_events (*c3);
- reverse_curve (_inverse_fade_in, _fade_in );
+ reverse_curve (_inverse_fade_in.val(), _fade_in.val());
break;
}
@@ -1068,7 +1077,7 @@ void
AudioRegion::set_fade_out (boost::shared_ptr f)
{
_fade_out->freeze ();
- *_fade_out = *f;
+ *(_fade_out.val()) = *f;
_fade_out->thaw ();
_default_fade_out = false;
@@ -1089,19 +1098,19 @@ AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
case FadeLinear:
_fade_out->fast_simple_add (0.0, 1.0);
_fade_out->fast_simple_add (len, VERY_SMALL_SIGNAL);
- reverse_curve (_inverse_fade_out, _fade_out);
+ reverse_curve (_inverse_fade_out.val(), _fade_out.val());
break;
case FadeFast:
- generate_db_fade (_fade_out, len, 10, -60);
- generate_inverse_power_curve (_inverse_fade_out, _fade_out);
+ generate_db_fade (_fade_out.val(), len, 10, -60);
+ generate_inverse_power_curve (_inverse_fade_out.val(), _fade_out.val());
break;
case FadeSlow:
generate_db_fade (c1, len, 10, -1); //start off with a slow fade
generate_db_fade (c2, len, 10, -80); //end with a fast fade
- merge_curves (_fade_out, c1, c2);
- generate_inverse_power_curve (_inverse_fade_out, _fade_out);
+ merge_curves (_fade_out.val(), c1, c2);
+ generate_inverse_power_curve (_inverse_fade_out.val(), _fade_out.val());
break;
case FadeConstantPower:
@@ -1113,7 +1122,7 @@ AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
_fade_out->fast_simple_add ((len * dist), cos(dist*M_PI/2));
}
_fade_out->fast_simple_add (len, VERY_SMALL_SIGNAL);
- reverse_curve (_inverse_fade_out, _fade_out);
+ reverse_curve (_inverse_fade_out.val(), _fade_out.val());
break;
case FadeSymmetric:
@@ -1132,7 +1141,7 @@ AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
_fade_out->fast_simple_add (len* (breakpoint+((1.0-breakpoint)*(double)i/(double)num_steps)), coeff);
}
_fade_out->fast_simple_add (len, VERY_SMALL_SIGNAL);
- reverse_curve (_inverse_fade_out, _fade_out);
+ reverse_curve (_inverse_fade_out.val(), _fade_out.val());
break;
}
diff --git a/libs/ardour/automation_list.cc b/libs/ardour/automation_list.cc
index 54d838f6e2..26ca7b097a 100644
--- a/libs/ardour/automation_list.cc
+++ b/libs/ardour/automation_list.cc
@@ -510,3 +510,24 @@ AutomationList::set_state (const XMLNode& node, int version)
return 0;
}
+bool
+AutomationList::operator!= (AutomationList const & other) const
+{
+ return (
+ static_cast (*this) != static_cast (other) ||
+ _state != other._state ||
+ _style != other._style ||
+ _touching != other._touching
+ );
+}
+
+PBD::PropertyBase *
+AutomationListProperty::clone () const
+{
+ return new AutomationListProperty (
+ this->property_id(),
+ boost::shared_ptr (new AutomationList (*this->_old.get())),
+ boost::shared_ptr (new AutomationList (*this->_current.get()))
+ );
+}
+
diff --git a/libs/ardour/filesystem_paths.cc b/libs/ardour/filesystem_paths.cc
index a8a684a4aa..760b16c409 100644
--- a/libs/ardour/filesystem_paths.cc
+++ b/libs/ardour/filesystem_paths.cc
@@ -124,7 +124,6 @@ ardour_config_search_path ()
search_path = sp;
have_path = true;
- info << "CONFIG PATH: " << search_path.to_string() << endmsg;
}
return search_path;
@@ -153,7 +152,6 @@ ardour_data_search_path ()
search_path = sp;
have_path = true;
- info << "DATA PATH: " << search_path.to_string() << endmsg;
}
return search_path;
diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc
index 361b682fcb..385d956b4c 100644
--- a/libs/ardour/globals.cc
+++ b/libs/ardour/globals.cc
@@ -116,34 +116,6 @@ extern void setup_enum_writer ();
*/
PBD::PropertyChange ARDOUR::bounds_change;
-namespace ARDOUR {
- namespace Properties {
-
- /* the envelope and fades are not scalar items and so
- currently (2010/02) are not stored using Property.
- However, these descriptors enable us to notify
- about changes to them via PropertyChange.
-
- Declared in ardour/audioregion.h ...
- */
-
- PBD::PropertyDescriptor fade_in;
- PBD::PropertyDescriptor fade_out;
- PBD::PropertyDescriptor envelope;
- }
-}
-
-void
-ARDOUR::make_property_quarks ()
-{
- Properties::fade_in.property_id = g_quark_from_static_string (X_("fade_in_FAKE"));
- DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for fade_in_FAKE = %1\n", Properties::fade_in.property_id));
- Properties::fade_out.property_id = g_quark_from_static_string (X_("fade_out_FAKE"));
- DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for fade_out_FAKE = %1\n", Properties::fade_out.property_id));
- Properties::envelope.property_id = g_quark_from_static_string (X_("envelope_FAKE"));
- DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for envelope_FAKE = %1\n", Properties::envelope.property_id));
-}
-
void
setup_hardware_optimization (bool try_optimization)
{
@@ -249,7 +221,6 @@ ARDOUR::init (bool use_windows_vst, bool try_optimization)
PBD::ID::init ();
SessionEvent::init_event_pool ();
- make_property_quarks ();
SessionObject::make_property_quarks ();
Region::make_property_quarks ();
MidiRegion::make_property_quarks ();
diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc
index 6c8fb3c9db..f8a41c5ecd 100644
--- a/libs/ardour/lv2_plugin.cc
+++ b/libs/ardour/lv2_plugin.cc
@@ -835,7 +835,6 @@ LV2Plugin::find_presets()
bool
LV2Plugin::load_preset(PresetRecord r)
{
- Plugin::load_preset(r);
std::map::iterator it;
@@ -862,18 +861,97 @@ LV2Plugin::load_preset(PresetRecord r)
lilv_node_free(lv2_symbol);
lilv_node_free(lv2_port);
+ Plugin::load_preset(r);
+
return true;
}
-std::string
-LV2Plugin::do_save_preset(string /*name*/)
+const void*
+ARDOUR::lv2plugin_get_port_value(const char* port_symbol,
+ void* user_data,
+ uint32_t* size,
+ uint32_t* type)
{
- return "";
+ // cerr << "get_port_value(" << port_symbol << ", ...) ... ";
+ LV2Plugin *plugin = (LV2Plugin *) user_data;
+
+ uint32_t index = plugin->port_index(port_symbol);
+ if (index != (uint32_t) -1) {
+ if (plugin->parameter_is_input(index) && plugin->parameter_is_control(index)) {
+ float *value;
+ *size = sizeof(float);
+ *type = plugin->_uri_map.uri_to_id(LV2_ATOM__Float);
+ value = &plugin->_shadow_data[index];
+ // cerr << "index="<< index << ",*size=" << *size << ",*type=" << *type << ",*value=" << *value << endl;
+
+ return value;
+ }
+ // cerr << "port is not input control port! ";
+ }
+
+ // cerr << "returning NULL!" << endl;
+ *size = *type = 0;
+ return NULL;
+}
+
+
+std::string
+LV2Plugin::do_save_preset(string name)
+{
+ // cerr << "LV2Plugin::do_save_preset(" << name << ")" << endl;
+
+ string pset_uri = uri();
+ pset_uri += "#";
+ pset_uri += name;
+
+ string save_dir = Glib::build_filename(
+ Glib::get_home_dir(),
+ Glib::build_filename(".lv2", "presets")
+ );
+
+ LilvState* state = lilv_state_new_from_instance(
+ _impl->plugin,
+ _impl->instance,
+ _uri_map.urid_map(),
+ scratch_dir().c_str(), // file_dir
+ NULL, // copy_dir
+ NULL, // link_dir
+ save_dir.c_str(), // save_dir
+ lv2plugin_get_port_value, // get_value
+ (void*) this, // user_data
+ LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE, // flags
+ _features // features
+ );
+
+ lilv_state_set_label(state, name.c_str());
+ lilv_state_save(
+ _world.world, // world
+ _uri_map.urid_map(), // map
+ _uri_map.urid_unmap(), // unmap
+ state, // state
+ pset_uri.c_str(), // uri
+ save_dir.c_str(), // dir
+ (name + ".ttl").c_str() // filename
+
+ );
+
+ lilv_state_free(state);
+ return pset_uri;
}
void
-LV2Plugin::do_remove_preset(string /*name*/)
-{}
+LV2Plugin::do_remove_preset(string name)
+{
+ string preset_file = Glib::build_filename(
+ Glib::get_home_dir(),
+ Glib::build_filename(
+ Glib::build_filename(".lv2", "presets"),
+ name + ".ttl"
+ )
+ );
+ unlink(preset_file.c_str());
+
+}
bool
LV2Plugin::has_editor() const
diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc
index a8757d7575..5e2a6e23b9 100644
--- a/libs/ardour/midi_diskstream.cc
+++ b/libs/ardour/midi_diskstream.cc
@@ -506,6 +506,14 @@ MidiDiskstream::seek (framepos_t frame, bool complete_refill)
Glib::Mutex::Lock lm (state_lock);
int ret = -1;
+ if (g_atomic_int_get (&_frames_read_from_ringbuffer) == 0) {
+ /* we haven't read anything since the last seek,
+ so flush all note trackers to prevent
+ wierdness
+ */
+ reset_tracker ();
+ }
+
_playback_buf->reset();
_capture_buf->reset();
g_atomic_int_set(&_frames_read_from_ringbuffer, 0);
@@ -1269,6 +1277,13 @@ MidiDiskstream::use_pending_capture_data (XMLNode& /*node*/)
return 0;
}
+void
+MidiDiskstream::flush_playback (framepos_t start, framepos_t end)
+{
+ _playback_buf->flush (start, end);
+ g_atomic_int_add (&_frames_read_from_ringbuffer, end - start);
+}
+
/** Writes playback events from playback_sample for nframes to dst, translating time stamps
* so that an event at playback_sample has time = 0
*/
diff --git a/libs/ardour/midi_port.cc b/libs/ardour/midi_port.cc
index 9a7d3eeb27..63004f658b 100644
--- a/libs/ardour/midi_port.cc
+++ b/libs/ardour/midi_port.cc
@@ -188,6 +188,12 @@ MidiPort::flush_buffers (pframes_t nframes)
}
}
+void
+MidiPort::require_resolve ()
+{
+ _resolve_required = true;
+}
+
void
MidiPort::transport_stopped ()
{
diff --git a/libs/ardour/midi_ring_buffer.cc b/libs/ardour/midi_ring_buffer.cc
index 30f42aba19..786ed3c080 100644
--- a/libs/ardour/midi_ring_buffer.cc
+++ b/libs/ardour/midi_ring_buffer.cc
@@ -98,7 +98,9 @@ MidiRingBuffer::read(MidiBuffer& dst, framepos_t start, framepos_t end, frame
break;
} else if (ev_time + loop_offset < start) {
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("MRB event @ %1 before start @ %2\n", ev_time, start));
- break;
+ this->increment_read_ptr (prefix_size);
+ this->increment_read_ptr (ev_size);
+ continue;
} else {
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("MRB event @ %1 in range %2 .. %3\n", ev_time, start, end));
}
@@ -193,6 +195,36 @@ MidiRingBuffer::read(MidiBuffer& dst, framepos_t start, framepos_t end, frame
return count;
}
+template
+void
+MidiRingBuffer::flush (framepos_t start, framepos_t end)
+{
+ const size_t prefix_size = sizeof(T) + sizeof(Evoral::EventType) + sizeof(uint32_t);
+
+ while (this->read_space() >= prefix_size) {
+ uint8_t peekbuf[prefix_size];
+ bool success;
+ uint32_t ev_size;
+ T ev_time;
+
+ success = this->peek (peekbuf, prefix_size);
+ /* this cannot fail, because we've already verified that there
+ is prefix_space to read
+ */
+ assert (success);
+
+ ev_time = *((T*) peekbuf);
+
+ if (ev_time >= end) {
+ break;
+ }
+
+ ev_size = *((uint32_t*)(peekbuf + sizeof(T) + sizeof (Evoral::EventType)));
+ this->increment_read_ptr (prefix_size);
+ this->increment_read_ptr (ev_size);
+ }
+}
+
template
void
MidiRingBuffer::dump(ostream& str)
diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc
index 64e61e79f9..a8a0e218a6 100644
--- a/libs/ardour/midi_track.cc
+++ b/libs/ardour/midi_track.cc
@@ -54,7 +54,6 @@ MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mo
, _step_edit_ring_buffer(64) // FIXME: size?
, _note_mode(Sustained)
, _step_editing (false)
- , _midi_thru (true)
, _input_active (true)
{
}
@@ -155,10 +154,6 @@ MidiTrack::set_state (const XMLNode& node, int version)
// No destructive MIDI tracks (yet?)
_mode = Normal;
- if ((prop = node.property ("midi-thru")) != 0) {
- set_midi_thru (string_is_affirmative (prop->value()));
- }
-
if ((prop = node.property ("input-active")) != 0) {
set_input_active (string_is_affirmative (prop->value()));
}
@@ -205,7 +200,6 @@ MidiTrack::state(bool full_state)
root.add_property ("step-editing", (_step_editing ? "yes" : "no"));
root.add_property ("note-mode", enum_2_string (_note_mode));
- root.add_property ("midi-thru", (_midi_thru ? "yes" : "no"));
root.add_property ("input-active", (_input_active ? "yes" : "no"));
return root;
@@ -315,6 +309,7 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame
return dret;
}
+
_silent = false;
if ((dret = diskstream->process (transport_frame, nframes, playback_distance)) != 0) {
@@ -335,9 +330,18 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame
at least potentially (depending on monitoring options)
*/
+ /* because the playback buffer is event based and not a
+ * continuous stream, we need to make sure that we empty
+ * it of events every cycle to avoid it filling up with events
+ * read from disk, while we are actually monitoring input
+ */
+
+ diskstream->flush_playback (start_frame, end_frame);
+
passthru (start_frame, end_frame, nframes, 0);
} else {
+
/*
XXX is it true that the earlier test on n_outputs()
means that we can avoid checking it again here? i think
@@ -349,7 +353,6 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame
/* copy the diskstream data to all output buffers */
- //const size_t limit = n_process_buffers().n_audio();
BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers());
MidiBuffer& mbuf (bufs.get_midi (0));
@@ -477,11 +480,6 @@ MidiTrack::write_out_of_band_data (BufferSet& bufs, framepos_t /*start*/, framep
_immediate_events.read (buf, 0, 1, nframes-1, true);
}
-
- // MIDI thru: send incoming data "through" output
- if (_midi_thru && _session.transport_speed() != 0.0f && _input->n_ports().n_midi()) {
- buf.merge_in_place (_input->midi(0)->get_midi_buffer(nframes));
- }
}
int
@@ -625,12 +623,6 @@ MidiTrack::set_step_editing (bool yn)
}
}
-void
-MidiTrack::set_midi_thru (bool yn)
-{
- _midi_thru = yn;
-}
-
boost::shared_ptr
MidiTrack::write_source (uint32_t)
{
@@ -752,12 +744,28 @@ MidiTrack::act_on_mute ()
void
MidiTrack::set_monitoring (MonitorChoice mc)
{
- Track::set_monitoring (mc);
+ if (mc != _monitoring) {
- boost::shared_ptr md (midi_diskstream());
+ Track::set_monitoring (mc);
+
+ /* monitoring state changed, so flush out any on notes at the
+ * port level.
+ */
- if (md) {
- md->reset_tracker ();
+ PortSet& ports (_output->ports());
+
+ for (PortSet::iterator p = ports.begin(); p != ports.end(); ++p) {
+ boost::shared_ptr mp = boost::dynamic_pointer_cast (*p);
+ if (mp) {
+ mp->require_resolve ();
+ }
+ }
+
+ boost::shared_ptr md (midi_diskstream());
+
+ if (md) {
+ md->reset_tracker ();
+ }
}
}
diff --git a/libs/ardour/panner_manager.cc b/libs/ardour/panner_manager.cc
index cf148f08fa..691a8f31ee 100644
--- a/libs/ardour/panner_manager.cc
+++ b/libs/ardour/panner_manager.cc
@@ -26,6 +26,7 @@
#include "pbd/compose.h"
#include "pbd/file_utils.h"
+#include "ardour/debug.h"
#include "ardour/panner_manager.h"
#include "ardour/panner_search_path.h"
@@ -72,7 +73,7 @@ PannerManager::discover_panners ()
find_matching_files_in_search_path (panner_search_path (),
dylib_extension_pattern, panner_modules);
- info << string_compose (_("looking for panners in %1"), panner_search_path().to_string()) << endmsg;
+ DEBUG_TRACE (DEBUG::Panning, string_compose (_("looking for panners in %1"), panner_search_path().to_string()));
for (vector::iterator i = panner_modules.begin(); i != panner_modules.end(); ++i) {
panner_discover ((*i).to_string());
@@ -95,7 +96,7 @@ PannerManager::panner_discover (string path)
if (i == panner_info.end()) {
panner_info.push_back (pinfo);
- info << string_compose(_("Panner discovered: \"%1\" in %2"), pinfo->descriptor.name, path) << endmsg;
+ DEBUG_TRACE (DEBUG::Panning, string_compose(_("Panner discovered: \"%1\" in %2"), pinfo->descriptor.name, path));
}
}
diff --git a/libs/ardour/plugin.cc b/libs/ardour/plugin.cc
index 4afc39b4ec..8cdbf98b89 100644
--- a/libs/ardour/plugin.cc
+++ b/libs/ardour/plugin.cc
@@ -327,6 +327,16 @@ Plugin::load_preset (PresetRecord r)
return true;
}
+void
+Plugin::clear_preset ()
+{
+ _last_preset.uri = "";
+ _last_preset.label = "";
+ _parameter_changed_since_last_preset = false;
+
+ PresetLoaded (); /* EMIT SIGNAL */
+}
+
/** @param val `plugin' value */
void
Plugin::set_parameter (uint32_t which, float val)
diff --git a/libs/ardour/process_thread.cc b/libs/ardour/process_thread.cc
index ae7466c7f0..5d3b54cb13 100644
--- a/libs/ardour/process_thread.cc
+++ b/libs/ardour/process_thread.cc
@@ -40,7 +40,9 @@ release_thread_buffer (void* arg)
void
ProcessThread::init ()
{
- _private_thread_buffers = new Private (release_thread_buffer);
+ if (_private_thread_buffers == 0) {
+ _private_thread_buffers = new Private (release_thread_buffer);
+ }
}
ProcessThread::ProcessThread ()
diff --git a/libs/ardour/region_factory.cc b/libs/ardour/region_factory.cc
index fa948844ab..ddc0451523 100644
--- a/libs/ardour/region_factory.cc
+++ b/libs/ardour/region_factory.cc
@@ -39,8 +39,9 @@ PBD::Signal1 > RegionFactory::CheckNewRegion;
Glib::StaticMutex RegionFactory::region_map_lock;
RegionFactory::RegionMap RegionFactory::region_map;
PBD::ScopedConnectionList* RegionFactory::region_list_connections = 0;
-Glib::StaticMutex RegionFactory::region_name_map_lock;
-std::map RegionFactory::region_name_map;
+Glib::StaticMutex RegionFactory::region_name_maps_mutex;
+std::map RegionFactory::region_name_number_map;
+std::map RegionFactory::region_name_map;
RegionFactory::CompoundAssociations RegionFactory::_compound_associations;
boost::shared_ptr
@@ -320,7 +321,7 @@ RegionFactory::map_add (boost::shared_ptr r)
r->DropReferences.connect_same_thread (*region_list_connections, boost::bind (&RegionFactory::map_remove, boost::weak_ptr (r)));
r->PropertyChanged.connect_same_thread (*region_list_connections, boost::bind (&RegionFactory::region_changed, _1, boost::weak_ptr (r)));
- update_region_name_map (r);
+ add_to_region_name_maps (r);
}
void
@@ -335,6 +336,7 @@ RegionFactory::map_remove (boost::weak_ptr w)
RegionMap::iterator i = region_map.find (r->id());
if (i != region_map.end()) {
+ remove_from_region_name_map (i->second->name ());
region_map.erase (i);
}
}
@@ -384,6 +386,7 @@ RegionFactory::clear_map ()
Glib::Mutex::Lock lm (region_map_lock);
region_map.clear ();
_compound_associations.clear ();
+ region_name_map.clear ();
}
}
@@ -418,8 +421,49 @@ RegionFactory::nregions ()
return region_map.size ();
}
+/** Add a region to the two region name maps */
void
-RegionFactory::update_region_name_map (boost::shared_ptr region)
+RegionFactory::add_to_region_name_maps (boost::shared_ptr region)
+{
+ update_region_name_number_map (region);
+
+ Glib::Mutex::Lock lm (region_name_maps_mutex);
+ region_name_map[region->name()] = region->id ();
+}
+
+/** Account for a region rename in the two region name maps */
+void
+RegionFactory::rename_in_region_name_maps (boost::shared_ptr region)
+{
+ update_region_name_number_map (region);
+
+ Glib::Mutex::Lock lm (region_name_maps_mutex);
+
+ map::iterator i = region_name_map.begin();
+ while (i != region_name_map.end() && i->second != region->id ()) {
+ ++i;
+ }
+
+ /* Erase the entry for the old name and put in a new one */
+ if (i != region_name_map.end()) {
+ region_name_map.erase (i);
+ region_name_map[region->name()] = region->id ();
+ }
+}
+
+/** Remove a region's details from the region_name_map */
+void
+RegionFactory::remove_from_region_name_map (string n)
+{
+ map::iterator i = region_name_map.find (n);
+ if (i != region_name_map.end ()) {
+ region_name_map.erase (i);
+ }
+}
+
+/** Update a region's entry in the region_name_number_map */
+void
+RegionFactory::update_region_name_number_map (boost::shared_ptr region)
{
string::size_type const last_period = region->name().find_last_of ('.');
@@ -432,8 +476,8 @@ RegionFactory::update_region_name_map (boost::shared_ptr region)
which is just fine
*/
- Glib::Mutex::Lock lm (region_name_map_lock);
- region_name_map[base] = atoi (number.c_str ());
+ Glib::Mutex::Lock lm (region_name_maps_mutex);
+ region_name_number_map[base] = atoi (number.c_str ());
}
}
@@ -446,7 +490,7 @@ RegionFactory::region_changed (PropertyChange const & what_changed, boost::weak_
}
if (what_changed.contains (Properties::name)) {
- update_region_name_map (r);
+ rename_in_region_name_maps (r);
}
}
@@ -482,15 +526,15 @@ RegionFactory::region_name (string& result, string base, bool newlevel)
}
{
- Glib::Mutex::Lock lm (region_name_map_lock);
+ Glib::Mutex::Lock lm (region_name_maps_mutex);
map::iterator x;
result = subbase;
- if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
+ if ((x = region_name_number_map.find (subbase)) == region_name_number_map.end()) {
result += ".1";
- region_name_map[subbase] = 1;
+ region_name_number_map[subbase] = 1;
} else {
x->second++;
snprintf (buf, sizeof (buf), ".%d", x->second);
@@ -555,8 +599,6 @@ RegionFactory::new_region_name (string old)
while (number < (UINT_MAX-1)) {
- const RegionMap& regions (RegionFactory::regions());
- RegionMap::const_iterator i;
string sbuf;
number++;
@@ -564,13 +606,7 @@ RegionFactory::new_region_name (string old)
snprintf (buf, len, "%s%" PRIu32 "%s", old.substr (0, last_period + 1).c_str(), number, remainder.c_str());
sbuf = buf;
- for (i = regions.begin(); i != regions.end(); ++i) {
- if (i->second->name() == sbuf) {
- break;
- }
- }
-
- if (i == regions.end()) {
+ if (region_name_map.find (sbuf) == region_name_map.end ()) {
break;
}
}
@@ -607,6 +643,7 @@ RegionFactory::remove_regions_using_source (boost::shared_ptr src)
++j;
if (i->second->uses_source (src)) {
+ remove_from_region_name_map (i->second->name ());
region_map.erase (i);
}
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 318524d8ed..28cefd5ae5 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -26,6 +26,8 @@
#include
#include
+#include
+
#include "pbd/xml++.h"
#include "pbd/enumwriter.h"
#include "pbd/memento_command.h"
@@ -2127,6 +2129,8 @@ Route::set_state (const XMLNode& node, int version)
} else if (child->name() == Controllable::xml_node_name && (prop = child->property("name")) != 0) {
if (prop->value() == "solo") {
_solo_control->set_state (*child, version);
+ } else if (prop->value() == "mute") {
+ _mute_control->set_state (*child, version);
}
} else if (child->name() == X_("RemoteControl")) {
@@ -2164,7 +2168,9 @@ Route::set_state_2X (const XMLNode& node, int version)
}
if ((prop = node.property (X_("flags"))) != 0) {
- _flags = Flag (string_2_enum (prop->value(), _flags));
+ string f = prop->value ();
+ boost::replace_all (f, "ControlOut", "MonitorOut");
+ _flags = Flag (string_2_enum (f, _flags));
} else {
_flags = Flag (0);
}
diff --git a/libs/ardour/run-profiling.sh b/libs/ardour/run-profiling.sh
index 3f2148fbed..30daac9e6e 100644
--- a/libs/ardour/run-profiling.sh
+++ b/libs/ardour/run-profiling.sh
@@ -8,24 +8,43 @@ if [ ! -f './tempo.cc' ]; then
exit 1;
fi
-srcdir=`pwd`
-cd ../../build
+if [ "$1" == "" ]; then
+ echo "Syntax: run-profiling.sh [flag] []"
+ exit 1;
+fi
+
+cd ../..
+top=`pwd`
+cd build
libs='libs'
export LD_LIBRARY_PATH=$libs/audiographer:$libs/vamp-sdk:$libs/surfaces:$libs/surfaces/control_protocol:$libs/ardour:$libs/midi++2:$libs/pbd:$libs/rubberband:$libs/soundtouch:$libs/gtkmm2ext:$libs/appleutility:$libs/taglib:$libs/evoral:$libs/evoral/src/libsmf:$libs/timecode:/usr/local/lib:/usr/local/lib64:$LD_LIBRARY_PATH
+export ARDOUR_CONFIG_PATH=$top:$top/gtk2_ardour:$libs/..:$libs/../gtk2_ardour
export ARDOUR_PANNER_PATH=$libs/panners/2in2out:$libs/panners/1in2out:$libs/panners/vbap
+export ARDOUR_SURFACES_PATH=$libs/surfaces/osc:$libs/surfaces/generic_midi:$libs/surfaces/tranzport:$libs/surfaces/powermate:$libs/surfaces/mackie
+export ARDOUR_MCP_PATH="../mcp"
+export ARDOUR_DLL_PATH=$libs
+export ARDOUR_DATA_PATH=$top/gtk2_ardour:$top/build/gtk2_ardour:.
export LD_PRELOAD=/home/carl/src/libfakejack/libjack.so
-session='32tracks'
+# session='32tracks'
-if [ "$1" == "--debug" ]; then
- gdb --args ./libs/ardour/run-profiling $session
-elif [ "$1" == "--valgrind" ]; then
- valgrind ./libs/ardour/run-profiling $session
-elif [ "$1" == "--callgrind" ]; then
- valgrind --tool=callgrind ./libs/ardour/run-profiling $session
-else
- ./libs/ardour/run-profiling $session
+p=$1
+if [ "$p" == "--debug" -o "$p" == "--valgrind" -o "$p" == "--callgrind" ]; then
+ f=$p
+ p=$2
+ shift 1
+fi
+shift 1
+
+if [ "$f" == "--debug" ]; then
+ gdb --args ./libs/ardour/$p $*
+elif [ "$f" == "--valgrind" ]; then
+ valgrind ./libs/ardour/$p $*
+elif [ "$f" == "--callgrind" ]; then
+ valgrind --tool=callgrind ./libs/ardour/$p $*
+else
+ ./libs/ardour/$p $*
fi
diff --git a/libs/ardour/run-session-tests.sh b/libs/ardour/run-session-tests.sh
new file mode 100644
index 0000000000..63218d8887
--- /dev/null
+++ b/libs/ardour/run-session-tests.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+#
+# Run simple session load tester over a corpus of sessions.
+#
+
+if [ ! -f './tempo.cc' ]; then
+ echo "This script must be run from within the libs/ardour directory";
+ exit 1;
+fi
+
+cd ../..
+top=`pwd`
+cd build
+
+libs='libs'
+
+export LD_LIBRARY_PATH=$libs/audiographer:$libs/vamp-sdk:$libs/surfaces:$libs/surfaces/control_protocol:$libs/ardour:$libs/midi++2:$libs/pbd:$libs/rubberband:$libs/soundtouch:$libs/gtkmm2ext:$libs/appleutility:$libs/taglib:$libs/evoral:$libs/evoral/src/libsmf:$libs/timecode:/usr/local/lib:/usr/local/lib64:$LD_LIBRARY_PATH
+
+export ARDOUR_CONFIG_PATH=$top:$top/gtk2_ardour:$libs/..:$libs/../gtk2_ardour
+export ARDOUR_PANNER_PATH=$libs/panners/2in2out:$libs/panners/1in2out:$libs/panners/vbap
+export ARDOUR_SURFACES_PATH=$libs/surfaces/osc:$libs/surfaces/generic_midi:$libs/surfaces/tranzport:$libs/surfaces/powermate:$libs/surfaces/mackie
+export ARDOUR_MCP_PATH="../mcp"
+export ARDOUR_DLL_PATH=$libs
+export ARDOUR_DATA_PATH=$top/gtk2_ardour:$top/build/gtk2_ardour:.
+
+f=""
+if [ "$1" == "--debug" -o "$1" == "--valgrind" ]; then
+ f=$1
+ shift 1
+fi
+
+d=$1
+if [ "$d" == "" ]; then
+ echo "Syntax: run-session-tests.sh "
+ exit 1
+fi
+
+for s in `find $d -mindepth 1 -maxdepth 1 -type d`; do
+ n=`basename $s`
+ if [ "$f" == "--debug" ]; then
+ gdb --args ./libs/ardour/load-session $s $n
+ elif [ "$f" == "--valgrind" ]; then
+ valgrind ./libs/ardour/load-session $s $n
+ else
+ ./libs/ardour/load-session $s $n
+ fi
+done
+
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 9e46f38f6a..72c2a8654f 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -125,7 +125,7 @@ PBD::Signal0 Session::SuccessfulGraphSort;
static void clean_up_session_event (SessionEvent* ev) { delete ev; }
const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
-/** @param snapshot_name Snapshot name, without .ardour prefix */
+/** @param snapshot_name Snapshot name, without .ardour suffix */
Session::Session (AudioEngine &eng,
const string& fullpath,
const string& snapshot_name,
@@ -248,6 +248,8 @@ Session::destroy ()
_butler->drop_references ();
delete _butler;
+ _butler = 0;
+
delete midi_control_ui;
delete _all_route_group;
@@ -1483,7 +1485,7 @@ Session::resort_routes_using (boost::shared_ptr r)
trace_terminal (*i, *i);
}
- r = sorted_routes;
+ *r = *sorted_routes;
#ifndef NDEBUG
DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 30f8571c01..347c4ee35b 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -675,7 +675,7 @@ Session::rename_state (string old_name, string new_name)
void
Session::remove_state (string snapshot_name)
{
- if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
+ if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
// refuse to remove the current snapshot or the "main" one
return;
}
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index 5fef402d9f..7c23e2aee7 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -1476,9 +1476,11 @@ Session::engine_halted ()
the picture.
*/
- g_atomic_int_set (&_butler->should_do_transport_work, 0);
- set_post_transport_work (PostTransportWork (0));
- _butler->stop ();
+ if (_butler) {
+ g_atomic_int_set (&_butler->should_do_transport_work, 0);
+ set_post_transport_work (PostTransportWork (0));
+ _butler->stop ();
+ }
realtime_stop (false, true);
non_realtime_stop (false, 0, ignored);
diff --git a/libs/ardour/test/automation_list_property_test.cc b/libs/ardour/test/automation_list_property_test.cc
new file mode 100644
index 0000000000..90e2e22989
--- /dev/null
+++ b/libs/ardour/test/automation_list_property_test.cc
@@ -0,0 +1,129 @@
+/*
+ Copyright (C) 2012 Paul Davis
+
+ 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 "pbd/properties.h"
+#include "pbd/stateful_diff_command.h"
+#include "ardour/automation_list.h"
+#include "automation_list_property_test.h"
+#include "test_util.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION (AutomationListPropertyTest);
+
+using namespace std;
+using namespace PBD;
+using namespace ARDOUR;
+
+void
+AutomationListPropertyTest::basicTest ()
+{
+ list ignore_properties;
+ ignore_properties.push_back ("id");
+
+ PropertyDescriptor > descriptor;
+ descriptor.property_id = g_quark_from_static_string ("FadeIn");
+ AutomationListProperty property (
+ descriptor,
+ boost::shared_ptr (new AutomationList (Evoral::Parameter (FadeInAutomation)))
+ );
+
+ property.clear_changes ();
+
+ /* No change since we just cleared them */
+ CPPUNIT_ASSERT_EQUAL (false, property.changed());
+
+ property->add (1, 2);
+ property->add (3, 4);
+
+ /* Now it has changed */
+ CPPUNIT_ASSERT_EQUAL (true, property.changed());
+
+ XMLNode* foo = new XMLNode ("test");
+ property.get_changes_as_xml (foo);
+ check_xml (foo, "../libs/ardour/test/data/automation_list_property_test1.ref", ignore_properties);
+
+ /* Do some more */
+ property.clear_changes ();
+ CPPUNIT_ASSERT_EQUAL (false, property.changed());
+ property->add (5, 6);
+ property->add (7, 8);
+ CPPUNIT_ASSERT_EQUAL (true, property.changed());
+ foo = new XMLNode ("test");
+ property.get_changes_as_xml (foo);
+ check_xml (foo, "../libs/ardour/test/data/automation_list_property_test2.ref", ignore_properties);
+}
+
+/** Here's a StatefulDestructible class that has a AutomationListProperty */
+class Fred : public StatefulDestructible
+{
+public:
+ Fred ()
+ : _jim (_descriptor, boost::shared_ptr (new AutomationList (Evoral::Parameter (FadeInAutomation))))
+
+ {
+ add_property (_jim);
+ }
+
+ XMLNode & get_state () {
+ XMLNode* n = new XMLNode ("State");
+ add_properties (*n);
+ return *n;
+ }
+
+ int set_state (XMLNode const & node, int) {
+ set_values (node);
+ return 0;
+ }
+
+ static void make_property_quarks () {
+ _descriptor.property_id = g_quark_from_static_string ("FadeIn");
+ }
+
+ AutomationListProperty _jim;
+ static PropertyDescriptor > _descriptor;
+};
+
+PropertyDescriptor > Fred::_descriptor;
+
+void
+AutomationListPropertyTest::undoTest ()
+{
+ list ignore_properties;
+ ignore_properties.push_back ("id");
+
+ Fred::make_property_quarks ();
+
+ boost::shared_ptr sheila (new Fred);
+
+ /* Add some data */
+ sheila->_jim->add (1, 2);
+ sheila->_jim->add (3, 4);
+
+ /* Do a `command' */
+ sheila->clear_changes ();
+ sheila->_jim->add (5, 6);
+ sheila->_jim->add (7, 8);
+ StatefulDiffCommand sdc (sheila);
+
+ /* Undo */
+ sdc.undo ();
+ check_xml (&sheila->get_state(), "../libs/ardour/test/data/automation_list_property_test3.ref", ignore_properties);
+
+ /* Redo */
+ sdc.redo ();
+ check_xml (&sheila->get_state(), "../libs/ardour/test/data/automation_list_property_test4.ref", ignore_properties);
+}
diff --git a/libs/ardour/test/automation_list_property_test.h b/libs/ardour/test/automation_list_property_test.h
new file mode 100644
index 0000000000..8885d23242
--- /dev/null
+++ b/libs/ardour/test/automation_list_property_test.h
@@ -0,0 +1,32 @@
+/*
+ Copyright (C) 2012 Paul Davis
+
+ 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
+#include
+
+class AutomationListPropertyTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE (AutomationListPropertyTest);
+ CPPUNIT_TEST (basicTest);
+ CPPUNIT_TEST (undoTest);
+ CPPUNIT_TEST_SUITE_END ();
+
+public:
+ void basicTest ();
+ void undoTest ();
+};
diff --git a/libs/ardour/test/combine_regions_test.cc b/libs/ardour/test/combine_regions_test.cc
index 7c4d5f0e68..385a6e852f 100644
--- a/libs/ardour/test/combine_regions_test.cc
+++ b/libs/ardour/test/combine_regions_test.cc
@@ -76,8 +76,6 @@ CombineRegionsTest::check_crossfade1 ()
r0 *= fade_out[i - 128];
float const r1 = (i - 128) * fade_in[i - 128];
- cout << setprecision(12);
- cout << "\t\ti=" << i << " fade_out=" << fade_out[i - 128] << " r1=" << r1 << " r0=" << r0 << "\n";
CPPUNIT_ASSERT_DOUBLES_EQUAL (r0 + r1, buf[i], 1e-16);
}
@@ -180,8 +178,6 @@ CombineRegionsTest::check_crossfade2 ()
float r1 = (i - 128) * region_fade_in;
r1 *= fade_in[i - 128];
- cout << setprecision(12);
- cout << "\t\ti=" << i << " fade_out=" << fade_out[i - 128] << " r1=" << r1 << " r0=" << r0 << "\n";
CPPUNIT_ASSERT_DOUBLES_EQUAL (r0 + r1, buf[i], 1e-16);
}
@@ -203,8 +199,6 @@ CombineRegionsTest::check_crossfade2 ()
void
CombineRegionsTest::crossfadeTest2 ()
{
- cout << "\n\n\nCOMBINE\n";
-
/* Two regions, both 256 frames in length, overlapping by 128 frames in the middle */
_ar[0]->set_default_fade_in ();
@@ -231,7 +225,6 @@ CombineRegionsTest::crossfadeTest2 ()
CPPUNIT_ASSERT_EQUAL (false, _ar[1]->fade_out_is_xfade ());
/* Check that the read comes back correctly */
- cout << "\n\n\nFIRST READ\n";
check_crossfade2 ();
/* Combine the two regions */
diff --git a/libs/ardour/test/data/automation_list_property_test1.ref b/libs/ardour/test/data/automation_list_property_test1.ref
new file mode 100644
index 0000000000..36e8389bf5
--- /dev/null
+++ b/libs/ardour/test/data/automation_list_property_test1.ref
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+ 1 2
+3 4
+
+
+
+
+
diff --git a/libs/ardour/test/data/automation_list_property_test2.ref b/libs/ardour/test/data/automation_list_property_test2.ref
new file mode 100644
index 0000000000..cacfe510aa
--- /dev/null
+++ b/libs/ardour/test/data/automation_list_property_test2.ref
@@ -0,0 +1,21 @@
+
+
+
+
+
+ 1 2
+3 4
+
+
+
+
+
+ 1 2
+3 4
+5 6
+7 8
+
+
+
+
+
diff --git a/libs/ardour/test/data/automation_list_property_test3.ref b/libs/ardour/test/data/automation_list_property_test3.ref
new file mode 100644
index 0000000000..e5e6117d69
--- /dev/null
+++ b/libs/ardour/test/data/automation_list_property_test3.ref
@@ -0,0 +1,10 @@
+
+
+
+
+ 1 2
+3 4
+
+
+
+
diff --git a/libs/ardour/test/data/automation_list_property_test4.ref b/libs/ardour/test/data/automation_list_property_test4.ref
new file mode 100644
index 0000000000..573e16d291
--- /dev/null
+++ b/libs/ardour/test/data/automation_list_property_test4.ref
@@ -0,0 +1,12 @@
+
+
+
+
+ 1 2
+3 4
+5 6
+7 8
+
+
+
+
diff --git a/libs/ardour/test/load_session.cc b/libs/ardour/test/load_session.cc
new file mode 100644
index 0000000000..3c6bd9bb10
--- /dev/null
+++ b/libs/ardour/test/load_session.cc
@@ -0,0 +1,48 @@
+#include "test_util.h"
+#include "pbd/failed_constructor.h"
+#include "ardour/ardour.h"
+#include "ardour/audioengine.h"
+#include "ardour/session.h"
+#include "midi++/manager.h"
+#include
+#include
+
+using namespace std;
+using namespace ARDOUR;
+
+int main (int argc, char* argv[])
+{
+ if (argc != 3) {
+ cerr << "Syntax: " << argv[0] << " \n";
+ exit (EXIT_FAILURE);
+ }
+
+ ARDOUR::init (false, true);
+
+ Session* s = 0;
+
+ try {
+ s = load_session (argv[1], argv[2]);
+ } catch (failed_constructor& e) {
+ cerr << "failed_constructor: " << e.what() << "\n";
+ exit (EXIT_FAILURE);
+ } catch (AudioEngine::PortRegistrationFailure& e) {
+ cerr << "PortRegistrationFailure: " << e.what() << "\n";
+ exit (EXIT_FAILURE);
+ } catch (exception& e) {
+ cerr << "exception: " << e.what() << "\n";
+ exit (EXIT_FAILURE);
+ } catch (...) {
+ cerr << "unknown exception.\n";
+ exit (EXIT_FAILURE);
+ }
+
+ AudioEngine::instance()->remove_session ();
+ delete s;
+ AudioEngine::instance()->stop (true);
+
+ MIDI::Manager::destroy ();
+ AudioEngine::destroy ();
+
+ return 0;
+}
diff --git a/libs/ardour/test/playlist_equivalent_regions_test.cc b/libs/ardour/test/playlist_equivalent_regions_test.cc
new file mode 100644
index 0000000000..12853d39dd
--- /dev/null
+++ b/libs/ardour/test/playlist_equivalent_regions_test.cc
@@ -0,0 +1,95 @@
+/*
+ Copyright (C) 2012 Paul Davis
+
+ 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/playlist.h"
+#include "ardour/playlist_factory.h"
+#include "ardour/region.h"
+#include "playlist_equivalent_regions_test.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION (PlaylistEquivalentRegionsTest);
+
+using namespace std;
+using namespace ARDOUR;
+
+void
+PlaylistEquivalentRegionsTest::setUp ()
+{
+ AudioRegionTest::setUp ();
+
+ _playlist_b = PlaylistFactory::create (DataType::AUDIO, *_session, "testB");
+}
+
+void
+PlaylistEquivalentRegionsTest::tearDown ()
+{
+ _playlist_b.reset ();
+
+ AudioRegionTest::tearDown ();
+}
+
+/* Test simple equivalency operations */
+void
+PlaylistEquivalentRegionsTest::basicsTest ()
+{
+ /* Put _r[0] on _playlist */
+ _playlist->add_region (_r[0], 42);
+
+ /* And _r[1] on _playlist_b at the same position */
+ _playlist_b->add_region (_r[1], 42);
+
+ /* Look for the equivalents to _r[0] on _playlist_b */
+ vector > e;
+ _playlist_b->get_equivalent_regions (_r[0], e);
+
+ /* That should be _r[1] */
+ CPPUNIT_ASSERT_EQUAL (size_t (1), e.size ());
+ CPPUNIT_ASSERT_EQUAL (e.front(), _r[1]);
+
+ /* Move _r[1] */
+ _r[1]->set_position (66);
+
+ /* Look again for the equivalents to _r[0] on _playlist_b */
+ e.clear ();
+ _playlist_b->get_equivalent_regions (_r[0], e);
+
+ /* There should be none */
+ CPPUNIT_ASSERT (e.empty ());
+}
+
+void
+PlaylistEquivalentRegionsTest::multiLayerTest ()
+{
+ _playlist->clear ();
+ _playlist_b->clear ();
+
+ /* Put _r[0] and _r[1] at the same position on _playlist so that they overlap */
+ _playlist->add_region (_r[0], 42);
+ _playlist->add_region (_r[1], 42);
+
+ /* And _r[2], _r[3] similarly on _playlist_b */
+ _playlist_b->add_region (_r[2], 42);
+ _playlist_b->add_region (_r[3], 42);
+
+ /* Look for equivalents to _r[0] on _playlist_b */
+ vector > e;
+ _playlist_b->get_equivalent_regions (_r[0], e);
+
+ /* That should be _r[2] and _r[3] */
+ CPPUNIT_ASSERT_EQUAL (size_t (2), e.size ());
+ CPPUNIT_ASSERT ((e.front() == _r[2] && e.back() == _r[3]) || (e.front() == _r[3] && e.back() == _r[2]));
+}
diff --git a/libs/ardour/test/playlist_equivalent_regions_test.h b/libs/ardour/test/playlist_equivalent_regions_test.h
new file mode 100644
index 0000000000..a3447bbe80
--- /dev/null
+++ b/libs/ardour/test/playlist_equivalent_regions_test.h
@@ -0,0 +1,36 @@
+/*
+ Copyright (C) 2012 Paul Davis
+
+ 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 "audio_region_test.h"
+
+class PlaylistEquivalentRegionsTest : public AudioRegionTest
+{
+ CPPUNIT_TEST_SUITE (PlaylistEquivalentRegionsTest);
+ CPPUNIT_TEST (basicsTest);
+ CPPUNIT_TEST (multiLayerTest);
+ CPPUNIT_TEST_SUITE_END ();
+
+public:
+ void setUp ();
+ void tearDown ();
+ void basicsTest ();
+ void multiLayerTest ();
+
+private:
+ boost::shared_ptr _playlist_b;
+};
diff --git a/libs/ardour/test/profiling/load_session.cc b/libs/ardour/test/profiling/load_session.cc
new file mode 100644
index 0000000000..3c6bd9bb10
--- /dev/null
+++ b/libs/ardour/test/profiling/load_session.cc
@@ -0,0 +1,48 @@
+#include "test_util.h"
+#include "pbd/failed_constructor.h"
+#include "ardour/ardour.h"
+#include "ardour/audioengine.h"
+#include "ardour/session.h"
+#include "midi++/manager.h"
+#include
+#include
+
+using namespace std;
+using namespace ARDOUR;
+
+int main (int argc, char* argv[])
+{
+ if (argc != 3) {
+ cerr << "Syntax: " << argv[0] << " \n";
+ exit (EXIT_FAILURE);
+ }
+
+ ARDOUR::init (false, true);
+
+ Session* s = 0;
+
+ try {
+ s = load_session (argv[1], argv[2]);
+ } catch (failed_constructor& e) {
+ cerr << "failed_constructor: " << e.what() << "\n";
+ exit (EXIT_FAILURE);
+ } catch (AudioEngine::PortRegistrationFailure& e) {
+ cerr << "PortRegistrationFailure: " << e.what() << "\n";
+ exit (EXIT_FAILURE);
+ } catch (exception& e) {
+ cerr << "exception: " << e.what() << "\n";
+ exit (EXIT_FAILURE);
+ } catch (...) {
+ cerr << "unknown exception.\n";
+ exit (EXIT_FAILURE);
+ }
+
+ AudioEngine::instance()->remove_session ();
+ delete s;
+ AudioEngine::instance()->stop (true);
+
+ MIDI::Manager::destroy ();
+ AudioEngine::destroy ();
+
+ return 0;
+}
diff --git a/libs/ardour/test/profiling/lots_of_regions.cc b/libs/ardour/test/profiling/lots_of_regions.cc
new file mode 100644
index 0000000000..5c27e8425a
--- /dev/null
+++ b/libs/ardour/test/profiling/lots_of_regions.cc
@@ -0,0 +1,49 @@
+#include "test_util.h"
+#include "ardour/ardour.h"
+#include "ardour/midi_track.h"
+#include "ardour/midi_region.h"
+#include "ardour/session.h"
+#include "ardour/playlist.h"
+#include "pbd/stateful_diff_command.h"
+
+using namespace std;
+using namespace ARDOUR;
+using namespace PBD;
+
+int
+main (int argc, char* argv[])
+{
+ ARDOUR::init (false, true);
+ Session* session = load_session ("../libs/ardour/test/profiling/sessions/1region", "1region");
+
+ assert (session->get_routes()->size() == 2);
+
+ /* Find the track */
+ boost::shared_ptr track = boost::dynamic_pointer_cast (session->get_routes()->back());
+ assert (track);
+
+ /* And the playlist */
+ boost::shared_ptr playlist = track->playlist ();
+ assert (playlist);
+
+ /* And the region */
+ boost::shared_ptr region = boost::dynamic_pointer_cast (playlist->region_list().rlist().front());
+ assert (region);
+
+ /* Duplicate it a lot */
+ session->begin_reversible_command ("foo");
+ playlist->clear_changes ();
+ playlist->duplicate (region, region->last_frame(), 1000);
+ session->add_command (new StatefulDiffCommand (playlist));
+ session->commit_reversible_command ();
+
+ /* Undo that */
+ session->undo (1);
+
+ /* And do it again */
+ session->begin_reversible_command ("foo");
+ playlist->clear_changes ();
+ playlist->duplicate (region, region->last_frame(), 1000);
+ session->add_command (new StatefulDiffCommand (playlist));
+ session->commit_reversible_command ();
+}
diff --git a/libs/ardour/test/profiling/runpc.cc b/libs/ardour/test/profiling/runpc.cc
index 90f9136e23..ef5d322df2 100644
--- a/libs/ardour/test/profiling/runpc.cc
+++ b/libs/ardour/test/profiling/runpc.cc
@@ -5,49 +5,12 @@
#include "pbd/enumwriter.h"
#include "ardour/session.h"
#include "ardour/audioengine.h"
+#include "test_util.h"
using namespace std;
using namespace PBD;
using namespace ARDOUR;
-class TestReceiver : public Receiver
-{
-protected:
- void receive (Transmitter::Channel chn, const char * str) {
- const char *prefix = "";
-
- switch (chn) {
- case Transmitter::Error:
- prefix = ": [ERROR]: ";
- break;
- case Transmitter::Info:
- /* ignore */
- return;
- case Transmitter::Warning:
- prefix = ": [WARNING]: ";
- break;
- case Transmitter::Fatal:
- prefix = ": [FATAL]: ";
- break;
- case Transmitter::Throw:
- /* this isn't supposed to happen */
- abort ();
- }
-
- /* note: iostreams are already thread-safe: no external
- lock required.
- */
-
- cout << prefix << str << endl;
-
- if (chn == Transmitter::Fatal) {
- exit (9);
- }
- }
-};
-
-TestReceiver test_receiver;
-
int
main (int argc, char* argv[])
{
@@ -55,29 +18,18 @@ main (int argc, char* argv[])
cerr << argv[0] << ": \n";
exit (EXIT_FAILURE);
}
-
- string const test_session_path = string_compose ("../libs/ardour/test/profiling/sessions/%1", argv[1]);
- string const test_session_snapshot = string_compose ("%1.ardour", argv[1]);
-
- init (false, true);
- SessionEvent::create_per_thread_pool ("test", 512);
- test_receiver.listen_to (error);
- test_receiver.listen_to (info);
- test_receiver.listen_to (fatal);
- test_receiver.listen_to (warning);
+ ARDOUR::init (false, true);
- AudioEngine* engine = new AudioEngine ("test", "");
- engine->start ();
- MIDI::Manager::create (engine->jack ());
-
- Session* session = new Session (*engine, test_session_path, test_session_snapshot);
- engine->set_session (session);
+ Session* session = load_session (
+ string_compose ("../libs/ardour/test/profiling/sessions/%1", argv[1]),
+ string_compose ("%1.ardour", argv[1])
+ );
cout << "INFO: " << session->get_routes()->size() << " routes.\n";
for (int i = 0; i < 32768; ++i) {
- session->process (64);
+ session->process (session->engine().frames_per_cycle ());
}
return 0;
diff --git a/libs/ardour/test/profiling/sessions/1region/1region.ardour b/libs/ardour/test/profiling/sessions/1region/1region.ardour
new file mode 100644
index 0000000000..a3fc264dab
--- /dev/null
+++ b/libs/ardour/test/profiling/sessions/1region/1region.ardour
@@ -0,0 +1,181 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/ardour/test/profiling/sessions/1region/1region.ardour.bak b/libs/ardour/test/profiling/sessions/1region/1region.ardour.bak
new file mode 100644
index 0000000000..4a3e63f351
--- /dev/null
+++ b/libs/ardour/test/profiling/sessions/1region/1region.ardour.bak
@@ -0,0 +1,148 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/ardour/test/profiling/sessions/1region/1region.history b/libs/ardour/test/profiling/sessions/1region/1region.history
new file mode 100644
index 0000000000..27732c0340
--- /dev/null
+++ b/libs/ardour/test/profiling/sessions/1region/1region.history
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/ardour/test/profiling/sessions/1region/1region.history.bak b/libs/ardour/test/profiling/sessions/1region/1region.history.bak
new file mode 100644
index 0000000000..6dd2506a89
--- /dev/null
+++ b/libs/ardour/test/profiling/sessions/1region/1region.history.bak
@@ -0,0 +1,2 @@
+
+
diff --git a/libs/ardour/test/profiling/sessions/1region/instant.xml b/libs/ardour/test/profiling/sessions/1region/instant.xml
new file mode 100644
index 0000000000..5f0c8e83dd
--- /dev/null
+++ b/libs/ardour/test/profiling/sessions/1region/instant.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/ardour/test/profiling/sessions/1region/interchange/1region/midifiles/MIDI 1-1.mid b/libs/ardour/test/profiling/sessions/1region/interchange/1region/midifiles/MIDI 1-1.mid
new file mode 100644
index 0000000000..80d4f9fda2
Binary files /dev/null and b/libs/ardour/test/profiling/sessions/1region/interchange/1region/midifiles/MIDI 1-1.mid differ
diff --git a/libs/ardour/test/profiling/sessions/32tracks/32tracks.ardour b/libs/ardour/test/profiling/sessions/32tracks/32tracks.ardour
index 43b597c17b..6794c67bc9 100644
--- a/libs/ardour/test/profiling/sessions/32tracks/32tracks.ardour
+++ b/libs/ardour/test/profiling/sessions/32tracks/32tracks.ardour
@@ -1,11 +1,10 @@
-
+
+
-
-
@@ -21,8 +20,6 @@
-
-
@@ -52,72 +49,72 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -228,9 +225,7 @@
-
-
-
+
@@ -266,9 +261,7 @@
-
-
-
+
@@ -304,9 +297,7 @@
-
-
-
+
@@ -342,9 +333,7 @@
-
-
-
+
@@ -380,9 +369,7 @@
-
-
-
+
@@ -418,9 +405,7 @@
-
-
-
+
@@ -456,9 +441,7 @@
-
-
-
+
@@ -494,9 +477,7 @@
-
-
-
+
@@ -532,9 +513,7 @@
-
-
-
+
@@ -570,9 +549,7 @@
-
-
-
+
@@ -608,9 +585,7 @@
-
-
-
+
@@ -646,9 +621,7 @@
-
-
-
+
@@ -684,9 +657,7 @@
-
-
-
+
@@ -722,9 +693,7 @@
-
-
-
+
@@ -760,9 +729,7 @@
-
-
-
+
@@ -798,9 +765,7 @@
-
-
-
+
@@ -836,9 +801,7 @@
-
-
-
+
@@ -874,9 +837,7 @@
-
-
-
+
@@ -912,9 +873,7 @@
-
-
-
+
@@ -950,9 +909,7 @@
-
-
-
+
@@ -988,9 +945,7 @@
-
-
-
+
@@ -1026,9 +981,7 @@
-
-
-
+
@@ -1064,9 +1017,7 @@
-
-
-
+
@@ -1102,9 +1053,7 @@
-
-
-
+
@@ -1216,9 +1165,7 @@
-
-
-
+
@@ -1254,9 +1201,7 @@
-
-
-
+
@@ -1292,9 +1237,7 @@
-
-
-
+
@@ -1330,9 +1273,7 @@
-
-
-
+
@@ -1368,38 +1309,38 @@
-
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
@@ -1412,6 +1353,9 @@
+
+
+
@@ -1424,8 +1368,10 @@
-
-
+
+
+
+
diff --git a/libs/ardour/test/profiling/sessions/32tracks/32tracks.ardour.bak b/libs/ardour/test/profiling/sessions/32tracks/32tracks.ardour.bak
index 66adbab0a8..6794c67bc9 100644
--- a/libs/ardour/test/profiling/sessions/32tracks/32tracks.ardour.bak
+++ b/libs/ardour/test/profiling/sessions/32tracks/32tracks.ardour.bak
@@ -1,11 +1,10 @@
-
+
+
-
-
@@ -21,8 +20,6 @@
-
-
@@ -52,72 +49,72 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -150,7 +147,7 @@
-
+
@@ -188,7 +185,7 @@
-
+
@@ -226,11 +223,9 @@
-
+
-
-
-
+
@@ -264,11 +259,9 @@
-
+
-
-
-
+
@@ -302,11 +295,9 @@
-
+
-
-
-
+
@@ -340,11 +331,9 @@
-
+
-
-
-
+
@@ -378,11 +367,9 @@
-
+
-
-
-
+
@@ -416,11 +403,9 @@
-
+
-
-
-
+
@@ -454,11 +439,9 @@
-
+
-
-
-
+
@@ -492,11 +475,9 @@
-
+
-
-
-
+
@@ -530,11 +511,9 @@
-
+
-
-
-
+
@@ -568,11 +547,9 @@
-
+
-
-
-
+
@@ -606,11 +583,9 @@
-
+
-
-
-
+
@@ -644,11 +619,9 @@
-
+
-
-
-
+
@@ -682,11 +655,9 @@
-
+
-
-
-
+
@@ -720,11 +691,9 @@
-
+
-
-
-
+
@@ -758,11 +727,9 @@
-
+
-
-
-
+
@@ -796,11 +763,9 @@
-
+
-
-
-
+
@@ -834,11 +799,9 @@
-
+
-
-
-
+
@@ -872,11 +835,9 @@
-
+
-
-
-
+
@@ -910,11 +871,9 @@
-
+
-
-
-
+
@@ -948,11 +907,9 @@
-
+
-
-
-
+
@@ -986,11 +943,9 @@
-
+
-
-
-
+
@@ -1024,11 +979,9 @@
-
+
-
-
-
+
@@ -1062,11 +1015,9 @@
-
+
-
-
-
+
@@ -1100,11 +1051,9 @@
-
+
-
-
-
+
@@ -1138,7 +1087,7 @@
-
+
@@ -1176,7 +1125,7 @@
-
+
@@ -1214,11 +1163,9 @@
-
+
-
-
-
+
@@ -1252,11 +1199,9 @@
-
+
-
-
-
+
@@ -1290,11 +1235,9 @@
-
+
-
-
-
+
@@ -1328,11 +1271,9 @@
-
+
-
-
-
+
@@ -1368,38 +1309,38 @@
-
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
@@ -1412,6 +1353,9 @@
+
+
+
@@ -1424,7 +1368,349 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+