4 * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
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.
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.
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
22 #include "automation.h"
24 #include "cplayback.h"
26 #include "cwindowgui.h"
29 #include "edlsession.h"
31 #include "localsession.h"
32 #include "maincursor.h"
34 #include "mainsession.h"
37 #include "mwindowgui.h"
39 #include "playbackengine.h"
41 #include "resourcethread.h"
42 #include "samplescroll.h"
44 #include "trackcanvas.h"
46 #include "transportque.h"
50 void MWindow::update_plugins()
52 // Show plugins which are visible and hide plugins which aren't
53 // Update plugin pointers in plugin servers
57 int MWindow::expand_sample()
61 if(edl->local_session->zoom_sample < 0x100000)
63 edl->local_session->zoom_sample *= 2;
64 gui->zoombar->sample_zoom->update(edl->local_session->zoom_sample);
65 zoom_sample(edl->local_session->zoom_sample);
71 int MWindow::zoom_in_sample()
75 if(edl->local_session->zoom_sample > 1)
77 edl->local_session->zoom_sample /= 2;
78 gui->zoombar->sample_zoom->update(edl->local_session->zoom_sample);
79 zoom_sample(edl->local_session->zoom_sample);
85 int MWindow::zoom_sample(int64_t zoom_sample)
87 CLAMP(zoom_sample, 1, 0x100000);
88 edl->local_session->zoom_sample = zoom_sample;
91 TimelinePane *pane = gui->get_focused_pane();
92 samplemovement(edl->local_session->view_start[pane->number], pane->number);
96 void MWindow::find_cursor()
98 TimelinePane *pane = gui->get_focused_pane();
99 edl->local_session->view_start[pane->number] =
100 Units::round((edl->local_session->get_selectionend(1) +
101 edl->local_session->get_selectionstart(1)) /
103 edl->session->sample_rate /
104 edl->local_session->zoom_sample -
105 (double)pane->canvas->get_w() /
108 if(edl->local_session->view_start[pane->number] < 0)
109 edl->local_session->view_start[pane->number] = 0;
113 void MWindow::fit_selection()
115 if(EQUIV(edl->local_session->get_selectionstart(1),
116 edl->local_session->get_selectionend(1)))
118 double total_samples = edl->tracks->total_length() *
119 edl->session->sample_rate;
120 TimelinePane *pane = gui->get_focused_pane();
121 for(edl->local_session->zoom_sample = 1;
122 pane->canvas->get_w() * edl->local_session->zoom_sample < total_samples;
123 edl->local_session->zoom_sample *= 2)
128 double total_samples = (edl->local_session->get_selectionend(1) -
129 edl->local_session->get_selectionstart(1)) *
130 edl->session->sample_rate;
131 TimelinePane *pane = gui->get_focused_pane();
132 for(edl->local_session->zoom_sample = 1;
133 pane->canvas->get_w() * edl->local_session->zoom_sample < total_samples;
134 edl->local_session->zoom_sample *= 2)
138 edl->local_session->zoom_sample = MIN(0x100000,
139 edl->local_session->zoom_sample);
140 zoom_sample(edl->local_session->zoom_sample);
144 void MWindow::fit_autos(int doall)
146 float min = 0, max = 0;
150 if(EQUIV(edl->local_session->get_selectionstart(1),
151 edl->local_session->get_selectionend(1)))
154 end = edl->tracks->total_length();
157 // Test autos in highlighting only
159 start = edl->local_session->get_selectionstart(1);
160 end = edl->local_session->get_selectionend(1);
163 int forstart = edl->local_session->zoombar_showautotype;
164 int forend = edl->local_session->zoombar_showautotype + 1;
168 forend = AUTOGROUPTYPE_COUNT;
171 for (int i = forstart; i < forend; i++)
173 // Adjust min and max
174 edl->tracks->get_automation_extents(&min, &max, start, end, i);
175 //printf("MWindow::fit_autos %d %f %f results in ", i, min, max);
177 float range = max - min;
180 case AUTOGROUPTYPE_AUDIO_FADE:
182 min = MIN(min, edl->local_session->automation_mins[i]);
183 max = MAX(max, edl->local_session->automation_maxs[i]);
184 if( min >= max-0.1 ) { min = -80.0; min = 6.0; }
187 case AUTOGROUPTYPE_VIDEO_FADE:
189 min = MIN(min, edl->local_session->automation_mins[i]);
190 max = MAX(max, edl->local_session->automation_maxs[i]);
191 if( min >= max-0.1 ) { min = 0.0; min = 100.0; }
194 case AUTOGROUPTYPE_ZOOM:
196 min = floor(min*50)/100;
197 max = floor(max*200)/100;
200 case AUTOGROUPTYPE_SPEED:
202 min = floor(min*5)/100;
203 max = floor(max*300)/100;
206 case AUTOGROUPTYPE_X:
207 case AUTOGROUPTYPE_Y:
209 float scale = bmin(edl->session->output_w, edl->session->output_h);
210 min = floor((min+max)/2) - 0.5*scale;
211 max = floor((min+max)/2) + 0.5*scale;
215 //printf("%f %f\n", min, max);
216 if (!Automation::autogrouptypes_fixedrange[i])
218 edl->local_session->automation_mins[i] = min;
219 edl->local_session->automation_maxs[i] = max;
223 // Show range in zoombar
224 gui->zoombar->update();
227 gui->draw_overlays(1);
231 void MWindow::change_currentautorange(int autogrouptype, int increment, int changemax)
235 val = edl->local_session->automation_maxs[autogrouptype];
237 val = edl->local_session->automation_mins[autogrouptype];
242 switch (autogrouptype) {
243 case AUTOGROUPTYPE_AUDIO_FADE:
246 case AUTOGROUPTYPE_VIDEO_FADE:
249 case AUTOGROUPTYPE_ZOOM:
250 case AUTOGROUPTYPE_SPEED:
256 case AUTOGROUPTYPE_X:
257 case AUTOGROUPTYPE_Y:
258 val = floor(val + 5);
264 switch (autogrouptype) {
265 case AUTOGROUPTYPE_AUDIO_FADE:
268 case AUTOGROUPTYPE_VIDEO_FADE:
271 case AUTOGROUPTYPE_ZOOM:
272 case AUTOGROUPTYPE_SPEED:
273 if (val > 0) val = val/2;
275 case AUTOGROUPTYPE_X:
276 case AUTOGROUPTYPE_Y:
282 AUTOMATIONVIEWCLAMPS(val, autogrouptype);
285 if (val > edl->local_session->automation_mins[autogrouptype])
286 edl->local_session->automation_maxs[autogrouptype] = val;
290 if (val < edl->local_session->automation_maxs[autogrouptype])
291 edl->local_session->automation_mins[autogrouptype] = val;
296 void MWindow::expand_autos(int changeall, int domin, int domax)
299 for (int i = 0; i < AUTOGROUPTYPE_COUNT; i++) {
300 if (domin) change_currentautorange(i, 1, 0);
301 if (domax) change_currentautorange(i, 1, 1);
305 if (domin) change_currentautorange(edl->local_session->zoombar_showautotype, 1, 0);
306 if (domax) change_currentautorange(edl->local_session->zoombar_showautotype, 1, 1);
308 gui->zoombar->update_autozoom();
309 gui->draw_overlays(0);
310 gui->update_patchbay();
311 gui->flash_canvas(1);
314 void MWindow::shrink_autos(int changeall, int domin, int domax)
317 for (int i = 0; i < AUTOGROUPTYPE_COUNT; i++) {
318 if (domin) change_currentautorange(i, 0, 0);
319 if (domax) change_currentautorange(i, 0, 1);
323 if (domin) change_currentautorange(edl->local_session->zoombar_showautotype, 0, 0);
324 if (domax) change_currentautorange(edl->local_session->zoombar_showautotype, 0, 1);
326 gui->zoombar->update_autozoom();
327 gui->draw_overlays(0);
328 gui->update_patchbay();
329 gui->flash_canvas(1);
333 void MWindow::zoom_autos(float min, float max)
335 int i = edl->local_session->zoombar_showautotype;
336 edl->local_session->automation_mins[i] = min;
337 edl->local_session->automation_maxs[i] = max;
338 gui->zoombar->update_autozoom();
339 gui->draw_overlays(1);
343 void MWindow::zoom_amp(int64_t zoom_amp)
345 edl->local_session->zoom_y = zoom_amp;
346 gui->draw_canvas(0, 0);
347 gui->flash_canvas(0);
348 gui->update_patchbay();
352 void MWindow::zoom_track(int64_t zoom_track)
355 edl->local_session->zoom_y = (int64_t)((float)edl->local_session->zoom_y *
357 edl->local_session->zoom_track);
358 CLAMP(edl->local_session->zoom_y, MIN_AMP_ZOOM, MAX_AMP_ZOOM);
361 double scale = (double)zoom_track / edl->local_session->zoom_track;
362 edl->local_session->zoom_track = zoom_track;
364 // shift row position
365 for(int i = 0; i < TOTAL_PANES; i++)
367 edl->local_session->track_start[i] *= scale;
369 edl->tracks->update_y_pixels(theme);
370 gui->draw_trackmovement();
371 //printf("MWindow::zoom_track %d %d\n", edl->local_session->zoom_y, edl->local_session->zoom_track);
374 void MWindow::trackmovement(int offset, int pane_number)
376 edl->local_session->track_start[pane_number] += offset;
377 if(edl->local_session->track_start[pane_number] < 0)
378 edl->local_session->track_start[pane_number] = 0;
380 if(pane_number == TOP_RIGHT_PANE ||
381 pane_number == TOP_LEFT_PANE)
383 edl->local_session->track_start[TOP_LEFT_PANE] =
384 edl->local_session->track_start[TOP_RIGHT_PANE] =
385 edl->local_session->track_start[pane_number];
388 if(pane_number == BOTTOM_RIGHT_PANE ||
389 pane_number == BOTTOM_LEFT_PANE)
391 edl->local_session->track_start[BOTTOM_LEFT_PANE] =
392 edl->local_session->track_start[BOTTOM_RIGHT_PANE] =
393 edl->local_session->track_start[pane_number];
397 edl->tracks->update_y_pixels(theme);
398 gui->draw_trackmovement();
401 void MWindow::move_up(int64_t distance)
403 TimelinePane *pane = gui->get_focused_pane();
404 if(distance == 0) distance = edl->local_session->zoom_track;
406 trackmovement(-distance, pane->number);
409 void MWindow::move_down(int64_t distance)
411 TimelinePane *pane = gui->get_focused_pane();
412 if(distance == 0) distance = edl->local_session->zoom_track;
414 trackmovement(distance, pane->number);
417 int MWindow::goto_end()
419 TimelinePane *pane = gui->get_focused_pane();
420 int64_t old_view_start = edl->local_session->view_start[pane->number];
422 if(edl->tracks->total_length() > (double)pane->canvas->get_w() *
423 edl->local_session->zoom_sample /
424 edl->session->sample_rate)
426 edl->local_session->view_start[pane->number] =
427 Units::round(edl->tracks->total_length() *
428 edl->session->sample_rate /
429 edl->local_session->zoom_sample -
430 pane->canvas->get_w() /
435 edl->local_session->view_start[pane->number] = 0;
438 if(gui->shift_down())
440 edl->local_session->set_selectionend(edl->tracks->total_length());
444 edl->local_session->set_selectionstart(edl->tracks->total_length());
445 edl->local_session->set_selectionend(edl->tracks->total_length());
448 if(edl->local_session->view_start[pane->number] != old_view_start)
450 samplemovement(edl->local_session->view_start[pane->number], pane->number);
451 gui->draw_samplemovement();
454 update_plugin_guis();
456 gui->update_patchbay();
457 gui->update_cursor();
458 gui->activate_timeline();
459 gui->zoombar->update();
460 gui->update_timebar(1);
461 cwindow->update(1, 0, 0, 0, 1);
465 int MWindow::goto_start()
467 TimelinePane *pane = gui->get_focused_pane();
468 int64_t old_view_start = edl->local_session->view_start[pane->number];
470 edl->local_session->view_start[pane->number] = 0;
471 if(gui->shift_down())
473 edl->local_session->set_selectionstart(0);
477 edl->local_session->set_selectionstart(0);
478 edl->local_session->set_selectionend(0);
481 if(edl->local_session->view_start[pane->number] != old_view_start)
483 samplemovement(edl->local_session->view_start[pane->number], pane->number);
484 gui->draw_samplemovement();
487 update_plugin_guis();
488 gui->update_patchbay();
489 gui->update_cursor();
490 gui->activate_timeline();
491 gui->zoombar->update();
492 gui->update_timebar(1);
493 cwindow->update(1, 0, 0, 0, 1);
497 int MWindow::goto_position(double position)
499 TimelinePane *pane = gui->get_focused_pane();
500 int64_t old_view_start = edl->local_session->view_start[pane->number];
501 edl->local_session->set_selectionstart(position);
502 edl->local_session->set_selectionend(position);
504 int64_t new_view_start = edl->local_session->view_start[pane->number];
505 if(new_view_start != old_view_start)
506 samplemovement(new_view_start, pane->number);
507 update_plugin_guis();
508 gui->update_patchbay();
509 gui->update_cursor();
510 gui->activate_timeline();
511 gui->zoombar->update();
512 gui->update_timebar(1);
513 cwindow->update(1, 0, 0, 0, 1);
517 int MWindow::samplemovement(int64_t view_start, int pane_number)
519 if( view_start < 0 ) view_start = 0;
520 edl->local_session->view_start[pane_number] = view_start;
521 if(edl->local_session->view_start[pane_number] < 0)
522 edl->local_session->view_start[pane_number] = 0;
524 if(pane_number == TOP_LEFT_PANE ||
525 pane_number == BOTTOM_LEFT_PANE)
527 edl->local_session->view_start[TOP_LEFT_PANE] =
528 edl->local_session->view_start[BOTTOM_LEFT_PANE] =
529 edl->local_session->view_start[pane_number];
533 edl->local_session->view_start[TOP_RIGHT_PANE] =
534 edl->local_session->view_start[BOTTOM_RIGHT_PANE] =
535 edl->local_session->view_start[pane_number];
538 gui->draw_samplemovement();
543 int MWindow::move_left(int64_t distance)
545 TimelinePane *pane = gui->get_focused_pane();
547 distance = pane->canvas->get_w() /
549 edl->local_session->view_start[pane->number] -= distance;
550 samplemovement(edl->local_session->view_start[pane->number],
555 int MWindow::move_right(int64_t distance)
557 TimelinePane *pane = gui->get_focused_pane();
559 distance = pane->canvas->get_w() /
561 edl->local_session->view_start[pane->number] += distance;
562 samplemovement(edl->local_session->view_start[pane->number],
567 void MWindow::select_all()
569 if( edl->local_session->get_selectionstart(1) == 0 &&
570 edl->local_session->get_selectionend(1) == edl->tracks->total_length() )
571 edl->local_session->set_selectionend(0);
573 edl->local_session->set_selectionstart(0);
574 edl->local_session->set_selectionend(edl->tracks->total_length());
576 gui->update(0, 1, 1, 1, 0, 1, 0);
577 gui->activate_timeline();
578 cwindow->update(1, 0, 0, 0, 1);
579 update_plugin_guis();
582 int MWindow::next_label(int shift_down)
584 double cursor_position = edl->local_session->get_selectionstart(1);
585 Label *current = edl->labels->next_label(cursor_position);
586 double position = !current ? -1 : current->position;
588 // last playback endpoints as fake label positions
589 double playback_start = edl->local_session->playback_start;
590 double playback_end = edl->local_session->playback_end;
591 if( playback_start > cursor_position && ( position < 0 || playback_start < position ) )
592 position = playback_start;
593 else if( playback_end > cursor_position && ( position < 0 || playback_end < position ) )
594 position = playback_end;
596 if( position >= 0 ) {
597 edl->local_session->set_selectionend(position);
599 edl->local_session->set_selectionstart(
600 edl->local_session->get_selectionend(1));
602 update_plugin_guis();
603 TimelinePane *pane = gui->get_focused_pane();
604 if(edl->local_session->get_selectionend(1) >=
605 (double)edl->local_session->view_start[pane->number] *
606 edl->local_session->zoom_sample / edl->session->sample_rate +
607 pane->canvas->time_visible() ||
608 edl->local_session->get_selectionend(1) < (double)edl->local_session->view_start[pane->number] *
609 edl->local_session->zoom_sample / edl->session->sample_rate) {
610 samplemovement((int64_t)(edl->local_session->get_selectionend(1) *
611 edl->session->sample_rate /
612 edl->local_session->zoom_sample -
613 pane->canvas->get_w() /
616 cwindow->update(1, 0, 0, 0, 0);
620 gui->update_patchbay();
621 gui->update_timebar(0);
624 gui->zoombar->update();
625 gui->flash_canvas(1);
626 cwindow->update(1, 0, 0, 0, 1);
636 int MWindow::prev_label(int shift_down)
638 double cursor_position = edl->local_session->get_selectionstart(1);
639 Label *current = edl->labels->prev_label(cursor_position);
640 double position = !current ? -1 : current->position;
642 // last playback endpoints as fake label positions
643 double playback_start = edl->local_session->playback_start;
644 double playback_end = edl->local_session->playback_end;
645 if( playback_end < cursor_position && ( position < 0 || playback_end > position ) )
646 position = playback_end;
647 else if( playback_start < cursor_position && ( position < 0 || playback_start > position ) )
648 position = playback_start;
650 if( position >= 0 ) {
651 edl->local_session->set_selectionstart(position);
653 edl->local_session->set_selectionend(edl->local_session->get_selectionstart(1));
655 update_plugin_guis();
656 TimelinePane *pane = gui->get_focused_pane();
657 if(edl->local_session->get_selectionstart(1) >= edl->local_session->view_start[pane->number] *
658 edl->local_session->zoom_sample / edl->session->sample_rate +
659 pane->canvas->time_visible() ||
660 edl->local_session->get_selectionstart(1) < edl->local_session->view_start[pane->number] *
661 edl->local_session->zoom_sample / edl->session->sample_rate ) {
662 samplemovement((int64_t)(edl->local_session->get_selectionstart(1) *
663 edl->session->sample_rate /
664 edl->local_session->zoom_sample -
665 pane->canvas->get_w() /
668 cwindow->update(1, 0, 0, 0, 0);
671 // Don't scroll the display
673 gui->update_patchbay();
674 gui->update_timebar(0);
677 gui->zoombar->update();
678 gui->flash_canvas(1);
679 cwindow->update(1, 0, 0, 0, 1);
690 int MWindow::next_edit_handle(int shift_down)
692 double position = edl->local_session->get_selectionend(1);
693 double new_position = edl->next_edit(position);
694 if( new_position < edl->tracks->total_length() ) {
695 edl->local_session->set_selectionend(new_position);
696 //printf("MWindow::next_edit_handle %d\n", shift_down);
698 edl->local_session->set_selectionstart(
699 edl->local_session->get_selectionend(1));
701 update_plugin_guis();
702 TimelinePane *pane = gui->get_focused_pane();
703 if(edl->local_session->get_selectionend(1) >=
704 (double)edl->local_session->view_start[pane->number] *
705 edl->local_session->zoom_sample /
706 edl->session->sample_rate +
707 pane->canvas->time_visible() ||
708 edl->local_session->get_selectionend(1) < (double)edl->local_session->view_start[pane->number] *
709 edl->local_session->zoom_sample /
710 edl->session->sample_rate)
712 samplemovement((int64_t)(edl->local_session->get_selectionend(1) *
713 edl->session->sample_rate /
714 edl->local_session->zoom_sample -
715 pane->canvas->get_w() /
718 cwindow->update(1, 0, 0, 0, 0);
722 gui->update_patchbay();
723 gui->update_timebar(0);
726 gui->zoombar->update();
727 gui->flash_canvas(1);
728 cwindow->update(1, 0, 0, 0, 1);
738 int MWindow::prev_edit_handle(int shift_down)
740 double position = edl->local_session->get_selectionstart(1);
741 double new_position = edl->prev_edit(position);
743 if(new_position != -1) {
744 edl->local_session->set_selectionstart(new_position);
745 //printf("MWindow::next_edit_handle %d\n", shift_down);
747 edl->local_session->set_selectionend(edl->local_session->get_selectionstart(1));
749 update_plugin_guis();
750 // Scroll the display
751 TimelinePane *pane = gui->get_focused_pane();
752 if(edl->local_session->get_selectionstart(1) >= edl->local_session->view_start[pane->number] *
753 edl->local_session->zoom_sample /
754 edl->session->sample_rate +
755 pane->canvas->time_visible()
757 edl->local_session->get_selectionstart(1) < edl->local_session->view_start[pane->number] *
758 edl->local_session->zoom_sample /
759 edl->session->sample_rate)
761 samplemovement((int64_t)(edl->local_session->get_selectionstart(1) *
762 edl->session->sample_rate /
763 edl->local_session->zoom_sample -
764 pane->canvas->get_w() /
767 cwindow->update(1, 0, 0, 0, 0);
770 // Don't scroll the display
772 gui->update_patchbay();
773 gui->update_timebar(0);
776 gui->zoombar->update();
777 gui->flash_canvas(1);
778 cwindow->update(1, 0, 0, 0, 1);
795 int MWindow::expand_y()
797 int result = edl->local_session->zoom_y * 2;
798 result = MIN(result, MAX_AMP_ZOOM);
800 gui->zoombar->update();
804 int MWindow::zoom_in_y()
806 int result = edl->local_session->zoom_y / 2;
807 result = MAX(result, MIN_AMP_ZOOM);
809 gui->zoombar->update();
813 int MWindow::expand_t()
815 int result = edl->local_session->zoom_track * 2;
816 result = MIN(result, MAX_TRACK_ZOOM);
818 gui->zoombar->update();
822 int MWindow::zoom_in_t()
824 int result = edl->local_session->zoom_track / 2;
825 result = MAX(result, MIN_TRACK_ZOOM);
827 gui->zoombar->update();
831 void MWindow::split_x()
833 gui->resource_thread->stop_draw(1);
835 if(gui->pane[TOP_RIGHT_PANE])
837 gui->delete_x_pane(theme->mcanvas_w);
838 edl->local_session->x_pane = -1;
842 gui->create_x_pane(theme->mcanvas_w / 2);
843 edl->local_session->x_pane = theme->mcanvas_w / 2;
846 gui->mainmenu->update_toggles(0);
847 gui->update_pane_dividers();
848 gui->update_cursor();
849 gui->draw_samplemovement();
850 // required to get new widgets to appear
853 gui->resource_thread->start_draw();
856 void MWindow::split_y()
858 gui->resource_thread->stop_draw(1);
859 if(gui->pane[BOTTOM_LEFT_PANE])
861 gui->delete_y_pane(theme->mcanvas_h);
862 edl->local_session->y_pane = -1;
866 gui->create_y_pane(theme->mcanvas_h / 2);
867 edl->local_session->y_pane = theme->mcanvas_h / 2;
870 gui->mainmenu->update_toggles(0);
871 gui->update_pane_dividers();
872 gui->update_cursor();
873 gui->draw_trackmovement();
874 // required to get new widgets to appear
876 gui->resource_thread->start_draw();