/***
Olive - Non-Linear Video Editor
Copyright (C) 2019 Olive Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
***/
#include "audiowaveformview.h"
#include
#include
#include
#include "common/clamp.h"
#include "config/config.h"
OLIVE_NAMESPACE_ENTER
AudioWaveformView::AudioWaveformView(QWidget *parent) :
SeekableWidget(parent),
backend_(nullptr)
{
setAutoFillBackground(true);
setBackgroundRole(QPalette::Base);
}
void AudioWaveformView::SetBackend(AudioRenderBackend *backend)
{
if (backend_) {
disconnect(backend_, &AudioRenderBackend::QueueComplete, this, &AudioWaveformView::ForceUpdate);
disconnect(backend_, &AudioRenderBackend::ParamsChanged, this, &AudioWaveformView::BackendParamsChanged);
SetTimebase(0);
}
backend_ = backend;
if (backend_) {
connect(backend_, &AudioRenderBackend::QueueComplete, this, &AudioWaveformView::ForceUpdate);
connect(backend_, &AudioRenderBackend::ParamsChanged, this, &AudioWaveformView::BackendParamsChanged);
SetTimebase(backend_->params().time_base());
}
ForceUpdate();
}
void AudioWaveformView::DrawWaveform(QPainter *painter, const QRect& rect, const double& scale, const SampleSummer::Sum* samples, int nb_samples, int channels)
{
int sample_index, next_sample_index = 0;
QVector summary;
int summary_index = -1;
int channel_height = rect.height() / channels;
int channel_half_height = channel_height / 2;
for (int i=0;i(SampleSummer::kSumSampleRate) * static_cast(i+1) / scale) * channels);
if (summary_index != sample_index) {
summary = SampleSummer::ReSumSamples(&samples[sample_index],
qMax(channels, next_sample_index - sample_index),
channels);
summary_index = sample_index;
}
int line_x = i + rect.x();
for (int j=0;jdrawLine(line_x,
channel_bottom - diff,
line_x,
channel_bottom);
} else{
int channel_mid = rect.y() + channel_height * j + channel_half_height;
painter->drawLine(line_x,
channel_mid + clamp(qRound(summary.at(j).min * channel_half_height), -channel_half_height, channel_half_height),
line_x,
channel_mid + clamp(qRound(summary.at(j).max * channel_half_height), -channel_half_height, channel_half_height));
}
}
}
}
void AudioWaveformView::paintEvent(QPaintEvent *event)
{
QWidget::paintEvent(event);
if (!backend_ || backend_->CachePathName().isEmpty() || !backend_->params().is_valid()) {
return;
}
const AudioRenderingParams& params = backend_->params();
if (cached_size_ != size()
|| cached_scale_ != GetScale()
|| cached_scroll_ != GetScroll()) {
cached_waveform_ = QPixmap(size());
cached_waveform_.fill(Qt::transparent);
QFile fs(backend_->CachePathName());
if (fs.open(QFile::ReadOnly)) {
QPainter wave_painter(&cached_waveform_);
// FIXME: Hardcoded color
wave_painter.setPen(QColor(64, 255, 160));
int channel_height = height() / params.channel_count();
int channel_half_height = channel_height / 2;
int drew = 0;
fs.seek(params.samples_to_bytes(ScreenToUnitRounded(0)));
for (int x=0; x samples = SampleSummer::SumSamples(reinterpret_cast(read_buffer.constData()),
samples_len,
params.channel_count());
for (int i=0;i(channel_half_height)),
x,
channel_mid + qRound(samples.at(i).max * static_cast(channel_half_height)));
}
drew++;
}
}
cached_size_ = size();
cached_scale_ = GetScale();
cached_scroll_ = GetScroll();
fs.close();
}
}
QPainter p(this);
// Draw in/out points
DrawTimelinePoints(&p);
// Draw cached waveform pixmap
p.drawPixmap(0, 0, cached_waveform_);
// Draw playhead
p.setPen(GetPlayheadColor());
int playhead_x = UnitToScreen(GetTime());
p.drawLine(playhead_x, 0, playhead_x, height());
}
void AudioWaveformView::BackendParamsChanged()
{
SetTimebase(backend_->params().time_base());
}
void AudioWaveformView::ForceUpdate()
{
cached_size_ = QSize();
update();
}
OLIVE_NAMESPACE_EXIT