ins mixers, match all and move for mixer align, cr in xml string kludge, save_as...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / mixersalign.h
1 /*
2  * CINELERRA
3  * Copyright (C) 2008-2015 Adam Williams <broadcast at earthling dot net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  */
20
21 #ifndef __MIXERSALIGN_H__
22 #define __MIXERSALIGN_H__
23
24 #include "edl.h"
25 #include "edit.inc"
26 #include "fourier.h"
27 #include "guicast.h"
28 #include "language.h"
29 #include "loadbalance.h"
30 #include "mainprogress.inc"
31 #include "mixersalign.inc"
32 #include "mwindow.inc"
33 #include "renderengine.h"
34 #include "samples.inc"
35 #include "track.inc"
36 #include "zwindow.inc"
37
38 class MixersAlignMixer
39 {
40 public:
41         MixersAlignMixer(Mixer *mix);
42         ~MixersAlignMixer();
43         Mixer *mixer;
44         double nudge;
45         double mx;
46         int64_t mi;
47         double *br, *bi;
48         int aidx;
49 };
50
51 class MixersAlignMixers : public ArrayList<MixersAlignMixer*>
52 {
53 public:
54         MixersAlignMixers() {}
55         ~MixersAlignMixers() { remove_all_objects(); }
56 };
57
58 class MixersAlignMixerList : public BC_ListBox
59 {
60         enum { MIX_MIXER, MIX_NUDGE, MIX_SZ };
61         static const char *mix_titles[MIX_SZ];
62         static int mix_widths[MIX_SZ];
63 public:
64         MixersAlignMixerList(MixersAlignWindow *gui,
65                 MixersAlign *dialog, int x, int y, int w, int h);
66         ~MixersAlignMixerList();
67
68         void clear();
69
70         void add_mixer(MixersAlignMixer *mixer);
71         void load_list();
72         void update();
73         int selection_changed();
74
75         MixersAlignWindow *gui;
76         MixersAlign *dialog;
77         MixersAlignMixers mixers;
78
79         const char *col_titles[MIX_SZ];
80         int col_widths[MIX_SZ];
81         ArrayList<BC_ListBoxItem*> cols[MIX_SZ];
82
83         void set_all_selected(int v) { BC_ListBox::set_all_selected(cols, v); }
84         void set_selected(int idx, int v) { BC_ListBox::set_selected(cols, idx, v); }
85         bool is_selected(int idx) { return cols[0][idx]->get_selected() != 0; }
86 };
87
88
89 class MixersAlignMTrack
90 {
91 public:
92         MixersAlignMTrack(Track *trk, int no);
93
94         Track *track;
95         int no;
96 };
97
98 class MixersAlignMTracks : public ArrayList<MixersAlignMTrack*>
99 {
100 public:
101         MixersAlignMTracks() {}
102         ~MixersAlignMTracks() { remove_all_objects(); }
103 };
104
105
106 class MixersAlignMTrackList : public BC_ListBox
107 {
108         enum { MTK_NO, MTK_MIXER, MTK_TRACK, MTK_SZ };
109         static const char *mtk_titles[MTK_SZ];
110         static int mtk_widths[MTK_SZ];
111 public:
112         MixersAlignMTrackList(MixersAlignWindow *gui,
113                 MixersAlign *dialog, int x, int y, int w, int h);
114         ~MixersAlignMTrackList();
115
116         void clear();
117         void add_mtrack(MixersAlignMTrack *mtrk);
118         void load_list();
119         void update();
120
121         MixersAlignWindow *gui;
122         MixersAlign *dialog;
123
124         ArrayList<BC_ListBoxItem*> cols[MTK_SZ];
125         const char *col_titles[MTK_SZ];
126         int col_widths[MTK_SZ];
127
128         void set_all_selected(int v) { BC_ListBox::set_all_selected(cols, v); }
129         void set_selected(int idx, int v) { BC_ListBox::set_selected(cols, idx, v); }
130         bool is_selected(int idx) { return cols[0][idx]->get_selected() != 0; }
131 };
132
133
134 class MixersAlignATrack
135 {
136 public:
137         MixersAlignATrack(Track *trk, int no);
138         ~MixersAlignATrack();
139
140         Track *track;
141         int no;
142         double nudge;
143         double ss;
144         double mx;
145         int64_t mi;
146 };
147
148 class MixersAlignATracks : public ArrayList<MixersAlignATrack*>
149 {
150 public:
151         MixersAlignATracks() {}
152         ~MixersAlignATracks() { remove_all_objects(); }
153 };
154
155 class MixersAlignATrackList : public BC_ListBox
156 {
157         enum { ATK_TRACK, ATK_AUDIO, ATK_NUDGE, ATK_MX, ATK_MI, ATK_SZ };
158         static const char *atk_titles[ATK_SZ];
159         static int atk_widths[ATK_SZ];
160 public:
161         MixersAlignATrackList(MixersAlignWindow *gui,
162                 MixersAlign *dialog, int x, int y, int w, int h);
163         ~MixersAlignATrackList();
164
165         void clear();
166         void add_atrack(MixersAlignATrack *track);
167         void load_list();
168         void update();
169         int selection_changed();
170
171         MixersAlignWindow *gui;
172         MixersAlign *dialog;
173
174         ArrayList<BC_ListBoxItem*> cols[ATK_SZ];
175         const char *col_titles[ATK_SZ];
176         int col_widths[ATK_SZ];
177
178         void set_all_selected(int v) { BC_ListBox::set_all_selected(cols, v); }
179         void set_selected(int idx, int v) { BC_ListBox::set_selected(cols, idx, v); }
180         bool is_selected(int idx) { return cols[0][idx]->get_selected() != 0; }
181 };
182
183 class MixersAlignReset : public BC_GenericButton
184 {
185 public:
186         MixersAlignReset(MixersAlignWindow *gui, MixersAlign *dialog, int x, int y);
187         int handle_event();
188         static int calculate_width(BC_WindowBase *gui);
189
190         MixersAlign *dialog;
191         MixersAlignWindow *gui;
192 };
193
194 class MixersAlignThread : public Thread
195 {
196 public:
197         MixersAlignThread(MixersAlign *dialog);
198         ~MixersAlignThread();
199         void start(int fwd);
200         void run();
201
202         MixersAlign *dialog;
203         int fwd;
204 };
205
206 class MixersAlignMatch : public BC_GenericButton
207 {
208 public:
209         MixersAlignMatch(MixersAlignWindow *gui, MixersAlign *dialog, int x, int y);
210         int handle_event();
211
212         MixersAlign *dialog;
213         MixersAlignWindow *gui;
214 };
215
216 class MixersAlignMatchAll : public BC_GenericButton
217 {
218 public:
219         MixersAlignMatchAll(MixersAlignWindow *gui, MixersAlign *dialog, int x, int y);
220         int handle_event();
221
222         MixersAlign *dialog;
223         MixersAlignWindow *gui;
224 };
225
226 class MixersAlignNudgeTracks : public BC_GenericButton
227 {
228 public:
229         MixersAlignNudgeTracks(MixersAlignWindow *gui, MixersAlign *dialog, int x, int y);
230         int handle_event();
231         static int calculate_width(BC_WindowBase *gui);
232
233         MixersAlign *dialog;
234         MixersAlignWindow *gui;
235 };
236
237 class MixersAlignNudgeSelected : public BC_GenericButton
238 {
239 public:
240         MixersAlignNudgeSelected(MixersAlignWindow *gui, MixersAlign *dialog, int x, int y);
241         int handle_event();
242         static int calculate_width(BC_WindowBase *gui);
243
244         MixersAlign *dialog;
245         MixersAlignWindow *gui;
246 };
247
248 class MixersAlignCheckPoint : public BC_GenericButton
249 {
250 public:
251         MixersAlignCheckPoint(MixersAlignWindow *gui, MixersAlign *dialog, int x, int y);
252         int handle_event();
253
254         MixersAlign *dialog;
255         MixersAlignWindow *gui;
256 };
257
258 class MixersAlignUndoEDLs : public ArrayList<EDL *>
259 {
260 public:
261         MixersAlignUndoEDLs() {}
262         ~MixersAlignUndoEDLs() {
263                 for( int i=size(); --i>=0; ) get(i)->remove_user();
264         }
265 };
266
267 class MixersAlignUndoItem : public BC_MenuItem
268 {
269 public:
270         MixersAlignUndoItem(const char *text, int no);
271         ~MixersAlignUndoItem();
272         int handle_event();
273
274         int no;
275 };
276
277 class MixersAlignUndo : public BC_PopupMenu
278 {
279 public:
280         MixersAlignUndo(MixersAlignWindow *gui, MixersAlign *dialog, int x, int y);
281         ~MixersAlignUndo();
282         void create_objects();
283         void add_undo_item(int no);
284
285         MixersAlign *dialog;
286         MixersAlignWindow *gui;
287 };
288
289
290 class MixersAlignWindow : public BC_Window
291 {
292 public:
293         MixersAlignWindow(MixersAlign *dialog, int x, int y);
294         ~MixersAlignWindow();
295
296         void create_objects();
297         int resize_event(int w, int h);
298         void load_lists();
299         void default_selection();
300         void update_gui();
301
302         MixersAlign *dialog;
303         BC_Title *mixer_title, *mtrack_title, *atrack_title;
304
305         MixersAlignMixerList *mixer_list;
306         MixersAlignMTrackList *mtrack_list;
307         MixersAlignATrackList *atrack_list;
308         MixersAlignMatch *match;
309         MixersAlignMatchAll *match_all;
310         MixersAlignReset *reset;
311         MixersAlignNudgeTracks *nudge_tracks;
312         MixersAlignNudgeSelected *nudge_selected;
313         MixersAlignCheckPoint *check_point;
314         MixersAlignUndo *undo;
315 };
316
317
318 class MixersAlignARender : public RenderEngine
319 {
320 public:
321         MixersAlignARender(MWindow *mwindow, EDL *edl);
322         ~MixersAlignARender();
323
324         int render(Samples **samples, int64_t len, int64_t pos);
325 };
326
327
328 class MixersAlignScanPackage : public LoadPackage
329 {
330 public:
331         MixersAlignScanPackage(MixersAlignScanFarm *farm);
332         ~MixersAlignScanPackage();
333
334         MixersAlignMixer *mixer;
335 };
336
337 class MixersAlignScanClient : public LoadClient
338 {
339 public:
340         MixersAlignScanClient(MixersAlignScanFarm *farm);
341         ~MixersAlignScanClient();
342         void process_package(LoadPackage *package);
343
344         MixersAlignScanFarm *farm;
345         MixersAlignScanPackage *pkg;
346         int64_t pos;
347         int len1;
348 };
349
350 class MixersAlignScanFarm : public LoadServer
351 {
352 public:
353         MixersAlignScanFarm(MixersAlign *dialog, int cpus, int n);
354         ~MixersAlignScanFarm();
355         void init_packages();
356         LoadClient *new_client();
357         LoadPackage *new_package();
358
359         MixersAlign *dialog;
360         Samples *samples;
361         int len;
362 };
363
364
365 class MixersAlignMatchFwdPackage : public LoadPackage
366 {
367 public:
368         MixersAlignMatchFwdPackage();
369         ~MixersAlignMatchFwdPackage();
370
371         MixersAlignMixer *mixer;
372 };
373
374 class MixersAlignMatchFwdClient : public LoadClient
375 {
376 public:
377         MixersAlignMatchFwdClient(MixersAlignMatchFwdFarm *farm);
378         ~MixersAlignMatchFwdClient();
379
380         void process_package(LoadPackage *package);
381         MixersAlignMatchFwdPackage *pkg;
382 };
383
384 class MixersAlignMatchFwdFarm : public LoadServer
385 {
386 public:
387         MixersAlignMatchFwdFarm(MixersAlign *dialog, int n);
388         ~MixersAlignMatchFwdFarm();
389         void init_packages();
390         LoadClient *new_client();
391         LoadPackage *new_package();
392
393         MixersAlign *dialog;
394 };
395
396
397 class MixersAlignMatchRevPackage : public LoadPackage
398 {
399 public:
400         MixersAlignMatchRevPackage();
401         ~MixersAlignMatchRevPackage();
402
403         MixersAlignMixer *mix;
404 };
405
406 class MixersAlignMatchRevClient : public LoadClient
407 {
408 public:
409         MixersAlignMatchRevClient(MixersAlignMatchRevFarm *farm);
410         ~MixersAlignMatchRevClient();
411
412         void process_package(LoadPackage *package);
413         MixersAlignMatchRevPackage *pkg;
414         double *re, *im;
415 };
416
417 class MixersAlignMatchRevFarm : public LoadServer
418 {
419 public:
420         MixersAlignMatchRevFarm(int n, int cpus,
421                 MixersAlign *dialog, double *ar, double *ai, int len);
422         ~MixersAlignMatchRevFarm();
423         void init_packages();
424         LoadClient *new_client();
425         LoadPackage *new_package();
426
427         MixersAlign *dialog;
428         Mutex *mixer_lock;
429         double *ar, *ai;
430         int len;
431         int64_t pos;
432 };
433
434
435 class MixersAlignTargetPackage : public LoadPackage
436 {
437 public:
438         MixersAlignTargetPackage(MixersAlignTarget *pfft);
439         ~MixersAlignTargetPackage();
440
441         double ss, sd2;
442         int64_t pos;
443         double *best;
444 };
445
446 class MixersAlignTargetClient : public LoadClient
447 {
448 public:
449         MixersAlignTargetClient();
450         ~MixersAlignTargetClient();
451
452         void process_package(LoadPackage *package);
453         MixersAlignTargetPackage *pkg;
454 };
455
456 class MixersAlignTarget : public LoadServer
457 {
458 public:
459         MixersAlignTarget(int n, int cpus,
460                 MixersAlignScanClient *scan, Samples **samples, int len);
461         ~MixersAlignTarget();
462         void init_packages();
463         LoadClient *new_client();
464         LoadPackage *new_package();
465
466         MixersAlignScanClient *scan;
467         Samples **samples;
468         int len;
469 };
470
471
472 class MixersAlign : public BC_DialogThread, public FFT
473 {
474 public:
475         MixersAlign(MWindow *mwindow);
476         ~MixersAlign();
477
478         void start_dialog(int wx, int wy);
479         BC_Window *new_gui();
480         void load_mixers();
481         void load_mtracks();
482         void load_atracks();
483         void handle_done_event(int result);
484         void handle_close_event(int result);
485
486         int atrack_of(MixersAlignMixer *mix, int ch);
487         int mixer_of(Track *track, int &midx);
488         int mixer_of(Track *track) { int midx = -1; return mixer_of(track, midx); }
489         int mmixer_of(int mi) {
490                 return mi>=0 && mi<mtracks.size() ? mixer_of(mtracks[mi]->track) : -1;
491         }
492         int amixer_of(int ai) {
493                 return ai>=0 && ai<atracks.size() ? mixer_of(atracks[ai]->track) : -1;
494         }
495
496         EDL *mixer_audio_clip(Mixer *mixer);
497         EDL *mixer_master_clip(Track *track);
498         int64_t mixer_tracks_total(int midx);
499         void load_master_audio(Track *track);
500         void scan_mixer_audio();
501         void start_progress(int64_t total_len);
502         void stop_progress(const char *msg);
503         void update_progress(int64_t len);
504         void match_fwd();
505         void match_rev();
506         void update_fwd();
507         void update_rev();
508         void update();
509         void apply_undo(int no);
510         void nudge_tracks();
511         void nudge_selected();
512         void clear_mixer_nudge();
513         void check_point();
514         void reset_targets();
515         void scan_targets();
516         void scan_master(Track *track);
517
518         MixersAlignWindow *ma_gui;
519         int wx, wy;
520         MixersAlignMixers mixers;
521         MixersAlignMTracks mtracks;
522         MixersAlignATracks atracks;
523         MWindow *mwindow;
524
525         MixersAlignUndoEDLs undo_edls;
526         Mutex *farming;
527         MainProgressBar *progress;
528         MixersAlignThread *thread;
529         Mutex *total_lock;
530         int64_t total_rendered;
531         int failed;
532         int64_t master_len, sample_len;
533         double *master_r, *master_i;
534         double master_start, master_end, master_ss;
535         double audio_start, audio_end;
536 };
537
538 #endif