comparison align/LinearAligner.cpp @ 767:dd742e566e60 pitch-align

Make a start on further alignment methods
author Chris Cannam
date Thu, 21 May 2020 16:21:57 +0100
parents
children 486add472c3f
comparison
equal deleted inserted replaced
761:6429a164b7e1 767:dd742e566e60
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Sonic Visualiser
5 An audio file viewer and annotation editor.
6 Centre for Digital Music, Queen Mary, University of London.
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version. See the file
12 COPYING included with this distribution for more information.
13 */
14
15 #include "LinearAligner.h"
16
17 #include "system/System.h"
18
19 #include "data/model/Path.h"
20 #include "data/model/AlignmentModel.h"
21
22 #include "framework/Document.h"
23
24 LinearAligner::LinearAligner(Document *doc,
25 ModelId reference,
26 ModelId toAlign,
27 bool trimmed) :
28 m_document(doc),
29 m_reference(reference),
30 m_toAlign(toAlign),
31 m_trimmed(trimmed)
32 {
33 }
34
35 LinearAligner::~LinearAligner()
36 {
37 }
38
39 void
40 LinearAligner::begin()
41 {
42 bool ready = false;
43 while (!ready) {
44 { // scope so as to release input shared_ptr before sleeping
45 auto reference = ModelById::get(m_reference);
46 auto toAlign = ModelById::get(m_toAlign);
47 if (!reference || !reference->isOK() ||
48 !toAlign || !toAlign->isOK()) {
49 return;
50 }
51 ready = reference->isReady() && toAlign->isReady();
52 }
53 if (!ready) {
54 SVDEBUG << "LinearAligner: Waiting for models..." << endl;
55 usleep(500000);
56 }
57 }
58
59 auto reference = ModelById::get(m_reference);
60 auto toAlign = ModelById::get(m_toAlign);
61
62 if (!reference || !reference->isOK() ||
63 !toAlign || !toAlign->isOK()) {
64 return;
65 }
66
67 sv_frame_t s0 = reference->getStartFrame(), s1 = toAlign->getStartFrame();
68 sv_frame_t e0 = reference->getEndFrame(), e1 = toAlign->getEndFrame();
69 sv_frame_t d0 = e0 - s0, d1 = e1 - s1;
70
71 if (d1 == 0) {
72 return;
73 }
74
75 double ratio = double(d0) / double(d1);
76 sv_frame_t resolution = 1024;
77
78 Path path(reference->getSampleRate(), resolution);
79
80 for (sv_frame_t f = s1; f < e1; f += resolution) {
81 sv_frame_t target = sv_frame_t(double(f - s1) * ratio);
82 path.add(PathPoint(f, target));
83 }
84
85 auto alignment = std::make_shared<AlignmentModel>(m_reference,
86 m_toAlign,
87 ModelId());
88
89 auto alignmentModelId = ModelById::add(alignment);
90
91 alignment->setPath(path);
92 toAlign->setAlignment(alignmentModelId);
93 m_document->addNonDerivedModel(alignmentModelId);
94 }
95
96 //!!! + trimmed