From: Good Guy Date: Sat, 23 Mar 2019 18:32:19 +0000 (-0600) Subject: mixer align audio, track dump tweak, zwdw refresh edl fix, sketcher tweak X-Git-Tag: 2019-08~79 X-Git-Url: https://git.cinelerra-gg.org/git/?a=commitdiff_plain;h=4a6b59824b2db18e6cc49b43a971923d5e5903ae;p=goodguy%2Fcinelerra.git mixer align audio, track dump tweak, zwdw refresh edl fix, sketcher tweak --- diff --git a/cinelerra-5.1/cinelerra/Makefile b/cinelerra-5.1/cinelerra/Makefile index ad888cf3..e0d94a3e 100644 --- a/cinelerra-5.1/cinelerra/Makefile +++ b/cinelerra-5.1/cinelerra/Makefile @@ -212,6 +212,7 @@ OBJS := $(OVERLAYS) \ $(OBJDIR)/menuveffects.o \ $(OBJDIR)/meterhistory.o \ $(OBJDIR)/meterpanel.o \ + $(OBJDIR)/mixersalign.o \ $(OBJDIR)/module.o \ $(OBJDIR)/mtimebar.o \ $(OBJDIR)/mwindowedit.o \ diff --git a/cinelerra-5.1/cinelerra/mainmenu.C b/cinelerra-5.1/cinelerra/mainmenu.C index 01bc15a3..8718915f 100644 --- a/cinelerra-5.1/cinelerra/mainmenu.C +++ b/cinelerra-5.1/cinelerra/mainmenu.C @@ -55,6 +55,7 @@ #include "menueditlength.h" #include "menutransitionlength.h" #include "menuveffects.h" +#include "mixersalign.h" #include "mwindowgui.h" #include "mwindow.h" #include "new.h" @@ -271,8 +272,8 @@ void MainMenu::create_objects() windowmenu->add_item(new BC_MenuItem("-")); windowmenu->add_item(split_x = new SplitX(mwindow)); windowmenu->add_item(split_y = new SplitY(mwindow)); - windowmenu->add_item(mixer_viewer = new MixerViewer(mwindow)); - windowmenu->add_item(new TileMixers(mwindow)); + windowmenu->add_item(mixer_items = new MixerItems(mwindow)); + mixer_items->create_objects(); windowmenu->add_item(new TileWindows(mwindow,_("Tile left"),0)); windowmenu->add_item(new TileWindows(mwindow,_("Tile right"),1)); windowmenu->add_item(new BC_MenuItem("-")); @@ -1590,6 +1591,21 @@ int SplitY::handle_event() } +MixerItems::MixerItems(MWindow *mwindow) + : BC_MenuItem(_("Mixers...")) +{ + this->mwindow = mwindow; +} + +void MixerItems::create_objects() +{ + BC_SubMenu *mixer_submenu = new BC_SubMenu(); + add_submenu(mixer_submenu); + mixer_submenu->add_submenuitem(new MixerViewer(mwindow)); + mixer_submenu->add_submenuitem(new TileMixers(mwindow)); + mixer_submenu->add_submenuitem(new AlignMixers(mwindow)); +} + MixerViewer::MixerViewer(MWindow *mwindow) : BC_MenuItem(_("Mixer Viewer"), _("Shift-M"), 'M') { @@ -1616,6 +1632,20 @@ int TileMixers::handle_event() return 1; } +AlignMixers::AlignMixers(MWindow *mwindow) + : BC_MenuItem(_("Align mixers")) +{ + this->mwindow = mwindow; +} + +int AlignMixers::handle_event() +{ + int wx, wy; + mwindow->gui->get_abs_cursor(wx, wy); + mwindow->mixers_align->start_dialog(wx, wy); + return 1; +} + LoadLayoutItem::LoadLayoutItem(LoadLayout *load_layout, const char *text, int idx, int hotkey) : BC_MenuItem(text, "", hotkey) diff --git a/cinelerra-5.1/cinelerra/mainmenu.h b/cinelerra-5.1/cinelerra/mainmenu.h index 64c86591..674be023 100644 --- a/cinelerra-5.1/cinelerra/mainmenu.h +++ b/cinelerra-5.1/cinelerra/mainmenu.h @@ -128,7 +128,7 @@ public: ShowLWindow *show_lwindow; SplitX *split_x; SplitY *split_y; - MixerViewer *mixer_viewer; + MixerItems *mixer_items; LoadLayout *load_layout; LoadLayout *save_layout; }; @@ -417,6 +417,22 @@ public: MWindow *mwindow; }; +class MixerItems : public BC_MenuItem +{ +public: + MixerItems(MWindow *mwindow); + void create_objects(); + MWindow *mwindow; +}; + +class MixerViewer : public BC_MenuItem +{ +public: + MixerViewer(MWindow *mwindow); + int handle_event(); + MWindow *mwindow; +}; + class TileMixers : public BC_MenuItem { public: @@ -425,6 +441,14 @@ public: MWindow *mwindow; }; +class AlignMixers : public BC_MenuItem +{ +public: + AlignMixers(MWindow *mwindow); + int handle_event(); + MWindow *mwindow; +}; + // ======================================== audio class AddAudioTrack : public BC_MenuItem @@ -706,14 +730,6 @@ public: MWindow *mwindow; }; -class MixerViewer : public BC_MenuItem -{ -public: - MixerViewer(MWindow *mwindow); - int handle_event(); - MWindow *mwindow; -}; - class LoadLayoutItem : public BC_MenuItem { diff --git a/cinelerra-5.1/cinelerra/mainmenu.inc b/cinelerra-5.1/cinelerra/mainmenu.inc index 81dd0c10..6cf77201 100644 --- a/cinelerra-5.1/cinelerra/mainmenu.inc +++ b/cinelerra-5.1/cinelerra/mainmenu.inc @@ -58,6 +58,8 @@ class CutCommercials; class DetachTransitions; class MuteSelection; class TrimSelection; +class MixerItems; +class MixerViewer; class TileMixers; class AddAudioTrack; class DeleteAudioTrack; @@ -92,7 +94,6 @@ class ShowLWindow; class TileWindows; class SplitX; class SplitY; -class MixerViewer; class LoadLayoutItem; class LoadLayout; class LoadLayoutDialog; diff --git a/cinelerra-5.1/cinelerra/mixersalign.C b/cinelerra-5.1/cinelerra/mixersalign.C new file mode 100644 index 00000000..34f230e9 --- /dev/null +++ b/cinelerra-5.1/cinelerra/mixersalign.C @@ -0,0 +1,1073 @@ +/* + * CINELERRA + * Copyright (C) 2008-2015 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "mixersalign.h" +#include "arender.h" +#include "clip.h" +#include "edit.h" +#include "edits.h" +#include "edl.h" +#include "localsession.h" +#include "mainerror.h" +#include "mainprogress.h" +#include "mwindow.h" +#include "mwindowgui.h" +#include "preferences.h" +#include "track.h" +#include "tracks.h" +#include "renderengine.h" +#include "samples.h" +#include "track.h" +#include "transportque.h" +#include "zwindow.h" + +MixersAlignMixer::MixersAlignMixer(Mixer *mix) +{ + this->mixer = mix; + this->nudge = 0; + mx = 0; mi = -1; + aidx = -1; +} + +const char *MixersAlignMixerList::mix_titles[MIX_SZ] = { + N_("Mixer"), N_("Nudge"), +}; + +int MixersAlignMixerList::mix_widths[MIX_SZ] = { + 130, 50, +}; + +MixersAlignMixerList::MixersAlignMixerList(MixersAlignWindow *gui, + MixersAlign *dialog, int x, int y, int w, int h) + : BC_ListBox(x, y, w, h, LISTBOX_TEXT) +{ + set_selection_mode(LISTBOX_MULTIPLE); + this->dialog = dialog; + this->gui = gui; + for( int i=MIX_SZ; --i>=0; ) { + col_widths[i] = mix_widths[i]; + col_titles[i] = _(mix_titles[i]); + } +} + +MixersAlignMixerList::~MixersAlignMixerList() +{ + clear(); +} + +void MixersAlignMixerList::clear() +{ + for( int i=MIX_SZ; --i>=0; ) + cols[i].remove_all_objects(); +} + +void MixersAlignMixerList::add_mixer(MixersAlignMixer *mixer) +{ + char mixer_text[BCSTRLEN]; + snprintf(mixer_text, sizeof(mixer_text), "%d: %s", + mixer->mixer->idx, mixer->mixer->title); + cols[MIX_MIXER].append(new BC_ListBoxItem(mixer_text)); + char nudge_text[BCSTRLEN]; + sprintf(nudge_text, _("%0.4f"), mixer->nudge); + cols[MIX_NUDGE].append(new BC_ListBoxItem(nudge_text)); +} + +void MixersAlignMixerList::load_list() +{ + clear(); + for( int i=0,sz=dialog->mixers.size(); imixers[i]); +} + +void MixersAlignMixerList::update() +{ + int xpos = get_xposition(), ypos = get_yposition(); + BC_ListBox::update(&cols[0], &col_titles[0],&col_widths[0],MIX_SZ, xpos,ypos); +} + +int MixersAlignMixerList::selection_changed() +{ + for( int m=0; mmixers.size(); ++m ) { + MixersAlignMixer *mix = dialog->mixers[m]; + if( !is_selected(m) ) { + for( int i=0; iatracks.size(); ++i ) { + if( m != dialog->amixer_of(i) ) continue; + gui->atrack_list->set_selected(i, 0); + } + mix->aidx = -1; + mix->mx = 0; + mix->mi = -1; + mix->nudge = 0; + } + else if( mix->aidx < 0 ) { + MixersAlignATrack *best = 0; int idx = -1; + for( int i=0; iatracks.size(); ++i ) { + if( m != dialog->amixer_of(i) ) continue; + MixersAlignATrack *atrk = dialog->atracks[i]; + if( atrk->mi < 0 ) continue; + gui->atrack_list->set_selected(i, 0); + if( best && best->mx >= atrk->mx ) continue; + best = atrk; idx = i; + } + if( idx >= 0 && best ) { + gui->atrack_list->set_selected(idx, 1); + MixersAlignMixer *mix = dialog->mixers[m]; + mix->aidx = idx; + mix->mx = best->mx; + mix->mi = best->mi; + mix->nudge = best->nudge; + } + else { + for( int i=0; iatracks.size(); ++i ) { + if( m != dialog->amixer_of(i) ) continue; + gui->atrack_list->set_selected(i, 1); + } + } + } + } + gui->atrack_list->update(); + + load_list(); + for( int i=0; iatracks.size(); ++i ) { + if( !gui->atrack_list->is_selected(i) ) continue; + int m = dialog->amixer_of(i); + if( m >= 0 ) set_selected(m, 1); + } + update(); + return 0; +} + +MixersAlignMTrack::MixersAlignMTrack(Track *trk, int no) +{ + this->track = trk; + this->no = no; +} + + +const char *MixersAlignMTrackList::mtk_titles[MTK_SZ] = { + N_("No"), N_("Mixer"), N_("Track"), +}; + +int MixersAlignMTrackList::mtk_widths[MTK_SZ] = { + 32, 48, 110, +}; + +MixersAlignMTrackList::MixersAlignMTrackList(MixersAlignWindow *gui, + MixersAlign *dialog, int x, int y, int w, int h) + : BC_ListBox(x, y, w, h, LISTBOX_TEXT) +{ + set_selection_mode(LISTBOX_SINGLE); + this->dialog = dialog; + this->gui = gui; + for( int i=MTK_SZ; --i>=0; ) { + col_widths[i] = mtk_widths[i]; + col_titles[i] = _(mtk_titles[i]); + } +} + +MixersAlignMTrackList::~MixersAlignMTrackList() +{ + clear(); +} + +void MixersAlignMTrackList::clear() +{ + for( int i=MTK_SZ; --i>=0; ) + cols[i].remove_all_objects(); +} + +void MixersAlignMTrackList::add_mtrack(MixersAlignMTrack *mtrk) +{ + char no_text[BCSTRLEN]; + snprintf(no_text, sizeof(no_text),"%d", mtrk->no+1); + cols[MTK_NO].append(new BC_ListBoxItem(no_text)); + char mixer_text[BCSTRLEN]; + Track *track = mtrk->track; + int midx = -1, m = dialog->mixer_of(track, midx); + snprintf(mixer_text, sizeof(mixer_text),"%d:%d", m+1,midx); + cols[MTK_MIXER].append(new BC_ListBoxItem(mixer_text)); + cols[MTK_TRACK].append(new BC_ListBoxItem(track->title)); +} + +void MixersAlignMTrackList::load_list() +{ + clear(); + for( int i=0,sz=dialog->mtracks.size(); imtracks[i]); +} + +void MixersAlignMTrackList::update() +{ + int xpos = get_xposition(), ypos = get_yposition(); + BC_ListBox::update(&cols[0], &col_titles[0],&col_widths[0],MTK_SZ, xpos,ypos); +} + + +MixersAlignATrack::MixersAlignATrack(Track *trk, int no) +{ + this->track = trk; + this->no = no; + this->nudge = 0; + mx = 0; mi = -1; +} + + +const char *MixersAlignATrackList::atk_titles[ATK_SZ] = { + N_("Track"), N_("Audio"), N_("Nudge"), N_("R"), N_("pos"), +}; + +int MixersAlignATrackList::atk_widths[ATK_SZ] = { + 40, 100, 60, 60, 60, +}; + +MixersAlignATrackList::MixersAlignATrackList(MixersAlignWindow *gui, + MixersAlign *dialog, int x, int y, int w, int h) + : BC_ListBox(x, y, w, h, LISTBOX_TEXT) +{ + set_selection_mode(LISTBOX_MULTIPLE); + this->dialog = dialog; + this->gui = gui; + for( int i=ATK_SZ; --i>=0; ) { + col_widths[i] = atk_widths[i]; + col_titles[i] = _(atk_titles[i]); + } +} + +MixersAlignATrackList::~MixersAlignATrackList() +{ + clear(); +} + +void MixersAlignATrackList::clear() +{ + for( int i=ATK_SZ; --i>=0; ) + cols[i].remove_all_objects(); +} + +void MixersAlignATrackList::add_atrack(MixersAlignATrack *atrack) +{ + char atrack_text[BCSTRLEN]; + Track *track = atrack->track; + int midx = -1, m = dialog->mixer_of(track, midx); + snprintf(atrack_text, sizeof(atrack_text), "%d/%d", atrack->no+1,m+1); + cols[ATK_TRACK].append(new BC_ListBoxItem(atrack_text)); + cols[ATK_AUDIO].append(new BC_ListBoxItem(track->title)); + char nudge_text[BCSTRLEN]; + sprintf(nudge_text, "%0.4f", atrack->nudge); + cols[ATK_NUDGE].append(new BC_ListBoxItem(nudge_text)); + char mx_text[BCSTRLEN]; + sprintf(mx_text, "%0.4f", atrack->mx); + cols[ATK_MX].append(new BC_ListBoxItem(mx_text)); + char mi_text[BCSTRLEN]; + sprintf(mi_text, "%jd", atrack->mi); + cols[ATK_MI].append(new BC_ListBoxItem(mi_text)); +} + + +void MixersAlignATrackList::load_list() +{ + clear(); + for( int i=0,sz=dialog->atracks.size(); iatracks[i]); +} + +void MixersAlignATrackList::update() +{ + int xpos = get_xposition(), ypos = get_yposition(); + BC_ListBox::update(&cols[0], &col_titles[0],&col_widths[0],ATK_SZ, xpos,ypos); +} + +int MixersAlignATrackList::selection_changed() +{ + int idx = get_buttonpress() == LEFT_BUTTON ? get_highlighted_item() : -1; + int m = idx >= 0 ? dialog->amixer_of(idx) : -1; + if( m >= 0 ) { + int sel = 0; + MixersAlignMixer *mix = dialog->mixers[m]; + for( int i=0; iatracks.size(); ++i ) { + int k = dialog->amixer_of(i); + if( k < 0 ) { set_selected(i, 0); continue; } + if( m != k ) continue; + MixersAlignATrack *atrk = dialog->atracks[i]; + if( atrk->mi < 0 ) continue; + int is_sel = is_selected(i); + set_selected(i, 0); + if( i != idx ) continue; + if( is_sel ) { + mix->aidx = idx; + mix->mx = atrk->mx; + mix->mi = atrk->mi; + mix->nudge = atrk->nudge; + sel = 1; + } + else { + mix->aidx = -1; + mix->mx = 0; + mix->mi = -1; + mix->nudge = 0; + } + } + if( sel ) + set_selected(idx, 1); + } + update(); + + gui->mixer_list->load_list(); + for( int i=0; iatracks.size(); ++i ) { + if( !is_selected(i) ) continue; + int m = dialog->amixer_of(i); + if( m < 0 ) continue; + gui->mixer_list->set_selected(m, 1); + } + gui->mixer_list->update(); + return 0; +} + +MixersAlignReset::MixersAlignReset(MixersAlignWindow *gui, + MixersAlign *dialog, int x, int y) + : BC_GenericButton(x, y, _("Reset")) +{ + this->gui = gui; + this->dialog = dialog; +} + +int MixersAlignReset::calculate_width(BC_WindowBase *gui) +{ + return BC_GenericButton::calculate_w(gui, _("Reset")); +} + +int MixersAlignReset::handle_event() +{ + dialog->load_mixers(); + dialog->load_mtracks(); + dialog->load_atracks(); + gui->load_lists(); + gui->default_selection(); + return 1; +} + +MixersAlignMatch::MixersAlignMatch(MixersAlignWindow *gui, + MixersAlign *dialog, int x, int y) + : BC_GenericButton(x, y, _("Match")) +{ + this->gui = gui; + this->dialog = dialog; +} + +int MixersAlignMatch::handle_event() +{ + if( !dialog->thread->running() ) { + gui->reset->disable(); + gui->match->disable(); + gui->apply->disable(); + gui->undo->disable(); + dialog->thread->start(); + } + return 1; +} + +MixersAlignApply::MixersAlignApply(MixersAlignWindow *gui, + MixersAlign *dialog, int x, int y) + : BC_GenericButton(x, y, _("Apply")) +{ + this->gui = gui; + this->dialog = dialog; +} + +int MixersAlignApply::calculate_width(BC_WindowBase *gui) +{ + return BC_GenericButton::calculate_w(gui, _("Apply")); +} + +int MixersAlignApply::handle_event() +{ + dialog->apply(); + return 1; +} + +MixersAlignUndo::MixersAlignUndo(MixersAlignWindow *gui, + MixersAlign *dialog, int x, int y) + : BC_GenericButton(x, y, _("Undo")) +{ + this->gui = gui; + this->dialog = dialog; +} + +int MixersAlignUndo::handle_event() +{ + MWindow *mwindow = dialog->mwindow; + mwindow->edl->copy_all(dialog->undo_edl); + mwindow->gui->lock_window("MixersAlignUndo::handle_event"); + mwindow->update_gui(1); + mwindow->gui->unlock_window(); + return gui->reset->handle_event(); +} + + +MixersAlignWindow::MixersAlignWindow(MixersAlign *dialog, int x, int y) + : BC_Window(_("Align Mixers"), x, y, 880, 380, 880, 380, 1) +{ + this->dialog = dialog; +} +MixersAlignWindow::~MixersAlignWindow() +{ +} + +void MixersAlignWindow::create_objects() +{ + int x = 10, y = 10, w4 = (get_w()-x-10)/4, lw = w4 + 20; + int x1 = x, x2 = x1 + lw , x3 = x2 + lw, x4 = get_w()-x; + mixer_title = new BC_Title(x1,y, _("Mixers:"), MEDIUMFONT, YELLOW); + add_subwindow(mixer_title); + mtrack_title = new BC_Title(x2,y, _("Master Track:"), MEDIUMFONT, YELLOW); + add_subwindow(mtrack_title); + atrack_title = new BC_Title(x3,y, _("Audio Tracks:"), MEDIUMFONT, YELLOW); + add_subwindow(atrack_title); + y += mixer_title->get_h() + 10; + int y1 = y, y2 = get_h() - BC_OKButton::calculate_h() - 15; + int lh = y2 - y1; + mixer_list = new MixersAlignMixerList(this, dialog, x1, y, x2-x1-20, lh); + add_subwindow(mixer_list); + mtrack_list = new MixersAlignMTrackList(this, dialog, x2, y, x3-x2-20, lh); + add_subwindow(mtrack_list); + atrack_list = new MixersAlignATrackList(this, dialog, x3, y, x4-x3-20, lh); + add_subwindow(atrack_list); + int xr = x2-10 - MixersAlignReset::calculate_width(this); + add_subwindow(reset = new MixersAlignReset(this, dialog, xr, y2+20)); + add_subwindow(match = new MixersAlignMatch(this, dialog, x2+10, y2+20)); + int xa = x3-10 - MixersAlignApply::calculate_width(this); + add_subwindow(apply = new MixersAlignApply(this, dialog, xa, y2+20)); + add_subwindow(undo = new MixersAlignUndo(this, dialog, x3+10, y2+20)); + + add_subwindow(new BC_OKButton(this)); + add_subwindow(new BC_CancelButton(this)); +} + +int MixersAlignWindow::resize_event(int w, int h) +{ + int x = 10, y = 10, w4 = (w-x-10)/4, lw = w4 + 20; + int x1 = x, x2 = x1 + lw , x3 = x2 + lw, x4 = w-x; + mixer_title->reposition_window(x1, y); + mtrack_title->reposition_window(x2, y); + atrack_title->reposition_window(x3, y); + y += mixer_title->get_h() + 10; + int y1 = y, y2 = h - BC_OKButton::calculate_h() - 15; + int lh = y2 - y1; + mixer_list->reposition_window(x1, y, x2-x1-20, lh); + mtrack_list->reposition_window(x2, y, x3-x2-20, lh); + atrack_list->reposition_window(x3, y, x4-x3-20, lh); + int xr = x2-10 - MixersAlignReset::calculate_width(this); + reset->reposition_window(xr, y2+20); + match->reposition_window(x2+10, y2+20); + int xa = x3-10 - MixersAlignApply::calculate_width(this); + apply->reposition_window(xa, y2+20); + undo->reposition_window(x3+10, y2+20); + return 0; +} + +void MixersAlignWindow::load_lists() +{ + mixer_list->load_list(); + mtrack_list->load_list(); + atrack_list->load_list(); +} + +void MixersAlignWindow::default_selection() +{ +// mixers selects all mixers + mixer_list->set_all_selected(1); +// master selects first mixer audio track + for( int i=0; imtracks.size(); ++i ) { + if( dialog->mmixer_of(i) >= 0 ) { + mtrack_list->set_selected(i, 1); + break; + } + } +// audio selects all mixer audio tracks + for( int i=0; iatracks.size(); ++i ) { + if( dialog->amixer_of(i) >= 0 ) + atrack_list->set_selected(i, 1); + } + update_gui(); +} + +void MixersAlignWindow::update_gui() +{ + mixer_list->update(); + mtrack_list->update(); + atrack_list->update(); +} + + +MixersAlign::MixersAlign(MWindow *mwindow) +{ + this->mwindow = mwindow; + this->ma_gui = 0; + farming = new Mutex("MixersAlign::farming"); + total_lock = new Mutex("MixersAlign::total_lock"); + thread = new MixersAlignThread(this); + total_rendered = 0; + master_r = 0; + master_i = 0; + master_len = 0; + progress = 0; + failed = 0; + undo_edl = 0; + master_start = master_end = 0; + audio_start = audio_end = 0; +} + +MixersAlign::~MixersAlign() +{ + failed = -1; + farming->lock("MixersAlign::~MixersAlign"); + close_window(); + delete farming; + delete thread; + delete total_lock; + delete progress; + delete [] master_r; + delete [] master_i; +} + +void MixersAlign::start_dialog(int wx, int wy) +{ + this->wx = wx; + this->wy = wy; + this->undo_edl = new EDL(); + undo_edl->create_objects(); + undo_edl->copy_all(mwindow->edl); + start(); +} + +BC_Window *MixersAlign::new_gui() +{ + load_mixers(); + load_mtracks(); + load_atracks(); + ma_gui = new MixersAlignWindow(this, wx, wy); + ma_gui->lock_window("MixersAlign::new_gui"); + ma_gui->create_objects(); + ma_gui->load_lists(); + ma_gui->default_selection(); + ma_gui->show_window(1); + ma_gui->unlock_window(); + return ma_gui; +} + +void MixersAlign::apply() +{ + int idx = ma_gui->mtrack_list->get_selection_number(0, 0); + int midx = -1, mid = mixer_of(mtracks[idx]->track, midx); + + for( int m, i=0; (m=ma_gui->mixer_list->get_selection_number(0,i))>=0; ++i ) { + if( m == mid ) continue; // master does not move + MixersAlignMixer *mix = mixers[m]; + Mixer *mixer = mix->mixer; + for( int i=0; imixer_ids.size(); ++i ) { + int id = mixer->mixer_ids[i]; + Track *track = mwindow->edl->tracks->first; + while( track && track->mixer_id != id ) track = track->next; + if( !track ) continue; + int64_t dt = track->to_units(mix->nudge, 0); + for( Edit *edit=track->edits->first; edit; edit=edit->next ) + edit->startproject += dt; + track->optimize(); + } + } + + mwindow->gui->lock_window("MixersAlign::handle_done_event"); + mwindow->update_gui(1); + mwindow->gui->unlock_window(); +} + + +MixersAlignThread::MixersAlignThread(MixersAlign *dialog) + : Thread(1, 0, 0) +{ + this->dialog = dialog; +} +MixersAlignThread::~MixersAlignThread() +{ + join(); +} + +void MixersAlignThread::run() +{ + dialog->update_match(); + MixersAlignWindow *ma_gui = dialog->ma_gui; + ma_gui->lock_window("MixersAlignThread::run"); + ma_gui->reset->enable(); + ma_gui->match->enable(); + ma_gui->apply->enable(); + ma_gui->undo->enable(); + ma_gui->unlock_window(); +} + + +void MixersAlign::handle_done_event(int result) +{ + if( !result ) { + EDL *edl = mwindow->edl; + mwindow->edl = undo_edl; + mwindow->undo_before(); + mwindow->edl = edl; + mwindow->undo_after(_("align mixers"), LOAD_ALL); + } + else if( thread->running() ) { + failed = -1; + thread->join(); + } +} + +void MixersAlign::handle_close_event(int result) +{ + undo_edl->remove_user(); + undo_edl = 0; + ma_gui = 0; +} + +void MixersAlign::load_mixers() +{ + mixers.remove_all_objects(); + Mixers &edl_mixers = mwindow->edl->mixers; + for( int i=0; iedl->tracks->first; + for( int no=0; track; ++no, track=track->next ) { + if( track->data_type != TRACK_AUDIO ) continue; + mtracks.append(new MixersAlignMTrack(track, no)); + } +} + +void MixersAlign::load_atracks() +{ + atracks.remove_all_objects(); + Track *track=mwindow->edl->tracks->first; + for( int no=0; track; ++no, track=track->next ) { + if( track->data_type != TRACK_AUDIO ) continue; + if( mixer_of(track) < 0 ) continue; + atracks.append(new MixersAlignATrack(track, no)); + } +} + + +int MixersAlign::mixer_of(Track *track, int &midx) +{ + int id = track->mixer_id, k = mixers.size(), idx = -1; + while( idx < 0 && --k >= 0 ) + idx = mixers[k]->mixer->mixer_ids.number_of(id); + midx = idx; + return k; +} + +EDL *MixersAlign::mixer_audio_clip(Mixer *mixer) +{ + EDL *edl = new EDL(mwindow->edl); + edl->create_objects(); + Track *track = mwindow->edl->tracks->first; + for( ; track; track=track->next ) { + int id = track->mixer_id; + if( track->data_type != TRACK_AUDIO ) continue; + if( mixer->mixer_ids.number_of(id) < 0 ) continue; + Track *mixer_audio = edl->tracks->add_audio_track(0, 0); + mixer_audio->copy_from(track); + mixer_audio->play = 1; + } + return edl; +} + +EDL *MixersAlign::mixer_master_clip(Track *track) +{ + EDL *edl = new EDL(mwindow->edl); + edl->create_objects(); + Track *master_audio = edl->tracks->add_audio_track(0, 0); + master_audio->copy_from(track); + master_audio->play = 1; + return edl; +} + +int64_t MixersAlign::mixer_tracks_total() +{ + int64_t total_len = 0; + int64_t sample_rate = mwindow->edl->get_sample_rate(); + int m = -1, idx = 0; + for( ; (m=ma_gui->mixer_list->get_selection_number(0, idx))>=0 ; ++idx ) { + Mixer *mixer = mixers[m]->mixer; + double render_end = 0; + Track *track = mwindow->edl->tracks->first; + for( ; track; track=track->next ) { + int id = track->mixer_id; + if( track->data_type != TRACK_AUDIO ) continue; + if( mixer->mixer_ids.number_of(id) < 0 ) continue; + double track_end = track->get_length(); + if( render_end < track_end ) render_end = track_end; + } + if( render_end > audio_end ) render_end = audio_end; + double len = render_end - audio_start; + if( len > 0 ) total_len += len * sample_rate; + } + return total_len; +} + +MixersAlignARender::MixersAlignARender(MWindow *mwindow, EDL *edl) + : RenderEngine(0, mwindow->preferences, 0, 0) +{ + TransportCommand command; + command.command = NORMAL_FWD; + command.get_edl()->copy_all(edl); + command.change_type = CHANGE_ALL; + command.realtime = 0; + set_vcache(mwindow->video_cache); + set_acache(mwindow->audio_cache); + arm_command(&command); +} + +MixersAlignARender::~MixersAlignARender() +{ +} + +int MixersAlignARender::render(Samples **samples, int64_t len, int64_t pos) +{ + return arender ? arender->process_buffer(samples, len, pos) : -1; +} + +MixersAlignPackage::MixersAlignPackage() +{ + mixer = 0; +} + +MixersAlignPackage::~MixersAlignPackage() +{ +} + +MixersAlignFarm::MixersAlignFarm(MixersAlign *dialog, int n) + : LoadServer(bmin(dialog->mwindow->preferences->processors, n), n) +{ + this->dialog = dialog; + dialog->farming->lock("MixersAlignFarm::MixersAlignFarm"); +} +MixersAlignFarm::~MixersAlignFarm() +{ + dialog->farming->unlock(); +} + +LoadPackage* MixersAlignFarm::new_package() +{ + return new MixersAlignPackage(); +} + +void MixersAlignFarm::init_packages() +{ + for( int i = 0; i < get_total_packages(); ++i ) { + int m = dialog->ma_gui->mixer_list->get_selection_number(0, i); + MixersAlignPackage *package = (MixersAlignPackage *)get_package(i); + package->mixer = dialog->mixers[m]; + } +} + +LoadClient* MixersAlignFarm::new_client() +{ + return new MixersAlignClient(this); +} + +MixersAlignClient::MixersAlignClient(MixersAlignFarm *farm) + : LoadClient(farm) +{ +} + +MixersAlignClient::~MixersAlignClient() +{ +} + +void MixersAlignClient::process_package(LoadPackage *pkg) +{ + MixersAlignFarm *farm = (MixersAlignFarm *)server; + MixersAlign *dialog = farm->dialog; + MixersAlignPackage *package = (MixersAlignPackage *)pkg; + dialog->process_package(farm, package); +} + +static inline void conj_product(int n, double *rp, double *ip, + double *arp, double *aip, double *brp, double *bip) +{ + for( int i=0; iis_cancelled() ) failed = -1; + if( failed ) return; + MixersAlignMixer *amix = package->mixer; + EDL *edl = mixer_audio_clip(amix->mixer); + + MixersAlignARender audio(mwindow, edl); + int sample_rate = edl->get_sample_rate(); + int channels = edl->get_audio_channels(); + int64_t audio_samples = edl->get_audio_samples(); + int64_t cur_pos = audio_start * sample_rate; + int64_t end_pos = audio_end * sample_rate; + if( end_pos > audio_samples ) end_pos = audio_samples; + int len = master_len, len2 = len/2; + double *audio_r = new double[len]; + double *audio_i = new double[len]; + Samples *samples[2][MAX_CHANNELS]; + for( int k=0; k<2; ++k ) { + for( int i=0; i end_pos ) nxt_pos = end_pos; + int len1 = nxt_pos - cur_pos; + int ret = audio.render(samples[k], len1, cur_pos); + while( !ret && !failed && cur_pos < end_pos ) { + update_progress(len1); + int64_t pos = cur_pos; + cur_pos = nxt_pos; nxt_pos += len2; + if( nxt_pos > end_pos ) nxt_pos = end_pos; + len1 = nxt_pos - cur_pos; + ret = audio.render(samples[1-k], len1, cur_pos); + if( ret ) break; + Track *track = edl->tracks->first; + for( int ch=0; chnext ) { + int id = track->mixer_id, atk = atracks.size(); + while( --atk >= 0 && id != atracks[atk]->track->mixer_id ); + if( atk < 0 ) continue; + int i = 0; + double *lp = samples[k][ch]->get_data(); + for( int j=0; jget_data(); + for( int j=0; jmx < mx ) { + atrack->mx = mx; + atrack->mi = mi; + } + } + k = 1-k; + if( progress->is_cancelled() ) failed = -1; + } + if( ret && !failed ) { + eprintf("Audio render failed:\n%s", edl->path); + failed = 1; + } + delete [] audio_r; + delete [] audio_i; + for( int k=0; k<2; ++k ) { + for( int i=channels; --i>=0; ) + delete samples[k][i]; + } + edl->remove_user(); +} + + +void MixersAlign::update_progress(int64_t len) +{ + total_lock->lock(); + total_rendered += len; + total_lock->unlock(); + progress->update(total_rendered); +} + +static inline uint64_t high_bit_mask(uint64_t n) +{ + n |= n >> 1; n |= n >> 2; + n |= n >> 4; n |= n >> 8; + n |= n >> 16; n |= n >> 32; + return n; +} + +void MixersAlign::load_master_audio(Track *track) +{ + EDL *edl = mixer_master_clip(track); + MixersAlignARender audio(mwindow, edl); + int sample_rate = edl->get_sample_rate(); + int channels = edl->get_audio_channels(); + int64_t audio_samples = edl->get_audio_samples(); + int64_t cur_pos = master_start * sample_rate; + int64_t end_pos = master_end * sample_rate; + if( end_pos > audio_samples ) end_pos = audio_samples; + if( cur_pos >= end_pos ) { + eprintf(_("master audio track empty")); + failed = 1; + return; + } + int64_t audio_len = end_pos - cur_pos; + if( audio_len > sample_rate * 60 ) { + eprintf(_("master audio track length > 60 seconds")); + failed = 1; + return; + } + int64_t fft_len = (high_bit_mask(audio_len)+1) << 1; + if( master_len != fft_len ) { + master_len = fft_len; + delete [] master_r; master_r = new double[master_len]; + delete [] master_i; master_i = new double[master_len]; + } + { Samples *samples[MAX_CHANNELS]; + for( int i=0; iremove_user(); + double *dp = samples[0]->get_data(); + int i = 0; double ss = 0; + for( ; i=0; ) + delete samples[i]; + } + do_fft(fft_len, 0, master_r, 0, master_r, master_i); +} + +void MixersAlign::scan_mixer_audio() +{ + for( int i=0; iaidx = -1; + int n = 0; + while( ma_gui->mixer_list->get_selection_number(0, n) >= 0 ) ++n; + if( !n ) { + eprintf(_("no mixers selected")); + return; + } + + Timer timer; + total_rendered = 0; + MixersAlignFarm farm(this, n); + int64_t total_len = mixer_tracks_total(); + mwindow->gui->lock_window("MixersAlign::scan_mixer_audio"); + progress = mwindow->mainprogress-> + start_progress(_("Render mixer audio"), total_len); + mwindow->gui->unlock_window(); + + farm.process_packages(); + if( progress->is_cancelled() ) failed = -1; + + char text[BCSTRLEN]; + double secs = timer.get_difference()/1000.; + sprintf(text, _("Render mixer done: %0.3f secs"), secs); + mwindow->gui->lock_window("MixersAlign::scan_mixer_audio"); + progress->update(0); + mwindow->mainprogress->end_progress(progress); + progress = 0; + mwindow->gui->show_message(text); + mwindow->gui->unlock_window(); +} + +void MixersAlign::update_match() +{ + int midx = ma_gui->mtrack_list->get_selection_number(0, 0); + if( midx < 0 ) { + eprintf(_("selection (master) not set")); + return; + } + master_start = mwindow->edl->local_session->get_inpoint(); + if( master_start < 0 ) { + eprintf(_("in point selection (master start) must be set")); + return; + } + master_end = mwindow->edl->local_session->get_outpoint(); + if( master_end < 0 ) { + eprintf(_("out point selection (master end) must be set")); + return; + } + if( master_start >= master_end ) { + eprintf(_("in/out point selection (master start/end) invalid")); + return; + } + audio_start = mwindow->edl->local_session->get_selectionstart(); + audio_end = mwindow->edl->local_session->get_selectionend(); + if( audio_start >= audio_end ) { + eprintf(_("selection (audio start/end) invalid")); + return; + } + + failed = 0; + if( !failed ) load_master_audio(mtracks[midx]->track); + if( !failed ) scan_mixer_audio(); + if( !failed ) update(); + if( failed < 0 ) { + mwindow->gui->lock_window("MixersAlign::update_match"); + mwindow->gui->show_message(_("mixer selection match canceled")); + mwindow->gui->unlock_window(); + } + else if( failed > 0 ) + eprintf(_("Error in match render.")); +} + +void MixersAlign::update() +{ +// mixer best matches + for( int m=0; mmixer; + mix->mx = 0; mix->mi = -1; mix->aidx = -1; + for( int i=0; imixer_ids.size(); ++i ) { + int id = mixer->mixer_ids[i], k = atracks.size(); + while( --k >= 0 && atracks[k]->track->mixer_id != id ); + if( k < 0 ) continue; + MixersAlignATrack *atrk = atracks[k]; + atrk->nudge = atrk->mi < 0 ? 0 : + master_start - atrk->track->from_units(atrk->mi); + if( mix->mx >= atrk->mx ) continue; + mix->aidx = k; + mix->mx = atrk->mx; + mix->mi = atrk->mi; + mix->nudge = atrk->nudge; + } + } + + ma_gui->lock_window("MixersAlign::update"); + ma_gui->mixer_list->load_list(); + ma_gui->mixer_list->set_all_selected(1); + ma_gui->mixer_list->update(); + + ma_gui->atrack_list->load_list(); + for( int m=0; maidx; + if( aidx >= 0 ) ma_gui->atrack_list->set_selected(aidx, 1); + } + ma_gui->atrack_list->update(); + ma_gui->unlock_window(); +} + diff --git a/cinelerra-5.1/cinelerra/mixersalign.h b/cinelerra-5.1/cinelerra/mixersalign.h new file mode 100644 index 00000000..86abbe6e --- /dev/null +++ b/cinelerra-5.1/cinelerra/mixersalign.h @@ -0,0 +1,348 @@ +/* + * CINELERRA + * Copyright (C) 2008-2015 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __MIXERSALIGN_H__ +#define __MIXERSALIGN_H__ + +#include "edl.inc" +#include "fourier.h" +#include "guicast.h" +#include "language.h" +#include "loadbalance.h" +#include "mainprogress.inc" +#include "mixersalign.inc" +#include "mwindow.inc" +#include "renderengine.h" +#include "samples.inc" +#include "track.inc" +#include "zwindow.inc" + +class MixersAlignMixer +{ +public: + MixersAlignMixer(Mixer *mix); + Mixer *mixer; + double nudge; + double mx; + int64_t mi; + int aidx; +}; + +class MixersAlignMixers : public ArrayList +{ +public: + MixersAlignMixers() {} + ~MixersAlignMixers() { remove_all_objects(); } +}; + +class MixersAlignMixerList : public BC_ListBox +{ + enum { MIX_MIXER, MIX_NUDGE, MIX_SZ }; + static const char *mix_titles[MIX_SZ]; + static int mix_widths[MIX_SZ]; +public: + MixersAlignMixerList(MixersAlignWindow *gui, + MixersAlign *dialog, int x, int y, int w, int h); + ~MixersAlignMixerList(); + + void clear(); + + void add_mixer(MixersAlignMixer *mixer); + void load_list(); + void update(); + int selection_changed(); + + MixersAlignWindow *gui; + MixersAlign *dialog; + MixersAlignMixers mixers; + + const char *col_titles[MIX_SZ]; + int col_widths[MIX_SZ]; + ArrayList cols[MIX_SZ]; + + void set_all_selected(int v) { BC_ListBox::set_all_selected(cols, v); } + void set_selected(int idx, int v) { BC_ListBox::set_selected(cols, idx, v); } + bool is_selected(int idx) { return cols[0][idx]->get_selected() != 0; } +}; + + +class MixersAlignMTrack +{ +public: + MixersAlignMTrack(Track *trk, int no); + + Track *track; + int no; +}; + +class MixersAlignMTracks : public ArrayList +{ +public: + MixersAlignMTracks() {} + ~MixersAlignMTracks() { remove_all_objects(); } +}; + + +class MixersAlignMTrackList : public BC_ListBox +{ + enum { MTK_NO, MTK_MIXER, MTK_TRACK, MTK_SZ }; + static const char *mtk_titles[MTK_SZ]; + static int mtk_widths[MTK_SZ]; +public: + MixersAlignMTrackList(MixersAlignWindow *gui, + MixersAlign *dialog, int x, int y, int w, int h); + ~MixersAlignMTrackList(); + + void clear(); + void add_mtrack(MixersAlignMTrack *mtrk); + void load_list(); + void update(); + + MixersAlignWindow *gui; + MixersAlign *dialog; + + ArrayList cols[MTK_SZ]; + const char *col_titles[MTK_SZ]; + int col_widths[MTK_SZ]; + + void set_all_selected(int v) { BC_ListBox::set_all_selected(cols, v); } + void set_selected(int idx, int v) { BC_ListBox::set_selected(cols, idx, v); } + bool is_selected(int idx) { return cols[0][idx]->get_selected() != 0; } +}; + + +class MixersAlignATrack +{ +public: + MixersAlignATrack(Track *trk, int no); + Track *track; + int no; + double nudge; + double mx; + int64_t mi; +}; + +class MixersAlignATracks : public ArrayList +{ +public: + MixersAlignATracks() {} + ~MixersAlignATracks() { remove_all_objects(); } +}; + +class MixersAlignATrackList : public BC_ListBox +{ + enum { ATK_TRACK, ATK_AUDIO, ATK_NUDGE, ATK_MX, ATK_MI, ATK_SZ }; + static const char *atk_titles[ATK_SZ]; + static int atk_widths[ATK_SZ]; +public: + MixersAlignATrackList(MixersAlignWindow *gui, + MixersAlign *dialog, int x, int y, int w, int h); + ~MixersAlignATrackList(); + + void clear(); + void add_atrack(MixersAlignATrack *track); + void load_list(); + void update(); + int selection_changed(); + + MixersAlignWindow *gui; + MixersAlign *dialog; + + ArrayList cols[ATK_SZ]; + const char *col_titles[ATK_SZ]; + int col_widths[ATK_SZ]; + + void set_all_selected(int v) { BC_ListBox::set_all_selected(cols, v); } + void set_selected(int idx, int v) { BC_ListBox::set_selected(cols, idx, v); } + bool is_selected(int idx) { return cols[0][idx]->get_selected() != 0; } +}; + +class MixersAlignReset : public BC_GenericButton +{ +public: + MixersAlignReset(MixersAlignWindow *gui, MixersAlign *dialog, int x, int y); + int handle_event(); + static int calculate_width(BC_WindowBase *gui); + + MixersAlign *dialog; + MixersAlignWindow *gui; +}; + +class MixersAlignThread : public Thread +{ +public: + MixersAlignThread(MixersAlign *dialog); + ~MixersAlignThread(); + void run(); + + MixersAlign *dialog; +}; + +class MixersAlignMatch : public BC_GenericButton +{ +public: + MixersAlignMatch(MixersAlignWindow *gui, MixersAlign *dialog, int x, int y); + int handle_event(); + + MixersAlign *dialog; + MixersAlignWindow *gui; +}; + +class MixersAlignApply : public BC_GenericButton +{ +public: + MixersAlignApply(MixersAlignWindow *gui, MixersAlign *dialog, int x, int y); + int handle_event(); + static int calculate_width(BC_WindowBase *gui); + + MixersAlign *dialog; + MixersAlignWindow *gui; +}; + +class MixersAlignUndo : public BC_GenericButton +{ +public: + MixersAlignUndo(MixersAlignWindow *gui, MixersAlign *dialog, int x, int y); + int handle_event(); + + MixersAlign *dialog; + MixersAlignWindow *gui; +}; + + +class MixersAlignWindow : public BC_Window +{ +public: + MixersAlignWindow(MixersAlign *dialog, int x, int y); + ~MixersAlignWindow(); + + void create_objects(); + int resize_event(int w, int h); + void load_lists(); + void default_selection(); + void update_gui(); + + MixersAlign *dialog; + BC_Title *mixer_title, *mtrack_title, *atrack_title; + + MixersAlignMixerList *mixer_list; + MixersAlignMTrackList *mtrack_list; + MixersAlignATrackList *atrack_list; + MixersAlignMatch *match; + MixersAlignReset *reset; + MixersAlignApply *apply; + MixersAlignUndo *undo; +}; + + +class MixersAlignARender : public RenderEngine +{ +public: + MixersAlignARender(MWindow *mwindow, EDL *edl); + ~MixersAlignARender(); + + int render(Samples **samples, int64_t len, int64_t pos); +}; + +class MixersAlignPackage : public LoadPackage +{ +public: + MixersAlignPackage(); + ~MixersAlignPackage(); + + MixersAlignMixer *mixer; +}; + +class MixersAlignClient : public LoadClient +{ +public: + MixersAlignClient(MixersAlignFarm *farm); + ~MixersAlignClient(); + + void process_package(LoadPackage *pkg); +}; + +class MixersAlignFarm : public LoadServer +{ +public: + MixersAlignFarm(MixersAlign *dialog, int n); + ~MixersAlignFarm(); + void init_packages(); + LoadClient *new_client(); + LoadPackage *new_package(); + + MixersAlign *dialog; +}; + +class MixersAlign : public BC_DialogThread, public FFT +{ +public: + MixersAlign(MWindow *mwindow); + ~MixersAlign(); + + void start_dialog(int wx, int wy); + BC_Window *new_gui(); + void load_mixers(); + void load_mtracks(); + void load_atracks(); + void handle_done_event(int result); + void handle_close_event(int result); + + int mixer_of(Track *track, int &midx); + int mixer_of(Track *track) { int midx = -1; return mixer_of(track, midx); } + int mmixer_of(int mi) { + return mi>=0 && mitrack) : -1; + } + int amixer_of(int ai) { + return ai>=0 && aitrack) : -1; + } + + EDL *mixer_audio_clip(Mixer *mixer); + EDL *mixer_master_clip(Track *track); + int64_t mixer_tracks_total(); + void load_master_audio(Track *track); + void scan_mixer_audio(); + void update_progress(int64_t len); + void update_match(); + void update(); + void process_package(MixersAlignFarm *farm, MixersAlignPackage *package); + void apply(); + + MixersAlignWindow *ma_gui; + int wx, wy; + MixersAlignMixers mixers; + MixersAlignMTracks mtracks; + MixersAlignATracks atracks; + MWindow *mwindow; + + EDL *undo_edl; + Mutex *farming; + MainProgressBar *progress; + MixersAlignThread *thread; + Mutex *total_lock; + int64_t total_rendered; + int failed; + int64_t master_len; + double *master_r, *master_i; + double master_start, master_end, master_ss; + double audio_start, audio_end; +}; + +#endif diff --git a/cinelerra-5.1/cinelerra/mixersalign.inc b/cinelerra-5.1/cinelerra/mixersalign.inc new file mode 100644 index 00000000..7e17048a --- /dev/null +++ b/cinelerra-5.1/cinelerra/mixersalign.inc @@ -0,0 +1,20 @@ +#ifndef __MIXERSALIGN_INC__ +#define __MIXERSALIGN_INC__ + +class MixersAlignMixer; +class MixersAlignMixers; +class MixersAlignMixerList; +class MixersAlignMTrack; +class MixersAlignMTracks; +class MixersAlignMTrackList; +class MixersAlignATrack; +class MixersAlignATracks; +class MixersAlignATrackList; +class MixersAlignWindow; +class MixersAlignARender; +class MixersAlignPackage; +class MixersAlignClient; +class MixersAlignFarm; +class MixersAlign; + +#endif diff --git a/cinelerra-5.1/cinelerra/mwindow.C b/cinelerra-5.1/cinelerra/mwindow.C index da6056d9..9a49f178 100644 --- a/cinelerra-5.1/cinelerra/mwindow.C +++ b/cinelerra-5.1/cinelerra/mwindow.C @@ -80,6 +80,7 @@ #include "mainsession.h" #include "mainundo.h" #include "mbuttons.h" +#include "mixersalign.h" #include "mutex.h" #include "mwindowgui.h" #include "mwindow.h" @@ -240,6 +241,7 @@ MWindow::MWindow() speed_edl = 0; proxy_beep = 0; shuttle = 0; + mixers_align = 0; } @@ -264,6 +266,7 @@ MWindow::~MWindow() delete shuttle; shuttle = 0; delete batch_render; batch_render = 0; delete render; render = 0; + delete mixers_align; mixers_align = 0; commit_commercial(); if( commercials && !commercials->remove_user() ) commercials = 0; close_mixers(); @@ -1549,6 +1552,8 @@ void MWindow::init_menus() ILACEFIXMETHODLISTADD(ILACE_FIXMETHOD_NONE); ILACEFIXMETHODLISTADD(ILACE_FIXMETHOD_UPONE); ILACEFIXMETHODLISTADD(ILACE_FIXMETHOD_DOWNONE); + + mixers_align = new MixersAlign(this); } void MWindow::init_indexes() diff --git a/cinelerra-5.1/cinelerra/mwindow.h b/cinelerra-5.1/cinelerra/mwindow.h index 3add4e79..0331d5c6 100644 --- a/cinelerra-5.1/cinelerra/mwindow.h +++ b/cinelerra-5.1/cinelerra/mwindow.h @@ -62,6 +62,7 @@ #include "mainsession.inc" #include "mainundo.inc" #include "maxchannels.h" +#include "mixersalign.inc" #include "mutex.inc" #include "mwindow.inc" #include "mwindowgui.inc" @@ -227,7 +228,6 @@ public: void start_mixer(); int select_zwindow(ZWindow *zwindow); void tile_mixers(); - int load_filenames(ArrayList *filenames, int load_mode = LOADMODE_REPLACE, // Cause the project filename on the top of the window to be updated. @@ -635,6 +635,8 @@ public: // Mixer Mutex *zwindows_lock; ArrayList zwindows; + MixersAlign *mixers_align; + // Asset manager AWindow *awindow; // Automation window diff --git a/cinelerra-5.1/cinelerra/track.C b/cinelerra-5.1/cinelerra/track.C index 6bebe819..b5382c33 100644 --- a/cinelerra-5.1/cinelerra/track.C +++ b/cinelerra-5.1/cinelerra/track.C @@ -850,46 +850,22 @@ void Track::synchronize_params(Track *track) } - - - int Track::dump(FILE *fp) { - fprintf(fp," Data type %d\n", data_type); + fprintf(fp," Data type %d, draw %d, gang %d, play %d, record %d, nudge %jd\n", + data_type, draw, gang, play, record, nudge); fprintf(fp," Title %s\n", title); fprintf(fp," Edits:\n"); for(Edit* current = edits->first; current; current = NEXT) - { current->dump(fp); - } automation->dump(fp); fprintf(fp," Plugin Sets: %d\n", plugin_set.total); - for(int i = 0; i < plugin_set.total; i++) - plugin_set.values[i]->dump(fp); -//printf("Track::dump 2\n"); + for( int i=0; idump(fp); return 0; } - - - - - - - - - - - - - - - - - - - Track::Track() : ListItem() { diff --git a/cinelerra-5.1/cinelerra/zwindow.C b/cinelerra-5.1/cinelerra/zwindow.C index a6f6d73f..65c3f31c 100644 --- a/cinelerra-5.1/cinelerra/zwindow.C +++ b/cinelerra-5.1/cinelerra/zwindow.C @@ -219,8 +219,7 @@ void ZWindow::handle_close_event(int result) void ZWindow::change_source(EDL *edl) { if( this->edl == edl ) return; - if( !edl || !this->edl || this->edl->equivalent_output(edl) >= 0 ) - zgui->playback_engine->refresh_frame(CHANGE_ALL, edl); + zgui->playback_engine->refresh_frame(CHANGE_ALL, edl); if( this->edl ) this->edl->remove_user(); this->edl = edl; diff --git a/cinelerra-5.1/plugins/sketcher/sketcherwindow.h b/cinelerra-5.1/plugins/sketcher/sketcherwindow.h index 5b4d8cce..6e388a02 100644 --- a/cinelerra-5.1/plugins/sketcher/sketcherwindow.h +++ b/cinelerra-5.1/plugins/sketcher/sketcherwindow.h @@ -18,8 +18,8 @@ * */ -#ifndef __CRIKEYWINDOW_H__ -#define __CRIKEYWINDOW_H__ +#ifndef __SKETCHERWINDOW_H__ +#define __SKETCHERWINDOW_H__ #include "sketcher.h" #include "guicast.h"