Mercurial > hg > cepstral-pitchtracker
comparison PeakInterpolator.cpp @ 39:822cf7b8e070
Start separating out PeakInterpolator & writing test for it
author | Chris Cannam |
---|---|
date | Thu, 19 Jul 2012 18:10:50 +0100 |
parents | |
children | 8f56ef28b0b1 |
comparison
equal
deleted
inserted
replaced
38:944898c2e14e | 39:822cf7b8e070 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 /* | |
3 This file is Copyright (c) 2012 Chris Cannam | |
4 | |
5 Permission is hereby granted, free of charge, to any person | |
6 obtaining a copy of this software and associated documentation | |
7 files (the "Software"), to deal in the Software without | |
8 restriction, including without limitation the rights to use, copy, | |
9 modify, merge, publish, distribute, sublicense, and/or sell copies | |
10 of the Software, and to permit persons to whom the Software is | |
11 furnished to do so, subject to the following conditions: | |
12 | |
13 The above copyright notice and this permission notice shall be | |
14 included in all copies or substantial portions of the Software. | |
15 | |
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
17 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
19 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR | |
20 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |
21 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
22 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
23 */ | |
24 | |
25 #include "PeakInterpolator.h" | |
26 | |
27 static double cubicInterpolate(const double y[4], double x) | |
28 { | |
29 double a0 = y[3] - y[2] - y[0] + y[1]; | |
30 double a1 = y[0] - y[1] - a0; | |
31 double a2 = y[2] - y[0]; | |
32 double a3 = y[1]; | |
33 return | |
34 a0 * x * x * x + | |
35 a1 * x * x + | |
36 a2 * x + | |
37 a3; | |
38 } | |
39 | |
40 double | |
41 PeakInterpolator::findPeakLocation(const double *data, int size, int peakIndex) | |
42 { | |
43 if (peakIndex < 2 || peakIndex > size - 3) { | |
44 return peakIndex; | |
45 } | |
46 | |
47 double maxval = 0.0; | |
48 double location = peakIndex; | |
49 | |
50 const int divisions = 10; | |
51 double y[4]; | |
52 | |
53 y[0] = data[peakIndex-1]; | |
54 y[1] = data[peakIndex]; | |
55 y[2] = data[peakIndex+1]; | |
56 y[3] = data[peakIndex+2]; | |
57 for (int i = 0; i < divisions; ++i) { | |
58 double probe = double(i) / double(divisions); | |
59 double value = cubicInterpolate(y, probe); | |
60 if (value > maxval) { | |
61 maxval = value; | |
62 location = peakIndex + probe; | |
63 } | |
64 } | |
65 | |
66 y[3] = y[2]; | |
67 y[2] = y[1]; | |
68 y[1] = y[0]; | |
69 y[0] = data[peakIndex-2]; | |
70 for (int i = 0; i < divisions; ++i) { | |
71 double probe = double(i) / double(divisions); | |
72 double value = cubicInterpolate(y, probe); | |
73 if (value > maxval) { | |
74 maxval = value; | |
75 location = peakIndex - 1 + probe; | |
76 } | |
77 } | |
78 | |
79 return location; | |
80 } | |
81 |