annotate data/model/AggregateWaveModel.cpp @ 1455:ec9e65fcf749

The use of the begin/end pairs here just seems to cause too many rows to be deleted (from the visual representation, not the underlying model). Things apparently work better if we just modify the underlying model and let the change signals percolate back up again. To that end, update the change handlers so as to cover their proper ranges with dataChanged signals.
author Chris Cannam
date Mon, 23 Apr 2018 16:03:35 +0100
parents 2c0e04062a99
children 7b4d56b01440
rev   line source
Chris@297 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@297 2
Chris@297 3 /*
Chris@297 4 Sonic Visualiser
Chris@297 5 An audio file viewer and annotation editor.
Chris@297 6 Centre for Digital Music, Queen Mary, University of London.
Chris@297 7 This file copyright 2007 QMUL.
Chris@297 8
Chris@297 9 This program is free software; you can redistribute it and/or
Chris@297 10 modify it under the terms of the GNU General Public License as
Chris@297 11 published by the Free Software Foundation; either version 2 of the
Chris@297 12 License, or (at your option) any later version. See the file
Chris@297 13 COPYING included with this distribution for more information.
Chris@297 14 */
Chris@297 15
Chris@297 16 #include "AggregateWaveModel.h"
Chris@297 17
Chris@297 18 #include <iostream>
Chris@297 19
Chris@314 20 #include <QTextStream>
Chris@314 21
Chris@1096 22 using namespace std;
Chris@1096 23
Chris@297 24 PowerOfSqrtTwoZoomConstraint
Chris@297 25 AggregateWaveModel::m_zoomConstraint;
Chris@297 26
Chris@297 27 AggregateWaveModel::AggregateWaveModel(ChannelSpecList channelSpecs) :
Chris@1389 28 m_components(channelSpecs),
Chris@1389 29 m_invalidated(false)
Chris@297 30 {
Chris@297 31 for (ChannelSpecList::const_iterator i = channelSpecs.begin();
Chris@297 32 i != channelSpecs.end(); ++i) {
Chris@1389 33
Chris@1389 34 connect(i->model, SIGNAL(aboutToBeDeleted()),
Chris@1389 35 this, SLOT(componentModelAboutToBeDeleted()));
Chris@1389 36
Chris@297 37 if (i->model->getSampleRate() !=
Chris@297 38 channelSpecs.begin()->model->getSampleRate()) {
Chris@690 39 SVDEBUG << "AggregateWaveModel::AggregateWaveModel: WARNING: Component models do not all have the same sample rate" << endl;
Chris@297 40 break;
Chris@297 41 }
Chris@297 42 }
Chris@297 43 }
Chris@297 44
Chris@297 45 AggregateWaveModel::~AggregateWaveModel()
Chris@297 46 {
Chris@297 47 }
Chris@297 48
Chris@1389 49 void
Chris@1389 50 AggregateWaveModel::componentModelAboutToBeDeleted()
Chris@1389 51 {
Chris@1389 52 SVDEBUG << "AggregateWaveModel::componentModelAboutToBeDeleted: invalidating"
Chris@1389 53 << endl;
Chris@1389 54 m_components.clear();
Chris@1389 55 m_invalidated = true;
Chris@1390 56 emit modelInvalidated();
Chris@1389 57 }
Chris@1389 58
Chris@297 59 bool
Chris@297 60 AggregateWaveModel::isOK() const
Chris@297 61 {
Chris@1389 62 if (m_invalidated) {
Chris@1389 63 return false;
Chris@1389 64 }
Chris@297 65 for (ChannelSpecList::const_iterator i = m_components.begin();
Chris@297 66 i != m_components.end(); ++i) {
Chris@1389 67 if (!i->model->isOK()) {
Chris@1389 68 return false;
Chris@1389 69 }
Chris@297 70 }
Chris@297 71 return true;
Chris@297 72 }
Chris@297 73
Chris@297 74 bool
Chris@297 75 AggregateWaveModel::isReady(int *completion) const
Chris@297 76 {
Chris@297 77 if (completion) *completion = 100;
Chris@1389 78
Chris@297 79 bool ready = true;
Chris@297 80 for (ChannelSpecList::const_iterator i = m_components.begin();
Chris@297 81 i != m_components.end(); ++i) {
Chris@297 82 int completionHere = 100;
Chris@297 83 if (!i->model->isReady(&completionHere)) ready = false;
Chris@297 84 if (completion && completionHere < *completion) {
Chris@297 85 *completion = completionHere;
Chris@297 86 }
Chris@297 87 }
Chris@297 88 return ready;
Chris@297 89 }
Chris@297 90
Chris@1038 91 sv_frame_t
Chris@297 92 AggregateWaveModel::getFrameCount() const
Chris@297 93 {
Chris@1038 94 sv_frame_t count = 0;
Chris@297 95 for (ChannelSpecList::const_iterator i = m_components.begin();
Chris@297 96 i != m_components.end(); ++i) {
Chris@1389 97 sv_frame_t thisCount =
Chris@1389 98 i->model->getEndFrame() - i->model->getStartFrame();
Chris@297 99 if (thisCount > count) count = thisCount;
Chris@297 100 }
Chris@297 101 return count;
Chris@297 102 }
Chris@297 103
Chris@929 104 int
Chris@297 105 AggregateWaveModel::getChannelCount() const
Chris@297 106 {
Chris@1038 107 return int(m_components.size());
Chris@297 108 }
Chris@297 109
Chris@1040 110 sv_samplerate_t
Chris@297 111 AggregateWaveModel::getSampleRate() const
Chris@297 112 {
Chris@297 113 if (m_components.empty()) return 0;
Chris@297 114 return m_components.begin()->model->getSampleRate();
Chris@297 115 }
Chris@297 116
Chris@1326 117 floatvec_t
Chris@1096 118 AggregateWaveModel::getData(int channel, sv_frame_t start, sv_frame_t count) const
Chris@297 119 {
Chris@297 120 int ch0 = channel, ch1 = channel;
Chris@297 121 if (channel == -1) {
Chris@297 122 ch0 = 0;
Chris@297 123 ch1 = getChannelCount()-1;
Chris@297 124 }
Chris@297 125
Chris@1326 126 floatvec_t result(count, 0.f);
Chris@1038 127 sv_frame_t longest = 0;
Chris@1008 128
Chris@297 129 for (int c = ch0; c <= ch1; ++c) {
Chris@1096 130
Chris@1096 131 auto here = m_components[c].model->getData(m_components[c].channel,
Chris@1096 132 start, count);
Chris@1100 133 if (sv_frame_t(here.size()) > longest) {
Chris@1100 134 longest = sv_frame_t(here.size());
Chris@1008 135 }
Chris@1096 136 for (sv_frame_t i = 0; in_range_for(here, i); ++i) {
Chris@1096 137 result[i] += here[i];
Chris@297 138 }
Chris@297 139 }
Chris@297 140
Chris@1096 141 result.resize(longest);
Chris@1096 142 return result;
Chris@297 143 }
Chris@363 144
Chris@1326 145 vector<floatvec_t>
Chris@1086 146 AggregateWaveModel::getMultiChannelData(int fromchannel, int tochannel,
Chris@1096 147 sv_frame_t start, sv_frame_t count) const
Chris@363 148 {
Chris@1038 149 sv_frame_t min = count;
Chris@363 150
Chris@1326 151 vector<floatvec_t> result;
Chris@1096 152
Chris@929 153 for (int c = fromchannel; c <= tochannel; ++c) {
Chris@1096 154 auto here = getData(c, start, count);
Chris@1100 155 if (sv_frame_t(here.size()) < min) {
Chris@1100 156 min = sv_frame_t(here.size());
Chris@1100 157 }
Chris@1096 158 result.push_back(here);
Chris@1096 159 }
Chris@1096 160
Chris@1096 161 if (min < count) {
Chris@1096 162 for (auto &v : result) v.resize(min);
Chris@363 163 }
Chris@363 164
Chris@1096 165 return result;
Chris@363 166 }
Chris@377 167
Chris@929 168 int
Chris@929 169 AggregateWaveModel::getSummaryBlockSize(int desired) const
Chris@377 170 {
Chris@377 171 //!!! complete
Chris@377 172 return desired;
Chris@377 173 }
Chris@297 174
Chris@297 175 void
Chris@1038 176 AggregateWaveModel::getSummaries(int, sv_frame_t, sv_frame_t,
Chris@929 177 RangeBlock &, int &) const
Chris@297 178 {
Chris@297 179 //!!! complete
Chris@297 180 }
Chris@297 181
Chris@297 182 AggregateWaveModel::Range
Chris@1038 183 AggregateWaveModel::getSummary(int, sv_frame_t, sv_frame_t) const
Chris@297 184 {
Chris@297 185 //!!! complete
Chris@297 186 return Range();
Chris@297 187 }
Chris@297 188
Chris@929 189 int
Chris@297 190 AggregateWaveModel::getComponentCount() const
Chris@297 191 {
Chris@1038 192 return int(m_components.size());
Chris@297 193 }
Chris@297 194
Chris@297 195 AggregateWaveModel::ModelChannelSpec
Chris@929 196 AggregateWaveModel::getComponent(int c) const
Chris@297 197 {
Chris@297 198 return m_components[c];
Chris@297 199 }
Chris@297 200
Chris@297 201 void
Chris@297 202 AggregateWaveModel::componentModelChanged()
Chris@297 203 {
Chris@297 204 emit modelChanged();
Chris@297 205 }
Chris@297 206
Chris@297 207 void
Chris@1038 208 AggregateWaveModel::componentModelChangedWithin(sv_frame_t start, sv_frame_t end)
Chris@297 209 {
Chris@947 210 emit modelChangedWithin(start, end);
Chris@297 211 }
Chris@297 212
Chris@297 213 void
Chris@297 214 AggregateWaveModel::componentModelCompletionChanged()
Chris@297 215 {
Chris@297 216 emit completionChanged();
Chris@297 217 }
Chris@297 218
Chris@297 219 void
Chris@1391 220 AggregateWaveModel::toXml(QTextStream &out,
Chris@1391 221 QString indent,
Chris@1391 222 QString extraAttributes) const
Chris@297 223 {
Chris@1391 224 QStringList componentStrings;
Chris@1391 225 for (const auto &c: m_components) {
Chris@1391 226 componentStrings.push_back(QString("%1").arg(getObjectExportId(c.model)));
Chris@1391 227 }
Chris@1391 228 Model::toXml(out, indent,
Chris@1391 229 QString("type=\"aggregatewave\" components=\"%1\" %2")
Chris@1391 230 .arg(componentStrings.join(","))
Chris@1391 231 .arg(extraAttributes));
Chris@297 232 }
Chris@297 233