annotate base/ColumnOp.h @ 1520:954d0cf29ca7 import-audio-data

Switch the normalisation option in WritableWaveFileModel from normalising on read to normalising on write, so that the saved file is already normalised and therefore can be read again without having to remember to normalise it
author Chris Cannam
date Wed, 12 Sep 2018 13:56:56 +0100
parents 48e9f538e6e9
children 1b688ab5f1b3
rev   line source
Chris@1187 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@1187 2
Chris@1187 3 /*
Chris@1187 4 Sonic Visualiser
Chris@1187 5 An audio file viewer and annotation editor.
Chris@1187 6 Centre for Digital Music, Queen Mary, University of London.
Chris@1188 7 This file copyright 2006-2016 Chris Cannam and QMUL.
Chris@1187 8
Chris@1187 9 This program is free software; you can redistribute it and/or
Chris@1187 10 modify it under the terms of the GNU General Public License as
Chris@1187 11 published by the Free Software Foundation; either version 2 of the
Chris@1187 12 License, or (at your option) any later version. See the file
Chris@1187 13 COPYING included with this distribution for more information.
Chris@1187 14 */
Chris@1187 15
Chris@1187 16 #ifndef COLUMN_OP_H
Chris@1187 17 #define COLUMN_OP_H
Chris@1187 18
Chris@1187 19 #include "BaseTypes.h"
Chris@1187 20
Chris@1265 21 #include <vector>
Chris@1187 22
Chris@1190 23 /**
Chris@1193 24 * Display normalization types for columns in e.g. grid plots.
Chris@1193 25 *
Chris@1193 26 * Max1 means to normalize to max value = 1.0.
Chris@1193 27 * Sum1 means to normalize to sum of values = 1.0.
Chris@1193 28 *
Chris@1394 29 * Range01 means to normalize such that the max value = 1.0 and the
Chris@1394 30 * min value (if different from the max value) = 0.0.
Chris@1394 31 *
Chris@1193 32 * Hybrid means normalize to max = 1.0 and then multiply by
Chris@1193 33 * log10 of the max value, to retain some difference between
Chris@1193 34 * levels of neighbouring columns.
Chris@1193 35 *
Chris@1193 36 * Area normalization is handled separately.
Chris@1193 37 */
Chris@1193 38 enum class ColumnNormalization {
Chris@1193 39 None,
Chris@1193 40 Max1,
Chris@1193 41 Sum1,
Chris@1394 42 Range01,
Chris@1193 43 Hybrid
Chris@1193 44 };
Chris@1193 45
Chris@1193 46 /**
Chris@1190 47 * Class containing static functions for simple operations on data
Chris@1190 48 * columns, for use by display layers.
Chris@1190 49 */
Chris@1187 50 class ColumnOp
Chris@1187 51 {
Chris@1187 52 public:
Chris@1190 53 /**
Chris@1190 54 * Column type.
Chris@1190 55 */
Chris@1187 56 typedef std::vector<float> Column;
Chris@1187 57
Chris@1190 58 /**
Chris@1195 59 * Scale the given column using the given gain multiplier.
Chris@1195 60 */
Chris@1197 61 static Column applyGain(const Column &in, double gain) {
Chris@1266 62 if (gain == 1.0) return in;
Chris@1429 63 Column out;
Chris@1429 64 out.reserve(in.size());
Chris@1429 65 for (auto v: in) out.push_back(float(v * gain));
Chris@1429 66 return out;
Chris@1195 67 }
Chris@1195 68
Chris@1195 69 /**
Chris@1394 70 * Shift the values in the given column by the given offset.
Chris@1394 71 */
Chris@1394 72 static Column applyShift(const Column &in, float offset) {
Chris@1394 73 if (offset == 0.f) return in;
Chris@1429 74 Column out;
Chris@1429 75 out.reserve(in.size());
Chris@1429 76 for (auto v: in) out.push_back(v + offset);
Chris@1429 77 return out;
Chris@1394 78 }
Chris@1394 79
Chris@1394 80 /**
Chris@1265 81 * Scale an FFT output downward by half the FFT size.
Chris@1190 82 */
Chris@1266 83 static Column fftScale(const Column &in, int fftSize);
Chris@1187 84
Chris@1190 85 /**
Chris@1190 86 * Determine whether an index points to a local peak.
Chris@1190 87 */
Chris@1187 88 static bool isPeak(const Column &in, int ix) {
Chris@1265 89 if (!in_range_for(in, ix)) {
Chris@1265 90 return false;
Chris@1265 91 }
Chris@1265 92 if (ix == 0) {
Chris@1265 93 return in[0] >= in[1];
Chris@1265 94 }
Chris@1265 95 if (!in_range_for(in, ix+1)) {
Chris@1265 96 return in[ix] > in[ix-1];
Chris@1265 97 }
Chris@1429 98 if (in[ix] < in[ix+1]) {
Chris@1265 99 return false;
Chris@1265 100 }
Chris@1429 101 if (in[ix] <= in[ix-1]) {
Chris@1265 102 return false;
Chris@1265 103 }
Chris@1429 104 return true;
Chris@1187 105 }
Chris@1187 106
Chris@1190 107 /**
Chris@1190 108 * Return a column containing only the local peak values (all
Chris@1190 109 * others zero).
Chris@1190 110 */
Chris@1266 111 static Column peakPick(const Column &in);
Chris@1187 112
Chris@1190 113 /**
Chris@1190 114 * Return a column normalized from the input column according to
Chris@1190 115 * the given normalization scheme.
Chris@1266 116 *
Chris@1266 117 * Note that the sum or max (as appropriate) used for
Chris@1266 118 * normalisation will be calculated from the absolute values of
Chris@1266 119 * the column elements, should any of them be negative.
Chris@1190 120 */
Chris@1266 121 static Column normalize(const Column &in, ColumnNormalization n);
Chris@1266 122
Chris@1190 123 /**
Chris@1190 124 * Distribute the given column into a target vector of a different
Chris@1190 125 * size, optionally using linear interpolation. The binfory vector
Chris@1190 126 * contains a mapping from y coordinate (i.e. index into the
Chris@1265 127 * target vector) to bin (i.e. index into the source column). The
Chris@1265 128 * source column ("in") may be a partial column; it's assumed to
Chris@1265 129 * contain enough bins to span the destination range, starting
Chris@1265 130 * with the bin of index minbin.
Chris@1190 131 */
Chris@1187 132 static Column distribute(const Column &in,
Chris@1429 133 int h,
Chris@1429 134 const std::vector<double> &binfory,
Chris@1429 135 int minbin,
Chris@1429 136 bool interpolate);
Chris@1187 137
Chris@1187 138 };
Chris@1187 139
Chris@1187 140 #endif
Chris@1187 141