From: David Robillard Date: Fri, 19 Sep 2008 01:16:44 +0000 (+0000) Subject: Tidy. X-Git-Tag: 3.0-alpha5~4138 X-Git-Url: https://main.carlh.net/gitweb/?p=ardour.git;a=commitdiff_plain;h=d8ade6d30595a3a8be343b392e47d422940eac27 Tidy. git-svn-id: svn://localhost/ardour2/branches/3.0@3755 d708f5d6-7413-0410-9779-e7cbd77b26cf --- diff --git a/gtk2_ardour/automation_controller.cc b/gtk2_ardour/automation_controller.cc index dc9b8bb2c4..775c12f668 100644 --- a/gtk2_ardour/automation_controller.cc +++ b/gtk2_ardour/automation_controller.cc @@ -19,7 +19,7 @@ */ #include -#include "ardour/automation_event.h" +#include "ardour/automation_list.h" #include "ardour/automation_control.h" #include "ardour_ui.h" #include "utils.h" diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc index de3e2d9873..dd6990b17d 100644 --- a/gtk2_ardour/automation_line.cc +++ b/gtk2_ardour/automation_line.cc @@ -26,9 +26,9 @@ #include #include -#include -#include +#include #include +#include #include "simplerect.h" #include "automation_line.h" diff --git a/gtk2_ardour/automation_line.h b/gtk2_ardour/automation_line.h index ace2145ff3..bc9c75e8f7 100644 --- a/gtk2_ardour/automation_line.h +++ b/gtk2_ardour/automation_line.h @@ -33,7 +33,7 @@ #include #include -#include +#include using std::vector; diff --git a/gtk2_ardour/control_point.h b/gtk2_ardour/control_point.h index 47b0d131b7..013ba71e49 100644 --- a/gtk2_ardour/control_point.h +++ b/gtk2_ardour/control_point.h @@ -22,7 +22,7 @@ #include -#include +#include #include "canvas.h" #include "simplerect.h" diff --git a/gtk2_ardour/crossfade_edit.cc b/gtk2_ardour/crossfade_edit.cc index 80b6224bd3..3e85bd22db 100644 --- a/gtk2_ardour/crossfade_edit.cc +++ b/gtk2_ardour/crossfade_edit.cc @@ -27,8 +27,8 @@ #include -#include -#include +#include +#include #include #include #include diff --git a/gtk2_ardour/crossfade_edit.h b/gtk2_ardour/crossfade_edit.h index e0e9926687..9e4db3be88 100644 --- a/gtk2_ardour/crossfade_edit.h +++ b/gtk2_ardour/crossfade_edit.h @@ -26,7 +26,7 @@ #include #include -#include +#include #include "ardour_dialog.h" #include "canvas.h" diff --git a/gtk2_ardour/curvetest.cc b/gtk2_ardour/curvetest.cc index ec552848d2..88c7b8e116 100644 --- a/gtk2_ardour/curvetest.cc +++ b/gtk2_ardour/curvetest.cc @@ -22,7 +22,8 @@ #include #include -#include +#include +#include using namespace std; using namespace ARDOUR; diff --git a/gtk2_ardour/region_gain_line.cc b/gtk2_ardour/region_gain_line.cc index 9b2ff346dd..61f7dde0c7 100644 --- a/gtk2_ardour/region_gain_line.cc +++ b/gtk2_ardour/region_gain_line.cc @@ -17,7 +17,7 @@ */ -#include +#include #include #include diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript index b51e81c2ca..55e287f46b 100644 --- a/libs/ardour/SConscript +++ b/libs/ardour/SConscript @@ -49,7 +49,7 @@ auto_bundle.cc automatable.cc automation.cc automation_control.cc -automation_event.cc +automation_list.cc base_audio_port.cc base_midi_port.cc broadcast_info.cc @@ -60,7 +60,6 @@ configuration.cc control_protocol_manager.cc control_protocol_search_path.cc crossfade.cc -curve.cc cycle_timer.cc default_click.cc directory_names.cc diff --git a/libs/ardour/ardour/automatable.h b/libs/ardour/ardour/automatable.h index ce31721802..99e7891ce8 100644 --- a/libs/ardour/ardour/automatable.h +++ b/libs/ardour/ardour/automatable.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/libs/ardour/ardour/automation_control.h b/libs/ardour/ardour/automation_control.h index c414f7bc40..24d1db3eec 100644 --- a/libs/ardour/ardour/automation_control.h +++ b/libs/ardour/ardour/automation_control.h @@ -25,7 +25,7 @@ #include #include #include -#include +#include namespace ARDOUR { diff --git a/libs/ardour/ardour/automation_event.h b/libs/ardour/ardour/automation_event.h deleted file mode 100644 index ed3379bc15..0000000000 --- a/libs/ardour/ardour/automation_event.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - Copyright (C) 2002 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. - -*/ - -#ifndef __ardour_automation_event_h__ -#define __ardour_automation_event_h__ - -#include -#include -#include - -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include - -#include - -using Evoral::ControlEvent; - -namespace ARDOUR { - -class AutomationList : public PBD::StatefulDestructible, public Evoral::ControlList -{ - public: - AutomationList (Parameter id); - AutomationList (const XMLNode&, Parameter id); - ~AutomationList(); - - virtual boost::shared_ptr create(Evoral::Parameter id); - - AutomationList (const AutomationList&); - AutomationList (const AutomationList&, double start, double end); - AutomationList& operator= (const AutomationList&); - bool operator== (const AutomationList&); - - void freeze(); - void thaw (); - void mark_dirty () const; - - void set_automation_state (AutoState); - AutoState automation_state() const { return _state; } - sigc::signal automation_state_changed; - - void set_automation_style (AutoStyle m); - AutoStyle automation_style() const { return _style; } - sigc::signal automation_style_changed; - - bool automation_playback() const { - return (_state & Play) || ((_state & Touch) && !_touching); - } - bool automation_write () const { - return (_state & Write) || ((_state & Touch) && _touching); - } - - sigc::signal StateChanged; - - static sigc::signal AutomationListCreated; - mutable sigc::signal Dirty; - - void start_touch (); - void stop_touch (); - bool touching() const { return _touching; } - - XMLNode& get_state(void); - int set_state (const XMLNode &s); - XMLNode& state (bool full); - XMLNode& serialize_events (); - - private: - int deserialize_events (const XMLNode&); - - void maybe_signal_changed (); - - AutoState _state; - AutoStyle _style; - bool _touching; -}; - -} // namespace - -#endif /* __ardour_automation_event_h__ */ diff --git a/libs/ardour/ardour/automation_list.h b/libs/ardour/ardour/automation_list.h new file mode 100644 index 0000000000..ed3379bc15 --- /dev/null +++ b/libs/ardour/ardour/automation_list.h @@ -0,0 +1,105 @@ +/* + Copyright (C) 2002 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. + +*/ + +#ifndef __ardour_automation_event_h__ +#define __ardour_automation_event_h__ + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include + +using Evoral::ControlEvent; + +namespace ARDOUR { + +class AutomationList : public PBD::StatefulDestructible, public Evoral::ControlList +{ + public: + AutomationList (Parameter id); + AutomationList (const XMLNode&, Parameter id); + ~AutomationList(); + + virtual boost::shared_ptr create(Evoral::Parameter id); + + AutomationList (const AutomationList&); + AutomationList (const AutomationList&, double start, double end); + AutomationList& operator= (const AutomationList&); + bool operator== (const AutomationList&); + + void freeze(); + void thaw (); + void mark_dirty () const; + + void set_automation_state (AutoState); + AutoState automation_state() const { return _state; } + sigc::signal automation_state_changed; + + void set_automation_style (AutoStyle m); + AutoStyle automation_style() const { return _style; } + sigc::signal automation_style_changed; + + bool automation_playback() const { + return (_state & Play) || ((_state & Touch) && !_touching); + } + bool automation_write () const { + return (_state & Write) || ((_state & Touch) && _touching); + } + + sigc::signal StateChanged; + + static sigc::signal AutomationListCreated; + mutable sigc::signal Dirty; + + void start_touch (); + void stop_touch (); + bool touching() const { return _touching; } + + XMLNode& get_state(void); + int set_state (const XMLNode &s); + XMLNode& state (bool full); + XMLNode& serialize_events (); + + private: + int deserialize_events (const XMLNode&); + + void maybe_signal_changed (); + + AutoState _state; + AutoStyle _style; + bool _touching; +}; + +} // namespace + +#endif /* __ardour_automation_event_h__ */ diff --git a/libs/ardour/ardour/crossfade.h b/libs/ardour/ardour/crossfade.h index 9ba3689e82..b0785a6e59 100644 --- a/libs/ardour/ardour/crossfade.h +++ b/libs/ardour/ardour/crossfade.h @@ -30,9 +30,9 @@ #include #include -#include #include #include +#include namespace ARDOUR { diff --git a/libs/ardour/ardour/curve.h b/libs/ardour/ardour/curve.h deleted file mode 100644 index 433b00a270..0000000000 --- a/libs/ardour/ardour/curve.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (C) 2001-2007 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. - -*/ - -#ifndef __ardour_curve_h__ -#define __ardour_curve_h__ - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace ARDOUR { - -class Curve : public boost::noncopyable -{ - public: - Curve (const AutomationList& al); - - bool rt_safe_get_vector (double x0, double x1, float *arg, int32_t veclen); - void get_vector (double x0, double x1, float *arg, int32_t veclen); - - void solve (); - - private: - double unlocked_eval (double where); - double multipoint_eval (double x); - - void _get_vector (double x0, double x1, float *arg, int32_t veclen); - - void on_list_dirty() { _dirty = true; } - - bool _dirty; - const AutomationList& _list; -}; - -} // namespace ARDOUR - -extern "C" { - void curve_get_vector_from_c (void *arg, double, double, float*, int32_t); -} - -#endif /* __ardour_curve_h__ */ diff --git a/libs/ardour/ardour/gain.h b/libs/ardour/ardour/gain.h index e57cfdc0d7..0c7d9f957d 100644 --- a/libs/ardour/ardour/gain.h +++ b/libs/ardour/ardour/gain.h @@ -21,7 +21,8 @@ #define __ardour_gain_h__ #include "ardour.h" -#include "curve.h" +#include "automation_list.h" +#include namespace ARDOUR { diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h index b44e131d8a..6cae11a7fa 100644 --- a/libs/ardour/ardour/io.h +++ b/libs/ardour/ardour/io.h @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include diff --git a/libs/ardour/ardour/io_processor.h b/libs/ardour/ardour/io_processor.h index a535ce3bb4..d2bd210516 100644 --- a/libs/ardour/ardour/io_processor.h +++ b/libs/ardour/ardour/io_processor.h @@ -34,7 +34,7 @@ #include #include #include -#include +#include using std::map; using std::set; diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h index 1b85495d7a..47ef212d58 100644 --- a/libs/ardour/ardour/panner.h +++ b/libs/ardour/ardour/panner.h @@ -31,7 +31,6 @@ #include #include -#include #include using std::istream; diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h index 8db9fb14fe..f80f26098d 100644 --- a/libs/ardour/ardour/plugin_insert.h +++ b/libs/ardour/ardour/plugin_insert.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include class XMLNode; diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index a8601a562a..fa074071c5 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -705,7 +705,7 @@ class Session : public PBD::StatefulDestructible sigc::signal NamedSelectionRemoved; /* Curves and AutomationLists (TODO when they go away) */ - void add_curve(Curve*); + void add_curve(Evoral::Curve*); void add_automation_list(AutomationList*); /* fade curves */ @@ -1540,7 +1540,7 @@ class Session : public PBD::StatefulDestructible NamedSelection *XMLNamedSelectionFactory (const XMLNode&); /* CURVES and AUTOMATION LISTS */ - std::map curves; + std::map curves; std::map automation_lists; /* DEFAULT FADE CURVES */ diff --git a/libs/ardour/automation_event.cc b/libs/ardour/automation_event.cc deleted file mode 100644 index 2d98f1c27c..0000000000 --- a/libs/ardour/automation_event.cc +++ /dev/null @@ -1,446 +0,0 @@ -/* - Copyright (C) 2002 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace sigc; -using namespace PBD; - -sigc::signal AutomationList::AutomationListCreated; - -#if 0 -static void dumpit (const AutomationList& al, string prefix = "") -{ - cerr << prefix << &al << endl; - for (AutomationList::const_iterator i = al.const_begin(); i != al.const_end(); ++i) { - cerr << prefix << '\t' << (*i)->when << ',' << (*i)->value << endl; - } - cerr << "\n"; -} -#endif - -/* XXX: min_val max_val redundant? (param.min() param.max()) */ -AutomationList::AutomationList (Parameter id) - : ControlList(id) -{ - _state = Off; - _style = Absolute; - _touching = false; - - assert(_parameter.type() != NullAutomation); - AutomationListCreated(this); -} - -AutomationList::AutomationList (const AutomationList& other) - : ControlList(other) -{ - _state = other._state; - _touching = other._touching; - - assert(_parameter.type() != NullAutomation); - AutomationListCreated(this); -} - -AutomationList::AutomationList (const AutomationList& other, double start, double end) - : ControlList(other) -{ - _style = other._style; - _state = other._state; - _touching = other._touching; - - assert(_parameter.type() != NullAutomation); - AutomationListCreated(this); -} - -/** \a id is used for legacy sessions where the type is not present - * in or below the node. It is used if \a id is non-null. - */ -AutomationList::AutomationList (const XMLNode& node, Parameter id) - : ControlList(id) -{ - _touching = false; - _state = Off; - _style = Absolute; - - set_state (node); - - if (id) - _parameter = id; - - assert(_parameter.type() != NullAutomation); - AutomationListCreated(this); -} - -AutomationList::~AutomationList() -{ - GoingAway (); -} - -boost::shared_ptr -AutomationList::create(Evoral::Parameter id) -{ - return boost::shared_ptr(new AutomationList(id)); -} - -bool -AutomationList::operator== (const AutomationList& other) -{ - return _events == other._events; -} - -AutomationList& -AutomationList::operator= (const AutomationList& other) -{ - if (this != &other) { - - _events.clear (); - - for (const_iterator i = other._events.begin(); i != other._events.end(); ++i) { - _events.push_back (new ControlEvent (**i)); - } - - _min_yval = other._min_yval; - _max_yval = other._max_yval; - _max_xval = other._max_xval; - _default_value = other._default_value; - - mark_dirty (); - maybe_signal_changed (); - } - - return *this; -} - -void -AutomationList::maybe_signal_changed () -{ - ControlList::maybe_signal_changed (); - - if (!_frozen) { - StateChanged (); /* EMIT SIGNAL */ - } -} - -void -AutomationList::set_automation_state (AutoState s) -{ - if (s != _state) { - _state = s; - automation_state_changed (); /* EMIT SIGNAL */ - } -} - -void -AutomationList::set_automation_style (AutoStyle s) -{ - if (s != _style) { - _style = s; - automation_style_changed (); /* EMIT SIGNAL */ - } -} - -void -AutomationList::start_touch () -{ - _touching = true; - _new_value = true; -} - -void -AutomationList::stop_touch () -{ - _touching = false; - _new_value = false; -} - -void -AutomationList::freeze () -{ - _frozen++; -} - -void -AutomationList::thaw () -{ - ControlList::thaw(); - - if (_changed_when_thawed) { - StateChanged(); /* EMIT SIGNAL */ - } -} - -void -AutomationList::mark_dirty () const -{ - ControlList::mark_dirty (); - Dirty (); /* EMIT SIGNAL */ -} - -XMLNode& -AutomationList::get_state () -{ - return state (true); -} - -XMLNode& -AutomationList::state (bool full) -{ - XMLNode* root = new XMLNode (X_("AutomationList")); - char buf[64]; - LocaleGuard lg (X_("POSIX")); - - root->add_property ("automation-id", _parameter.symbol()); - - root->add_property ("id", _id.to_s()); - - snprintf (buf, sizeof (buf), "%.12g", _default_value); - root->add_property ("default", buf); - snprintf (buf, sizeof (buf), "%.12g", _min_yval); - root->add_property ("min_yval", buf); - snprintf (buf, sizeof (buf), "%.12g", _max_yval); - root->add_property ("max_yval", buf); - snprintf (buf, sizeof (buf), "%.12g", _max_xval); - root->add_property ("max_xval", buf); - - root->add_property ("interpolation-style", enum_2_string (_interpolation)); - - if (full) { - root->add_property ("state", auto_state_to_string (_state)); - } else { - /* never save anything but Off for automation state to a template */ - root->add_property ("state", auto_state_to_string (Off)); - } - - root->add_property ("style", auto_style_to_string (_style)); - - if (!_events.empty()) { - root->add_child_nocopy (serialize_events()); - } - - return *root; -} - -XMLNode& -AutomationList::serialize_events () -{ - XMLNode* node = new XMLNode (X_("events")); - stringstream str; - - for (iterator xx = _events.begin(); xx != _events.end(); ++xx) { - str << (double) (*xx)->when; - str << ' '; - str <<(double) (*xx)->value; - str << '\n'; - } - - /* XML is a bit wierd */ - - XMLNode* content_node = new XMLNode (X_("foo")); /* it gets renamed by libxml when we set content */ - content_node->set_content (str.str()); - - node->add_child_nocopy (*content_node); - - return *node; -} - -int -AutomationList::deserialize_events (const XMLNode& node) -{ - if (node.children().empty()) { - return -1; - } - - XMLNode* content_node = node.children().front(); - - if (content_node->content().empty()) { - return -1; - } - - freeze (); - clear (); - - stringstream str (content_node->content()); - - double x; - double y; - bool ok = true; - - while (str) { - str >> x; - if (!str) { - break; - } - str >> y; - if (!str) { - ok = false; - break; - } - fast_simple_add (x, y); - } - - if (!ok) { - clear (); - error << _("automation list: cannot load coordinates from XML, all points ignored") << endmsg; - } else { - mark_dirty (); - reposition_for_rt_add (0); - maybe_signal_changed (); - } - - thaw (); - - return 0; -} - -int -AutomationList::set_state (const XMLNode& node) -{ - XMLNodeList nlist = node.children(); - XMLNode* nsos; - XMLNodeIterator niter; - const XMLProperty* prop; - - if (node.name() == X_("events")) { - /* partial state setting*/ - return deserialize_events (node); - } - - if (node.name() == X_("Envelope") || node.name() == X_("FadeOut") || node.name() == X_("FadeIn")) { - - if ((nsos = node.child (X_("AutomationList")))) { - /* new school in old school clothing */ - return set_state (*nsos); - } - - /* old school */ - - const XMLNodeList& elist = node.children(); - XMLNodeConstIterator i; - XMLProperty* prop; - nframes_t x; - double y; - - freeze (); - clear (); - - for (i = elist.begin(); i != elist.end(); ++i) { - - if ((prop = (*i)->property ("x")) == 0) { - error << _("automation list: no x-coordinate stored for control point (point ignored)") << endmsg; - continue; - } - x = atoi (prop->value().c_str()); - - if ((prop = (*i)->property ("y")) == 0) { - error << _("automation list: no y-coordinate stored for control point (point ignored)") << endmsg; - continue; - } - y = atof (prop->value().c_str()); - - fast_simple_add (x, y); - } - - thaw (); - - return 0; - } - - if (node.name() != X_("AutomationList") ) { - error << string_compose (_("AutomationList: passed XML node called %1, not \"AutomationList\" - ignored"), node.name()) << endmsg; - return -1; - } - - if ((prop = node.property ("id")) != 0) { - _id = prop->value (); - /* update session AL list */ - AutomationListCreated(this); - } - - if ((prop = node.property (X_("automation-id"))) != 0){ - _parameter = Parameter(prop->value()); - } else { - warning << "Legacy session: automation list has no automation-id property."; - } - - if ((prop = node.property (X_("interpolation-style"))) != 0) { - _interpolation = (InterpolationStyle)string_2_enum(prop->value(), _interpolation); - } else { - _interpolation = Linear; - } - - if ((prop = node.property (X_("default"))) != 0){ - _default_value = atof (prop->value().c_str()); - } else { - _default_value = 0.0; - } - - if ((prop = node.property (X_("style"))) != 0) { - _style = string_to_auto_style (prop->value()); - } else { - _style = Absolute; - } - - if ((prop = node.property (X_("state"))) != 0) { - _state = string_to_auto_state (prop->value()); - } else { - _state = Off; - } - - if ((prop = node.property (X_("min_yval"))) != 0) { - _min_yval = atof (prop->value ().c_str()); - } else { - _min_yval = FLT_MIN; - } - - if ((prop = node.property (X_("max_yval"))) != 0) { - _max_yval = atof (prop->value ().c_str()); - } else { - _max_yval = FLT_MAX; - } - - if ((prop = node.property (X_("max_xval"))) != 0) { - _max_xval = atof (prop->value ().c_str()); - } else { - _max_xval = 0; // means "no limit ; - } - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - if ((*niter)->name() == X_("events")) { - deserialize_events (*(*niter)); - } - } - - return 0; -} - diff --git a/libs/ardour/automation_list.cc b/libs/ardour/automation_list.cc new file mode 100644 index 0000000000..b9aeabb4b5 --- /dev/null +++ b/libs/ardour/automation_list.cc @@ -0,0 +1,446 @@ +/* + Copyright (C) 2002 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "i18n.h" + +using namespace std; +using namespace ARDOUR; +using namespace sigc; +using namespace PBD; + +sigc::signal AutomationList::AutomationListCreated; + +#if 0 +static void dumpit (const AutomationList& al, string prefix = "") +{ + cerr << prefix << &al << endl; + for (AutomationList::const_iterator i = al.const_begin(); i != al.const_end(); ++i) { + cerr << prefix << '\t' << (*i)->when << ',' << (*i)->value << endl; + } + cerr << "\n"; +} +#endif + +/* XXX: min_val max_val redundant? (param.min() param.max()) */ +AutomationList::AutomationList (Parameter id) + : ControlList(id) +{ + _state = Off; + _style = Absolute; + _touching = false; + + assert(_parameter.type() != NullAutomation); + AutomationListCreated(this); +} + +AutomationList::AutomationList (const AutomationList& other) + : ControlList(other) +{ + _state = other._state; + _touching = other._touching; + + assert(_parameter.type() != NullAutomation); + AutomationListCreated(this); +} + +AutomationList::AutomationList (const AutomationList& other, double start, double end) + : ControlList(other) +{ + _style = other._style; + _state = other._state; + _touching = other._touching; + + assert(_parameter.type() != NullAutomation); + AutomationListCreated(this); +} + +/** \a id is used for legacy sessions where the type is not present + * in or below the node. It is used if \a id is non-null. + */ +AutomationList::AutomationList (const XMLNode& node, Parameter id) + : ControlList(id) +{ + _touching = false; + _state = Off; + _style = Absolute; + + set_state (node); + + if (id) + _parameter = id; + + assert(_parameter.type() != NullAutomation); + AutomationListCreated(this); +} + +AutomationList::~AutomationList() +{ + GoingAway (); +} + +boost::shared_ptr +AutomationList::create(Evoral::Parameter id) +{ + return boost::shared_ptr(new AutomationList(id)); +} + +bool +AutomationList::operator== (const AutomationList& other) +{ + return _events == other._events; +} + +AutomationList& +AutomationList::operator= (const AutomationList& other) +{ + if (this != &other) { + + _events.clear (); + + for (const_iterator i = other._events.begin(); i != other._events.end(); ++i) { + _events.push_back (new ControlEvent (**i)); + } + + _min_yval = other._min_yval; + _max_yval = other._max_yval; + _max_xval = other._max_xval; + _default_value = other._default_value; + + mark_dirty (); + maybe_signal_changed (); + } + + return *this; +} + +void +AutomationList::maybe_signal_changed () +{ + ControlList::maybe_signal_changed (); + + if (!_frozen) { + StateChanged (); /* EMIT SIGNAL */ + } +} + +void +AutomationList::set_automation_state (AutoState s) +{ + if (s != _state) { + _state = s; + automation_state_changed (); /* EMIT SIGNAL */ + } +} + +void +AutomationList::set_automation_style (AutoStyle s) +{ + if (s != _style) { + _style = s; + automation_style_changed (); /* EMIT SIGNAL */ + } +} + +void +AutomationList::start_touch () +{ + _touching = true; + _new_value = true; +} + +void +AutomationList::stop_touch () +{ + _touching = false; + _new_value = false; +} + +void +AutomationList::freeze () +{ + _frozen++; +} + +void +AutomationList::thaw () +{ + ControlList::thaw(); + + if (_changed_when_thawed) { + StateChanged(); /* EMIT SIGNAL */ + } +} + +void +AutomationList::mark_dirty () const +{ + ControlList::mark_dirty (); + Dirty (); /* EMIT SIGNAL */ +} + +XMLNode& +AutomationList::get_state () +{ + return state (true); +} + +XMLNode& +AutomationList::state (bool full) +{ + XMLNode* root = new XMLNode (X_("AutomationList")); + char buf[64]; + LocaleGuard lg (X_("POSIX")); + + root->add_property ("automation-id", _parameter.symbol()); + + root->add_property ("id", _id.to_s()); + + snprintf (buf, sizeof (buf), "%.12g", _default_value); + root->add_property ("default", buf); + snprintf (buf, sizeof (buf), "%.12g", _min_yval); + root->add_property ("min_yval", buf); + snprintf (buf, sizeof (buf), "%.12g", _max_yval); + root->add_property ("max_yval", buf); + snprintf (buf, sizeof (buf), "%.12g", _max_xval); + root->add_property ("max_xval", buf); + + root->add_property ("interpolation-style", enum_2_string (_interpolation)); + + if (full) { + root->add_property ("state", auto_state_to_string (_state)); + } else { + /* never save anything but Off for automation state to a template */ + root->add_property ("state", auto_state_to_string (Off)); + } + + root->add_property ("style", auto_style_to_string (_style)); + + if (!_events.empty()) { + root->add_child_nocopy (serialize_events()); + } + + return *root; +} + +XMLNode& +AutomationList::serialize_events () +{ + XMLNode* node = new XMLNode (X_("events")); + stringstream str; + + for (iterator xx = _events.begin(); xx != _events.end(); ++xx) { + str << (double) (*xx)->when; + str << ' '; + str <<(double) (*xx)->value; + str << '\n'; + } + + /* XML is a bit wierd */ + + XMLNode* content_node = new XMLNode (X_("foo")); /* it gets renamed by libxml when we set content */ + content_node->set_content (str.str()); + + node->add_child_nocopy (*content_node); + + return *node; +} + +int +AutomationList::deserialize_events (const XMLNode& node) +{ + if (node.children().empty()) { + return -1; + } + + XMLNode* content_node = node.children().front(); + + if (content_node->content().empty()) { + return -1; + } + + freeze (); + clear (); + + stringstream str (content_node->content()); + + double x; + double y; + bool ok = true; + + while (str) { + str >> x; + if (!str) { + break; + } + str >> y; + if (!str) { + ok = false; + break; + } + fast_simple_add (x, y); + } + + if (!ok) { + clear (); + error << _("automation list: cannot load coordinates from XML, all points ignored") << endmsg; + } else { + mark_dirty (); + reposition_for_rt_add (0); + maybe_signal_changed (); + } + + thaw (); + + return 0; +} + +int +AutomationList::set_state (const XMLNode& node) +{ + XMLNodeList nlist = node.children(); + XMLNode* nsos; + XMLNodeIterator niter; + const XMLProperty* prop; + + if (node.name() == X_("events")) { + /* partial state setting*/ + return deserialize_events (node); + } + + if (node.name() == X_("Envelope") || node.name() == X_("FadeOut") || node.name() == X_("FadeIn")) { + + if ((nsos = node.child (X_("AutomationList")))) { + /* new school in old school clothing */ + return set_state (*nsos); + } + + /* old school */ + + const XMLNodeList& elist = node.children(); + XMLNodeConstIterator i; + XMLProperty* prop; + nframes_t x; + double y; + + freeze (); + clear (); + + for (i = elist.begin(); i != elist.end(); ++i) { + + if ((prop = (*i)->property ("x")) == 0) { + error << _("automation list: no x-coordinate stored for control point (point ignored)") << endmsg; + continue; + } + x = atoi (prop->value().c_str()); + + if ((prop = (*i)->property ("y")) == 0) { + error << _("automation list: no y-coordinate stored for control point (point ignored)") << endmsg; + continue; + } + y = atof (prop->value().c_str()); + + fast_simple_add (x, y); + } + + thaw (); + + return 0; + } + + if (node.name() != X_("AutomationList") ) { + error << string_compose (_("AutomationList: passed XML node called %1, not \"AutomationList\" - ignored"), node.name()) << endmsg; + return -1; + } + + if ((prop = node.property ("id")) != 0) { + _id = prop->value (); + /* update session AL list */ + AutomationListCreated(this); + } + + if ((prop = node.property (X_("automation-id"))) != 0){ + _parameter = Parameter(prop->value()); + } else { + warning << "Legacy session: automation list has no automation-id property."; + } + + if ((prop = node.property (X_("interpolation-style"))) != 0) { + _interpolation = (InterpolationStyle)string_2_enum(prop->value(), _interpolation); + } else { + _interpolation = Linear; + } + + if ((prop = node.property (X_("default"))) != 0){ + _default_value = atof (prop->value().c_str()); + } else { + _default_value = 0.0; + } + + if ((prop = node.property (X_("style"))) != 0) { + _style = string_to_auto_style (prop->value()); + } else { + _style = Absolute; + } + + if ((prop = node.property (X_("state"))) != 0) { + _state = string_to_auto_state (prop->value()); + } else { + _state = Off; + } + + if ((prop = node.property (X_("min_yval"))) != 0) { + _min_yval = atof (prop->value ().c_str()); + } else { + _min_yval = FLT_MIN; + } + + if ((prop = node.property (X_("max_yval"))) != 0) { + _max_yval = atof (prop->value ().c_str()); + } else { + _max_yval = FLT_MAX; + } + + if ((prop = node.property (X_("max_xval"))) != 0) { + _max_xval = atof (prop->value ().c_str()); + } else { + _max_xval = 0; // means "no limit ; + } + + for (niter = nlist.begin(); niter != nlist.end(); ++niter) { + if ((*niter)->name() == X_("events")) { + deserialize_events (*(*niter)); + } + } + + return 0; +} + diff --git a/libs/ardour/curve.cc b/libs/ardour/curve.cc deleted file mode 100644 index dcce3c0c6c..0000000000 --- a/libs/ardour/curve.cc +++ /dev/null @@ -1,406 +0,0 @@ -/* - Copyright (C) 2001-2007 Paul Davis - - Contains ideas derived from "Constrained Cubic Spline Interpolation" - by CJC Kruger (www.korf.co.uk/spline.pdf). - - 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 -#include -#include -#include -#include - -#include -#include - -#include "ardour/curve.h" -#include "ardour/automation_event.h" - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace sigc; -using namespace PBD; - -Curve::Curve (const AutomationList& al) - : _dirty (true) - , _list (al) -{ - _list.Dirty.connect(mem_fun(*this, &Curve::on_list_dirty)); -} - -void -Curve::solve () -{ - uint32_t npoints; - - if (!_dirty) { - return; - } - - if ((npoints = _list.events().size()) > 2) { - - /* Compute coefficients needed to efficiently compute a constrained spline - curve. See "Constrained Cubic Spline Interpolation" by CJC Kruger - (www.korf.co.uk/spline.pdf) for more details. - */ - - double x[npoints]; - double y[npoints]; - uint32_t i; - AutomationList::EventList::const_iterator xx; - - for (i = 0, xx = _list.events().begin(); xx != _list.events().end(); ++xx, ++i) { - x[i] = (double) (*xx)->when; - y[i] = (double) (*xx)->value; - } - - double lp0, lp1, fpone; - - lp0 = (x[1] - x[0])/(y[1] - y[0]); - lp1 = (x[2] - x[1])/(y[2] - y[1]); - - if (lp0*lp1 < 0) { - fpone = 0; - } else { - fpone = 2 / (lp1 + lp0); - } - - double fplast = 0; - - for (i = 0, xx = _list.events().begin(); xx != _list.events().end(); ++xx, ++i) { - - double xdelta; /* gcc is wrong about possible uninitialized use */ - double xdelta2; /* ditto */ - double ydelta; /* ditto */ - double fppL, fppR; - double fpi; - - if (i > 0) { - xdelta = x[i] - x[i-1]; - xdelta2 = xdelta * xdelta; - ydelta = y[i] - y[i-1]; - } - - /* compute (constrained) first derivatives */ - - if (i == 0) { - - /* first segment */ - - fplast = ((3 * (y[1] - y[0]) / (2 * (x[1] - x[0]))) - (fpone * 0.5)); - - /* we don't store coefficients for i = 0 */ - - continue; - - } else if (i == npoints - 1) { - - /* last segment */ - - fpi = ((3 * ydelta) / (2 * xdelta)) - (fplast * 0.5); - - } else { - - /* all other segments */ - - double slope_before = ((x[i+1] - x[i]) / (y[i+1] - y[i])); - double slope_after = (xdelta / ydelta); - - if (slope_after * slope_before < 0.0) { - /* slope changed sign */ - fpi = 0.0; - } else { - fpi = 2 / (slope_before + slope_after); - } - - } - - /* compute second derivative for either side of control point `i' */ - - fppL = (((-2 * (fpi + (2 * fplast))) / (xdelta))) + - ((6 * ydelta) / xdelta2); - - fppR = (2 * ((2 * fpi) + fplast) / xdelta) - - ((6 * ydelta) / xdelta2); - - /* compute polynomial coefficients */ - - double b, c, d; - - d = (fppR - fppL) / (6 * xdelta); - c = ((x[i] * fppL) - (x[i-1] * fppR))/(2 * xdelta); - - double xim12, xim13; - double xi2, xi3; - - xim12 = x[i-1] * x[i-1]; /* "x[i-1] squared" */ - xim13 = xim12 * x[i-1]; /* "x[i-1] cubed" */ - xi2 = x[i] * x[i]; /* "x[i] squared" */ - xi3 = xi2 * x[i]; /* "x[i] cubed" */ - - b = (ydelta - (c * (xi2 - xim12)) - (d * (xi3 - xim13))) / xdelta; - - /* store */ - - (*xx)->create_coeffs(); - (*xx)->coeff[0] = y[i-1] - (b * x[i-1]) - (c * xim12) - (d * xim13); - (*xx)->coeff[1] = b; - (*xx)->coeff[2] = c; - (*xx)->coeff[3] = d; - - fplast = fpi; - } - - } - - _dirty = false; -} - -bool -Curve::rt_safe_get_vector (double x0, double x1, float *vec, int32_t veclen) -{ - Glib::Mutex::Lock lm(_list.lock(), Glib::TRY_LOCK); - - if (!lm.locked()) { - return false; - } else { - _get_vector (x0, x1, vec, veclen); - return true; - } -} - -void -Curve::get_vector (double x0, double x1, float *vec, int32_t veclen) -{ - Glib::Mutex::Lock lm(_list.lock()); - _get_vector (x0, x1, vec, veclen); -} - -void -Curve::_get_vector (double x0, double x1, float *vec, int32_t veclen) -{ - double rx, dx, lx, hx, max_x, min_x; - int32_t i; - int32_t original_veclen; - int32_t npoints; - - if ((npoints = _list.events().size()) == 0) { - for (i = 0; i < veclen; ++i) { - vec[i] = _list.default_value(); - } - return; - } - - /* events is now known not to be empty */ - - max_x = _list.events().back()->when; - min_x = _list.events().front()->when; - - lx = max (min_x, x0); - - if (x1 < 0) { - x1 = _list.events().back()->when; - } - - hx = min (max_x, x1); - - original_veclen = veclen; - - if (x0 < min_x) { - - /* fill some beginning section of the array with the - initial (used to be default) value - */ - - double frac = (min_x - x0) / (x1 - x0); - int32_t subveclen = (int32_t) floor (veclen * frac); - - subveclen = min (subveclen, veclen); - - for (i = 0; i < subveclen; ++i) { - vec[i] = _list.events().front()->value; - } - - veclen -= subveclen; - vec += subveclen; - } - - if (veclen && x1 > max_x) { - - /* fill some end section of the array with the default or final value */ - - double frac = (x1 - max_x) / (x1 - x0); - - int32_t subveclen = (int32_t) floor (original_veclen * frac); - - float val; - - subveclen = min (subveclen, veclen); - - val = _list.events().back()->value; - - i = veclen - subveclen; - - for (i = veclen - subveclen; i < veclen; ++i) { - vec[i] = val; - } - - veclen -= subveclen; - } - - if (veclen == 0) { - return; - } - - if (npoints == 1 ) { - - for (i = 0; i < veclen; ++i) { - vec[i] = _list.events().front()->value; - } - return; - } - - - if (npoints == 2) { - - /* linear interpolation between 2 points */ - - /* XXX I'm not sure that this is the right thing to - do here. but its not a common case for the envisaged - uses. - */ - - if (veclen > 1) { - dx = (hx - lx) / (veclen - 1) ; - } else { - dx = 0; // not used - } - - double slope = (_list.events().back()->value - _list.events().front()->value)/ - (_list.events().back()->when - _list.events().front()->when); - double yfrac = dx*slope; - - vec[0] = _list.events().front()->value + slope * (lx - _list.events().front()->when); - - for (i = 1; i < veclen; ++i) { - vec[i] = vec[i-1] + yfrac; - } - - return; - } - - if (_dirty) { - solve (); - } - - rx = lx; - - if (veclen > 1) { - - dx = (hx - lx) / veclen; - - for (i = 0; i < veclen; ++i, rx += dx) { - vec[i] = multipoint_eval (rx); - } - } -} - -double -Curve::unlocked_eval (double x) -{ - // I don't see the point of this... - - if (_dirty) { - solve (); - } - - return _list.unlocked_eval (x); -} - -double -Curve::multipoint_eval (double x) -{ - pair range; - - AutomationList::LookupCache& lookup_cache = _list.lookup_cache(); - - if ((lookup_cache.left < 0) || - ((lookup_cache.left > x) || - (lookup_cache.range.first == _list.events().end()) || - ((*lookup_cache.range.second)->when < x))) { - - ControlEvent cp (x, 0.0); - - lookup_cache.range = equal_range (_list.events().begin(), _list.events().end(), &cp, AutomationList::time_comparator); - } - - range = lookup_cache.range; - - /* EITHER - - a) x is an existing control point, so first == existing point, second == next point - - OR - - b) x is between control points, so range is empty (first == second, points to where - to insert x) - - */ - - if (range.first == range.second) { - - /* x does not exist within the list as a control point */ - - lookup_cache.left = x; - - if (range.first == _list.events().begin()) { - /* we're before the first point */ - // return default_value; - _list.events().front()->value; - } - - if (range.second == _list.events().end()) { - /* we're after the last point */ - return _list.events().back()->value; - } - - double x2 = x * x; - ControlEvent* ev = *range.second; - - return ev->coeff[0] + (ev->coeff[1] * x) + (ev->coeff[2] * x2) + (ev->coeff[3] * x2 * x); - } - - /* x is a control point in the data */ - /* invalidate the cached range because its not usable */ - lookup_cache.left = -1; - return (*range.first)->value; -} - -extern "C" { - -void -curve_get_vector_from_c (void *arg, double x0, double x1, float* vec, int32_t vecsize) -{ - static_cast(arg)->get_vector (x0, x1, vec, vecsize); -} - -} diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc index 8158e55cc2..4f92295e55 100644 --- a/libs/ardour/plugin_insert.cc +++ b/libs/ardour/plugin_insert.cc @@ -30,7 +30,7 @@ #include #include #include -#include +#include #ifdef HAVE_SLV2 #include diff --git a/libs/ardour/session_command.cc b/libs/ardour/session_command.cc index 72bc3f23d7..b696f7d410 100644 --- a/libs/ardour/session_command.cc +++ b/libs/ardour/session_command.cc @@ -104,7 +104,7 @@ Session::memento_command_factory(XMLNode *n) } } else if (obj_T == typeid (Route).name() || obj_T == typeid (AudioTrack).name() || obj_T == typeid(MidiTrack).name()) { return new MementoCommand(*route_by_id(id), before, after); - } else if (obj_T == typeid (Curve).name() || obj_T == typeid (AutomationList).name()) { + } else if (obj_T == typeid (Evoral::Curve).name() || obj_T == typeid (AutomationList).name()) { if (automation_lists.count(id)) return new MementoCommand(*automation_lists[id], before, after); } else if (registry.count(id)) { // For Editor and AutomationLine which are off-limits here