Files
DrumMachine/graphrenderer.cpp
2022-12-27 21:19:21 +01:00

92 lines
2.5 KiB
C++

#include "graphrenderer.h"
#include <iterator>
#include <QPixmap>
#include <QPainter>
#include <QPalette>
#include <QRect>
#include <QPoint>
#include "audioformat.h"
QPixmap GraphRenderer::render(const QSize &size, const frame_t *begin, const frame_t *end, const QPalette &palette)
{
QPixmap pixmap{size};
{
QPainter painter;
painter.begin(&pixmap);
painter.setPen({});
painter.setBrush(palette.base());
painter.drawRect(pixmap.rect());
painter.setPen(QPen{palette.color(QPalette::Text)});
painter.setBrush(palette.text());
render(pixmap.rect(), begin, end, painter);
painter.end();
}
return pixmap;
}
void GraphRenderer::render(const QRect &rect, const frame_t *begin, const frame_t *end, QPainter &painter)
{
if (end == begin)
return;
std::pair<frame_t, frame_t> arr[rect.width()];
reduceSamples(begin, end, arr, arr+rect.width());
render(rect.topLeft(), rect.height(), arr, arr+rect.width(), painter);
}
void GraphRenderer::render(const QPoint &pos, int height, std::pair<frame_t, frame_t> *begin, std::pair<frame_t, frame_t> *end, QPainter &painter)
{
int x = pos.x();
for (auto iter = begin; iter != end; iter++)
{
const frame_t &min = iter->first;
const frame_t &max = iter->second;
painter.drawLine(x, pos.y() + (height / 2) - (min[0] * (height / 2)),
x, pos.y() + (height / 2) + (max[0] * (height / 2)));
x++;
}
}
void GraphRenderer::reduceSamples(const frame_t *inputBegin, const frame_t *inputEnd, std::pair<frame_t, frame_t> *outputBegin, std::pair<frame_t, frame_t> *outputEnd)
{
const auto inputLength = std::distance(inputBegin, inputEnd);
const auto outputLength = std::distance(outputBegin, outputEnd);
const auto framesPerPixel = inputLength / outputLength;
for (int i = 0; i < outputLength; i++)
{
frame_t &min = outputBegin[i].first;
frame_t &max = outputBegin[i].second;
min = {1.f, 1.f};
max = {-1.f, -1.f};
const frame_t *begin = inputBegin + (i * framesPerPixel);
const frame_t *end = begin + framesPerPixel;
for (auto iter = begin; iter != end; iter++)
{
if ((*iter)[0] < min[0])
min[0] = (*iter)[0];
if ((*iter)[1] < min[1])
min[1] = (*iter)[1];
if ((*iter)[0] > max[0])
max[0] = (*iter)[0];
if ((*iter)[1] > max[1])
max[1] = (*iter)[1];
}
}
}