many many things

This commit is contained in:
itsmattkc
2018-07-09 20:59:22 +01:00
parent ef31d6a29d
commit f11447e516
22 changed files with 359 additions and 235 deletions
+2 -2
View File
@@ -50,8 +50,8 @@ void PanEffect::save(QXmlStreamWriter *stream) {
void PanEffect::process_audio(quint8 *samples, int nb_bytes) {
if (pan_val->value() != 0) {
for (int i=0;i<nb_bytes;i+=4) {
qint16 left_sample = (qint16) ((samples[i+1] << 8) | samples[i]);
qint16 right_sample = (qint16) ((samples[i+3] << 8) | samples[i+2]);
qint16 left_sample = (qint16) (((samples[i+1] & 0xFF) << 8) | (samples[i] & 0xFF));
qint16 right_sample = (qint16) (((samples[i+3] & 0xFF) << 8) | (samples[i+2] & 0xFF));
float val = qPow(pan_val->value()*0.01f, 3);
if (val < 0) {
+9 -2
View File
@@ -5,6 +5,7 @@
#include <QtMath>
#include <QDebug>
#include "playback/audio.h"
#include "ui/labelslider.h"
#include "ui/collapsiblewidget.h"
@@ -50,9 +51,15 @@ void VolumeEffect::save(QXmlStreamWriter* stream) {
void VolumeEffect::process_audio(quint8* samples, int nb_bytes) {
if (volume_val->value() != 100) {
for (int i=0;i<nb_bytes;i+=2) {
qint16 samp = (qint16) ((samples[i+1] << 8) | samples[i]);
float val = qPow(volume_val->value()*0.01f, 3);
qint32 samp = (qint16) (((samples[i+1] & 0xFF) << 8) | (samples[i] & 0xFF));
double val = qPow(volume_val->value()*0.01, 3);
samp *= val;
if (samp > INT16_MAX) {
samp = INT16_MAX;
} else if (samp < INT16_MIN) {
samp = INT16_MIN;
}
samples[i+1] = (quint8) (samp >> 8);
samples[i] = (quint8) samp;
}
+2
View File
@@ -27,5 +27,7 @@
<file>ripple-disabled.png</file>
<file>rolling-disabled.png</file>
<file>slip-disabled.png</file>
<file>slide.png</file>
<file>slide-disabled.png</file>
</qresource>
</RCC>
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

-1
View File
@@ -23,7 +23,6 @@ struct MediaStream {
int audio_channels;
// preview thumbnail/waveform
QMutex preview_lock;
bool preview_done;
QImage video_preview; // TODO change to QPixmap
QVector<qint8> audio_preview;
-2
View File
@@ -105,7 +105,6 @@ void PreviewGenerator::run() {
// delete [] data;
s->preview_done = true;
s->preview_lock.unlock();
sws_freeContext(sws_ctx);
@@ -179,7 +178,6 @@ void PreviewGenerator::run() {
}
for (int i=0;i<media->audio_tracks.size();i++) {
media->audio_tracks.at(i)->preview_done = true;
media->audio_tracks.at(i)->preview_lock.unlock();
}
av_frame_free(&temp_frame);
for (unsigned int i=0;i<fmt_ctx->nb_streams;i++) {
+5
View File
@@ -526,3 +526,8 @@ void MainWindow::on_actionSeek_to_the_End_of_Pastes_triggered()
void MainWindow::on_actionAdd_Default_Transition_triggered() {
if (panel_timeline->focused()) panel_timeline->add_transition();
}
void MainWindow::on_actionSlide_Tool_triggered()
{
if (panel_timeline->focused()) panel_timeline->ui->toolSlideButton->click();
}
+2
View File
@@ -137,6 +137,8 @@ private slots:
void on_actionAdd_Default_Transition_triggered();
void on_actionSlide_Tool_triggered();
private:
Ui::MainWindow *ui;
void setup_layout();
+12
View File
@@ -125,6 +125,7 @@
<addaction name="actionRolling_Tool"/>
<addaction name="actionRazor_Tool"/>
<addaction name="actionSlip_Tool"/>
<addaction name="actionSlide_Tool"/>
<addaction name="separator"/>
<addaction name="actionToggle_Snapping"/>
<addaction name="actionSelecting_Also_Seeks"/>
@@ -268,6 +269,9 @@
<property name="text">
<string>Sequence...</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+N</string>
</property>
</action>
<action name="actionZoom_In">
<property name="text">
@@ -571,6 +575,14 @@
<string>Ctrl+Shift+D</string>
</property>
</action>
<action name="actionSlide_Tool">
<property name="text">
<string>Slide Tool</string>
</property>
<property name="shortcut">
<string>U</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.6.2, 2018-07-08T12:53:52. -->
<!-- Written by QtCreator 4.6.2, 2018-07-09T18:24:32. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
-1
View File
@@ -140,7 +140,6 @@ Media* Project::import_file(QString file) {
} else {
MediaStream* ms = new MediaStream();
ms->preview_done = false;
ms->preview_lock.lock();
ms->file_index = i;
if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
bool infinite_length = (pFormatCtx->streams[i]->avg_frame_rate.den == 0);
+47 -57
View File
@@ -55,6 +55,7 @@ Timeline::Timeline(QWidget *parent) :
tool_buttons.append(ui->toolRazorButton);
tool_buttons.append(ui->toolSlipButton);
tool_buttons.append(ui->toolRollingButton);
tool_buttons.append(ui->toolSlideButton);
ui->toolArrowButton->click();
@@ -383,36 +384,7 @@ void Timeline::ripple(long ripple_point, long ripple_length) {
void Timeline::decheck_tool_buttons(QObject* sender) {
for (int i=0;i<tool_buttons.count();i++) {
if (tool_buttons[i] != sender) {
tool_buttons[i]->setChecked(false);
}
}
}
void Timeline::on_toolEditButton_toggled(bool checked)
{
if (checked) {
decheck_tool_buttons(sender());
ui->timeline_area->setCursor(Qt::IBeamCursor);
tool = TIMELINE_TOOL_EDIT;
}
}
void Timeline::on_toolArrowButton_toggled(bool checked)
{
if (checked) {
decheck_tool_buttons(sender());
ui->timeline_area->setCursor(Qt::ArrowCursor);
tool = TIMELINE_TOOL_POINTER;
}
}
void Timeline::on_toolRazorButton_toggled(bool checked)
{
if (checked) {
decheck_tool_buttons(sender());
ui->timeline_area->setCursor(Qt::IBeamCursor);
tool = TIMELINE_TOOL_RAZOR;
tool_buttons[i]->setChecked(tool_buttons.at(i) == sender);
}
}
@@ -436,33 +408,6 @@ bool Timeline::is_clip_selected(Clip* clip) {
return false;
}
void Timeline::on_toolRippleButton_toggled(bool checked)
{
if (checked) {
decheck_tool_buttons(sender());
ui->timeline_area->setCursor(Qt::ArrowCursor);
tool = TIMELINE_TOOL_RIPPLE;
}
}
void Timeline::on_toolRollingButton_toggled(bool checked)
{
if (checked) {
decheck_tool_buttons(sender());
ui->timeline_area->setCursor(Qt::ArrowCursor);
tool = TIMELINE_TOOL_ROLLING;
}
}
void Timeline::on_toolSlipButton_toggled(bool checked)
{
if (checked) {
decheck_tool_buttons(sender());
ui->timeline_area->setCursor(Qt::ArrowCursor);
tool = TIMELINE_TOOL_SLIP;
}
}
void Timeline::on_snappingButton_toggled(bool checked)
{
snapping = checked;
@@ -849,3 +794,48 @@ long Timeline::getFrameFromScreenPoint(int x) {
int Timeline::getScreenPointFromFrame(long frame) {
return (int) round(frame*zoom);
}
void Timeline::on_toolArrowButton_clicked() {
decheck_tool_buttons(sender());
ui->timeline_area->setCursor(Qt::ArrowCursor);
tool = TIMELINE_TOOL_POINTER;
}
void Timeline::on_toolEditButton_clicked() {
decheck_tool_buttons(sender());
ui->timeline_area->setCursor(Qt::IBeamCursor);
tool = TIMELINE_TOOL_EDIT;
}
void Timeline::on_toolRippleButton_clicked() {
decheck_tool_buttons(sender());
ui->timeline_area->setCursor(Qt::ArrowCursor);
tool = TIMELINE_TOOL_RIPPLE;
}
void Timeline::on_toolRollingButton_clicked() {
decheck_tool_buttons(sender());
ui->timeline_area->setCursor(Qt::ArrowCursor);
tool = TIMELINE_TOOL_ROLLING;
}
void Timeline::on_toolRazorButton_clicked()
{
decheck_tool_buttons(sender());
ui->timeline_area->setCursor(Qt::IBeamCursor);
tool = TIMELINE_TOOL_RAZOR;
}
void Timeline::on_toolSlipButton_clicked()
{
decheck_tool_buttons(sender());
ui->timeline_area->setCursor(Qt::ArrowCursor);
tool = TIMELINE_TOOL_SLIP;
}
void Timeline::on_toolSlideButton_clicked()
{
decheck_tool_buttons(sender());
ui->timeline_area->setCursor(Qt::ArrowCursor);
tool = TIMELINE_TOOL_SLIDE;
}
+16 -12
View File
@@ -35,6 +35,7 @@ struct Ghost {
long ghost_length;
long media_length;
bool trim_in;
bool trimming;
};
struct Selection {
@@ -164,24 +165,27 @@ public slots:
void repaint_timeline();
private slots:
void on_toolEditButton_toggled(bool checked);
void on_toolArrowButton_toggled(bool checked);
void on_toolRazorButton_toggled(bool checked);
void on_pushButton_4_clicked();
void on_pushButton_5_clicked();
void on_toolRippleButton_toggled(bool checked);
void on_toolRollingButton_toggled(bool checked);
void on_toolSlipButton_toggled(bool checked);
void on_pushButton_5_clicked();
void on_snappingButton_toggled(bool checked);
void on_toolSlideButton_clicked();
void on_toolArrowButton_clicked();
void on_toolEditButton_clicked();
void on_toolRippleButton_clicked();
void on_toolRollingButton_clicked();
void on_toolRazorButton_clicked();
void on_toolSlipButton_clicked();
private:
QVector<QPushButton*> tool_buttons;
void decheck_tool_buttons(QObject* sender);
+34 -3
View File
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>523</width>
<height>363</height>
<height>376</height>
</rect>
</property>
<property name="windowTitle">
@@ -233,7 +233,38 @@
<property name="icon">
<iconset>
<normalon>:/icons/slip.png</normalon>
<disabledoff>:/icons/slip-disabled.png</disabledoff>
<disabledon>:/icons/slip-disabled.png</disabledon>
</iconset>
</property>
<property name="iconSize">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="toolSlideButton">
<property name="maximumSize">
<size>
<width>40</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Slide Tool (U)</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/icons/slide.png</normalon>
<disabledon>:/icons/slide-disabled.png</disabledon>
</iconset>
</property>
<property name="iconSize">
@@ -331,7 +362,7 @@
<x>0</x>
<y>0</y>
<width>408</width>
<height>314</height>
<height>327</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
+1 -1
View File
@@ -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), qRound(((frame-audio_ibuffer_frame)/sequence->frame_rate)*sequence->audio_frequency), AV_SAMPLE_FMT_S16, 1);
return qFloor(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)/4)*4;
} else {
qDebug() << "[WARNING] get_buffer_offset_from_frame called incorrectly";
return 0;
+3
View File
@@ -3,6 +3,9 @@
#include <QVector>
#define INT16_MAX 0x7fff
#define INT16_MIN (-INT16_MAX-1)
class QAudioOutput;
class QIODevice;
+20 -4
View File
@@ -15,6 +15,8 @@ extern "C" {
}
#include <QDebug>
#include <QtMath>
#include <math.h>
void cache_audio_worker(Clip* c) {
int written = 0;
@@ -94,10 +96,24 @@ void cache_audio_worker(Clip* c) {
written = max_write;
break;
} else {
audio_ibuffer[c->audio_buffer_write%audio_ibuffer_size] += frame->data[0][c->frame_sample_index];
c->audio_buffer_write++;
c->frame_sample_index++;
written++;
int upper_byte_index = (c->audio_buffer_write+1)%audio_ibuffer_size;
int lower_byte_index = (c->audio_buffer_write)%audio_ibuffer_size;
qint16 old_sample = (qint16) ((audio_ibuffer[upper_byte_index] & 0xFF) << 8 | (audio_ibuffer[lower_byte_index] & 0xFF));
qint16 new_sample = (qint16) ((frame->data[0][c->frame_sample_index+1] & 0xFF) << 8 | (frame->data[0][c->frame_sample_index] & 0xFF));
qint32 mixed_sample;
mixed_sample = old_sample + new_sample;
if (mixed_sample > INT16_MAX) {
mixed_sample = INT16_MAX;
} else if (mixed_sample < INT16_MIN) {
mixed_sample = INT16_MIN;
}
audio_ibuffer[upper_byte_index] = (quint8) (mixed_sample >> 8);
audio_ibuffer[lower_byte_index] = (quint8) mixed_sample;
c->audio_buffer_write+=2;
c->frame_sample_index+=2;
written+=2;
}
}
if (c->frame_sample_index == nb_bytes) {
+2
View File
@@ -3,6 +3,8 @@
#include <QWidget>
#define AUDIO_MONITOR_RESOLUTION 16
class AudioMonitor : public QWidget
{
Q_OBJECT
+3 -2
View File
@@ -7,7 +7,8 @@
#define TIMELINE_TOOL_RIPPLE 3
#define TIMELINE_TOOL_ROLLING 4
#define TIMELINE_TOOL_SLIP 5
#define TIMELINE_TOOL_HAND 6
#define TIMELINE_TOOL_ZOOM 7
#define TIMELINE_TOOL_SLIDE 6
#define TIMELINE_TOOL_HAND 7
#define TIMELINE_TOOL_ZOOM 8
#endif // TIMELINETOOLS_H
+199 -146
View File
@@ -52,8 +52,8 @@ void TimelineWidget::resizeEvent(QResizeEvent*) {
void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
if (static_cast<SourceTable*>(event->source()) == panel_project->source_table) {
event->accept();
QPoint pos = event->pos();
event->accept();
QList<QTreeWidgetItem*> items = panel_project->source_table->selectedItems();
long entry_point = panel_timeline->getFrameFromScreenPoint(pos.x());
panel_timeline->drag_frame_start = entry_point + panel_timeline->getFrameFromScreenPoint(50);
@@ -61,25 +61,35 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
for (int i=0;i<items.size();i++) {
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 = {0, entry_point, entry_point + duration};
Ghost g;
g.clip = -1;
g.media = m;
g.clip_in = 0;
g.old_clip_in = g.clip_in = 0;
g.in = entry_point;
entry_point += m->get_length_in_frames(sequence->frame_rate);
g.out = entry_point;
g.trimming = false;
for (int j=0;j<m->audio_tracks.size();j++) {
g.track = j;
g.track = j;
g.media_stream = m->audio_tracks.at(j);
ignore_infinite_length = true;
panel_timeline->ghosts.append(g);
}
for (int j=0;j<m->video_tracks.size();j++) {
g.track = -1-j;
g.track = -1-j;
g.media_stream = m->video_tracks.at(j);
if (m->video_tracks[j]->infinite_length && !ignore_infinite_length) g.out = g.in + 100;
panel_timeline->ghosts.append(g);
}
entry_point += duration;
}
init_ghosts();
}
}
for (int i=0;i<panel_timeline->ghosts.size();i++) {
Ghost& g = panel_timeline->ghosts[i];
g.old_in = g.in;
g.old_out = g.out;
g.old_track = g.track;
}
// init_ghosts();
panel_timeline->importing = true;
}
}
@@ -87,7 +97,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
void TimelineWidget::dragMoveEvent(QDragMoveEvent *event) {
if (panel_timeline->importing) {
QPoint pos = event->pos();
update_ghosts(pos);
update_ghosts(pos);
panel_timeline->repaint_timeline();
}
}
@@ -211,6 +221,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) {
case TIMELINE_TOOL_RIPPLE:
case TIMELINE_TOOL_SLIP:
case TIMELINE_TOOL_ROLLING:
case TIMELINE_TOOL_SLIDE:
{
if (track_resizing) {
track_resize_mouse_cache = event->pos().y();
@@ -474,10 +485,10 @@ void TimelineWidget::init_ghosts() {
g.out = g.old_out = c->timeline_out;
g.track = g.old_track = c->track;
g.clip_in = g.old_clip_in = c->clip_in;
g.ghost_length = g.old_out - g.old_in;
if (panel_timeline->trim_target > -1 || panel_timeline->tool == TIMELINE_TOOL_SLIP) {
if (panel_timeline->trim_target > -1 || panel_timeline->tool == TIMELINE_TOOL_SLIP || panel_timeline->tool == TIMELINE_TOOL_SLIDE) {
// used for trim ops
g.ghost_length = g.old_out - g.old_in;
g.media_length = sequence->get_clip(g.clip)->media->get_length_in_frames(sequence->frame_rate);
}
}
@@ -489,7 +500,7 @@ void TimelineWidget::init_ghosts() {
}
}
bool subvalidate_snapping(Ghost& g, long* frame_diff, long snap_point) {
bool subvalidate_snapping(const Ghost& g, long* frame_diff, long snap_point) {
int snap_range = panel_timeline->get_snap_range();
long in_validator = g.old_in + *frame_diff - snap_point;
long out_validator = g.old_out + *frame_diff - snap_point;
@@ -508,7 +519,7 @@ bool subvalidate_snapping(Ghost& g, long* frame_diff, long snap_point) {
return false;
}
void validate_snapping(Ghost& g, long* frame_diff) {
void validate_snapping(const Ghost& g, long* frame_diff) {
panel_timeline->snapped = false;
if (panel_timeline->snapping) {
if (!subvalidate_snapping(g, frame_diff, panel_timeline->playhead)) {
@@ -528,48 +539,64 @@ void validate_snapping(Ghost& g, long* frame_diff) {
void TimelineWidget::update_ghosts(QPoint& mouse_pos) {
int mouse_track = getTrackFromScreenPoint(mouse_pos.y());
long frame_diff = panel_timeline->getFrameFromScreenPoint(mouse_pos.x()) - panel_timeline->drag_frame_start;
int track_diff = mouse_track - panel_timeline->drag_track_start;
int track_diff = (panel_timeline->tool == TIMELINE_TOOL_SLIDE) ? 0 : mouse_track - panel_timeline->drag_track_start;
long validator;
long validator;
if (panel_timeline->trim_target > -1) { // if trimming
// trim ops
// first try to snap
// first try to snap
if (panel_timeline->tool != TIMELINE_TOOL_SLIP) {
// slipping doesn't move the clips so we don't bother snapping for it
for (int i=0;i<panel_timeline->ghosts.size();i++) {
Ghost& g = panel_timeline->ghosts[i];
validate_snapping(g, &frame_diff);
}
}
// validate ghosts
for (int i=0;i<panel_timeline->ghosts.size();i++) {
Ghost& g = panel_timeline->ghosts[i];
Clip* c = sequence->get_clip(g.clip);
bool clips_are_movable = (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->tool == TIMELINE_TOOL_SLIDE || panel_timeline->importing);
// validate ghosts
long temp_frame_diff = frame_diff; // cache to see if we change it (thus cancelling any snap)
for (int i=0;i<panel_timeline->ghosts.size();i++) {
const Ghost& g = panel_timeline->ghosts.at(i);
Clip* c = NULL;
if (g.clip != -1) c = sequence->get_clip(g.clip);
// validate ghosts for trimming
if (panel_timeline->tool == TIMELINE_TOOL_SLIP) {
if (!sequence->get_clip(g.clip)->media_stream->infinite_length) {
// prevent slip moving a clip below 0 clip_in
validator = g.old_clip_in - frame_diff;
if (validator < 0) frame_diff += validator;
// prevent slip moving clip beyond media length
validator += g.ghost_length;
if (validator > g.media_length) frame_diff += validator - g.media_length;
}
} else if (g.trimming) {
if (g.trim_in) {
// prevent clip length from being less than 1 frame long
validator = g.ghost_length - frame_diff;
if (validator < 1) frame_diff -= (1 - validator);
// prevent clip length from being less than 1 frame long
validator = g.ghost_length - frame_diff;
if (validator < 1) frame_diff -= (1 - validator);
// prevent timeline in from going below 0
validator = g.old_in + frame_diff;
if (validator < 0) frame_diff -= validator;
// prevent timeline in from going below 0
validator = g.old_in + frame_diff;
if (validator < 0) frame_diff -= validator;
if (!c->media_stream->infinite_length) {
// prevent clip_in from going below 0
validator = g.old_clip_in + frame_diff;
if (validator < 0) frame_diff -= validator;
// prevent clip_in from going below 0
validator = g.old_clip_in + frame_diff;
if (validator < 0) frame_diff -= validator;
}
} else {
// prevent clip length from being less than 1 frame long
validator = g.ghost_length + frame_diff;
if (validator < 1) frame_diff += (1 - validator);
} else {
// prevent clip length from being less than 1 frame long
validator = g.ghost_length + frame_diff;
if (validator < 1) frame_diff += (1 - validator);
if (!c->media_stream->infinite_length) {
// prevent clip length exceeding media length
validator = g.ghost_length + frame_diff;
if (validator > g.media_length) frame_diff -= validator - g.media_length;
// 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) {
@@ -594,112 +621,85 @@ void TimelineWidget::update_ghosts(QPoint& mouse_pos) {
}
}
}
} else if (clips_are_movable) { // validate ghosts for moving
// prevent clips from moving below 0 on the timeline
validator = g.old_in + frame_diff;
if (validator < 0) frame_diff -= validator;
// prevent clips from crossing tracks
if (same_sign(g.old_track, panel_timeline->drag_track_start)) {
while (!same_sign(g.old_track, g.old_track + track_diff)) {
if (g.old_track < 0) {
track_diff--;
} else {
track_diff++;
}
}
}
}
}
if (temp_frame_diff != frame_diff) {
panel_timeline->snapped = false;
}
// resize ghosts
for (int i=0;i<panel_timeline->ghosts.size();i++) {
Ghost& g = panel_timeline->ghosts[i];
// apply changes to ghosts
for (int i=0;i<panel_timeline->ghosts.size();i++) {
Ghost& g = panel_timeline->ghosts[i];
if (g.trimming) {
if (g.trim_in) {
g.in = g.old_in + frame_diff;
g.clip_in = g.old_clip_in + frame_diff;
} else {
g.out = g.old_out + frame_diff;
}
}
} else if (clips_are_movable) {
g.track = g.old_track;
g.in = g.old_in + frame_diff;
g.out = g.old_out + frame_diff;
// resize selections
if (panel_timeline->importing) {
int abs_track_diff = abs(track_diff);
if (g.old_track < 0) { // clip is video
g.track -= abs_track_diff;
} else { // clip is audio
g.track += abs_track_diff;
}
} else if (same_sign(g.old_track, panel_timeline->drag_track_start)) {
g.track += track_diff;
}
}
}
// apply changes to selections
if (panel_timeline->tool != TIMELINE_TOOL_SLIP) {
for (int i=0;i<panel_timeline->selections.size();i++) {
Selection& s = panel_timeline->selections[i];
if (panel_timeline->trim_in_point) {
s.in = s.old_in + frame_diff;
if (panel_timeline->trim_target > -1) {
if (panel_timeline->trim_in_point) {
s.in = s.old_in + frame_diff;
} else {
s.out = s.old_out + frame_diff;
}
} else {
s.out = s.old_out + frame_diff;
for (int i=0;i<panel_timeline->selections.size();i++) {
Selection& s = panel_timeline->selections[i];
s.in = s.old_in + frame_diff;
s.out = s.old_out + frame_diff;
s.track = s.old_track;
if (panel_timeline->importing) {
int abs_track_diff = abs(track_diff);
if (s.old_track < 0) {
s.track -= abs_track_diff;
} else {
s.track += abs_track_diff;
}
} else {
if (same_sign(s.track, panel_timeline->drag_track_start)) s.track += track_diff;
}
}
}
}
} else if (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->importing) { // only move clips on pointer (not ripple or rolling)
// validate ghosts
for (int i=0;i<panel_timeline->ghosts.size();i++) {
Ghost& g = panel_timeline->ghosts[i];
// prevent clips from moving below 0 on the timeline
validator = g.old_in + frame_diff;
if (validator < 0) frame_diff -= validator;
// prevent clips from crossing tracks
if (same_sign(g.old_track, panel_timeline->drag_track_start)) {
while (!same_sign(g.old_track, g.old_track + track_diff)) {
if (g.old_track < 0) {
track_diff--;
} else {
track_diff++;
}
}
}
validate_snapping(g, &frame_diff);
}
// move ghosts
for (int i=0;i<panel_timeline->ghosts.size();i++) {
Ghost& g = panel_timeline->ghosts[i];
g.in = g.old_in + frame_diff;
g.out = g.old_out + frame_diff;
g.track = g.old_track;
if (panel_timeline->importing) {
int abs_track_diff = abs(track_diff);
if (g.old_track < 0) { // clip is video
g.track -= abs_track_diff;
} else { // clip is audio
g.track += abs_track_diff;
}
} else {
if (same_sign(g.old_track, panel_timeline->drag_track_start)) g.track += track_diff;
}
}
// move selections
if (!panel_timeline->importing) {
for (int i=0;i<panel_timeline->selections.size();i++) {
Selection& s = panel_timeline->selections[i];
s.in = s.old_in + frame_diff;
s.out = s.old_out + frame_diff;
s.track = s.old_track;
if (panel_timeline->importing) {
int abs_track_diff = abs(track_diff);
if (s.old_track < 0) {
s.track -= abs_track_diff;
} else {
s.track += abs_track_diff;
}
} else {
if (same_sign(s.track, panel_timeline->drag_track_start)) s.track += track_diff;
}
}
}
} else if (panel_timeline->tool == TIMELINE_TOOL_SLIP) {
// validate ghosts
for (int i=0;i<panel_timeline->ghosts.size();i++) {
Ghost& g = panel_timeline->ghosts[i];
if (!sequence->get_clip(g.clip)->media_stream->infinite_length) {
// prevent slip moving a clip below 0 clip_in
validator = g.old_clip_in - frame_diff;
if (validator < 0) frame_diff += validator;
// prevent slip moving clip beyond media length
validator += g.ghost_length;
if (validator > g.media_length) frame_diff += validator - g.media_length;
}
}
// slip ghosts
for (int i=0;i<panel_timeline->ghosts.size();i++) {
Ghost& g = panel_timeline->ghosts[i];
g.clip_in = g.old_clip_in - frame_diff;
}
}
}
@@ -786,15 +786,31 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
if (c != NULL && panel_timeline->is_clip_selected(c)) {
Ghost g;
g.clip = i;
g.trimming = (panel_timeline->trim_target > -1);
g.trim_in = panel_timeline->trim_in_point;
panel_timeline->ghosts.append(g);
}
}
int size = panel_timeline->ghosts.size();
if (panel_timeline->tool == TIMELINE_TOOL_ROLLING) {
int size = panel_timeline->ghosts.size();
for (int i=0;i<size;i++) {
Clip* ghost_clip = sequence->get_clip(panel_timeline->ghosts.at(i).clip);
// see if any ghosts are touching, in which case flip them
for (int k=0;k<size;k++) {
Clip* comp_clip = sequence->get_clip(panel_timeline->ghosts.at(k).clip);
if ((panel_timeline->trim_in_point && comp_clip->timeline_out == ghost_clip->timeline_in) ||
(!panel_timeline->trim_in_point && comp_clip->timeline_in == ghost_clip->timeline_out)) {
panel_timeline->ghosts[k].trim_in = !panel_timeline->trim_in_point;
}
}
}
// then look for other clips we're touching
for (int i=0;i<size;i++) {
const Ghost& g = panel_timeline->ghosts.at(i);
Clip* ghost_clip = sequence->get_clip(g.clip);
for (int j=0;j<sequence->clip_count();j++) {
Clip* comp_clip = sequence->get_clip(j);
if (comp_clip->track == ghost_clip->track) {
@@ -802,20 +818,56 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
(!panel_timeline->trim_in_point && comp_clip->timeline_in == ghost_clip->timeline_out)) {
// see if this clip is already selected, and if so just switch the trim_in
bool found = false;
for (int k=0;k<size;k++) {
if (panel_timeline->ghosts.at(k).clip == j) {
panel_timeline->ghosts[k].trim_in = !panel_timeline->trim_in_point;
int duplicate_ghost_index;
for (duplicate_ghost_index=0;duplicate_ghost_index<size;duplicate_ghost_index++) {
if (panel_timeline->ghosts.at(duplicate_ghost_index).clip == j) {
found = true;
break;
}
}
if (!found) {
// add ghost for this clip with opposite trim_in
Ghost g;
g.clip = j;
g.trim_in = !panel_timeline->trim_in_point;
panel_timeline->ghosts.append(g);
if (g.trim_in == panel_timeline->trim_in_point) {
if (!found) {
// add ghost for this clip with opposite trim_in
Ghost gh;
gh.clip = j;
gh.trimming = (panel_timeline->trim_target > -1);
gh.trim_in = !panel_timeline->trim_in_point;
panel_timeline->ghosts.append(gh);
}
} else {
if (found) {
panel_timeline->ghosts.removeAt(duplicate_ghost_index);
size--;
if (duplicate_ghost_index < i) i--;
}
}
}
}
}
}
} else if (panel_timeline->tool == TIMELINE_TOOL_SLIDE) {
for (int i=0;i<size;i++) {
const Ghost& g = panel_timeline->ghosts.at(i);
Clip* ghost_clip = sequence->get_clip(g.clip);
panel_timeline->ghosts[i].trimming = false;
for (int j=0;j<sequence->clip_count();j++) {
Clip* c = sequence->get_clip(j);
if (c->track == ghost_clip->track) {
bool found = false;
for (int k=0;k<size;k++) {
if (panel_timeline->ghosts.at(k).clip == j) {
found = true;
break;
}
}
if (!found) {
bool is_in = (c->timeline_in == ghost_clip->timeline_out);
if (is_in || c->timeline_out == ghost_clip->timeline_in) {
Ghost gh;
gh.clip = j;
gh.trimming = true;
gh.trim_in = is_in;
panel_timeline->ghosts.append(gh);
}
}
}
@@ -1134,8 +1186,9 @@ void TimelineWidget::redraw_clips() {
for (int j=0;j<clip->media_stream->audio_channels;j++) {
int mid = clip_rect.top()+channel_height*j+(channel_height/2);
int offset = waveform_index+(j*2);
qint8 min = (float)clip->media_stream->audio_preview[offset] / 128.0f * (channel_height/2);
qint8 max = (float)clip->media_stream->audio_preview[offset+1] / 128.0f * (channel_height/2);
qint8 min = (double)clip->media_stream->audio_preview.at(offset) / 128.0 * (channel_height/2);
qint8 max = (double)clip->media_stream->audio_preview.at(offset+1) / 128.0 * (channel_height/2);
clip_painter.drawLine(clip_rect.left()+i, mid+min, clip_rect.left()+i, mid+max);
}
}
+1 -1
View File
@@ -186,7 +186,7 @@ void ViewerWidget::paintGL() {
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;
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++;
}