Files
Renderive/YSGraphic_Core/plottable/AudioFrequent_p.h
T
2026-07-23 13:41:30 +08:00

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