#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 mDataList; void clear() override { mDataList.clear(); } }; struct AudioFrequentRenderState : RenderState, AudioFrequent_Prop {}; struct AudioFrequentPrivate : RenderData { D_Ptr(AudioFrequent) Psc::StreamRingBuffer_ST buffer; std::vector 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(); } }; }