ardour
pannable.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 Paul Davis
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18 */
19 
20 #include "pbd/error.h"
21 #include "pbd/convert.h"
22 #include "pbd/compose.h"
23 #include "pbd/boost_debug.h"
24 
25 #include "ardour/debug.h"
27 #include "ardour/automation_list.h"
28 #include "ardour/pannable.h"
29 #include "ardour/panner.h"
31 #include "ardour/session.h"
32 
33 #include "i18n.h"
34 
35 using namespace std;
36 using namespace PBD;
37 using namespace ARDOUR;
38 
39 Pannable::Pannable (Session& s)
40  : Automatable (s)
41  , SessionHandleRef (s)
42  , pan_azimuth_control (new PanControllable (s, "", this, PanAzimuthAutomation))
43  , pan_elevation_control (new PanControllable (s, "", this, PanElevationAutomation))
44  , pan_width_control (new PanControllable (s, "", this, PanWidthAutomation))
45  , pan_frontback_control (new PanControllable (s, "", this, PanFrontBackAutomation))
46  , pan_lfe_control (new PanControllable (s, "", this, PanLFEAutomation))
47  , _auto_state (Off)
48  , _auto_style (Absolute)
49  , _has_state (false)
50  , _responding_to_control_auto_state_change (0)
51 {
52  //boost_debug_shared_ptr_mark_interesting (this, "pannable");
53 
59 
60  /* all controls change state together */
61 
62  pan_azimuth_control->alist()->automation_state_changed.connect_same_thread (*this, boost::bind (&Pannable::control_auto_state_changed, this, _1));
63  pan_elevation_control->alist()->automation_state_changed.connect_same_thread (*this, boost::bind (&Pannable::control_auto_state_changed, this, _1));
64  pan_width_control->alist()->automation_state_changed.connect_same_thread (*this, boost::bind (&Pannable::control_auto_state_changed, this, _1));
65  pan_frontback_control->alist()->automation_state_changed.connect_same_thread (*this, boost::bind (&Pannable::control_auto_state_changed, this, _1));
66  pan_lfe_control->alist()->automation_state_changed.connect_same_thread (*this, boost::bind (&Pannable::control_auto_state_changed, this, _1));
67 
68  pan_azimuth_control->Changed.connect_same_thread (*this, boost::bind (&Pannable::value_changed, this));
69  pan_elevation_control->Changed.connect_same_thread (*this, boost::bind (&Pannable::value_changed, this));
70  pan_width_control->Changed.connect_same_thread (*this, boost::bind (&Pannable::value_changed, this));
71  pan_frontback_control->Changed.connect_same_thread (*this, boost::bind (&Pannable::value_changed, this));
72  pan_lfe_control->Changed.connect_same_thread (*this, boost::bind (&Pannable::value_changed, this));
73 }
74 
76 {
77  DEBUG_TRACE (DEBUG::Destruction, string_compose ("pannable @ %1 destructor\n", this));
78 }
79 
80 void
82 {
84  return;
85  }
86 
88 
89  pan_azimuth_control->set_automation_state (new_state);
90  pan_width_control->set_automation_state (new_state);
91  pan_elevation_control->set_automation_state (new_state);
92  pan_frontback_control->set_automation_state (new_state);
93  pan_lfe_control->set_automation_state (new_state);
94 
96 
97  _auto_state = new_state;
98  automation_state_changed (new_state); /* EMIT SIGNAL */
99 }
100 
101 void
103 {
104  _panner = p;
105 }
106 
107 void
109 {
110  _session.set_dirty ();
111 }
112 
113 void
115 {
116  if (state != _auto_state) {
117  _auto_state = state;
118 
119  const Controls& c (controls());
120 
121  for (Controls::const_iterator ci = c.begin(); ci != c.end(); ++ci) {
123  if (ac) {
124  ac->alist()->set_automation_state (state);
125  }
126  }
127 
128  session().set_dirty ();
130  }
131 }
132 
133 void
135 {
136  if (style != _auto_style) {
137  _auto_style = style;
138 
139  const Controls& c (controls());
140 
141  for (Controls::const_iterator ci = c.begin(); ci != c.end(); ++ci) {
143  if (ac) {
144  ac->alist()->set_automation_style (style);
145  }
146  }
147 
148  session().set_dirty ();
150  }
151 }
152 
153 void
155 {
156  const Controls& c (controls());
157 
158  for (Controls::const_iterator ci = c.begin(); ci != c.end(); ++ci) {
160  if (ac) {
161  ac->alist()->start_touch (when);
162  }
163  }
164  g_atomic_int_set (&_touching, 1);
165 }
166 
167 void
168 Pannable::stop_touch (bool mark, double when)
169 {
170  const Controls& c (controls());
171 
172  for (Controls::const_iterator ci = c.begin(); ci != c.end(); ++ci) {
174  if (ac) {
175  ac->alist()->stop_touch (mark, when);
176  }
177  }
178  g_atomic_int_set (&_touching, 0);
179 }
180 
181 XMLNode&
183 {
184  return state (true);
185 }
186 
187 XMLNode&
188 Pannable::state (bool /*full*/)
189 {
190  XMLNode* node = new XMLNode (X_("Pannable"));
191 
192  node->add_child_nocopy (pan_azimuth_control->get_state());
193  node->add_child_nocopy (pan_width_control->get_state());
194  node->add_child_nocopy (pan_elevation_control->get_state());
195  node->add_child_nocopy (pan_frontback_control->get_state());
196  node->add_child_nocopy (pan_lfe_control->get_state());
197 
199 
200  return *node;
201 }
202 
203 int
204 Pannable::set_state (const XMLNode& root, int version)
205 {
206  if (root.name() != X_("Pannable")) {
207  warning << string_compose (_("Pannable given XML data for %1 - ignored"), root.name()) << endmsg;
208  return -1;
209  }
210 
211  const XMLNodeList& nlist (root.children());
212  XMLNodeConstIterator niter;
213 
214  for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
215  if ((*niter)->name() == Controllable::xml_node_name) {
216  const XMLProperty* prop = (*niter)->property (X_("name"));
217 
218  if (!prop) {
219  continue;
220  }
221 
222  if (prop->value() == pan_azimuth_control->name()) {
223  pan_azimuth_control->set_state (**niter, version);
224  } else if (prop->value() == pan_width_control->name()) {
225  pan_width_control->set_state (**niter, version);
226  } else if (prop->value() == pan_elevation_control->name()) {
227  pan_elevation_control->set_state (**niter, version);
228  } else if (prop->value() == pan_frontback_control->name()) {
229  pan_frontback_control->set_state (**niter, version);
230  } else if (prop->value() == pan_lfe_control->name()) {
231  pan_lfe_control->set_state (**niter, version);
232  }
233 
234  } else if ((*niter)->name() == Automatable::xml_node_name) {
236 
237  } else {
238  const XMLProperty* prop;
239 
240  /* old school (alpha1-6) XML info */
241 
242  if ((*niter)->name() == X_("azimuth")) {
243  prop = (*niter)->property (X_("value"));
244  if (prop) {
245  pan_azimuth_control->set_value (atof (prop->value()));
246  }
247  } else if ((*niter)->name() == X_("width")) {
248  prop = (*niter)->property (X_("value"));
249  if (prop) {
250  pan_width_control->set_value (atof (prop->value()));
251  }
252  } else if ((*niter)->name() == X_("elevation")) {
253  prop = (*niter)->property (X_("value"));
254  if (prop) {
255  pan_elevation_control->set_value (atof (prop->value()));
256  }
257  } else if ((*niter)->name() == X_("frontback")) {
258  prop = (*niter)->property (X_("value"));
259  if (prop) {
260  pan_frontback_control->set_value (atof (prop->value()));
261  }
262  } else if ((*niter)->name() == X_("lfe")) {
263  prop = (*niter)->property (X_("value"));
264  if (prop) {
265  pan_lfe_control->set_value (atof (prop->value()));
266  }
267  }
268  }
269  }
270 
271  _has_state = true;
272 
273  return 0;
274 }
275 
276 string
278 {
280 
281  if (p) {
282  return p->value_as_string (ac);
283  }
284 
285  return Automatable::value_as_string (ac);
286 }
void set_automation_state(AutoState)
virtual std::string value_as_string(boost::shared_ptr< AutomationControl >) const
Definition: panner.cc:112
AutoStyle _auto_style
Definition: pannable.h:88
ARDOUR::Session & _session
void set_panner(boost::shared_ptr< Panner >)
Definition: pannable.cc:102
const std::string & value() const
Definition: xml++.h:159
PBD::Signal0< void > automation_style_changed
Definition: pannable.h:62
void set_automation_state(AutoState)
Definition: pannable.cc:114
LIBARDOUR_API uint64_t Destruction
Definition: debug.cc:38
AutoState _auto_state
Definition: pannable.h:87
void set_automation_style(AutoStyle m)
Definition: pannable.cc:134
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
Definition: shared_ptr.hpp:396
int set_state(const XMLNode &, int version)
Definition: pannable.cc:204
const std::string & name() const
Definition: xml++.h:104
boost::shared_ptr< AutomationControl > pan_elevation_control
Definition: pannable.h:46
boost::weak_ptr< Panner > _panner
Definition: pannable.h:86
Definition: Beats.hpp:239
LIBPBD_API Transmitter warning
const XMLNodeList & children(const std::string &str=std::string()) const
Definition: xml++.cc:329
std::ostream & endmsg(std::ostream &ostr)
Definition: transmitter.h:71
virtual void add_control(boost::shared_ptr< Evoral::Control >)
Definition: automatable.cc:138
AutoStyle
Definition: types.h:155
std::list< XMLNode * > XMLNodeList
Definition: xml++.h:44
#define _(Text)
Definition: i18n.h:11
PBD::Signal1< void, AutoState > automation_state_changed
Definition: pannable.h:58
#define X_(Text)
Definition: i18n.h:13
virtual std::string value_as_string(boost::shared_ptr< AutomationControl >) const
Definition: automatable.cc:494
void stop_touch(bool mark, double when)
Definition: amp.h:29
Session & session()
Definition: pannable.h:54
void set_automation_style(AutoStyle m)
boost::shared_ptr< AutomationControl > pan_frontback_control
Definition: pannable.h:48
#define DEBUG_TRACE(bits, str)
Definition: debug.h:55
boost::shared_ptr< AutomationControl > pan_azimuth_control
Definition: pannable.h:45
std::map< Parameter, boost::shared_ptr< Control > > Controls
Definition: ControlSet.hpp:57
XMLNode & get_state()
Definition: pannable.cc:182
boost::shared_ptr< Panner > panner() const
Definition: pannable.h:51
uint32_t _responding_to_control_auto_state_change
Definition: pannable.h:91
void start_touch(double when)
int set_automation_xml_state(const XMLNode &, Evoral::Parameter default_param)
Definition: automatable.cc:198
static const std::string xml_node_name
Definition: controllable.h:116
void value_changed()
Definition: pannable.cc:108
void add_child_nocopy(XMLNode &)
Definition: xml++.cc:357
XMLNode & state(bool full_state)
Definition: pannable.cc:188
boost::shared_ptr< AutomationControl > pan_width_control
Definition: pannable.h:47
Definition: xml++.h:95
Controls & controls()
Definition: ControlSet.hpp:58
std::string value_as_string(boost::shared_ptr< AutomationControl >) const
Definition: pannable.cc:277
void control_auto_state_changed(AutoState)
Definition: pannable.cc:81
void start_touch(double when)
Definition: pannable.cc:154
Definition: debug.h:30
void stop_touch(bool mark, double when)
Definition: pannable.cc:168
XMLNode & get_automation_xml_state()
Definition: automatable.cc:252
boost::shared_ptr< AutomationList > alist() const
boost::shared_ptr< AutomationControl > pan_lfe_control
Definition: pannable.h:49
Off
Definition: widget_state.h:13
XMLNodeList::const_iterator XMLNodeConstIterator
Definition: xml++.h:49
static const std::string xml_node_name
Definition: automatable.h:79
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208
double atof(const string &s)
Definition: convert.cc:158
AutoState
Definition: types.h:145