From 0b739fcb7662fb7a99011b8845bdf05bbcc6d868 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sun, 8 Jul 2018 12:19:07 +0100 Subject: [PATCH] fixed #95 and added minimal support for #66 --- effects/transition.cpp | 17 +++ effects/transition.h | 4 + io/media.h | 1 + mainwindow.cpp | 20 ++-- mainwindow.h | 2 + mainwindow.ui | 19 ++- olive.pro | 6 +- olive.pro.user | 2 +- panels/project.cpp | 13 +++ panels/timeline.cpp | 38 ++++-- panels/timeline.h | 1 + panels/timeline.ui | 18 ++- playback/audio.cpp | 2 +- playback/playback.cpp | 8 +- ui/timelinewidget.cpp | 255 +++++++++++++++++++---------------------- ui/timelinewidget.h | 4 +- ui/viewerwidget.cpp | 16 ++- 17 files changed, 261 insertions(+), 165 deletions(-) diff --git a/effects/transition.cpp b/effects/transition.cpp index ade3d2525..eaca658a0 100644 --- a/effects/transition.cpp +++ b/effects/transition.cpp @@ -1,5 +1,9 @@ #include "transition.h" +#include "project/clip.h" + +#include + Transition::Transition() { length = 30; link = NULL; @@ -10,3 +14,16 @@ Transition* Transition::copy() { } void Transition::process_transition(float) {} + +Transition* create_transition(int transition_id, Clip* c) { + if (c->track < 0) { + switch (transition_id) { + case VIDEO_DISSOLVE_TRANSITION: return new CrossDissolveTransition(); + } + } else { + switch (transition_id) { + } + } + qDebug() << "[ERROR] Invalid transition ID"; + return NULL; +} diff --git a/effects/transition.h b/effects/transition.h index 3473198d8..696133955 100644 --- a/effects/transition.h +++ b/effects/transition.h @@ -3,6 +3,8 @@ #include +struct Clip; + enum VideoTransitions { VIDEO_DISSOLVE_TRANSITION, VIDEO_TRANSITION_COUNT @@ -32,4 +34,6 @@ public: Transition* copy(); }; +Transition* create_transition(int transition_id, Clip* c); + #endif // TRANSITION_H diff --git a/io/media.h b/io/media.h index 458de3315..26c34c7fe 100644 --- a/io/media.h +++ b/io/media.h @@ -11,6 +11,7 @@ #define MEDIA_TYPE_FOOTAGE 0 #define MEDIA_TYPE_SEQUENCE 1 #define MEDIA_TYPE_FOLDER 2 +#define MEDIA_TYPE_SOLID 3 struct Sequence; diff --git a/mainwindow.cpp b/mainwindow.cpp index ca4f53b89..4442c39c3 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,4 +1,4 @@ -#include "mainwindow.h" +#include "mainwindow.h" #include "ui_mainwindow.h" #include "io/config.h" @@ -273,6 +273,9 @@ void MainWindow::autorecover_interval() { bool MainWindow::save_project_as() { QString fn = QFileDialog::getSaveFileName(this, "Save Project As...", "", OLIVE_FILE_FILTER); if (!fn.isEmpty()) { + if (!fn.endsWith(".ove", Qt::CaseInsensitive)) { + fn += ".ove"; + } project_url = fn; panel_project->save_project(); return true; @@ -308,12 +311,10 @@ void MainWindow::on_action_Save_Project_triggered() void MainWindow::on_action_Open_Project_triggered() { - if (can_close_project()) { - QString fn = QFileDialog::getOpenFileName(this, "Open Project...", "", OLIVE_FILE_FILTER); - if (!fn.isEmpty()) { - project_url = fn; - panel_project->load_project(); - } + QString fn = QFileDialog::getOpenFileName(this, "Open Project...", "", OLIVE_FILE_FILTER); + if (!fn.isEmpty() && can_close_project()) { + project_url = fn; + panel_project->load_project(); } } @@ -496,6 +497,7 @@ void MainWindow::toolMenu_About_To_Be_Shown() { ui->actionEdit_Tool_Selects_Links->setChecked(panel_timeline->edit_tool_selects_links); ui->actionSelecting_Also_Seeks->setChecked(panel_timeline->select_also_seeks); ui->actionSeek_to_the_End_of_Pastes->setChecked(panel_timeline->paste_seeks); + ui->actionToggle_Snapping->setChecked(panel_timeline->snapping); } void MainWindow::on_actionEdit_Tool_Selects_Links_triggered() { @@ -520,3 +522,7 @@ void MainWindow::on_actionSeek_to_the_End_of_Pastes_triggered() { panel_timeline->paste_seeks = !panel_timeline->paste_seeks; } + +void MainWindow::on_actionAdd_Default_Transition_triggered() { + if (panel_timeline->focused()) panel_timeline->add_transition(); +} diff --git a/mainwindow.h b/mainwindow.h index 18786aded..8797d4151 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -135,6 +135,8 @@ private slots: void on_actionSeek_to_the_End_of_Pastes_triggered(); + void on_actionAdd_Default_Transition_triggered(); + private: Ui::MainWindow *ui; void setup_layout(); diff --git a/mainwindow.ui b/mainwindow.ui index 8a314f4c2..f480292c8 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -24,7 +24,7 @@ 0 0 653 - 17 + 29 @@ -68,6 +68,7 @@ + @@ -448,8 +449,14 @@ + + true + - Toggle Snapping + Snapping + + + Snapping S @@ -556,6 +563,14 @@ Seek to the End of Pastes + + + Add Default Transition + + + Ctrl+Shift+D + + diff --git a/olive.pro b/olive.pro index 4c4870b16..db6da3f52 100644 --- a/olive.pro +++ b/olive.pro @@ -57,7 +57,8 @@ SOURCES += \ ui/labelslider.cpp \ dialogs/preferencesdialog.cpp \ effects/transition.cpp \ - effects/crossdissolvetransition.cpp + effects/crossdissolvetransition.cpp \ + ui/audiomonitor.cpp HEADERS += \ mainwindow.h \ @@ -89,7 +90,8 @@ HEADERS += \ io/previewgenerator.h \ ui/labelslider.h \ dialogs/preferencesdialog.h \ - effects/transition.h + effects/transition.h \ + ui/audiomonitor.h FORMS += \ mainwindow.ui \ diff --git a/olive.pro.user b/olive.pro.user index 4a19494e0..38f91c8f9 100644 --- a/olive.pro.user +++ b/olive.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/panels/project.cpp b/panels/project.cpp index 654be2b48..21d2e89f5 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -10,6 +10,7 @@ #include "panels/timeline.h" #include "project/sequence.h" #include "project/effect.h" +#include "effects/transition.h" #include "io/previewgenerator.h" #include @@ -467,6 +468,12 @@ void Project::load_project() { } else if (stream.name() == "track") { stream.readNext(); temp_clip->track = stream.text().toInt(); + } else if (stream.name() == "opening") { + stream.readNext(); + temp_clip->opening_transition = create_transition(stream.text().toInt(), temp_clip); + } else if (stream.name() == "closing") { + stream.readNext(); + temp_clip->closing_transition = create_transition(stream.text().toInt(), temp_clip); } else if (stream.name() == "color") { for (int j=0;jtimeline_in)); stream.writeTextElement("out", QString::number(c->timeline_out)); stream.writeTextElement("track", QString::number(c->track)); + if (c->opening_transition != NULL) { + stream.writeTextElement("opening", QString::number(c->opening_transition->id)); + } + if (c->closing_transition != NULL) { + stream.writeTextElement("closing", QString::number(c->closing_transition->id)); + } stream.writeStartElement("color"); stream.writeAttribute("r", QString::number(c->color_r)); stream.writeAttribute("g", QString::number(c->color_g)); diff --git a/panels/timeline.cpp b/panels/timeline.cpp index 0c3c5fb68..63dc8633e 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -12,6 +12,7 @@ #include "panels/viewer.h" #include "playback/cacher.h" #include "playback/playback.h" +#include "effects/transition.h" #include "ui_viewer.h" #include @@ -126,6 +127,7 @@ void Timeline::reset_all_audio() { c->audio_buffer_write = 0; } } + ui->audio_monitor->reset(); clear_audio_ibuffer(); } @@ -173,6 +175,21 @@ int Timeline::get_track_height_size(bool video) { } } +void Timeline::add_transition() { + for (int i=0;iclip_count();i++) { + Clip* c = sequence->get_clip(i); + if (c != NULL && is_clip_selected(c)) { + if (c->opening_transition == NULL) { + c->opening_transition = create_transition(0, c); + } + if (c->closing_transition == NULL) { + c->closing_transition = create_transition(0, c); + } + } + } + redraw_all_clips(true); +} + int Timeline::calculate_track_height(int track, int value) { int index = (track < 0) ? qAbs(track + 1) : track; QVector& vector = (track < 0) ? video_track_heights : audio_track_heights; @@ -242,6 +259,7 @@ void Timeline::repaint_timeline() { ui->audio_area->update(); if (last_frame != playhead) { panel_viewer->viewer_widget->update(); + ui->audio_monitor->update(); last_frame = playhead; } panel_viewer->update_playhead_timecode(); @@ -343,20 +361,24 @@ void Timeline::set_zoom(bool in) { } void Timeline::ripple(long ripple_point, long ripple_length) { + // ripple all clips around the ripple_point for (int i=0;iclip_count();i++) { Clip* c = sequence->get_clip(i); if (c != NULL && c->timeline_in >= ripple_point) { c->timeline_in += ripple_length; c->timeline_out += ripple_length; } - } - for (int i=0;i= ripple_point) { - s.in += ripple_length; - s.out += ripple_length; - } - } + } + + // ripple the selections + for (int i=0;i= ripple_point) { + s.in += ripple_length; + s.out += ripple_length; + } + } } void Timeline::decheck_tool_buttons(QObject* sender) { diff --git a/panels/timeline.h b/panels/timeline.h index 943b75234..1e21753a3 100644 --- a/panels/timeline.h +++ b/panels/timeline.h @@ -74,6 +74,7 @@ public: void update_sequence(); void increase_track_height(); void decrease_track_height(); + void add_transition(); int get_snap_range(); int getScreenPointFromFrame(long frame); diff --git a/panels/timeline.ui b/panels/timeline.ui index c50ec79a3..7b17c0261 100644 --- a/panels/timeline.ui +++ b/panels/timeline.ui @@ -330,7 +330,7 @@ 0 0 - 458 + 408 314 @@ -396,6 +396,16 @@ + + + + + 50 + 0 + + + + @@ -412,6 +422,12 @@
ui/timelineheader.h
1 + + AudioMonitor + QWidget +
ui/audiomonitor.h
+ 1 +
diff --git a/playback/audio.cpp b/playback/audio.cpp index 80fb17d73..1eca26d6a 100644 --- a/playback/audio.cpp +++ b/playback/audio.cpp @@ -57,7 +57,7 @@ void clear_audio_ibuffer() { int get_buffer_offset_from_frame(long frame) { if (frame >= audio_ibuffer_frame) { - return av_samples_get_buffer_size(NULL, av_get_channel_layout_nb_channels(sequence->audio_layout), qFloor(((frame-audio_ibuffer_frame)/sequence->frame_rate)*sequence->audio_frequency), AV_SAMPLE_FMT_S16, 1); + return av_samples_get_buffer_size(NULL, av_get_channel_layout_nb_channels(sequence->audio_layout), qRound(((frame-audio_ibuffer_frame)/sequence->frame_rate)*sequence->audio_frequency), AV_SAMPLE_FMT_S16, 1); } else { qDebug() << "[WARNING] get_buffer_offset_from_frame called incorrectly"; return 0; diff --git a/playback/playback.cpp b/playback/playback.cpp index 81a586e82..ff75ff098 100644 --- a/playback/playback.cpp +++ b/playback/playback.cpp @@ -189,12 +189,8 @@ long seconds_to_clip_frame(Clip* c, float seconds) { } float clip_frame_to_seconds(Clip* c, long clip_frame) { - // returns frame number as seconds (decimal) - if (c->stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { - return (double) clip_frame / av_q2d(c->stream->avg_frame_rate); - } else { - return (double) clip_frame / c->sequence->frame_rate; - } + // returns frame number in decimal seconds + return (float) clip_frame / c->sequence->frame_rate; } int retrieve_next_frame(Clip* c, AVFrame* f) { diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index 383259ad0..46b4ba6ce 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -62,7 +62,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { bool ignore_infinite_length = false; Media* m = panel_project->get_media_from_tree(items.at(i)); long duration = m->get_length_in_frames(sequence->frame_rate); - Ghost g = {NULL, entry_point, entry_point + duration}; + Ghost g = {0, entry_point, entry_point + duration}; g.media = m; g.clip_in = 0; for (int j=0;jaudio_tracks.size();j++) { @@ -289,7 +289,34 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { bool repaint = false; if (panel_timeline->moving_proc) { - if (event->modifiers() & Qt::AltModifier) { // if holding alt, duplicate rather than move + // if we were RIPPLING, move all the clips + if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) { + long ripple_length, ripple_point; + + // ripple_length becomes the length/number of frames we trimmed + // ripple point becomes the point to ripple (i.e. the point after or before which we move every clip) + if (panel_timeline->trim_in) { + ripple_length = panel_timeline->ghosts.at(0).old_in - panel_timeline->ghosts.at(0).in; + ripple_point = panel_timeline->ghosts.at(0).old_in; + } else { + // if we're trimming an out-point + ripple_length = panel_timeline->ghosts.at(0).old_out - panel_timeline->ghosts.at(0).out; + ripple_point = panel_timeline->ghosts.at(0).old_out; + } + for (int i=0;ighosts.size();i++) { + long comp_point; + if (panel_timeline->trim_in) { + comp_point = panel_timeline->ghosts.at(i).old_in; + } else { + comp_point = panel_timeline->ghosts.at(i).old_out; + } + if (ripple_point > comp_point) ripple_point = comp_point; + } + if (!panel_timeline->trim_in) ripple_length = -ripple_length; + panel_timeline->ripple(ripple_point, ripple_length); + } + + if (panel_timeline->tool == TIMELINE_TOOL_POINTER && (event->modifiers() & Qt::AltModifier)) { // if holding alt, duplicate rather than move // duplicate clips QVector copy_clips; QVector old_clips; @@ -326,67 +353,43 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { } else { // move clips // TODO can we do this better than 3 consecutive for loops? - for (int i=0;ighosts.size();i++) { - // step 1 - set clips that are moving to "undeletable" (to avoid step 2 deleting any part of them) - sequence->get_clip(panel_timeline->ghosts[i].clip)->undeletable = true; - } - // step 2 - delete areas - QVector delete_areas; - for (int i=0;ighosts.size();i++) { - const Ghost& g = panel_timeline->ghosts.at(i); - - if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { + if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { + for (int i=0;ighosts.size();i++) { + // step 1 - set clips that are moving to "undeletable" (to avoid step 2 deleting any part of them) + sequence->get_clip(panel_timeline->ghosts[i].clip)->undeletable = true; + } + // step 2 - delete areas + QVector delete_areas; + for (int i=0;ighosts.size();i++) { // step 2 - delete anything that exists in area that clip is moving to // note: ripples are non-destructive so this is pointer-tool exclusive + const Ghost& g = panel_timeline->ghosts.at(i); Selection s; s.in = g.in; s.out = g.out; s.track = g.track; delete_areas.append(s); } + panel_timeline->delete_areas_and_relink(delete_areas); } - panel_timeline->delete_areas_and_relink(delete_areas); for (int i=0;ighosts.size();i++) { Ghost& g = panel_timeline->ghosts[i]; // step 3 - move clips Clip* c = sequence->get_clip(g.clip); - c->timeline_in = g.in; - c->timeline_out = g.out; - c->track = g.track; - c->clip_in = g.clip_in; + c->timeline_in += (g.in - g.old_in); + c->timeline_out += (g.out - g.old_out); + c->track += (g.track - g.old_track); + c->clip_in += (g.clip_in - g.old_clip_in); } - for (int i=0;ighosts.size();i++) { - // step 4 - set clips back to deletable - sequence->get_clip(panel_timeline->ghosts[i].clip)->undeletable = false; + if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { + for (int i=0;ighosts.size();i++) { + // step 4 - set clips back to deletable + sequence->get_clip(panel_timeline->ghosts[i].clip)->undeletable = false; + } } } - // ripple ops - if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) { - long ripple_length, ripple_point; - if (panel_timeline->trim_in) { - ripple_length = panel_timeline->ghosts.at(0).old_in - panel_timeline->ghosts.at(0).in; - ripple_point = (ripple_length < 0) ? panel_timeline->ghosts.at(0).old_in : panel_timeline->ghosts.at(0).in; - } else { - ripple_length = panel_timeline->ghosts.at(0).old_out - panel_timeline->ghosts.at(0).out; - ripple_point = (ripple_length < 0) ? panel_timeline->ghosts.at(0).old_out : panel_timeline->ghosts.at(0).out; - } - for (int i=0;ighosts.size();i++) { - long comp_point; - if (panel_timeline->trim_in) { - comp_point = (ripple_length < 0) ? panel_timeline->ghosts.at(i).old_in : panel_timeline->ghosts.at(i).in; - } else { - comp_point = (ripple_length < 0) ? panel_timeline->ghosts.at(i).old_out : panel_timeline->ghosts.at(i).out; - } - if (ripple_point > comp_point) ripple_point = comp_point; - } - if (panel_timeline->trim_in) { - panel_timeline->ripple(ripple_point, ripple_length); - } else { - panel_timeline->ripple(ripple_point, -ripple_length); - } - } panel_timeline->redraw_all_clips(true); } else if (panel_timeline->selecting) { // remove duplicate selections @@ -533,6 +536,8 @@ void TimelineWidget::update_ghosts(QPoint& mouse_pos) { Ghost& g = panel_timeline->ghosts[i]; Clip* c = sequence->get_clip(g.clip); + validate_snapping(g, &frame_diff); + if (panel_timeline->trim_in) { // prevent clip length from being less than 1 frame long validator = g.ghost_length - frame_diff; @@ -546,25 +551,6 @@ void TimelineWidget::update_ghosts(QPoint& mouse_pos) { // prevent clip_in from going below 0 validator = g.old_clip_in + frame_diff; if (validator < 0) frame_diff -= validator; - } - - // ripple ops - if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) { - for (int j=0;jtimeline_in - frame_diff; - if (validator < 0) frame_diff += validator; - - // prevent any post-clips colliding with pre-clips - for (int k=0;ktrack == post->track) { - validator = post->timeline_in - frame_diff - pre->timeline_out; - if (validator < 0) frame_diff += validator; - } - } - } } } else { // prevent clip length from being less than 1 frame long @@ -575,26 +561,32 @@ void TimelineWidget::update_ghosts(QPoint& mouse_pos) { // prevent clip length exceeding media length validator = g.ghost_length + frame_diff; if (validator > g.media_length) frame_diff -= validator - g.media_length; - } - - // ripple ops - if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) { - for (int j=0;jtrack == post->track) { - validator = post->timeline_in + frame_diff - pre->timeline_out; - if (validator < 0) frame_diff -= validator; - } - } - } - } + } } - validate_snapping(g, &frame_diff); + // ripple ops + if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) { + for (int j=0;jtimeline_in - frame_diff; + if (validator < 0) frame_diff += validator; + + // prevent any post-clips colliding with pre-clips + for (int k=0;ktrack == post->track) { + if (panel_timeline->trim_in) { + validator = post->timeline_in - frame_diff - pre->timeline_out; + if (validator < 0) frame_diff += validator; + } else { + validator = post->timeline_in + frame_diff - pre->timeline_out; + if (validator < 0) frame_diff -= validator; + } + } + } + } + } } // resize ghosts @@ -798,62 +790,51 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { // ripple edit prep if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) { - for (int i=0;ighosts.size();i++) { - // get clips before and after ripple point - for (int j=0;jclip_count();j++) { - Clip* cc = sequence->get_clip(j); + QVector axis_ghosts; + for (int i=0;ighosts.size();i++) { + Clip* c = sequence->get_clip(panel_timeline->ghosts.at(i).clip); + bool found = false; + for (int j=0;jtrack == cc->track && + ((panel_timeline->trim_in && c->timeline_in < cc->timeline_in) || + (!panel_timeline->trim_in && c->timeline_out > cc->timeline_out))) { + axis_ghosts[j] = c; + found = true; + break; + } + } + if (!found) { + axis_ghosts.append(c); + } + } - if (cc != NULL) { - // don't cache any currently selected clips - Clip* c = sequence->get_clip(panel_timeline->ghosts.at(i).clip); - bool is_selected = false; - for (int k=0;kghosts.size();k++) { - if (panel_timeline->ghosts.at(k).clip == j) { - is_selected = true; + for (int i=0;iclip_count();i++) { + Clip* c = sequence->get_clip(i); + if (c != NULL && !panel_timeline->is_clip_selected(c)) { + for (int j=0;jtrim_in) ? axis->timeline_in : axis->timeline_out; + bool clip_is_pre = (c->timeline_in < comp_point); + QVector& clip_list = clip_is_pre ? pre_clips : post_clips; + bool found = false; + for (int k=0;ktrack == c->track) { + if (clip_is_pre == (c->timeline_in > cached->timeline_in)) { + clip_list[k] = c; + } + found = true; break; } } - - if (!is_selected) { - if (cc->timeline_in < c->timeline_in) { - // add clip to pre-cache UNLESS there is already a clip on that track closer to the ripple point - bool found = false; - for (int k=0;ktrack == cc->track) { - if (ccc->timeline_in < cc->timeline_in) { - // clip is closer to ripple point than the one in cache, replace it - ccc = cc; - } - found = true; - } - } - if (!found) { - // no clip from that track in the cache, add it - pre_clips.append(cc); - } - } else { - // add clip to post-cache UNLESS there is already a clip on that track closer to the ripple point - bool found = false; - for (int k=0;ktrack == cc->track) { - if (ccc->timeline_in > cc->timeline_in) { - // clip is closer to ripple point than the one in cache, replace it - ccc = cc; - } - found = true; - } - } - if (!found) { - // no clip from that track in the cache, add it - post_clips.append(cc); - } - } + if (!found) { + clip_list.append(c); } } - } + } } +// qDebug() << "found" << pre_clips.size() << "pres and" << post_clips.size() << "posts"; } init_ghosts(); @@ -1062,15 +1043,21 @@ void TimelineWidget::redraw_clips() { } if (t != NULL) { int transition_width = panel_timeline->getScreenPointFromFrame(t->length); - QRect transition_rect; + int transition_height = clip_rect.height() * 0.6; + if (transition_height <= TRACK_MIN_HEIGHT) { + transition_height = clip_rect.height(); + } + int tr_y = clip_rect.y() + ((clip_rect.height()-transition_height)/2); + int tr_x = 0; if (i == 0) { - transition_rect = QRect(clip_rect.x(), clip_rect.y(), transition_width, clip_rect.height()); + tr_x = clip_rect.x(); text_rect.setX(text_rect.x()+transition_width); thumb_x += transition_width; } else { - transition_rect = QRect(clip_rect.right()-transition_width, clip_rect.y(), transition_width, clip_rect.height()); + tr_x = clip_rect.right()-transition_width; text_rect.setWidth(text_rect.width()-transition_width); } + QRect transition_rect = QRect(tr_x, tr_y, transition_width, transition_height); clip_painter.fillRect(transition_rect, transition_color); QRect transition_text_rect(transition_rect.x() + CLIP_TEXT_PADDING, transition_rect.y() + CLIP_TEXT_PADDING, transition_rect.width() - CLIP_TEXT_PADDING, transition_rect.height() - CLIP_TEXT_PADDING); if (transition_text_rect.width() > MAX_TEXT_WIDTH) { diff --git a/ui/timelinewidget.h b/ui/timelinewidget.h index 3a77bf7cc..fe85f2dcc 100644 --- a/ui/timelinewidget.h +++ b/ui/timelinewidget.h @@ -50,8 +50,8 @@ private: bool track_resizing; int track_target; - QList pre_clips; - QList post_clips; + QVector pre_clips; + QVector post_clips; QPixmap clip_pixmap; // QPixmap selection_pixmap; diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index fbba9fc54..5a5bdb33a 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -9,6 +9,7 @@ #include "playback/playback.h" #include "playback/audio.h" #include "io/media.h" +#include "ui_timeline.h" #include #include @@ -176,8 +177,21 @@ void ViewerWidget::paintGL() { int adjusted_read_index = audio_ibuffer_read%audio_ibuffer_size; int max_write = audio_ibuffer_size - adjusted_read_index; int actual_write = audio_io_device->write((const char*) audio_ibuffer+adjusted_read_index, max_write); - memset(audio_ibuffer+adjusted_read_index, 0, actual_write); audio_ibuffer_read += actual_write; + + // send samples to audio monitor cache + if (panel_timeline->ui->audio_monitor->sample_cache_offset == -1) { + panel_timeline->ui->audio_monitor->sample_cache_offset = panel_timeline->playhead; + } + long sample_cache_playhead = panel_timeline->ui->audio_monitor->sample_cache_offset + panel_timeline->ui->audio_monitor->sample_cache.size(); + int buffer_offset, buffer_offset_adjusted; + while ((buffer_offset = get_buffer_offset_from_frame(sample_cache_playhead)) < audio_ibuffer_read) { + buffer_offset_adjusted = buffer_offset%audio_ibuffer_size; + panel_timeline->ui->audio_monitor->sample_cache.append((qint16) ((audio_ibuffer[buffer_offset_adjusted+1] << 8) | audio_ibuffer[buffer_offset_adjusted])); + sample_cache_playhead++; + } + + memset(audio_ibuffer+adjusted_read_index, 0, actual_write); if (actual_write == max_write) { // got all the bytes, write again actual_write = audio_io_device->write((const char*) audio_ibuffer, audio_ibuffer_size);