-
Notifications
You must be signed in to change notification settings - Fork 301
Expand file tree
/
Copy pathspectrogramplot.h
More file actions
146 lines (124 loc) · 4.23 KB
/
spectrogramplot.h
File metadata and controls
146 lines (124 loc) · 4.23 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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
* Copyright (C) 2015, Mike Walters <mike@flomp.net>
*
* This file is part of inspectrum.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QCache>
#include <QString>
#include <QWidget>
#include "fft.h"
#include "inputsource.h"
#include "plot.h"
#include "tuner.h"
#include "tunertransform.h"
#include <memory>
#include <array>
#include <math.h>
#include <vector>
class AnnotationLocation;
class TileCacheKey
{
public:
TileCacheKey(int fftSize, int zoomLevel, size_t sample) {
this->fftSize = fftSize;
this->zoomLevel = zoomLevel;
this->sample = sample;
}
bool operator==(const TileCacheKey &k2) const {
return (this->fftSize == k2.fftSize) &&
(this->zoomLevel == k2.zoomLevel) &&
(this->sample == k2.sample);
}
int fftSize;
int zoomLevel;
size_t sample;
};
class SpectrogramPlot : public Plot
{
Q_OBJECT
public:
SpectrogramPlot(std::shared_ptr<SampleSource<std::complex<float>>> src);
void invalidateEvent() override;
std::shared_ptr<AbstractSampleSource> output() override;
void paintFront(QPainter &painter, QRect &rect, range_t<size_t> sampleRange) override;
void paintMid(QPainter &painter, QRect &rect, range_t<size_t> sampleRange) override;
bool mouseEvent(QEvent::Type type, QMouseEvent *event) override;
void leaveEvent();
std::shared_ptr<SampleSource<std::complex<float>>> input() { return inputSource; };
void setSampleRate(double sampleRate);
bool tunerEnabled();
void enableScales(bool enabled);
void enableAnnotations(bool enabled);
void enableTimeFrequencyPointers(bool timePointer, bool frequencyPointer);
bool isAnnotationsEnabled();
QString *mouseAnnotationComment(const QMouseEvent *event);
public slots:
void setFFTSize(int size);
void setPowerMax(int power);
void setPowerMin(int power);
void setZoomLevel(int zoom);
void tunerMoved();
private:
const int linesPerGraduation = 50;
static const int tileSize = 65536; // This must be a multiple of the maximum FFT size
std::shared_ptr<SampleSource<std::complex<float>>> inputSource;
std::vector<AnnotationLocation> visibleAnnotationLocations;
std::unique_ptr<FFT> fft;
std::unique_ptr<float[]> window;
QCache<TileCacheKey, QPixmap> pixmapCache;
QCache<TileCacheKey, std::array<float, tileSize>> fftCache;
uint colormap[256];
int fftSize;
int zoomLevel;
float powerMax;
float powerMin;
double sampleRate;
bool frequencyScaleEnabled;
bool sigmfAnnotationsEnabled;
bool timePointerEnabled;
bool frequencyPointerEnabled;
int mouseX;
int mouseY;
Tuner tuner;
std::shared_ptr<TunerTransform> tunerTransform;
QPixmap* getPixmapTile(size_t tile);
float* getFFTTile(size_t tile);
void getLine(float *dest, size_t sample);
int getStride();
float getTunerPhaseInc();
std::vector<float> getTunerTaps();
int linesPerTile();
void paintFrequencyScale(QPainter &painter, QRect &rect);
void paintAnnotations(QPainter &painter, QRect &rect, range_t<size_t> sampleRange);
void paintTimeFrequencyPointers(QPainter &painter, QRect &rect, range_t<size_t> sampleRange);
};
class AnnotationLocation
{
public:
Annotation annotation;
AnnotationLocation(Annotation annotation, int x, int y, int width, int height)
: annotation(annotation), x(x), y(y), width(width), height(height) {}
bool isInside(int pos_x, int pos_y) {
return (x <= pos_x) && (pos_x <= x + width)
&& (y <= pos_y) && (pos_y <= y + height);
}
private:
int x;
int y;
int width;
int height;
};