Essentia  2.1-beta6-dev
bpfutil.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2021 Music Technology Group - Universitat Pompeu Fabra
3  *
4  * This file is part of Essentia
5  *
6  * Essentia is free software: you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License as published by the Free
8  * Software Foundation (FSF), either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the Affero GNU General Public License
17  * version 3 along with this program. If not, see http://www.gnu.org/licenses/
18  */
19 
20 #ifndef BPFUTIL_H
21 #define BPFUTIL_H
22 
23 #include "types.h"
24 
25 namespace essentia {
26  namespace util {
27  class BPF {
28  protected:
29  std::vector<Real> _xPoints;
30  std::vector<Real> _yPoints;
31  std::vector<Real> _slopes;
32 
33  public:
34  BPF() {
35  }
36  BPF(std::vector<Real> xPoints, std::vector<Real> yPoints) {
37  init(xPoints,yPoints);
38  }
39  void init(std::vector<Real> xPoints, std::vector<Real> yPoints) {
40  _xPoints = xPoints;
41  _yPoints = yPoints;
42  if (_xPoints.size() != _yPoints.size()) {
43  throw EssentiaException("BPF: xPoints and yPoints do not have the same size");
44  }
45 
46  if (_xPoints.size() < 2) {
47  throw EssentiaException("BPF: There are less than 2 points, which is the minimum required for the break-point function");
48  }
49 
50  for (int i=1; i<int(_xPoints.size()); ++i) {
51  if (_xPoints[i-1] >= _xPoints[i] ) {
52  throw EssentiaException("BPF: xPoints are not sorted by increasing values");
53  }
54  }
55 
56  _slopes.resize(_xPoints.size()-1);
57 
58  for (int j=1; j<int(_xPoints.size()); ++j) {
59  // this never gives a division by zero as we checked just before that x[i-1] < x[i]
60  _slopes[j-1] = (_yPoints[j] - _yPoints[j-1]) / (_xPoints[j] - _xPoints[j-1]);
61  }
62  }
63 
64  inline float operator()(float x) {
65  if (x < _xPoints[0]) {
66  throw EssentiaException("BPF: Input x-value is before the first point");
67  }
68 
69  if (x > _xPoints.back()) {
70  throw EssentiaException("BPF: Input x-value is past the last point");
71  }
72 
73  std::vector<Real>::size_type j = 0;
74  while (x > _xPoints[j+1]) {
75  j += 1;
76  }
77 
78  return (x - _xPoints[j]) * _slopes[j] + _yPoints[j];
79  }
80  };
81  }
82 }
83 
84 #endif // BPFUTIL_H
Definition: types.h:77
Definition: bpfutil.h:27
void init(std::vector< Real > xPoints, std::vector< Real > yPoints)
Definition: bpfutil.h:39
BPF()
Definition: bpfutil.h:34
std::vector< Real > _yPoints
Definition: bpfutil.h:30
std::vector< Real > _xPoints
Definition: bpfutil.h:29
std::vector< Real > _slopes
Definition: bpfutil.h:31
float operator()(float x)
Definition: bpfutil.h:64
BPF(std::vector< Real > xPoints, std::vector< Real > yPoints)
Definition: bpfutil.h:36
Definition: algorithm.h:28