audiowaveformcache: improve passthrough system
This commit is contained in:
@@ -126,6 +126,17 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OverlapsWith(const TimeRange& r, bool in_inclusive = true, bool out_inclusive = true) const
|
||||
{
|
||||
for (const TimeRange &range : array_) {
|
||||
if (range.OverlapsWith(r, in_inclusive, out_inclusive)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isEmpty() const
|
||||
{
|
||||
return array_.isEmpty();
|
||||
|
||||
@@ -22,113 +22,94 @@
|
||||
|
||||
namespace olive {
|
||||
|
||||
#define super PlaybackCache
|
||||
|
||||
AudioWaveformCache::AudioWaveformCache(QObject *parent) :
|
||||
PlaybackCache{parent}
|
||||
super{parent}
|
||||
{
|
||||
waveforms_ = std::make_shared<AudioVisualWaveform>();
|
||||
}
|
||||
|
||||
void AudioWaveformCache::WriteWaveform(const TimeRange &range, const TimeRangeList &valid_ranges, const AudioVisualWaveform *waveform)
|
||||
{
|
||||
// Write each valid range to the segments
|
||||
foreach (const TimeRange& r, valid_ranges) {
|
||||
#ifdef AVW_USE_LIST
|
||||
// Write visual
|
||||
TimeRangeList::util_remove(&waveforms_, r);
|
||||
|
||||
if (waveform) {
|
||||
TimeRangeWithWaveform wv = r;
|
||||
rational local_start = r.in() - range.in();
|
||||
if (local_start != 0) {
|
||||
wv.waveform = waveform->Mid(local_start, r.length());
|
||||
} else {
|
||||
wv.waveform = *waveform;
|
||||
}
|
||||
waveforms_.append(wv);
|
||||
waveforms_->OverwriteSums(*waveform, r.in(), r.in() - range.in(), r.length());
|
||||
}
|
||||
#else
|
||||
if (waveform) {
|
||||
waveforms_.OverwriteSums(*waveform, r.in(), r.in() - range.in(), r.length());
|
||||
}
|
||||
#endif
|
||||
|
||||
Validate(r);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSubRect(QPainter *painter, const QRect &rect, const double &scale, const TimeRange &wave_range, const AudioVisualWaveform &waveform, const TimeRange &subrange)
|
||||
{
|
||||
// Find start time of passthrough
|
||||
TimeRange intersect = wave_range.Intersected(subrange);
|
||||
|
||||
// Create new rect that starts at the offset of pass_start from start_time
|
||||
// Set rect width to either length of passthrough or until the end
|
||||
QRect pass_rect(rect.x() + (intersect.in() - wave_range.in()).toDouble() * scale,
|
||||
rect.y(),
|
||||
intersect.length().toDouble() * scale,
|
||||
rect.height());
|
||||
|
||||
// Draw waveform with this info
|
||||
AudioVisualWaveform::DrawWaveform(painter, pass_rect, scale, waveform, intersect.in());
|
||||
}
|
||||
|
||||
void AudioWaveformCache::Draw(QPainter *painter, const QRect &rect, const double &scale, const rational &start_time) const
|
||||
{
|
||||
rational end = start_time + rational::fromDouble(rect.width() / scale);
|
||||
TimeRange draw_range(start_time, end);
|
||||
if (!passthroughs_.empty()) {
|
||||
TimeRange wave_range(start_time, start_time + rational::fromDouble(rect.width() / scale));
|
||||
TimeRangeList draw_range = {wave_range};
|
||||
for (const WaveformPassthrough &p : passthroughs_) {
|
||||
if (draw_range.OverlapsWith(p, true, false)) {
|
||||
DrawSubRect(painter, rect, scale, wave_range, *p.waveform, p);
|
||||
|
||||
#ifdef AVW_USE_LIST
|
||||
foreach (const TimeRangeWithWaveform &wv, waveforms_) {
|
||||
if (wv.OverlapsWith(draw_range)) {
|
||||
rational substart = std::max(wv.in(), draw_range.in());
|
||||
rational subend = std::min(wv.out(), draw_range.out());
|
||||
|
||||
QRect subrect = rect;
|
||||
subrect.setLeft(subrect.left() + (substart - draw_range.in()).toDouble()*scale);
|
||||
subrect.setWidth((subend - substart).toDouble()*scale);
|
||||
|
||||
rational local_start = substart - wv.in();
|
||||
AudioVisualWaveform::DrawWaveform(painter, subrect, scale, wv.waveform, local_start);
|
||||
// Remove this range
|
||||
draw_range.remove(p);
|
||||
}
|
||||
}
|
||||
|
||||
for (const TimeRange &r : draw_range) {
|
||||
DrawSubRect(painter, rect, scale, wave_range, *waveforms_, r);
|
||||
}
|
||||
} else {
|
||||
AudioVisualWaveform::DrawWaveform(painter, rect, scale, *waveforms_, start_time);
|
||||
}
|
||||
#else
|
||||
AudioVisualWaveform::DrawWaveform(painter, rect, scale, waveforms_, start_time);
|
||||
#endif
|
||||
}
|
||||
|
||||
AudioVisualWaveform::Sample AudioWaveformCache::GetSummaryFromTime(const rational &start, const rational &length) const
|
||||
{
|
||||
#ifdef AVW_USE_LIST
|
||||
QMap<rational, AudioVisualWaveform::Sample> sample;
|
||||
|
||||
TimeRange acquire(start, start+length);
|
||||
foreach (const TimeRangeWithWaveform &wv, waveforms_) {
|
||||
if (wv.OverlapsWith(acquire)) {
|
||||
TimeRange this_range = wv.Intersected(acquire);
|
||||
auto sum = wv.waveform.GetSummaryFromTime(this_range.in() - wv.in(), this_range.length());
|
||||
sample.insert(this_range.in(), sum);
|
||||
}
|
||||
}
|
||||
|
||||
AudioVisualWaveform::Sample result;
|
||||
|
||||
for (auto it=sample.cbegin(); it!=sample.cend(); it++) {
|
||||
result.insert(result.end(), it.value().begin(), it.value().end());
|
||||
}
|
||||
|
||||
return result;
|
||||
#else
|
||||
return waveforms_.GetSummaryFromTime(start, length);
|
||||
#endif
|
||||
return waveforms_->GetSummaryFromTime(start, length);
|
||||
}
|
||||
|
||||
rational AudioWaveformCache::length() const
|
||||
{
|
||||
#ifdef AVW_USE_LIST
|
||||
rational len = 0;
|
||||
|
||||
foreach (const TimeRangeWithWaveform &wv, waveforms_) {
|
||||
len = std::max(len, wv.out());
|
||||
}
|
||||
|
||||
return len;
|
||||
#else
|
||||
return waveforms_.length();
|
||||
#endif
|
||||
return waveforms_->length();
|
||||
}
|
||||
|
||||
void AudioWaveformCache::SetPassthrough(PlaybackCache *cache)
|
||||
{
|
||||
AudioWaveformCache *c = static_cast<AudioWaveformCache*>(cache);
|
||||
waveforms_ = c->waveforms_;
|
||||
|
||||
for (const TimeRange &r : c->GetValidatedRanges()) {
|
||||
Validate(r);
|
||||
WaveformPassthrough t = r;
|
||||
t.waveform = c->waveforms_;
|
||||
passthroughs_.append(t);
|
||||
}
|
||||
passthroughs_.append(c->passthroughs_);
|
||||
|
||||
SetParameters(c->GetParameters());
|
||||
SetSavingEnabled(c->IsSavingEnabled());
|
||||
}
|
||||
|
||||
void AudioWaveformCache::InvalidateEvent(const TimeRange& range)
|
||||
{
|
||||
TimeRangeList::util_remove(&passthroughs_, range);
|
||||
|
||||
super::InvalidateEvent(range);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
#include "audio/audiovisualwaveform.h"
|
||||
#include "playbackcache.h"
|
||||
|
||||
//#define AVW_USE_LIST
|
||||
|
||||
namespace olive {
|
||||
|
||||
class AudioWaveformCache : public PlaybackCache
|
||||
@@ -40,7 +38,7 @@ public:
|
||||
void SetParameters(const AudioParams &p)
|
||||
{
|
||||
params_ = p;
|
||||
waveforms_.set_channel_count(p.channel_count());
|
||||
waveforms_->set_channel_count(p.channel_count());
|
||||
}
|
||||
|
||||
void Draw(QPainter* painter, const QRect &rect, const double &scale, const rational &start_time) const;
|
||||
@@ -51,45 +49,28 @@ public:
|
||||
|
||||
virtual void SetPassthrough(PlaybackCache *cache) override;
|
||||
|
||||
protected:
|
||||
virtual void InvalidateEvent(const TimeRange& range);
|
||||
|
||||
private:
|
||||
#ifdef AVW_USE_LIST
|
||||
class TimeRangeWithWaveform : public TimeRange
|
||||
{
|
||||
public:
|
||||
TimeRangeWithWaveform() = default;
|
||||
TimeRangeWithWaveform(const TimeRange &r) :
|
||||
TimeRange(r)
|
||||
{
|
||||
}
|
||||
using WaveformPtr = std::shared_ptr<AudioVisualWaveform>;
|
||||
|
||||
void set_in(const rational& in)
|
||||
{
|
||||
waveform.TrimIn(in - this->in());
|
||||
TimeRange::set_in(in);
|
||||
}
|
||||
|
||||
void set_out(const rational& out)
|
||||
{
|
||||
waveform.Resize(out - this->in());
|
||||
TimeRange::set_out(out);
|
||||
}
|
||||
|
||||
void set_range(const rational& in, const rational& out)
|
||||
{
|
||||
waveform.TrimRange(in, out-in);
|
||||
TimeRange::set_range(in, out);
|
||||
}
|
||||
|
||||
AudioVisualWaveform waveform;
|
||||
};
|
||||
|
||||
QVector<TimeRangeWithWaveform> waveforms_;
|
||||
#else
|
||||
AudioVisualWaveform waveforms_;
|
||||
#endif
|
||||
WaveformPtr waveforms_;
|
||||
|
||||
AudioParams params_;
|
||||
|
||||
class WaveformPassthrough : public TimeRange
|
||||
{
|
||||
public:
|
||||
WaveformPassthrough(const TimeRange &r) :
|
||||
TimeRange(r)
|
||||
{}
|
||||
|
||||
WaveformPtr waveform;
|
||||
};
|
||||
|
||||
QVector<WaveformPassthrough> passthroughs_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user