annotate align/DTW.h @ 755:b27815194752 pitch-align

Half-written rewrite of this part of SML code
author Chris Cannam
date Fri, 24 Apr 2020 17:24:56 +0100
parents
children f32df46d0c84
rev   line source
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