88 lines
3.2 KiB
C++
88 lines
3.2 KiB
C++
#pragma once
|
|
|
|
#include "AudioFrequent.h"
|
|
#include "../RenderAble.h"
|
|
#include "../Axis/Axis_p.h"
|
|
#include "../Axis/TimeAxis.h"
|
|
#include "../Axis/TimeAxis_p.h"
|
|
#include "../base/PerformanceShower_p.h"
|
|
#include "../base/Plot_p.h"
|
|
namespace YSG {
|
|
struct AudioFrequentInputData : InputData {
|
|
std::list<double> mDataList;
|
|
void clear() override {
|
|
mDataList.clear();
|
|
}
|
|
};
|
|
struct AudioFrequentRenderState : RenderState, AudioFrequent_Prop {};
|
|
|
|
struct AudioFrequentPrivate : RenderData {
|
|
D_Ptr(AudioFrequent)
|
|
Psc::StreamRingBuffer_ST buffer;
|
|
std::vector<double> powerSnapshot;
|
|
int dataCount{};
|
|
int pointCount{};
|
|
void resizePowerBuffer(int count) {
|
|
pointCount = count;
|
|
dataCount = 0;
|
|
powerSnapshot.resize(count);
|
|
buffer.init(sizeof(double) * count);
|
|
}
|
|
void pushPower(double power) {
|
|
if(dataCount == pointCount) {
|
|
double ignored;
|
|
std::size_t len = sizeof(double);
|
|
buffer.read(&ignored, len);
|
|
--dataCount;
|
|
}
|
|
buffer.write(&power, sizeof(double));
|
|
++dataCount;
|
|
}
|
|
void snapshotPowerBuffer() {
|
|
buffer.peek_best_effort(powerSnapshot.data(), sizeof(double) * dataCount);
|
|
}
|
|
void prepareData() override {
|
|
syncStatePipeline();
|
|
AudioFrequentRenderState *s = renderState();
|
|
AudioFrequentInputData *d = renderInputData();
|
|
if(pointCount != s->timePointSize) {
|
|
resizePowerBuffer(s->timePointSize);
|
|
PerformanceShower *shower = q()->mPlot->d->mShower;
|
|
if(shower) {
|
|
shower->setPerformanceLine("TimePointSize", PerformanceLine(QString("timePointSize:%1").arg(s->timePointSize)));
|
|
}
|
|
}
|
|
for(double& power : d->mDataList) {
|
|
pushPower(power);
|
|
}
|
|
snapshotPowerBuffer();
|
|
clearRenderInput();
|
|
}
|
|
|
|
|
|
void draw(QPainter* painter) override {
|
|
AudioFrequentRenderState *s = renderState();
|
|
PerformanceShower *shower = q()->mPlot->d->mShower;
|
|
if(shower) {
|
|
shower->setPerformanceLine("timePointSize", PerformanceLine(QString("timePointSize:%1").arg(s->timeAxis->timePointSize())));
|
|
}
|
|
painter->save();
|
|
QPolygonF polyline;
|
|
int start = (int)s->timeAxis->startCoord();
|
|
QPen newPen = QPen(s->color);
|
|
newPen.setWidth(0);
|
|
painter->setPen(newPen);
|
|
for(int i = 0; i < dataCount; ++i) {
|
|
double* power = powerSnapshot.data() + dataCount - 1 - i;
|
|
int index = s->timeAxis->d()->mTimeTicker.mStartCoordToEndCoord ? start + i :
|
|
start + s->timeAxis->d()->mTimeTicker.mTimePointSize - i;
|
|
double x = s->timeAxis->coordToPixel(index, SRC::Render);
|
|
double y = s->valueAxis->coordToPixel(*power, SRC::Render);
|
|
polyline.append({x, y});
|
|
}
|
|
painter->drawPolyline(polyline);
|
|
painter->restore();
|
|
}
|
|
};
|
|
}
|