Chris@755
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@755
|
2
|
Chris@755
|
3 /*
|
Chris@755
|
4 Sonic Visualiser
|
Chris@755
|
5 An audio file viewer and annotation editor.
|
Chris@755
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@755
|
7
|
Chris@755
|
8 This program is free software; you can redistribute it and/or
|
Chris@755
|
9 modify it under the terms of the GNU General Public License as
|
Chris@755
|
10 published by the Free Software Foundation; either version 2 of the
|
Chris@755
|
11 License, or (at your option) any later version. See the file
|
Chris@755
|
12 COPYING included with this distribution for more information.
|
Chris@755
|
13 */
|
Chris@755
|
14
|
Chris@755
|
15 #ifndef SV_DTW_H
|
Chris@755
|
16 #define SV_DTW_H
|
Chris@755
|
17
|
Chris@755
|
18 #include <vector>
|
Chris@755
|
19
|
Chris@755
|
20 class DTW
|
Chris@755
|
21 {
|
Chris@755
|
22 public:
|
Chris@755
|
23 typedef double cost_t;
|
Chris@755
|
24
|
Chris@755
|
25 struct CostOption {
|
Chris@755
|
26 bool present;
|
Chris@755
|
27 cost_t cost;
|
Chris@755
|
28 };
|
Chris@755
|
29
|
Chris@755
|
30 enum class Direction {
|
Chris@755
|
31 None,
|
Chris@755
|
32 Up,
|
Chris@755
|
33 Down
|
Chris@755
|
34 };
|
Chris@755
|
35
|
Chris@755
|
36 struct Value {
|
Chris@755
|
37 Direction direction;
|
Chris@755
|
38 cost_t cost;
|
Chris@755
|
39 };
|
Chris@755
|
40
|
Chris@755
|
41 static cost_t choose(CostOption x, CostOption y, CostOption d) {
|
Chris@755
|
42 if (x.present && y.present) {
|
Chris@755
|
43 if (!d.present) {
|
Chris@755
|
44 throw std::logic_error("if x & y both exist, so must diagonal");
|
Chris@755
|
45 }
|
Chris@755
|
46 return std::min(std::min(x.cost, y.cost), d.cost);
|
Chris@755
|
47 } else if (x.present) {
|
Chris@755
|
48 return x.cost;
|
Chris@755
|
49 } else if (y.present) {
|
Chris@755
|
50 return y.cost;
|
Chris@755
|
51 } else {
|
Chris@755
|
52 return 0.0;
|
Chris@755
|
53 }
|
Chris@755
|
54 }
|
Chris@755
|
55
|
Chris@755
|
56 static cost_t calculateCost(Value a, Value b) {
|
Chris@755
|
57 auto together = [](cost_t c1, cost_t c2) {
|
Chris@755
|
58 auto diff = std::abs(c1 - c2);
|
Chris@755
|
59 return (diff < 1.0 ? -1.0 :
|
Chris@755
|
60 diff > 3.0 ? 1.0 :
|
Chris@755
|
61 0.0);
|
Chris@755
|
62 };
|
Chris@755
|
63 auto opposing = [](cost_t c1, cost_t c2) {
|
Chris@755
|
64 auto diff = c1 + c2;
|
Chris@755
|
65 return (diff < 2.0 ? 1.0 :
|
Chris@755
|
66 2.0);
|
Chris@755
|
67 };
|
Chris@755
|
68 if (a.direction == Direction::None || b.direction == Direction::None) {
|
Chris@755
|
69 if (a.direction == b.direction) {
|
Chris@755
|
70 return 0.0;
|
Chris@755
|
71 } else {
|
Chris@755
|
72 return 1.0;
|
Chris@755
|
73 }
|
Chris@755
|
74 } else {
|
Chris@755
|
75 if (a.direction == b.direction) {
|
Chris@755
|
76 return together (a.cost, b.cost);
|
Chris@755
|
77 } else {
|
Chris@755
|
78 return opposing (a.cost, b.cost);
|
Chris@755
|
79 }
|
Chris@755
|
80 }
|
Chris@755
|
81 }
|
Chris@755
|
82
|
Chris@755
|
83 static std::vector<std::vector<cost_t>> costSeries(std::vector<Value> s1,
|
Chris@755
|
84 std::vector<Value> s2) {
|
Chris@755
|
85
|
Chris@755
|
86 }
|
Chris@755
|
87
|
Chris@755
|
88 };
|
Chris@755
|
89
|
Chris@755
|
90 #endif
|