Mercurial > hg > svgui
comparison layer/Colour3DPlotExporter.cpp @ 1561:d6f9fac336b3 spectrogram-export
Handle scale factor, needed for all spectrogram export; handle thresholding (using gain/normalisation for threshold calculation) in peak frequency export
author | Chris Cannam |
---|---|
date | Thu, 09 Jan 2020 14:34:51 +0000 |
parents | e6e7a8dc3b38 |
children | 62b7699e5bfe |
comparison
equal
deleted
inserted
replaced
1560:27f3e64489e1 | 1561:d6f9fac336b3 |
---|---|
113 | 113 |
114 sv_frame_t fr = model->getStartFrame() + i * model->getResolution(); | 114 sv_frame_t fr = model->getStartFrame() + i * model->getResolution(); |
115 if (fr < startFrame || fr >= startFrame + duration) { | 115 if (fr < startFrame || fr >= startFrame + duration) { |
116 continue; | 116 continue; |
117 } | 117 } |
118 | |
119 // Unlike Colour3DPlotRenderer, we don't want to scale or | |
120 // normalise | |
121 | |
122 //!!! (but might we want to threshold? we get a lot of | |
123 //!!! spurious output [i.e. elements not readily visible on | |
124 //!!! screen] for peak freqs) | |
125 | 118 |
126 //!!! (+ should we be handling phase layer type?) | 119 //!!! (+ phase layer type) |
127 | 120 |
128 auto column = model->getColumn(i); | 121 auto column = model->getColumn(i); |
129 column = ColumnOp::Column(column.data() + minbin, | 122 column = ColumnOp::Column(column.data() + minbin, |
130 column.data() + minbin + nbins); | 123 column.data() + minbin + nbins); |
124 | |
125 // The scale factor is always applied | |
126 column = ColumnOp::applyGain(column, m_params.scaleFactor); | |
131 | 127 |
132 QStringList list; | 128 QStringList list; |
133 | 129 |
134 if (binDisplay == BinDisplay::PeakFrequencies) { | 130 if (binDisplay == BinDisplay::PeakFrequencies) { |
135 | 131 |
136 FFTModel::PeakSet peaks = fftModel->getPeakFrequencies | 132 FFTModel::PeakSet peaks = fftModel->getPeakFrequencies |
137 (FFTModel::AllPeaks, i, minbin, minbin + nbins - 1); | 133 (FFTModel::AllPeaks, i, minbin, minbin + nbins - 1); |
138 | 134 |
135 // We don't apply normalisation or gain to the output, but | |
136 // we *do* perform thresholding when exporting the | |
137 // peak-frequency spectrogram, to give the user an | |
138 // opportunity to cut irrelevant peaks. And to make that | |
139 // match the display, we have to apply both normalisation | |
140 // and gain locally for thresholding | |
141 | |
142 auto toTest = ColumnOp::normalize(column, m_params.normalization); | |
143 toTest = ColumnOp::applyGain(toTest, m_params.gain); | |
144 | |
139 for (const auto &p: peaks) { | 145 for (const auto &p: peaks) { |
140 | 146 |
141 int bin = p.first; | 147 int bin = p.first; |
148 | |
149 if (toTest[bin - minbin] < m_params.threshold) { | |
150 continue; | |
151 } | |
152 | |
142 double freq = p.second; | 153 double freq = p.second; |
143 float mag = column[bin - minbin]; | 154 double value = column[bin - minbin]; |
144 | 155 |
145 list << QString("%1").arg(freq) << QString("%1").arg(mag); | 156 list << QString("%1").arg(freq) << QString("%1").arg(value); |
146 } | 157 } |
147 | 158 |
148 } else { | 159 } else { |
149 | 160 |
150 if (binDisplay == BinDisplay::PeakBins) { | 161 if (binDisplay == BinDisplay::PeakBins) { |
158 | 169 |
159 s += list.join(delimiter) + "\n"; | 170 s += list.join(delimiter) + "\n"; |
160 } | 171 } |
161 | 172 |
162 return s; | 173 return s; |
163 | |
164 | |
165 //!!! For reference, this is the body of | |
166 //!!! EditableDenseThreeDimensionalModel::toDelimitedDataString | |
167 /* | |
168 QString s; | |
169 for (int i = 0; in_range_for(m_data, i); ++i) { | |
170 sv_frame_t fr = m_startFrame + i * m_resolution; | |
171 if (fr >= startFrame && fr < startFrame + duration) { | |
172 QStringList list; | |
173 for (int j = 0; in_range_for(m_data.at(i), j); ++j) { | |
174 list << QString("%1").arg(m_data.at(i).at(j)); | |
175 } | |
176 s += list.join(delimiter) + "\n"; | |
177 } | |
178 } | |
179 return s; | |
180 */ | |
181 } | 174 } |
182 | 175 |