many many things
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 |
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -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;
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -137,6 +137,8 @@ private slots:
|
||||
|
||||
void on_actionAdd_Default_Transition_triggered();
|
||||
|
||||
void on_actionSlide_Tool_triggered();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
void setup_layout();
|
||||
|
||||
@@ -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
@@ -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>
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,6 +3,9 @@
|
||||
|
||||
#include <QVector>
|
||||
|
||||
#define INT16_MAX 0x7fff
|
||||
#define INT16_MIN (-INT16_MAX-1)
|
||||
|
||||
class QAudioOutput;
|
||||
class QIODevice;
|
||||
|
||||
|
||||
+20
-4
@@ -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) {
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#define AUDIO_MONITOR_RESOLUTION 16
|
||||
|
||||
class AudioMonitor : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
+3
-2
@@ -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
@@ -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
@@ -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++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user