From 686f42265e694155a9a726262e7dcedd01159e40 Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Mon, 27 Apr 2020 23:39:49 +0200 Subject: [PATCH] Implemented basic preview! --- audioplayer.cpp | 5 ++++- graphrenderer.cpp | 17 ++++++++-------- graphrenderer.h | 2 +- previewwidget.cpp | 2 +- scratchwidget.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++ scratchwidget.h | 13 +++++++------ 6 files changed, 70 insertions(+), 18 deletions(-) diff --git a/audioplayer.cpp b/audioplayer.cpp index edeea4a..764fb5a 100644 --- a/audioplayer.cpp +++ b/audioplayer.cpp @@ -59,8 +59,11 @@ void AudioPlayer::writeSamples(frame_t *begin, frame_t *end) m_position = position; const auto now = QDateTime::currentDateTime(); - if (m_lastPositionUpdate.isNull() || m_lastPositionUpdate.msecsTo(now) > 100) + if (m_lastPositionUpdate.isNull() || m_lastPositionUpdate.msecsTo(now) > 1000/30) + { emit positionChanged(m_position); + m_lastPositionUpdate = now; + } if (ended) emit playingChanged(m_playing = false); diff --git a/graphrenderer.cpp b/graphrenderer.cpp index a1f1c25..752ecd2 100644 --- a/graphrenderer.cpp +++ b/graphrenderer.cpp @@ -15,17 +15,16 @@ QPixmap GraphRenderer::render(const QSize &size, const frame_t *frameBegin, cons painter.fillRect(pixmap.rect(), palette.base()); - painter.setPen(Qt::white); - painter.setBrush(Qt::black); + painter.setBrush(palette.base()); - painter.drawRect(QRect({}, size)); + painter.drawRect(pixmap.rect()); - render(size, frameBegin, frameEnd, painter, palette); + render(pixmap.rect(), frameBegin, frameEnd, painter, palette); painter.end(); return pixmap; } -void GraphRenderer::render(const QSize &size, const frame_t *frameBegin, const frame_t *frameEnd, QPainter &painter, const QPalette &palette) +void GraphRenderer::render(const QRect &rect, const frame_t *frameBegin, const frame_t *frameEnd, QPainter &painter, const QPalette &palette) { if (frameEnd == frameBegin) return; @@ -33,9 +32,9 @@ void GraphRenderer::render(const QSize &size, const frame_t *frameBegin, const f painter.setPen(QPen{palette.color(QPalette::Text)}); painter.setBrush(palette.text()); - const auto framesPerPixel = std::distance(frameBegin, frameEnd) / size.width(); + const auto framesPerPixel = std::distance(frameBegin, frameEnd) / rect.width(); - for (int x = 0; x < size.width(); x++) + for (int x = 0; x < rect.width(); x++) { const frame_t *begin = frameBegin + (x * framesPerPixel); const frame_t *end = begin + framesPerPixel; @@ -53,7 +52,7 @@ void GraphRenderer::render(const QSize &size, const frame_t *frameBegin, const f max[1] = (*iter)[1]; } - painter.drawLine(x, (size.height() / 2) - (min[0] * (size.height() / 2)), - x, (size.height() / 2) + (max[0] * (size.height() / 2))); + painter.drawLine(rect.x() + x, rect.y() + (rect.height() / 2) - (min[0] * (rect.height() / 2)), + rect.x() + x, rect.y() + (rect.height() / 2) + (max[0] * (rect.height() / 2))); } } diff --git a/graphrenderer.h b/graphrenderer.h index 71eef46..0e4dcef 100644 --- a/graphrenderer.h +++ b/graphrenderer.h @@ -10,5 +10,5 @@ class QPalette; namespace GraphRenderer { QPixmap render(const QSize &size, const frame_t *frameBegin, const frame_t *frameEnd, const QPalette &palette); - void render(const QSize &size, const frame_t *frameBegin, const frame_t *frameEnd, QPainter &painter, const QPalette &palette); + void render(const QRect &rect, const frame_t *frameBegin, const frame_t *frameEnd, QPainter &painter, const QPalette &palette); } diff --git a/previewwidget.cpp b/previewwidget.cpp index d353424..8d86c31 100644 --- a/previewwidget.cpp +++ b/previewwidget.cpp @@ -27,7 +27,7 @@ void PreviewWidget::paintEvent(QPaintEvent *event) painter.drawRect(m_graphCache.rect()); if (m_buffer.isValid()) - GraphRenderer::render(size(), m_buffer.constData(), m_buffer.constData() + m_buffer.frameCount(), painter, palette()); + GraphRenderer::render(m_graphCache.rect(), m_buffer.constData(), m_buffer.constData() + m_buffer.frameCount(), painter, palette()); painter.end(); } diff --git a/scratchwidget.cpp b/scratchwidget.cpp index 2e30543..c906053 100644 --- a/scratchwidget.cpp +++ b/scratchwidget.cpp @@ -1,9 +1,13 @@ #include "scratchwidget.h" #include +#include +#include #include "graphrenderer.h" +constexpr auto theWidth = 100; + ScratchWidget::ScratchWidget(QWidget *parent) : QWidget{parent} { @@ -18,6 +22,29 @@ void ScratchWidget::paintEvent(QPaintEvent *event) painter.setBrush(palette().window()); painter.drawRect(rect()); + if (m_buffer.isValid() && m_position < m_buffer.frameCount() - sampleRate) + { + { + QPen pen{Qt::blue}; + pen.setWidth(3); + painter.setPen(pen); + } + + const auto doit = [&](int offset) + { + int x = ((width()/2)-(float(m_position % sampleRate) / sampleRate * theWidth)) + (theWidth*offset); + const auto pixmap = getPixmap((m_position/sampleRate)+offset); + if (!pixmap.isNull()) + painter.drawPixmap(x, 0, pixmap); + }; + + doit(-2); + doit(-1); + doit(0); + doit(1); + doit(2); + } + { QPen pen{Qt::red}; pen.setWidth(3); @@ -43,3 +70,25 @@ void ScratchWidget::mouseMoveEvent(QMouseEvent *event) { } + +QPixmap ScratchWidget::getPixmap(int index) +{ + { + const auto pixmap = m_graphCache[index]; + if (pixmap) + return *pixmap; + } + + if (!m_buffer.isValid() || index < 0 || index >= m_buffer.frameCount()/sampleRate) + { + qWarning() << index; + return {}; + } + + const auto *begin = m_buffer.constData() + (index*sampleRate); + const auto pixmap = GraphRenderer::render(QSize{theWidth, height()}, begin, begin+sampleRate, palette()); + + m_graphCache.insert(index, new QPixmap{pixmap}); + + return pixmap; +} diff --git a/scratchwidget.h b/scratchwidget.h index d95ea7f..544af16 100644 --- a/scratchwidget.h +++ b/scratchwidget.h @@ -1,9 +1,8 @@ #pragma once -#include - #include #include +#include class ScratchWidget : public QWidget { @@ -15,8 +14,8 @@ public: const QAudioBuffer &buffer() const { return m_buffer; } void setBuffer(const QAudioBuffer &buffer) { m_buffer = buffer; m_graphCache.clear(); repaint(); } - double position() const { return m_position; } - void setPosition(double position) { m_position = position; repaint(); } + std::size_t position() const { return m_position; } + void setPosition(std::size_t position) { m_position = position; repaint(); } protected: void paintEvent(QPaintEvent *event) override; @@ -25,7 +24,9 @@ protected: void mouseMoveEvent(QMouseEvent *event) override; private: + QPixmap getPixmap(int index); + QAudioBuffer m_buffer; - double m_position{}; - std::vector m_graphCache; + std::size_t m_position{}; + QCache m_graphCache; };