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;
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);

View File

@ -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)));
}
}

View File

@ -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);
}

View File

@ -27,7 +27,7 @@ void PreviewWidget::paintEvent(QPaintEvent *event)
painter.drawRect(m_graphCache.rect());
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();
}

View File

@ -1,9 +1,13 @@
#include "scratchwidget.h"
#include <QPainter>
#include <QRect>
#include <QDebug>
#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<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
#include <vector>
#include <QWidget>
#include <QAudioBuffer>
#include <QCache>
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<QPixmap> m_graphCache;
std::size_t m_position{};
QCache<int, QPixmap> m_graphCache;
};