Mercurial > hg > svcore
view data/model/AggregateWaveModel.cpp @ 1752:6d09d68165a4 by-id
Further review of ById: make IDs only available when adding a model to the ById store, not by querying the item directly. This means any id encountered in the wild must have been added to the store at some point (even if later released), which simplifies reasoning about lifecycles
author | Chris Cannam |
---|---|
date | Fri, 05 Jul 2019 15:28:07 +0100 |
parents | 87b4c596c0ef |
children | dffc70996f54 |
line wrap: on
line source
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ /* Sonic Visualiser An audio file viewer and annotation editor. Centre for Digital Music, Queen Mary, University of London. This file copyright 2007 QMUL. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. See the file COPYING included with this distribution for more information. */ #include "AggregateWaveModel.h" #include <iostream> #include <QTextStream> using namespace std; //#define DEBUG_AGGREGATE_WAVE_FILE_MODEL 1 PowerOfSqrtTwoZoomConstraint AggregateWaveModel::m_zoomConstraint; AggregateWaveModel::AggregateWaveModel(ChannelSpecList channelSpecs) : m_components(channelSpecs) { sv_samplerate_t overallRate = 0; for (int channel = 0; in_range_for(m_components, channel); ++channel) { auto model = ModelById::getAs<RangeSummarisableTimeValueModel> (m_components[channel].model); if (!model) { SVCERR << "AggregateWaveModel: WARNING: component for channel " << channel << " is not found or is of wrong model type" << endl; continue; } sv_samplerate_t rate = model->getSampleRate(); if (!rate) { SVCERR << "AggregateWaveModel: WARNING: component for channel " << channel << " reports zero sample rate" << endl; } else if (!overallRate) { overallRate = rate; } else if (rate != overallRate) { SVCERR << "AggregateWaveModel: WARNING: component for channel " << channel << " has different sample rate from earlier " << "channels (has " << rate << ", expected " << overallRate << ")" << endl; } } } AggregateWaveModel::~AggregateWaveModel() { SVDEBUG << "AggregateWaveModel::~AggregateWaveModel" << endl; } bool AggregateWaveModel::isOK() const { if (m_components.empty()) { return false; } for (const auto &c: m_components) { auto model = ModelById::get(c.model); if (!model || !model->isOK()) { return false; } } return true; } bool AggregateWaveModel::isReady(int *completion) const { if (completion) *completion = 100; bool ready = true; for (auto c: m_components) { int completionHere = 100; auto model = ModelById::get(c.model); if (!model) continue; if (!model->isReady(&completionHere)) { ready = false; } if (completion && completionHere < *completion) { *completion = completionHere; } } #ifdef DEBUG_AGGREGATE_WAVE_FILE_MODEL SVDEBUG << "AggregateWaveModel(" << objectName() << ")::isReady: returning " << ready << endl; #endif return ready; } sv_frame_t AggregateWaveModel::getFrameCount() const { sv_frame_t count = 0; for (auto c: m_components) { auto model = ModelById::get(c.model); if (!model) continue; sv_frame_t thisCount = model->getEndFrame() - model->getStartFrame(); if (thisCount > count) count = thisCount; } return count; } int AggregateWaveModel::getChannelCount() const { return int(m_components.size()); } sv_samplerate_t AggregateWaveModel::getSampleRate() const { if (m_components.empty()) return 0; auto model = ModelById::get(m_components.begin()->model); if (!model) return 0; return model->getSampleRate(); } floatvec_t AggregateWaveModel::getData(int channel, sv_frame_t start, sv_frame_t count) const { if (m_components.empty()) return {}; int ch0 = channel, ch1 = channel; if (channel == -1) { ch0 = 0; ch1 = getChannelCount()-1; } else if (!in_range_for(m_components, channel)) { return {}; } floatvec_t result(count, 0.f); sv_frame_t longest = 0; for (int c = ch0; c <= ch1; ++c) { auto model = ModelById::getAs<RangeSummarisableTimeValueModel> (m_components[c].model); if (!model) continue; auto here = model->getData(m_components[c].channel, start, count); if (sv_frame_t(here.size()) > longest) { longest = sv_frame_t(here.size()); } for (sv_frame_t i = 0; in_range_for(here, i); ++i) { result[i] += here[i]; } } result.resize(longest); return result; } vector<floatvec_t> AggregateWaveModel::getMultiChannelData(int fromchannel, int tochannel, sv_frame_t start, sv_frame_t count) const { sv_frame_t min = count; vector<floatvec_t> result; for (int c = fromchannel; c <= tochannel; ++c) { auto here = getData(c, start, count); if (sv_frame_t(here.size()) < min) { min = sv_frame_t(here.size()); } result.push_back(here); } if (min < count) { for (auto &v : result) v.resize(min); } return result; } int AggregateWaveModel::getSummaryBlockSize(int desired) const { //!!! complete return desired; } void AggregateWaveModel::getSummaries(int, sv_frame_t, sv_frame_t, RangeBlock &, int &) const { //!!! complete } AggregateWaveModel::Range AggregateWaveModel::getSummary(int, sv_frame_t, sv_frame_t) const { //!!! complete return Range(); } int AggregateWaveModel::getComponentCount() const { return int(m_components.size()); } AggregateWaveModel::ModelChannelSpec AggregateWaveModel::getComponent(int c) const { return m_components[c]; } void AggregateWaveModel::componentModelChanged() { emit modelChanged(); } void AggregateWaveModel::componentModelChangedWithin(sv_frame_t start, sv_frame_t end) { emit modelChangedWithin(start, end); } void AggregateWaveModel::componentModelCompletionChanged() { emit completionChanged(); } void AggregateWaveModel::toXml(QTextStream &out, QString indent, QString extraAttributes) const { QStringList componentStrings; for (const auto &c: m_components) { auto model = ModelById::get(c.model); if (!model) continue; componentStrings.push_back(QString("%1").arg(model->getExportId())); } Model::toXml(out, indent, QString("type=\"aggregatewave\" components=\"%1\" %2") .arg(componentStrings.join(",")) .arg(extraAttributes)); }