annotate data/model/AggregateWaveModel.cpp @ 823:f0558e69a074

Rename Resampling- to DecodingWavFileReader, and use it whenever we have an audio file that is not quickly seekable using libsndfile. Avoids very slow performance when analysing ogg files.
author Chris Cannam
date Wed, 17 Jul 2013 15:40:01 +0100
parents 1424aa29ae95
children 59e7fe1b1003
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@297 68 size_t
Chris@297 69 AggregateWaveModel::getFrameCount() const
Chris@297 70 {
Chris@297 71 size_t 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@297 75 size_t 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@297 82 size_t
Chris@297 83 AggregateWaveModel::getChannelCount() const
Chris@297 84 {
Chris@297 85 return m_components.size();
Chris@297 86 }
Chris@297 87
Chris@297 88 size_t
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@297 101 size_t
Chris@300 102 AggregateWaveModel::getData(int channel, size_t start, size_t 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@300 116 for (size_t i = 0; i < count; ++i) {
Chris@297 117 buffer[i] = 0.f;
Chris@297 118 }
Chris@297 119 }
Chris@297 120
Chris@300 121 size_t sz = count;
Chris@300 122
Chris@297 123 for (int c = ch0; c <= ch1; ++c) {
Chris@297 124 size_t szHere =
Chris@300 125 m_components[c].model->getData(m_components[c].channel,
Chris@300 126 start, count,
Chris@300 127 readbuf);
Chris@297 128 if (szHere < sz) sz = szHere;
Chris@297 129 if (mixing) {
Chris@300 130 for (size_t i = 0; i < count; ++i) {
Chris@297 131 buffer[i] += readbuf[i];
Chris@297 132 }
Chris@297 133 }
Chris@297 134 }
Chris@297 135
Chris@297 136 if (mixing) delete[] readbuf;
Chris@297 137 return sz;
Chris@297 138 }
Chris@297 139
Chris@297 140 size_t
Chris@300 141 AggregateWaveModel::getData(int channel, size_t start, size_t count,
Chris@300 142 double *buffer) const
Chris@297 143 {
Chris@297 144 int ch0 = channel, ch1 = channel;
Chris@297 145 bool mixing = false;
Chris@297 146 if (channel == -1) {
Chris@297 147 ch0 = 0;
Chris@297 148 ch1 = getChannelCount()-1;
Chris@297 149 mixing = true;
Chris@297 150 }
Chris@297 151
Chris@297 152 double *readbuf = buffer;
Chris@297 153 if (mixing) {
Chris@300 154 readbuf = new double[count];
Chris@300 155 for (size_t i = 0; i < count; ++i) {
Chris@300 156 buffer[i] = 0.0;
Chris@297 157 }
Chris@297 158 }
Chris@297 159
Chris@300 160 size_t sz = count;
Chris@297 161
Chris@297 162 for (int c = ch0; c <= ch1; ++c) {
Chris@297 163 size_t szHere =
Chris@300 164 m_components[c].model->getData(m_components[c].channel,
Chris@300 165 start, count,
Chris@300 166 readbuf);
Chris@297 167 if (szHere < sz) sz = szHere;
Chris@297 168 if (mixing) {
Chris@300 169 for (size_t i = 0; i < count; ++i) {
Chris@297 170 buffer[i] += readbuf[i];
Chris@297 171 }
Chris@297 172 }
Chris@297 173 }
Chris@297 174
Chris@297 175 if (mixing) delete[] readbuf;
Chris@297 176 return sz;
Chris@297 177 }
Chris@363 178
Chris@363 179 size_t
Chris@363 180 AggregateWaveModel::getData(size_t fromchannel, size_t tochannel,
Chris@363 181 size_t start, size_t count,
Chris@363 182 float **buffer) const
Chris@363 183 {
Chris@363 184 size_t min = count;
Chris@363 185
Chris@363 186 for (size_t c = fromchannel; c <= tochannel; ++c) {
Chris@363 187 size_t here = getData(c, start, count, buffer[c - fromchannel]);
Chris@363 188 if (here < min) min = here;
Chris@363 189 }
Chris@363 190
Chris@363 191 return min;
Chris@363 192 }
Chris@377 193
Chris@377 194 size_t
Chris@377 195 AggregateWaveModel::getSummaryBlockSize(size_t desired) const
Chris@377 196 {
Chris@377 197 //!!! complete
Chris@377 198 return desired;
Chris@377 199 }
Chris@297 200
Chris@297 201 void
Chris@300 202 AggregateWaveModel::getSummaries(size_t channel, size_t start, size_t count,
Chris@300 203 RangeBlock &ranges, size_t &blockSize) const
Chris@297 204 {
Chris@297 205 //!!! complete
Chris@297 206 }
Chris@297 207
Chris@297 208 AggregateWaveModel::Range
Chris@300 209 AggregateWaveModel::getSummary(size_t channel, size_t start, size_t count) const
Chris@297 210 {
Chris@297 211 //!!! complete
Chris@297 212 return Range();
Chris@297 213 }
Chris@297 214
Chris@297 215 size_t
Chris@297 216 AggregateWaveModel::getComponentCount() const
Chris@297 217 {
Chris@297 218 return m_components.size();
Chris@297 219 }
Chris@297 220
Chris@297 221 AggregateWaveModel::ModelChannelSpec
Chris@297 222 AggregateWaveModel::getComponent(size_t c) const
Chris@297 223 {
Chris@297 224 return m_components[c];
Chris@297 225 }
Chris@297 226
Chris@297 227 void
Chris@297 228 AggregateWaveModel::componentModelChanged()
Chris@297 229 {
Chris@297 230 emit modelChanged();
Chris@297 231 }
Chris@297 232
Chris@297 233 void
Chris@297 234 AggregateWaveModel::componentModelChanged(size_t start, size_t end)
Chris@297 235 {
Chris@297 236 emit modelChanged(start, end);
Chris@297 237 }
Chris@297 238
Chris@297 239 void
Chris@297 240 AggregateWaveModel::componentModelCompletionChanged()
Chris@297 241 {
Chris@297 242 emit completionChanged();
Chris@297 243 }
Chris@297 244
Chris@297 245 void
Chris@297 246 AggregateWaveModel::toXml(QTextStream &out,
Chris@297 247 QString indent,
Chris@297 248 QString extraAttributes) const
Chris@297 249 {
Chris@297 250 //!!! complete
Chris@297 251 }
Chris@297 252