-
Notifications
You must be signed in to change notification settings - Fork 65
Expand file tree
/
Copy pathWaveformWidget.h
More file actions
118 lines (99 loc) · 3.56 KB
/
Copy pathWaveformWidget.h
File metadata and controls
118 lines (99 loc) · 3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#pragma once
#include <QByteArray>
#include <QElapsedTimer>
#include <QRectF>
#include <QString>
#include <QTimer>
#include <QVector>
#include <QWidget>
class QMouseEvent;
class QPainter;
class QPaintEvent;
namespace AetherSDR {
class WaveformWidget : public QWidget {
Q_OBJECT
public:
enum class ViewMode {
Graph,
Envelope,
Bars,
VerticalBars
};
explicit WaveformWidget(QWidget* parent = nullptr);
QSize sizeHint() const override { return {240, 160}; }
QSize minimumSizeHint() const override { return {220, 110}; }
ViewMode viewMode() const { return m_viewMode; }
int zoomWindowMs() const { return m_windowMs; }
int refreshRateHz() const { return m_refreshRateHz; }
float amplitudeZoom() const { return m_amplitudeZoom; }
void setViewMode(ViewMode mode);
void setZoomWindowMs(int windowMs);
void setRefreshRateHz(int hz);
void setAmplitudeZoom(float zoom);
public slots:
void appendScopeSamples(const QByteArray& monoFloat32Pcm, int sampleRate, bool tx);
void setTransmitting(bool tx);
void clear();
signals:
void settingsDrawerToggleRequested();
protected:
void paintEvent(QPaintEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override;
void mouseDoubleClickEvent(QMouseEvent* event) override;
private:
struct RingBuffer {
QVector<float> samples;
int writeIndex{0};
int filled{0};
int sampleRate{24000};
QElapsedTimer lastSamples;
};
struct ColumnStats {
float min{0.0f};
float max{0.0f};
float peak{0.0f};
float rms{0.0f};
int clipped{0};
};
RingBuffer& activeBuffer();
const RingBuffer& activeBuffer() const;
void ensureCapacity(RingBuffer& buffer, int sampleRate);
void appendToRing(RingBuffer& buffer, const float* samples, int count, int sampleRate);
void clearRing(RingBuffer& buffer);
void copyLatest(const RingBuffer& buffer, int count, QVector<float>& out) const;
void setPaused(bool paused);
void buildColumns(int columnCount);
void drawGrid(QPainter& painter, const QRectF& plotRect, int sampleRate) const;
void drawBarsGrid(QPainter& painter, const QRectF& plotRect) const;
void drawGraph(QPainter& painter, const QRectF& plotRect, int clipCount);
void drawEnvelope(QPainter& painter, const QRectF& plotRect, int clipCount);
void drawBars(QPainter& painter, const QRectF& plotRect);
void drawVerticalBars(QPainter& painter, const QRectF& plotRect, int sampleRate);
void drawNoAudio(QPainter& painter, const QRectF& plotRect, const QString& source) const;
void drawPausedBadge(QPainter& painter, const QRectF& footerRect) const;
void scheduleRepaint();
static int sanitizeSampleRate(int sampleRate);
static int sanitizeWindowMs(int windowMs);
static int sanitizeRefreshRateHz(int hz);
static float sanitizeAmplitudeZoom(float zoom);
static float clampSample(float sample);
static float dbToAmplitude(float db);
static float linearToDb(float value);
RingBuffer m_rx;
RingBuffer m_tx;
QVector<float> m_displaySamples;
QVector<float> m_pausedSamples;
QVector<ColumnStats> m_columns;
QTimer m_clickTimer;
QElapsedTimer m_repaintThrottle;
bool m_ignoreNextRelease{false};
bool m_paused{false};
bool m_pausedTransmitting{false};
bool m_transmitting{false};
int m_pausedSampleRate{24000};
int m_windowMs{100};
int m_refreshRateHz{24};
float m_amplitudeZoom{1.7f};
ViewMode m_viewMode{ViewMode::Graph};
};
} // namespace AetherSDR