fix crash when copy'ing latent plugins
[ardour.git] / libs / ardour / phase_control.cc
1 /*
2     Copyright (C) 2016 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify it
5     under the terms of the GNU General Public License as published by the Free
6     Software Foundation; either version 2 of the License, or (at your option)
7     any later version.
8
9     This program is distributed in the hope that it will be useful, but WITHOUT
10     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12     for more details.
13
14     You should have received a copy of the GNU General Public License along
15     with this program; if not, write to the Free Software Foundation, Inc.,
16     675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #include "ardour/phase_control.h"
20 #include "ardour/session.h"
21
22 #include "pbd/i18n.h"
23
24 using namespace std;
25 using namespace PBD;
26 using namespace ARDOUR;
27
28 PhaseControl::PhaseControl (Session& session, std::string const & name)
29         : AutomationControl (session, PhaseAutomation, ParameterDescriptor (PhaseAutomation),
30                              boost::shared_ptr<AutomationList>(new AutomationList(Evoral::Parameter(PhaseAutomation))),
31                              name)
32 {
33 }
34
35 void
36 PhaseControl::actually_set_value (double val, Controllable::GroupControlDisposition gcd)
37 {
38         _phase_invert = boost::dynamic_bitset<> (std::numeric_limits<double>::digits, (unsigned long) val);
39
40         AutomationControl::actually_set_value (val, gcd);
41 }
42
43 /** @param c Audio channel index.
44  *  @param yn true to invert phase, otherwise false.
45  */
46 void
47 PhaseControl::set_phase_invert (uint32_t c, bool yn)
48 {
49         if (_phase_invert[c] != yn) {
50                 _phase_invert[c] = yn;
51                 AutomationControl::actually_set_value (_phase_invert.to_ulong(), Controllable::NoGroup);
52                 _session.set_dirty ();
53         }
54 }
55
56 void
57 PhaseControl::set_phase_invert (boost::dynamic_bitset<> p)
58 {
59         if (_phase_invert != p) {
60                 _phase_invert = p;
61                 AutomationControl::actually_set_value (_phase_invert.to_ulong(), Controllable::NoGroup);
62                 Changed (true, Controllable::NoGroup); /* EMIT SIGNAL */
63                 _session.set_dirty ();
64         }
65 }
66
67 void
68 PhaseControl::resize (uint32_t n)
69 {
70         _phase_invert.resize (n);
71 }
72
73 XMLNode&
74 PhaseControl::get_state ()
75 {
76         XMLNode& node (AutomationControl::get_state ());
77
78         string p;
79         boost::to_string (_phase_invert, p);
80         node.add_property("phase-invert", p);
81
82         return node;
83 }
84
85 int
86 PhaseControl::set_state (XMLNode const & node, int version)
87 {
88         AutomationControl::set_state (node, version);
89
90         const XMLProperty* prop;
91
92         if ((prop = node.property (X_("phase-invert"))) != 0) {
93                 set_phase_invert (boost::dynamic_bitset<> (prop->value ()));
94         }
95
96         return 0;
97 }