Chris@1187: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@1187: Chris@1187: /* Chris@1187: Sonic Visualiser Chris@1187: An audio file viewer and annotation editor. Chris@1187: Centre for Digital Music, Queen Mary, University of London. Chris@1188: This file copyright 2006-2016 Chris Cannam and QMUL. Chris@1187: Chris@1187: This program is free software; you can redistribute it and/or Chris@1187: modify it under the terms of the GNU General Public License as Chris@1187: published by the Free Software Foundation; either version 2 of the Chris@1187: License, or (at your option) any later version. See the file Chris@1187: COPYING included with this distribution for more information. Chris@1187: */ Chris@1187: Chris@1187: #ifndef COLUMN_OP_H Chris@1187: #define COLUMN_OP_H Chris@1187: Chris@1187: #include "BaseTypes.h" Chris@1187: Chris@1265: #include Chris@1187: Chris@1190: /** Chris@1193: * Display normalization types for columns in e.g. grid plots. Chris@1193: * Chris@1193: * Max1 means to normalize to max value = 1.0. Chris@1193: * Sum1 means to normalize to sum of values = 1.0. Chris@1193: * Chris@1394: * Range01 means to normalize such that the max value = 1.0 and the Chris@1394: * min value (if different from the max value) = 0.0. Chris@1394: * Chris@1193: * Hybrid means normalize to max = 1.0 and then multiply by Chris@1193: * log10 of the max value, to retain some difference between Chris@1193: * levels of neighbouring columns. Chris@1193: * Chris@1193: * Area normalization is handled separately. Chris@1193: */ Chris@1193: enum class ColumnNormalization { Chris@1193: None, Chris@1193: Max1, Chris@1193: Sum1, Chris@1394: Range01, Chris@1193: Hybrid Chris@1193: }; Chris@1193: Chris@1193: /** Chris@1190: * Class containing static functions for simple operations on data Chris@1190: * columns, for use by display layers. Chris@1190: */ Chris@1187: class ColumnOp Chris@1187: { Chris@1187: public: Chris@1190: /** Chris@1190: * Column type. Chris@1190: */ Chris@1187: typedef std::vector Column; Chris@1187: Chris@1190: /** Chris@1195: * Scale the given column using the given gain multiplier. Chris@1195: */ Chris@1197: static Column applyGain(const Column &in, double gain) { Chris@1266: if (gain == 1.0) return in; Chris@1429: Column out; Chris@1429: out.reserve(in.size()); Chris@1429: for (auto v: in) out.push_back(float(v * gain)); Chris@1429: return out; Chris@1195: } Chris@1195: Chris@1195: /** Chris@1394: * Shift the values in the given column by the given offset. Chris@1394: */ Chris@1394: static Column applyShift(const Column &in, float offset) { Chris@1394: if (offset == 0.f) return in; Chris@1429: Column out; Chris@1429: out.reserve(in.size()); Chris@1429: for (auto v: in) out.push_back(v + offset); Chris@1429: return out; Chris@1394: } Chris@1394: Chris@1394: /** Chris@1265: * Scale an FFT output downward by half the FFT size. Chris@1190: */ Chris@1266: static Column fftScale(const Column &in, int fftSize); Chris@1187: Chris@1190: /** Chris@1190: * Determine whether an index points to a local peak. Chris@1190: */ Chris@1187: static bool isPeak(const Column &in, int ix) { Chris@1265: if (!in_range_for(in, ix)) { Chris@1265: return false; Chris@1265: } Chris@1265: if (ix == 0) { Chris@1265: return in[0] >= in[1]; Chris@1265: } Chris@1265: if (!in_range_for(in, ix+1)) { Chris@1265: return in[ix] > in[ix-1]; Chris@1265: } Chris@1429: if (in[ix] < in[ix+1]) { Chris@1265: return false; Chris@1265: } Chris@1429: if (in[ix] <= in[ix-1]) { Chris@1265: return false; Chris@1265: } Chris@1429: return true; Chris@1187: } Chris@1187: Chris@1190: /** Chris@1190: * Return a column containing only the local peak values (all Chris@1190: * others zero). Chris@1190: */ Chris@1266: static Column peakPick(const Column &in); Chris@1187: Chris@1190: /** Chris@1190: * Return a column normalized from the input column according to Chris@1190: * the given normalization scheme. Chris@1266: * Chris@1266: * Note that the sum or max (as appropriate) used for Chris@1266: * normalisation will be calculated from the absolute values of Chris@1266: * the column elements, should any of them be negative. Chris@1190: */ Chris@1266: static Column normalize(const Column &in, ColumnNormalization n); Chris@1266: Chris@1190: /** Chris@1190: * Distribute the given column into a target vector of a different Chris@1190: * size, optionally using linear interpolation. The binfory vector Chris@1190: * contains a mapping from y coordinate (i.e. index into the Chris@1265: * target vector) to bin (i.e. index into the source column). The Chris@1265: * source column ("in") may be a partial column; it's assumed to Chris@1265: * contain enough bins to span the destination range, starting Chris@1265: * with the bin of index minbin. Chris@1190: */ Chris@1187: static Column distribute(const Column &in, Chris@1429: int h, Chris@1429: const std::vector &binfory, Chris@1429: int minbin, Chris@1429: bool interpolate); Chris@1187: Chris@1187: }; Chris@1187: Chris@1187: #endif Chris@1187: