1 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html
2
3 #include "smmorphlinear.hh"
4 #include "smmorphplan.hh"
5 #include "smleakdebugger.hh"
6
7 #include <assert.h>
8
9 using namespace SpectMorph;
10
11 using std::string;
12 using std::vector;
13
14 static LeakDebugger leak_debugger ("SpectMorph::MorphLinear");
15
MorphLinear(MorphPlan * morph_plan)16 MorphLinear::MorphLinear (MorphPlan *morph_plan) :
17 MorphOperator (morph_plan)
18 {
19 connect (morph_plan->signal_operator_removed, this, &MorphLinear::on_operator_removed);
20
21 m_left_op = NULL;
22 m_right_op = NULL;
23 m_control_op = NULL;
24 m_morphing = 0;
25 m_control_type = CONTROL_GUI;
26 m_db_linear = false;
27
28 leak_debugger.add (this);
29 }
30
~MorphLinear()31 MorphLinear::~MorphLinear()
32 {
33 leak_debugger.del (this);
34 }
35
36 const char *
type()37 MorphLinear::type()
38 {
39 return "SpectMorph::MorphLinear";
40 }
41
42 int
insert_order()43 MorphLinear::insert_order()
44 {
45 return 500;
46 }
47
48 bool
save(OutFile & out_file)49 MorphLinear::save (OutFile& out_file)
50 {
51 write_operator (out_file, "left", m_left_op);
52 write_operator (out_file, "right", m_right_op);
53 write_operator (out_file, "control", m_control_op);
54 out_file.write_string ("left_smset", m_left_smset);
55 out_file.write_string ("right_smset", m_right_smset);
56 out_file.write_float ("morphing", m_morphing);
57 out_file.write_int ("control_type", m_control_type);
58 out_file.write_bool ("db_linear", m_db_linear);
59
60 return true;
61 }
62
63 bool
load(InFile & ifile)64 MorphLinear::load (InFile& ifile)
65 {
66 load_left = "";
67 load_right = "";
68 load_control = "";
69
70 while (ifile.event() != InFile::END_OF_FILE)
71 {
72 if (ifile.event() == InFile::STRING)
73 {
74 if (ifile.event_name() == "left")
75 {
76 load_left = ifile.event_data();
77 }
78 else if (ifile.event_name() == "right")
79 {
80 load_right = ifile.event_data();
81 }
82 else if (ifile.event_name() == "control")
83 {
84 load_control = ifile.event_data();
85 }
86 else if (ifile.event_name() == "left_smset")
87 {
88 m_left_smset = ifile.event_data();
89 }
90 else if (ifile.event_name() == "right_smset")
91 {
92 m_right_smset = ifile.event_data();
93 }
94 else
95 {
96 g_printerr ("bad string\n");
97 return false;
98 }
99 }
100 else if (ifile.event() == InFile::FLOAT)
101 {
102 if (ifile.event_name() == "morphing")
103 {
104 m_morphing = ifile.event_float();
105 }
106 else
107 {
108 g_printerr ("bad float\n");
109 return false;
110 }
111 }
112 else if (ifile.event() == InFile::INT)
113 {
114 if (ifile.event_name() == "control_type")
115 {
116 m_control_type = static_cast<ControlType> (ifile.event_int());
117 }
118 else
119 {
120 g_printerr ("bad int\n");
121 return false;
122 }
123 }
124 else if (ifile.event() == InFile::BOOL)
125 {
126 if (ifile.event_name() == "db_linear")
127 {
128 m_db_linear = ifile.event_bool();
129 }
130 else if (ifile.event_name() == "use_lpc")
131 {
132 /* we need to skip this without error, as old files may contain this setting
133 * lpc is however no longer supported, so we always ignore the value
134 */
135 }
136 else
137 {
138 g_printerr ("bad bool\n");
139 return false;
140 }
141 }
142 else
143 {
144 g_printerr ("bad event\n");
145 return false;
146 }
147 ifile.next_event();
148 }
149 return true;
150 }
151
152 void
post_load(OpNameMap & op_name_map)153 MorphLinear::post_load (OpNameMap& op_name_map)
154 {
155 m_left_op = op_name_map[load_left];
156 m_right_op = op_name_map[load_right];
157 m_control_op = op_name_map[load_control];
158 }
159
160 MorphOperator::OutputType
output_type()161 MorphLinear::output_type()
162 {
163 return OUTPUT_AUDIO;
164 }
165
166 void
on_operator_removed(MorphOperator * op)167 MorphLinear::on_operator_removed (MorphOperator *op)
168 {
169 // plan changed will be emitted automatically after remove, so we don't emit it here
170
171 if (op == m_left_op)
172 m_left_op = nullptr;
173
174 if (op == m_right_op)
175 m_right_op = nullptr;
176
177 if (op == m_control_op)
178 {
179 m_control_op = nullptr;
180
181 if (m_control_type == CONTROL_OP)
182 m_control_type = CONTROL_GUI;
183 }
184 }
185
186 MorphOperator *
left_op()187 MorphLinear::left_op()
188 {
189 return m_left_op;
190 }
191
192 MorphOperator *
right_op()193 MorphLinear::right_op()
194 {
195 return m_right_op;
196 }
197
198 MorphOperator *
control_op()199 MorphLinear::control_op()
200 {
201 return m_control_op;
202 }
203
204 void
set_left_op(MorphOperator * op)205 MorphLinear::set_left_op (MorphOperator *op)
206 {
207 m_left_op = op;
208
209 m_morph_plan->emit_plan_changed();
210 }
211
212 void
set_right_op(MorphOperator * op)213 MorphLinear::set_right_op (MorphOperator *op)
214 {
215 m_right_op = op;
216
217 m_morph_plan->emit_plan_changed();
218 }
219
220 void
set_control_op(MorphOperator * op)221 MorphLinear::set_control_op (MorphOperator *op)
222 {
223 m_control_op = op;
224
225 m_morph_plan->emit_plan_changed();
226 }
227
228 void
set_control_type_and_op(ControlType control_type,MorphOperator * op)229 MorphLinear::set_control_type_and_op (ControlType control_type, MorphOperator *op)
230 {
231 m_control_type = control_type;
232 m_control_op = op;
233
234 m_morph_plan->emit_plan_changed();
235 }
236
237 string
left_smset()238 MorphLinear::left_smset()
239 {
240 return m_left_smset;
241 }
242
243 string
right_smset()244 MorphLinear::right_smset()
245 {
246 return m_right_smset;
247 }
248
249 void
set_left_smset(const string & smset)250 MorphLinear::set_left_smset (const string& smset)
251 {
252 m_left_smset = smset;
253
254 m_morph_plan->emit_plan_changed();
255 }
256
257 void
set_right_smset(const string & smset)258 MorphLinear::set_right_smset (const string& smset)
259 {
260 m_right_smset = smset;
261
262 m_morph_plan->emit_plan_changed();
263 }
264
265 double
morphing()266 MorphLinear::morphing()
267 {
268 return m_morphing;
269 }
270
271 void
set_morphing(double new_morphing)272 MorphLinear::set_morphing (double new_morphing)
273 {
274 m_morphing = new_morphing;
275
276 m_morph_plan->emit_plan_changed();
277 }
278
279 MorphLinear::ControlType
control_type()280 MorphLinear::control_type()
281 {
282 return m_control_type;
283 }
284
285 void
set_control_type(ControlType new_control_type)286 MorphLinear::set_control_type (ControlType new_control_type)
287 {
288 m_control_type = new_control_type;
289
290 m_morph_plan->emit_plan_changed();
291 }
292
293 bool
db_linear()294 MorphLinear::db_linear()
295 {
296 return m_db_linear;
297 }
298
299 void
set_db_linear(bool dbl)300 MorphLinear::set_db_linear (bool dbl)
301 {
302 m_db_linear = dbl;
303
304 m_morph_plan->emit_plan_changed();
305 }
306
307 vector<MorphOperator *>
dependencies()308 MorphLinear::dependencies()
309 {
310 return { m_left_op, m_right_op, m_control_type == CONTROL_OP ? m_control_op : nullptr };
311 }
312