annotate layer/Colour3DPlotExporter.cpp @ 1559:e6e7a8dc3b38 spectrogram-export

Update in-progress comments only
author Chris Cannam
date Wed, 08 Jan 2020 15:29:02 +0000
parents 760ada8e3972
children d6f9fac336b3
rev   line source
Chris@1554 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@1554 2
Chris@1554 3 /*
Chris@1554 4 Sonic Visualiser
Chris@1554 5 An audio file viewer and annotation editor.
Chris@1554 6 Centre for Digital Music, Queen Mary, University of London.
Chris@1554 7
Chris@1554 8 This program is free software; you can redistribute it and/or
Chris@1554 9 modify it under the terms of the GNU General Public License as
Chris@1554 10 published by the Free Software Foundation; either version 2 of the
Chris@1554 11 License, or (at your option) any later version. See the file
Chris@1554 12 COPYING included with this distribution for more information.
Chris@1554 13 */
Chris@1554 14
Chris@1554 15 #include "Colour3DPlotExporter.h"
Chris@1554 16
Chris@1554 17 #include "data/model/EditableDenseThreeDimensionalModel.h"
Chris@1554 18 #include "data/model/FFTModel.h"
Chris@1554 19
Chris@1554 20 #include "VerticalBinLayer.h"
Chris@1554 21
Chris@1556 22 Colour3DPlotExporter::Colour3DPlotExporter(Sources sources, Parameters params) :
Chris@1556 23 m_sources(sources),
Chris@1556 24 m_params(params)
Chris@1556 25 {
Chris@1556 26 SVCERR << "Colour3DPlotExporter::Colour3DPlotExporter: constructed at "
Chris@1556 27 << this << endl;
Chris@1556 28 }
Chris@1556 29
Chris@1556 30 Colour3DPlotExporter::~Colour3DPlotExporter()
Chris@1556 31 {
Chris@1556 32 SVCERR << "Colour3DPlotExporter[" << this << "]::~Colour3DPlotExporter"
Chris@1556 33 << endl;
Chris@1556 34 }
Chris@1556 35
Chris@1556 36 void
Chris@1556 37 Colour3DPlotExporter::discardSources()
Chris@1556 38 {
Chris@1556 39 SVCERR << "Colour3DPlotExporter[" << this << "]::discardSources"
Chris@1556 40 << endl;
Chris@1556 41 QMutexLocker locker(&m_mutex);
Chris@1556 42 m_sources.verticalBinLayer = nullptr;
Chris@1556 43 m_sources.source = {};
Chris@1556 44 m_sources.fft = {};
Chris@1556 45 m_sources.provider = nullptr;
Chris@1556 46 }
Chris@1556 47
Chris@1554 48 QString
Chris@1554 49 Colour3DPlotExporter::toDelimitedDataString(QString delimiter,
Chris@1554 50 DataExportOptions options,
Chris@1554 51 sv_frame_t startFrame,
Chris@1554 52 sv_frame_t duration) const
Chris@1554 53 {
Chris@1554 54 QMutexLocker locker(&m_mutex);
Chris@1554 55
Chris@1554 56 BinDisplay binDisplay = m_params.binDisplay;
Chris@1554 57
Chris@1556 58 (void)options; //!!!
Chris@1556 59
Chris@1554 60 auto model =
Chris@1554 61 ModelById::getAs<DenseThreeDimensionalModel>(m_sources.source);
Chris@1554 62 auto fftModel =
Chris@1554 63 ModelById::getAs<FFTModel>(m_sources.fft);
Chris@1554 64
Chris@1554 65 auto layer = m_sources.verticalBinLayer;
Chris@1554 66 auto provider = m_sources.provider;
Chris@1554 67
Chris@1554 68 if (!model || !layer) {
Chris@1554 69 SVCERR << "ERROR: Colour3DPlotExporter::toDelimitedDataString: Source model and layer required" << endl;
Chris@1554 70 return {};
Chris@1554 71 }
Chris@1556 72 if ((binDisplay == BinDisplay::PeakFrequencies) && !fftModel) {
Chris@1556 73 SVCERR << "ERROR: Colour3DPlotExporter::toDelimitedDataString: FFT model required in peak frequencies mode" << endl;
Chris@1556 74 return {};
Chris@1556 75 }
Chris@1554 76
Chris@1554 77 int minbin = 0;
Chris@1554 78 int sh = model->getHeight();
Chris@1554 79 int nbins = sh;
Chris@1554 80
Chris@1554 81 //!!! todo: consider what to do about the actual Colour 3D Plot
Chris@1554 82 //!!! Layer. In the existing application, this is exported full
Chris@1554 83 //!!! height. If we switch to using this code, we will be
Chris@1554 84 //!!! exporting only the displayed height. This is backward
Chris@1554 85 //!!! incompatible, but also not directly interpretable without
Chris@1554 86 //!!! any guide in the exported file as to what the bin indices
Chris@1554 87 //!!! are. Perhaps we should have a flag to export full height,
Chris@1554 88 //!!! and default to using it.
Chris@1554 89
Chris@1554 90 //!!! todo: what about the other export types besides
Chris@1554 91 //!!! delimited-data-string ?
Chris@1556 92
Chris@1559 93 //!!! todo: export selections only (we have the necessaries here,
Chris@1559 94 //!!! but it needs support higher up)
Chris@1556 95
Chris@1556 96 //!!! todo: option to include timestamps for columns
Chris@1554 97
Chris@1554 98 if (provider) {
Chris@1554 99
Chris@1554 100 minbin = layer->getIBinForY(provider, provider->getPaintHeight());
Chris@1554 101 if (minbin >= sh) minbin = sh - 1;
Chris@1554 102 if (minbin < 0) minbin = 0;
Chris@1554 103
Chris@1554 104 nbins = layer->getIBinForY(provider, 0) - minbin + 1;
Chris@1554 105 if (minbin + nbins > sh) nbins = sh - minbin;
Chris@1554 106 }
Chris@1554 107
Chris@1554 108 int w = model->getWidth();
Chris@1554 109
Chris@1554 110 QString s;
Chris@1554 111
Chris@1554 112 for (int i = 0; i < w; ++i) {
Chris@1556 113
Chris@1554 114 sv_frame_t fr = model->getStartFrame() + i * model->getResolution();
Chris@1554 115 if (fr < startFrame || fr >= startFrame + duration) {
Chris@1554 116 continue;
Chris@1554 117 }
Chris@1556 118
Chris@1556 119 // Unlike Colour3DPlotRenderer, we don't want to scale or
Chris@1556 120 // normalise
Chris@1559 121
Chris@1559 122 //!!! (but might we want to threshold? we get a lot of
Chris@1559 123 //!!! spurious output [i.e. elements not readily visible on
Chris@1559 124 //!!! screen] for peak freqs)
Chris@1556 125
Chris@1559 126 //!!! (+ should we be handling phase layer type?)
Chris@1556 127
Chris@1556 128 auto column = model->getColumn(i);
Chris@1556 129 column = ColumnOp::Column(column.data() + minbin,
Chris@1556 130 column.data() + minbin + nbins);
Chris@1556 131
Chris@1554 132 QStringList list;
Chris@1554 133
Chris@1556 134 if (binDisplay == BinDisplay::PeakFrequencies) {
Chris@1556 135
Chris@1556 136 FFTModel::PeakSet peaks = fftModel->getPeakFrequencies
Chris@1558 137 (FFTModel::AllPeaks, i, minbin, minbin + nbins - 1);
Chris@1554 138
Chris@1556 139 for (const auto &p: peaks) {
Chris@1556 140
Chris@1556 141 int bin = p.first;
Chris@1556 142 double freq = p.second;
Chris@1556 143 float mag = column[bin - minbin];
Chris@1556 144
Chris@1556 145 list << QString("%1").arg(freq) << QString("%1").arg(mag);
Chris@1556 146 }
Chris@1556 147
Chris@1556 148 } else {
Chris@1556 149
Chris@1556 150 if (binDisplay == BinDisplay::PeakBins) {
Chris@1556 151 column = ColumnOp::peakPick(column);
Chris@1556 152 }
Chris@1556 153
Chris@1556 154 for (auto value: column) {
Chris@1556 155 list << QString("%1").arg(value);
Chris@1556 156 }
Chris@1556 157 }
Chris@1556 158
Chris@1554 159 s += list.join(delimiter) + "\n";
Chris@1554 160 }
Chris@1554 161
Chris@1554 162 return s;
Chris@1554 163
Chris@1554 164
Chris@1554 165 //!!! For reference, this is the body of
Chris@1554 166 //!!! EditableDenseThreeDimensionalModel::toDelimitedDataString
Chris@1554 167 /*
Chris@1554 168 QString s;
Chris@1554 169 for (int i = 0; in_range_for(m_data, i); ++i) {
Chris@1554 170 sv_frame_t fr = m_startFrame + i * m_resolution;
Chris@1554 171 if (fr >= startFrame && fr < startFrame + duration) {
Chris@1554 172 QStringList list;
Chris@1554 173 for (int j = 0; in_range_for(m_data.at(i), j); ++j) {
Chris@1554 174 list << QString("%1").arg(m_data.at(i).at(j));
Chris@1554 175 }
Chris@1554 176 s += list.join(delimiter) + "\n";
Chris@1554 177 }
Chris@1554 178 }
Chris@1554 179 return s;
Chris@1554 180 */
Chris@1554 181 }
Chris@1554 182