Implemented basic preview!

This commit is contained in:
2020-04-27 23:39:49 +02:00
parent e9c905eb67
commit 686f42265e
6 changed files with 70 additions and 18 deletions

View File

@ -59,8 +59,11 @@ void AudioPlayer::writeSamples(frame_t *begin, frame_t *end)
m_position = position; m_position = position;
const auto now = QDateTime::currentDateTime(); 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); emit positionChanged(m_position);
m_lastPositionUpdate = now;
}
if (ended) if (ended)
emit playingChanged(m_playing = false); emit playingChanged(m_playing = false);

View File

@ -15,17 +15,16 @@ QPixmap GraphRenderer::render(const QSize &size, const frame_t *frameBegin, cons
painter.fillRect(pixmap.rect(), palette.base()); painter.fillRect(pixmap.rect(), palette.base());
painter.setPen(Qt::white); painter.setBrush(palette.base());
painter.setBrush(Qt::black);
painter.drawRect(QRect({}, size)); painter.drawRect(pixmap.rect());
render(size, frameBegin, frameEnd, painter, palette); render(pixmap.rect(), frameBegin, frameEnd, painter, palette);
painter.end(); painter.end();
return pixmap; 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) if (frameEnd == frameBegin)
return; 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.setPen(QPen{palette.color(QPalette::Text)});
painter.setBrush(palette.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 *begin = frameBegin + (x * framesPerPixel);
const frame_t *end = begin + 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]; max[1] = (*iter)[1];
} }
painter.drawLine(x, (size.height() / 2) - (min[0] * (size.height() / 2)), painter.drawLine(rect.x() + x, rect.y() + (rect.height() / 2) - (min[0] * (rect.height() / 2)),
x, (size.height() / 2) + (max[0] * (size.height() / 2))); rect.x() + x, rect.y() + (rect.height() / 2) + (max[0] * (rect.height() / 2)));
} }
} }

View File

@ -10,5 +10,5 @@ class QPalette;
namespace GraphRenderer namespace GraphRenderer
{ {
QPixmap render(const QSize &size, const frame_t *frameBegin, const frame_t *frameEnd, const QPalette &palette); 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);
} }

View File

@ -27,7 +27,7 @@ void PreviewWidget::paintEvent(QPaintEvent *event)
painter.drawRect(m_graphCache.rect()); painter.drawRect(m_graphCache.rect());
if (m_buffer.isValid()) if (m_buffer.isValid())
GraphRenderer::render(size(), m_buffer.constData<frame_t>(), m_buffer.constData<frame_t>() + m_buffer.frameCount(), painter, palette()); GraphRenderer::render(m_graphCache.rect(), m_buffer.constData<frame_t>(), m_buffer.constData<frame_t>() + m_buffer.frameCount(), painter, palette());
painter.end(); painter.end();
} }

View File

@ -1,9 +1,13 @@
#include "scratchwidget.h" #include "scratchwidget.h"
#include <QPainter> #include <QPainter>
#include <QRect>
#include <QDebug>
#include "graphrenderer.h" #include "graphrenderer.h"
constexpr auto theWidth = 100;
ScratchWidget::ScratchWidget(QWidget *parent) : ScratchWidget::ScratchWidget(QWidget *parent) :
QWidget{parent} QWidget{parent}
{ {
@ -18,6 +22,29 @@ void ScratchWidget::paintEvent(QPaintEvent *event)
painter.setBrush(palette().window()); painter.setBrush(palette().window());
painter.drawRect(rect()); 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}; QPen pen{Qt::red};
pen.setWidth(3); 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<frame_t>() + (index*sampleRate);
const auto pixmap = GraphRenderer::render(QSize{theWidth, height()}, begin, begin+sampleRate, palette());
m_graphCache.insert(index, new QPixmap{pixmap});
return pixmap;
}

View File

@ -1,9 +1,8 @@
#pragma once #pragma once
#include <vector>
#include <QWidget> #include <QWidget>
#include <QAudioBuffer> #include <QAudioBuffer>
#include <QCache>
class ScratchWidget : public QWidget class ScratchWidget : public QWidget
{ {
@ -15,8 +14,8 @@ public:
const QAudioBuffer &buffer() const { return m_buffer; } const QAudioBuffer &buffer() const { return m_buffer; }
void setBuffer(const QAudioBuffer &buffer) { m_buffer = buffer; m_graphCache.clear(); repaint(); } void setBuffer(const QAudioBuffer &buffer) { m_buffer = buffer; m_graphCache.clear(); repaint(); }
double position() const { return m_position; } std::size_t position() const { return m_position; }
void setPosition(double position) { m_position = position; repaint(); } void setPosition(std::size_t position) { m_position = position; repaint(); }
protected: protected:
void paintEvent(QPaintEvent *event) override; void paintEvent(QPaintEvent *event) override;
@ -25,7 +24,9 @@ protected:
void mouseMoveEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override;
private: private:
QPixmap getPixmap(int index);
QAudioBuffer m_buffer; QAudioBuffer m_buffer;
double m_position{}; std::size_t m_position{};
std::vector<QPixmap> m_graphCache; QCache<int, QPixmap> m_graphCache;
}; };