Mercurial > hg > svgui
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 |