comparison layer/Colour3DPlotExporter.cpp @ 1556:ac8da42674ff spectrogram-export

Handle peaks
author Chris Cannam
date Tue, 07 Jan 2020 11:18:57 +0000
parents a0b2f3b4dd2f
children 760ada8e3972
comparison
equal deleted inserted replaced
1555:745be36202aa 1556:ac8da42674ff
17 #include "data/model/EditableDenseThreeDimensionalModel.h" 17 #include "data/model/EditableDenseThreeDimensionalModel.h"
18 #include "data/model/FFTModel.h" 18 #include "data/model/FFTModel.h"
19 19
20 #include "VerticalBinLayer.h" 20 #include "VerticalBinLayer.h"
21 21
22 Colour3DPlotExporter::Colour3DPlotExporter(Sources sources, Parameters params) :
23 m_sources(sources),
24 m_params(params)
25 {
26 SVCERR << "Colour3DPlotExporter::Colour3DPlotExporter: constructed at "
27 << this << endl;
28 }
29
30 Colour3DPlotExporter::~Colour3DPlotExporter()
31 {
32 SVCERR << "Colour3DPlotExporter[" << this << "]::~Colour3DPlotExporter"
33 << endl;
34 }
35
36 void
37 Colour3DPlotExporter::discardSources()
38 {
39 SVCERR << "Colour3DPlotExporter[" << this << "]::discardSources"
40 << endl;
41 QMutexLocker locker(&m_mutex);
42 m_sources.verticalBinLayer = nullptr;
43 m_sources.source = {};
44 m_sources.fft = {};
45 m_sources.provider = nullptr;
46 }
47
22 QString 48 QString
23 Colour3DPlotExporter::toDelimitedDataString(QString delimiter, 49 Colour3DPlotExporter::toDelimitedDataString(QString delimiter,
24 DataExportOptions options, 50 DataExportOptions options,
25 sv_frame_t startFrame, 51 sv_frame_t startFrame,
26 sv_frame_t duration) const 52 sv_frame_t duration) const
27 { 53 {
28 QMutexLocker locker(&m_mutex); 54 QMutexLocker locker(&m_mutex);
29 55
30 BinDisplay binDisplay = m_params.binDisplay; 56 BinDisplay binDisplay = m_params.binDisplay;
57
58 (void)options; //!!!
31 59
32 auto model = 60 auto model =
33 ModelById::getAs<DenseThreeDimensionalModel>(m_sources.source); 61 ModelById::getAs<DenseThreeDimensionalModel>(m_sources.source);
34 auto fftModel = 62 auto fftModel =
35 ModelById::getAs<FFTModel>(m_sources.fft); 63 ModelById::getAs<FFTModel>(m_sources.fft);
37 auto layer = m_sources.verticalBinLayer; 65 auto layer = m_sources.verticalBinLayer;
38 auto provider = m_sources.provider; 66 auto provider = m_sources.provider;
39 67
40 if (!model || !layer) { 68 if (!model || !layer) {
41 SVCERR << "ERROR: Colour3DPlotExporter::toDelimitedDataString: Source model and layer required" << endl; 69 SVCERR << "ERROR: Colour3DPlotExporter::toDelimitedDataString: Source model and layer required" << endl;
70 return {};
71 }
72 if ((binDisplay == BinDisplay::PeakFrequencies) && !fftModel) {
73 SVCERR << "ERROR: Colour3DPlotExporter::toDelimitedDataString: FFT model required in peak frequencies mode" << endl;
42 return {}; 74 return {};
43 } 75 }
44 76
45 int minbin = 0; 77 int minbin = 0;
46 int sh = model->getHeight(); 78 int sh = model->getHeight();
55 //!!! are. Perhaps we should have a flag to export full height, 87 //!!! are. Perhaps we should have a flag to export full height,
56 //!!! and default to using it. 88 //!!! and default to using it.
57 89
58 //!!! todo: what about the other export types besides 90 //!!! todo: what about the other export types besides
59 //!!! delimited-data-string ? 91 //!!! delimited-data-string ?
92
93 //!!! todo: scripted regression tests for layer exports (of all
94 //!!! types)
95
96 //!!! todo: export selected region only (we have the necessaries
97 //!!! here, but it needs support higher up)
98
99 //!!! todo: option to include timestamps for columns
60 100
61 if (provider) { 101 if (provider) {
62 102
63 minbin = layer->getIBinForY(provider, provider->getPaintHeight()); 103 minbin = layer->getIBinForY(provider, provider->getPaintHeight());
64 if (minbin >= sh) minbin = sh - 1; 104 if (minbin >= sh) minbin = sh - 1;
71 int w = model->getWidth(); 111 int w = model->getWidth();
72 112
73 QString s; 113 QString s;
74 114
75 for (int i = 0; i < w; ++i) { 115 for (int i = 0; i < w; ++i) {
116
76 sv_frame_t fr = model->getStartFrame() + i * model->getResolution(); 117 sv_frame_t fr = model->getStartFrame() + i * model->getResolution();
77 if (fr < startFrame || fr >= startFrame + duration) { 118 if (fr < startFrame || fr >= startFrame + duration) {
78 continue; 119 continue;
79 } 120 }
121
122 // Unlike Colour3DPlotRenderer, we don't want to scale or
123 // normalise
124
125 //!!! (should we be handling phase layer type?)
126
127 auto column = model->getColumn(i);
128 column = ColumnOp::Column(column.data() + minbin,
129 column.data() + minbin + nbins);
130
131 //!!! todo: peaks, frequencies (the things we came here for)
132
80 QStringList list; 133 QStringList list;
81 134
82 //... 135 if (binDisplay == BinDisplay::PeakFrequencies) {
136
137 FFTModel::PeakSet peaks = fftModel->getPeakFrequencies
138 (FFTModel::AllPeaks, i, minbin, minbin + nbins + 1);
83 139
140 for (const auto &p: peaks) {
141
142 int bin = p.first;
143 double freq = p.second;
144 float mag = column[bin - minbin];
145
146 list << QString("%1").arg(freq) << QString("%1").arg(mag);
147 }
148
149 } else {
150
151 if (binDisplay == BinDisplay::PeakBins) {
152 column = ColumnOp::peakPick(column);
153 }
154
155 for (auto value: column) {
156 list << QString("%1").arg(value);
157 }
158 }
159
84 s += list.join(delimiter) + "\n"; 160 s += list.join(delimiter) + "\n";
85 } 161 }
86 162
87 return s; 163 return s;
88 164