/*** 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