annotate data/model/AggregateWaveModel.cpp @ 1008:d9e0e59a1581

When using an aggregate model to pass data to a transform, zero-pad the shorter input to the duration of the longer rather than truncating the longer. (This is better behaviour for e.g. MATCH, and in any case the code was previously truncating incorrectly and ending up with garbage data at the end.)
author Chris Cannam
date Fri, 14 Nov 2014 13:51:33 +0000
parents cd42620e3f40
children cc27f35aa75c
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@297 22 PowerOfSqrtTwoZoomConstraint
Chris@297 23 AggregateWaveModel::m_zoomConstraint;
Chris@297 24
Chris@297 25 AggregateWaveModel::AggregateWaveModel(ChannelSpecList channelSpecs) :
Chris@297 26 m_components(channelSpecs)
Chris@297 27 {
Chris@297 28 for (ChannelSpecList::const_iterator i = channelSpecs.begin();
Chris@297 29 i != channelSpecs.end(); ++i) {
Chris@297 30 if (i->model->getSampleRate() !=
Chris@297 31 channelSpecs.begin()->model->getSampleRate()) {
Chris@690 32 SVDEBUG << "AggregateWaveModel::AggregateWaveModel: WARNING: Component models do not all have the same sample rate" << endl;
Chris@297 33 break;
Chris@297 34 }
Chris@297 35 }
Chris@297 36 }
Chris@297 37
Chris@297 38 AggregateWaveModel::~AggregateWaveModel()
Chris@297 39 {
Chris@297 40 }
Chris@297 41
Chris@297 42 bool
Chris@297 43 AggregateWaveModel::isOK() const
Chris@297 44 {
Chris@297 45 for (ChannelSpecList::const_iterator i = m_components.begin();
Chris@297 46 i != m_components.end(); ++i) {
Chris@297 47 if (!i->model->isOK()) return false;
Chris@297 48 }
Chris@297 49 return true;
Chris@297 50 }
Chris@297 51
Chris@297 52 bool
Chris@297 53 AggregateWaveModel::isReady(int *completion) const
Chris@297 54 {
Chris@297 55 if (completion) *completion = 100;
Chris@297 56 bool ready = true;
Chris@297 57 for (ChannelSpecList::const_iterator i = m_components.begin();
Chris@297 58 i != m_components.end(); ++i) {
Chris@297 59 int completionHere = 100;
Chris@297 60 if (!i->model->isReady(&completionHere)) ready = false;
Chris@297 61 if (completion && completionHere < *completion) {
Chris@297 62 *completion = completionHere;
Chris@297 63 }
Chris@297 64 }
Chris@297 65 return ready;
Chris@297 66 }
Chris@297 67
Chris@929 68 int
Chris@297 69 AggregateWaveModel::getFrameCount() const
Chris@297 70 {
Chris@929 71 int count = 0;
Chris@297 72
Chris@297 73 for (ChannelSpecList::const_iterator i = m_components.begin();
Chris@297 74 i != m_components.end(); ++i) {
Chris@929 75 int thisCount = i->model->getEndFrame() - i->model->getStartFrame();
Chris@297 76 if (thisCount > count) count = thisCount;
Chris@297 77 }
Chris@297 78
Chris@297 79 return count;
Chris@297 80 }
Chris@297 81
Chris@929 82 int
Chris@297 83 AggregateWaveModel::getChannelCount() const
Chris@297 84 {
Chris@297 85 return m_components.size();
Chris@297 86 }
Chris@297 87
Chris@929 88 int
Chris@297 89 AggregateWaveModel::getSampleRate() const
Chris@297 90 {
Chris@297 91 if (m_components.empty()) return 0;
Chris@297 92 return m_components.begin()->model->getSampleRate();
Chris@297 93 }
Chris@297 94
Chris@297 95 Model *
Chris@297 96 AggregateWaveModel::clone() const
Chris@297 97 {
Chris@297 98 return new AggregateWaveModel(m_components);
Chris@297 99 }
Chris@297 100
Chris@929 101 int
Chris@929 102 AggregateWaveModel::getData(int channel, int start, int count,
Chris@300 103 float *buffer) const
Chris@297 104 {
Chris@297 105 int ch0 = channel, ch1 = channel;
Chris@297 106 bool mixing = false;
Chris@297 107 if (channel == -1) {
Chris@297 108 ch0 = 0;
Chris@297 109 ch1 = getChannelCount()-1;
Chris@297 110 mixing = true;
Chris@297 111 }
Chris@297 112
Chris@297 113 float *readbuf = buffer;
Chris@297 114 if (mixing) {
Chris@300 115 readbuf = new float[count];
Chris@929 116 for (int i = 0; i < count; ++i) {
Chris@297 117 buffer[i] = 0.f;
Chris@297 118 }
Chris@297 119 }
Chris@297 120
Chris@1008 121 int longest = 0;
Chris@1008 122
Chris@297 123 for (int c = ch0; c <= ch1; ++c) {
Chris@1008 124 int here =
Chris@300 125 m_components[c].model->getData(m_components[c].channel,
Chris@300 126 start, count,
Chris@300 127 readbuf);
Chris@1008 128 if (here > longest) {
Chris@1008 129 longest = here;
Chris@1008 130 }
Chris@1008 131 if (here < count) {
Chris@1008 132 for (int i = here; i < count; ++i) {
Chris@1008 133 readbuf[i] = 0.f;
Chris@1008 134 }
Chris@1008 135 }
Chris@297 136 if (mixing) {
Chris@929 137 for (int i = 0; i < count; ++i) {
Chris@297 138 buffer[i] += readbuf[i];
Chris@297 139 }
Chris@297 140 }
Chris@297 141 }
Chris@297 142
Chris@297 143 if (mixing) delete[] readbuf;
Chris@1008 144 return longest;
Chris@297 145 }
Chris@297 146
Chris@929 147 int
Chris@929 148 AggregateWaveModel::getData(int channel, int start, int count,
Chris@300 149 double *buffer) const
Chris@297 150 {
Chris@297 151 int ch0 = channel, ch1 = channel;
Chris@297 152 bool mixing = false;
Chris@297 153 if (channel == -1) {
Chris@297 154 ch0 = 0;
Chris@297 155 ch1 = getChannelCount()-1;
Chris@297 156 mixing = true;
Chris@297 157 }
Chris@297 158
Chris@297 159 double *readbuf = buffer;
Chris@297 160 if (mixing) {
Chris@300 161 readbuf = new double[count];
Chris@929 162 for (int i = 0; i < count; ++i) {
Chris@300 163 buffer[i] = 0.0;
Chris@297 164 }
Chris@297 165 }
Chris@297 166
Chris@1008 167 int longest = 0;
Chris@297 168
Chris@297 169 for (int c = ch0; c <= ch1; ++c) {
Chris@1008 170 int here =
Chris@300 171 m_components[c].model->getData(m_components[c].channel,
Chris@300 172 start, count,
Chris@300 173 readbuf);
Chris@1008 174 if (here > longest) {
Chris@1008 175 longest = here;
Chris@1008 176 }
Chris@1008 177 if (here < count) {
Chris@1008 178 for (int i = here; i < count; ++i) {
Chris@1008 179 readbuf[i] = 0.;
Chris@1008 180 }
Chris@1008 181 }
Chris@297 182 if (mixing) {
Chris@929 183 for (int i = 0; i < count; ++i) {
Chris@297 184 buffer[i] += readbuf[i];
Chris@297 185 }
Chris@297 186 }
Chris@297 187 }
Chris@297 188
Chris@297 189 if (mixing) delete[] readbuf;
Chris@1008 190 return longest;
Chris@297 191 }
Chris@363 192
Chris@929 193 int
Chris@929 194 AggregateWaveModel::getData(int fromchannel, int tochannel,
Chris@929 195 int start, int count,
Chris@363 196 float **buffer) const
Chris@363 197 {
Chris@929 198 int min = count;
Chris@363 199
Chris@929 200 for (int c = fromchannel; c <= tochannel; ++c) {
Chris@929 201 int here = getData(c, start, count, buffer[c - fromchannel]);
Chris@363 202 if (here < min) min = here;
Chris@363 203 }
Chris@363 204
Chris@363 205 return min;
Chris@363 206 }
Chris@377 207
Chris@929 208 int
Chris@929 209 AggregateWaveModel::getSummaryBlockSize(int desired) const
Chris@377 210 {
Chris@377 211 //!!! complete
Chris@377 212 return desired;
Chris@377 213 }
Chris@297 214
Chris@297 215 void
Chris@929 216 AggregateWaveModel::getSummaries(int, int, int,
Chris@929 217 RangeBlock &, int &) const
Chris@297 218 {
Chris@297 219 //!!! complete
Chris@297 220 }
Chris@297 221
Chris@297 222 AggregateWaveModel::Range
Chris@929 223 AggregateWaveModel::getSummary(int, int, int) const
Chris@297 224 {
Chris@297 225 //!!! complete
Chris@297 226 return Range();
Chris@297 227 }
Chris@297 228
Chris@929 229 int
Chris@297 230 AggregateWaveModel::getComponentCount() const
Chris@297 231 {
Chris@297 232 return m_components.size();
Chris@297 233 }
Chris@297 234
Chris@297 235 AggregateWaveModel::ModelChannelSpec
Chris@929 236 AggregateWaveModel::getComponent(int c) const
Chris@297 237 {
Chris@297 238 return m_components[c];
Chris@297 239 }
Chris@297 240
Chris@297 241 void
Chris@297 242 AggregateWaveModel::componentModelChanged()
Chris@297 243 {
Chris@297 244 emit modelChanged();
Chris@297 245 }
Chris@297 246
Chris@297 247 void
Chris@947 248 AggregateWaveModel::componentModelChangedWithin(int start, int end)
Chris@297 249 {
Chris@947 250 emit modelChangedWithin(start, end);
Chris@297 251 }
Chris@297 252
Chris@297 253 void
Chris@297 254 AggregateWaveModel::componentModelCompletionChanged()
Chris@297 255 {
Chris@297 256 emit completionChanged();
Chris@297 257 }
Chris@297 258
Chris@297 259 void
Chris@929 260 AggregateWaveModel::toXml(QTextStream &,
Chris@929 261 QString ,
Chris@929 262 QString ) const
Chris@297 263 {
Chris@297 264 //!!! complete
Chris@297 265 }
Chris@297 266