From 62f9e55609db5e9e4d778d067b7c249c6aec5202 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Tue, 24 Dec 2019 16:17:33 +1100 Subject: [PATCH] implemented foundational reversed block code Ensured renderers can handle clips that are reversed. --- app/dialog/speedduration/speedduration.cpp | 45 ++++++++++++++++++++-- app/dialog/speedduration/speedduration.h | 11 ++++++ app/node/block/block.cpp | 12 +++++- app/node/block/block.h | 2 + app/render/backend/audiorenderworker.cpp | 18 +++++++++ 5 files changed, 83 insertions(+), 5 deletions(-) diff --git a/app/dialog/speedduration/speedduration.cpp b/app/dialog/speedduration/speedduration.cpp index af94d4799..d2c3c200a 100644 --- a/app/dialog/speedduration/speedduration.cpp +++ b/app/dialog/speedduration/speedduration.cpp @@ -33,6 +33,7 @@ SpeedDurationDialog::SpeedDurationDialog(const rational& timebase, const QListis_reversed() != this_clip->is_reversed()) { + all_reversed = false; + } + // If we've already determined both are different, no need to continue - if (!same_speed && !same_duration) { + if (!same_speed + && !same_duration + && !all_reversed) { break; } } @@ -97,10 +106,15 @@ SpeedDurationDialog::SpeedDurationDialog(const rational& timebase, const QListaddWidget(reverse_speed_checkbox_); + reverse_speed_checkbox_ = new QCheckBox(tr("Reverse Speed")); + if (all_reversed) { + reverse_speed_checkbox_->setChecked(clips_.first()->is_reversed()); + } else { + reverse_speed_checkbox_->setTristate(); + } + layout->addWidget(reverse_speed_checkbox_); + } maintain_audio_pitch_checkbox_ = new QCheckBox(tr("Maintain Audio Pitch")); layout->addWidget(maintain_audio_pitch_checkbox_); @@ -216,6 +230,10 @@ void SpeedDurationDialog::accept() // Change the speed by calculating the appropriate media out point for this clip new BlockSetMediaOutCommand(clip, new_media_out, command); } + + if (!reverse_speed_checkbox_->isTristate() && clip->is_reversed() != reverse_speed_checkbox_->isChecked()) { + new BlockReverseCommand(clip, command); + } } olive::undo_stack.pushIfHasChildren(command); @@ -311,3 +329,22 @@ void SpeedDurationDialog::DurationChanged() } } } + +BlockReverseCommand::BlockReverseCommand(Block *block, QUndoCommand *parent) : + QUndoCommand(parent), + block_(block) +{ +} + +void BlockReverseCommand::redo() +{ + rational temp = block_->media_in(); + block_->set_media_in(block_->media_out()); + block_->set_media_out(temp); +} + +void BlockReverseCommand::undo() +{ + // Since it's a simple swap, we can just run redo() again + redo(); +} diff --git a/app/dialog/speedduration/speedduration.h b/app/dialog/speedduration/speedduration.h index 8ea9d5e78..6dec3968e 100644 --- a/app/dialog/speedduration/speedduration.h +++ b/app/dialog/speedduration/speedduration.h @@ -44,4 +44,15 @@ private slots: void DurationChanged(); }; +class BlockReverseCommand : public QUndoCommand { +public: + BlockReverseCommand(Block* block, QUndoCommand* parent = nullptr); + + virtual void redo() override; + virtual void undo() override; + +private: + Block* block_; +}; + #endif // SPEEDDURATIONDIALOG_H diff --git a/app/node/block/block.cpp b/app/node/block/block.cpp index 2da792fd9..2ba6046a9 100644 --- a/app/node/block/block.cpp +++ b/app/node/block/block.cpp @@ -178,7 +178,17 @@ rational Block::media_length() const double Block::speed() const { - return media_length().toDouble() / length().toDouble(); + return qAbs(media_length().toDouble() / length().toDouble()); +} + +bool Block::is_still() const +{ + return (media_in() == media_out()); +} + +bool Block::is_reversed() const +{ + return (media_out() < media_in()); } const QString &Block::block_name() const diff --git a/app/node/block/block.h b/app/node/block/block.h index 29eca56e0..a4456e6a4 100644 --- a/app/node/block/block.h +++ b/app/node/block/block.h @@ -73,6 +73,8 @@ public: rational media_length() const; double speed() const; + bool is_still() const; + bool is_reversed() const; const QString& block_name() const; void set_block_name(const QString& name); diff --git a/app/render/backend/audiorenderworker.cpp b/app/render/backend/audiorenderworker.cpp index b3f999acf..e4ce85908 100644 --- a/app/render/backend/audiorenderworker.cpp +++ b/app/render/backend/audiorenderworker.cpp @@ -70,6 +70,24 @@ NodeValueTable AudioRenderWorker::RenderBlock(const TrackOutput *track, const Ti samples_from_this_block = speed_adjusted_samples; } + if (b->is_reversed()) { + int sample_size = audio_params_.samples_to_bytes(1); + int half_buffer_sz = samples_from_this_block.size() / 2; + char* temp_buffer = new char[sample_size]; + + for (int src_index=0;src_index