Chris@767: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@767: Chris@767: /* Chris@767: Sonic Visualiser Chris@767: An audio file viewer and annotation editor. Chris@767: Centre for Digital Music, Queen Mary, University of London. Chris@767: Chris@767: This program is free software; you can redistribute it and/or Chris@767: modify it under the terms of the GNU General Public License as Chris@767: published by the Free Software Foundation; either version 2 of the Chris@767: License, or (at your option) any later version. See the file Chris@767: COPYING included with this distribution for more information. Chris@767: */ Chris@767: Chris@767: #include "LinearAligner.h" Chris@767: Chris@767: #include "system/System.h" Chris@767: Chris@767: #include "data/model/Path.h" Chris@767: #include "data/model/AlignmentModel.h" Chris@767: Chris@767: #include "framework/Document.h" Chris@767: Chris@767: LinearAligner::LinearAligner(Document *doc, Chris@767: ModelId reference, Chris@767: ModelId toAlign, Chris@767: bool trimmed) : Chris@767: m_document(doc), Chris@767: m_reference(reference), Chris@767: m_toAlign(toAlign), Chris@767: m_trimmed(trimmed) Chris@767: { Chris@767: } Chris@767: Chris@767: LinearAligner::~LinearAligner() Chris@767: { Chris@767: } Chris@767: Chris@767: void Chris@767: LinearAligner::begin() Chris@767: { Chris@767: bool ready = false; Chris@767: while (!ready) { Chris@767: { // scope so as to release input shared_ptr before sleeping Chris@767: auto reference = ModelById::get(m_reference); Chris@767: auto toAlign = ModelById::get(m_toAlign); Chris@767: if (!reference || !reference->isOK() || Chris@767: !toAlign || !toAlign->isOK()) { Chris@767: return; Chris@767: } Chris@767: ready = reference->isReady() && toAlign->isReady(); Chris@767: } Chris@767: if (!ready) { Chris@767: SVDEBUG << "LinearAligner: Waiting for models..." << endl; Chris@767: usleep(500000); Chris@767: } Chris@767: } Chris@767: Chris@767: auto reference = ModelById::get(m_reference); Chris@767: auto toAlign = ModelById::get(m_toAlign); Chris@767: Chris@767: if (!reference || !reference->isOK() || Chris@767: !toAlign || !toAlign->isOK()) { Chris@767: return; Chris@767: } Chris@767: Chris@767: sv_frame_t s0 = reference->getStartFrame(), s1 = toAlign->getStartFrame(); Chris@767: sv_frame_t e0 = reference->getEndFrame(), e1 = toAlign->getEndFrame(); Chris@767: sv_frame_t d0 = e0 - s0, d1 = e1 - s1; Chris@767: Chris@767: if (d1 == 0) { Chris@767: return; Chris@767: } Chris@767: Chris@767: double ratio = double(d0) / double(d1); Chris@767: sv_frame_t resolution = 1024; Chris@767: Chris@767: Path path(reference->getSampleRate(), resolution); Chris@767: Chris@767: for (sv_frame_t f = s1; f < e1; f += resolution) { Chris@767: sv_frame_t target = sv_frame_t(double(f - s1) * ratio); Chris@767: path.add(PathPoint(f, target)); Chris@767: } Chris@767: Chris@767: auto alignment = std::make_shared(m_reference, Chris@767: m_toAlign, Chris@767: ModelId()); Chris@767: Chris@767: auto alignmentModelId = ModelById::add(alignment); Chris@767: Chris@767: alignment->setPath(path); Chris@767: toAlign->setAlignment(alignmentModelId); Chris@767: m_document->addNonDerivedModel(alignmentModelId); Chris@767: } Chris@767: Chris@767: //!!! + trimmed