Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.git] / cinelerra-5.1 / cinelerra / automation.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008-2013 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "autoconf.h"
23 #include "automation.h"
24 #include "autos.h"
25 #include "atrack.inc"
26 #include "bcsignals.h"
27 #include "colors.h"
28 #include "edl.h"
29 #include "edlsession.h"
30 #include "filexml.h"
31 #include "floatautos.h"
32 #include "intautos.h"
33 #include "track.h"
34 #include "transportque.inc"
35
36
37 int Automation::autogrouptypes_fixedrange[] =
38 {
39         0,
40         0,
41         0,
42         0,
43         0,
44         1
45 };
46
47
48
49 Automation::Automation(EDL *edl, Track *track)
50 {
51         this->edl = edl;
52         this->track = track;
53         bzero(autos, sizeof(Autos*) * AUTOMATION_TOTAL);
54 }
55
56 Automation::~Automation()
57 {
58         for(int i = 0; i < AUTOMATION_TOTAL; i++)
59         {
60                 delete autos[i];
61         }
62 }
63
64 int Automation::autogrouptype(int autoidx, Track *track)
65 {
66         int autogrouptype = -1;
67         switch (autoidx)
68         {
69                 case AUTOMATION_CAMERA_X:
70                 case AUTOMATION_PROJECTOR_X:
71                         autogrouptype = AUTOGROUPTYPE_X;
72                         break;
73                 case AUTOMATION_CAMERA_Y:
74                 case AUTOMATION_PROJECTOR_Y:
75                         autogrouptype = AUTOGROUPTYPE_Y;
76                         break;
77                 case AUTOMATION_CAMERA_Z:
78                 case AUTOMATION_PROJECTOR_Z:
79                         autogrouptype = AUTOGROUPTYPE_ZOOM;
80                         break;
81                 case AUTOMATION_FADE:
82                         if (track->data_type == TRACK_AUDIO)
83                                 autogrouptype = AUTOGROUPTYPE_AUDIO_FADE;
84                         else
85                                 autogrouptype = AUTOGROUPTYPE_VIDEO_FADE;
86                         break;
87                 case AUTOMATION_MUTE:
88                         autogrouptype = AUTOGROUPTYPE_INT255;
89                         break;
90         }
91         return (autogrouptype);
92 }
93
94 void Automation::create_objects()
95 {
96         autos[AUTOMATION_MUTE] = new IntAutos(edl, track, 0);
97         autos[AUTOMATION_MUTE]->create_objects();
98         autos[AUTOMATION_MUTE]->autoidx = AUTOMATION_MUTE;
99         autos[AUTOMATION_MUTE]->autogrouptype = AUTOGROUPTYPE_INT255;
100         autos[AUTOMATION_SPEED] = new FloatAutos(edl, track, 1.0);
101         autos[AUTOMATION_SPEED]->create_objects();
102 }
103
104 Automation& Automation::operator=(Automation& automation)
105 {
106 //printf("Automation::operator= 1\n");
107         copy_from(&automation);
108         return *this;
109 }
110
111 void Automation::equivalent_output(Automation *automation, int64_t *result)
112 {
113         for(int i = 0; i < AUTOMATION_TOTAL; i++)
114         {
115                 if(autos[i] && automation->autos[i])
116                         autos[i]->equivalent_output(automation->autos[i], 0, result);
117         }
118 }
119
120 void Automation::copy_from(Automation *automation)
121 {
122         for(int i = 0; i < AUTOMATION_TOTAL; i++)
123         {
124                 if(autos[i] && automation->autos[i])
125                         autos[i]->copy_from(automation->autos[i]);
126         }
127 }
128
129 // These must match the enumerations
130 static const char *xml_titles[] =
131 {
132         "MUTEAUTOS",
133         "CAMERA_X",
134         "CAMERA_Y",
135         "CAMERA_Z",
136         "PROJECTOR_X",
137         "PROJECTOR_Y",
138         "PROJECTOR_Z",
139         "FADEAUTOS",
140         "PANAUTOS",
141         "MODEAUTOS",
142         "MASKAUTOS",
143         "SPEEDAUTOS",
144 };
145
146 int Automation::load(FileXML *file)
147 {
148         for(int i = 0; i < AUTOMATION_TOTAL; i++)
149         {
150                 if(file->tag.title_is(xml_titles[i]) && autos[i])
151                 {
152                         autos[i]->load(file);
153                         return 1;
154                 }
155         }
156         return 0;
157 }
158
159 int Automation::paste(int64_t start,
160         int64_t length,
161         double scale,
162         FileXML *file,
163         int default_only,
164         int active_only,
165         AutoConf *autoconf)
166 {
167         if(!autoconf) autoconf = edl->session->auto_conf;
168
169         for(int i = 0; i < AUTOMATION_TOTAL; i++)
170         {
171                 if(file->tag.title_is(xml_titles[i]) && autos[i] && autoconf->autos[i])
172                 {
173                         autos[i]->paste(start,
174                                 length,
175                                 scale,
176                                 file,
177                                 default_only,
178                                 active_only);
179                         return 1;
180                 }
181         }
182         return 0;
183 }
184
185 int Automation::copy(int64_t start,
186         int64_t end,
187         FileXML *file,
188         int default_only,
189         int active_only)
190 {
191 // Copy regardless of what's visible.
192         for(int i = 0; i < AUTOMATION_TOTAL; i++)
193         {
194                 if(autos[i])
195                 {
196                         file->tag.set_title(xml_titles[i]);
197                         file->append_tag();
198                         file->append_newline();
199                         autos[i]->copy(start,
200                                                         end,
201                                                         file,
202                                                         default_only,
203                                                         active_only);
204                         char string[BCTEXTLEN];
205                         sprintf(string, "/%s", xml_titles[i]);
206                         file->tag.set_title(string);
207                         file->append_tag();
208                         file->append_newline();
209                 }
210         }
211
212         return 0;
213 }
214
215
216 void Automation::clear(int64_t start,
217         int64_t end,
218         AutoConf *autoconf,
219         int shift_autos)
220 {
221         AutoConf *temp_autoconf = 0;
222
223         if(!autoconf)
224         {
225                 temp_autoconf = new AutoConf;
226                 temp_autoconf->set_all(1);
227                 autoconf = temp_autoconf;
228         }
229
230         for(int i = 0; i < AUTOMATION_TOTAL; i++)
231         {
232                 if(autos[i] && autoconf->autos[i])
233                 {
234                         autos[i]->clear(start, end, shift_autos);
235                 }
236         }
237
238         if(temp_autoconf) delete temp_autoconf;
239 }
240
241 void Automation::set_automation_mode(int64_t start,
242         int64_t end,
243         int mode,
244         AutoConf *autoconf)
245 {
246         AutoConf *temp_autoconf = 0;
247
248         if(!autoconf)
249         {
250                 temp_autoconf = new AutoConf;
251                 temp_autoconf->set_all(1);
252                 autoconf = temp_autoconf;
253         }
254
255         for(int i = 0; i < AUTOMATION_TOTAL; i++)
256         {
257                 if(autos[i] && autoconf->autos[i])
258                 {
259                         autos[i]->set_automation_mode(start, end, mode);
260                 }
261         }
262
263         if(temp_autoconf) delete temp_autoconf;
264 }
265
266
267 void Automation::paste_silence(int64_t start, int64_t end)
268 {
269 // Unit conversion done in calling routine
270         for(int i = 0; i < AUTOMATION_TOTAL; i++)
271         {
272                 if(autos[i])
273                         autos[i]->paste_silence(start, end);
274         }
275 }
276
277 // We don't replace it in pasting but
278 // when inserting the first EDL of a load operation we need to replace
279 // the default keyframe.
280 void Automation::insert_track(Automation *automation,
281         int64_t start_unit,
282         int64_t length_units,
283         int replace_default)
284 {
285         for(int i = 0; i < AUTOMATION_TOTAL; i++)
286         {
287                 if(autos[i] && automation->autos[i])
288                 {
289                         autos[i]->insert_track(automation->autos[i],
290                                 start_unit,
291                                 length_units,
292                                 replace_default);
293                 }
294         }
295
296
297 }
298
299 void Automation::resample(double old_rate, double new_rate)
300 {
301 // Run resample for all the autos structures and all the keyframes
302         for(int i = 0; i < AUTOMATION_TOTAL; i++)
303         {
304                 if(autos[i]) autos[i]->resample(old_rate, new_rate);
305         }
306 }
307
308
309
310 int Automation::direct_copy_possible(int64_t start, int direction)
311 {
312         return 1;
313 }
314
315
316
317
318 void Automation::get_projector(float *x,
319         float *y,
320         float *z,
321         int64_t position,
322         int direction)
323 {
324 }
325
326 void Automation::get_camera(float *x,
327         float *y,
328         float *z,
329         int64_t position,
330         int direction)
331 {
332 }
333
334
335
336
337 int64_t Automation::get_length()
338 {
339         int64_t length = 0;
340         int64_t total_length = 0;
341
342         for(int i = 0; i < AUTOMATION_TOTAL; i++)
343         {
344                 if(autos[i])
345                 {
346                         length = autos[i]->get_length();
347                         if(length > total_length) total_length = length;
348                 }
349         }
350
351
352         return total_length;
353 }
354
355 void Automation::get_extents(float *min,
356         float *max,
357         int *coords_undefined,
358         int64_t unit_start,
359         int64_t unit_end,
360         int autogrouptype)
361 {
362         for(int i = 0; i < AUTOMATION_TOTAL; i++)
363         {
364                 if(autos[i] && edl->session->auto_conf->autos[i])
365                 {
366                         if (autos[i]->autogrouptype == autogrouptype)
367                                 autos[i]->get_extents(min, max, coords_undefined, unit_start, unit_end);
368                 }
369         }
370 }
371
372
373 void Automation::dump(FILE *fp)
374 {
375         fprintf(fp,"   Automation: %p\n", this);
376
377
378         for(int i = 0; i < AUTOMATION_TOTAL; i++)
379         {
380                 if(autos[i])
381                 {
382                         fprintf(fp,"    %s %p\n", xml_titles[i], autos[i]);
383                         autos[i]->dump(fp);
384                 }
385         }
386
387 }