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