Mercurial > hg > svcore
diff data/model/AggregateWaveModel.cpp @ 297:c022976d18e8
* Merge from sv-match-alignment branch (excluding alignment-specific document).
- add aggregate wave model (not yet complete enough to be added as a true
model in a layer, but there's potential)
- add play solo mode
- add alignment model -- unused in plain SV
- fix two plugin leaks
- add m3u playlist support (opens all files at once, potentially hazardous)
- fix retrieval of pre-encoded URLs
- add ability to resample audio files on import, so as to match rates with
other files previously loaded; add preference for same
- add preliminary support in transform code for range and rate of transform
input
- reorganise preferences dialog, move dark-background option to preferences,
add option for temporary directory location
author | Chris Cannam |
---|---|
date | Fri, 28 Sep 2007 13:56:38 +0000 |
parents | |
children | 5877d68815c7 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/data/model/AggregateWaveModel.cpp Fri Sep 28 13:56:38 2007 +0000 @@ -0,0 +1,228 @@ +/* -*- 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> + +PowerOfSqrtTwoZoomConstraint +AggregateWaveModel::m_zoomConstraint; + +AggregateWaveModel::AggregateWaveModel(ChannelSpecList channelSpecs) : + m_components(channelSpecs) +{ + for (ChannelSpecList::const_iterator i = channelSpecs.begin(); + i != channelSpecs.end(); ++i) { + if (i->model->getSampleRate() != + channelSpecs.begin()->model->getSampleRate()) { + std::cerr << "AggregateWaveModel::AggregateWaveModel: WARNING: Component models do not all have the same sample rate" << std::endl; + break; + } + } +} + +AggregateWaveModel::~AggregateWaveModel() +{ +} + +bool +AggregateWaveModel::isOK() const +{ + for (ChannelSpecList::const_iterator i = m_components.begin(); + i != m_components.end(); ++i) { + if (!i->model->isOK()) return false; + } + return true; +} + +bool +AggregateWaveModel::isReady(int *completion) const +{ + if (completion) *completion = 100; + bool ready = true; + for (ChannelSpecList::const_iterator i = m_components.begin(); + i != m_components.end(); ++i) { + int completionHere = 100; + if (!i->model->isReady(&completionHere)) ready = false; + if (completion && completionHere < *completion) { + *completion = completionHere; + } + } + return ready; +} + +size_t +AggregateWaveModel::getFrameCount() const +{ + size_t count = 0; + + for (ChannelSpecList::const_iterator i = m_components.begin(); + i != m_components.end(); ++i) { + size_t thisCount = i->model->getEndFrame() - i->model->getStartFrame(); + if (thisCount > count) count = thisCount; + } + + return count; +} + +size_t +AggregateWaveModel::getChannelCount() const +{ + return m_components.size(); +} + +size_t +AggregateWaveModel::getSampleRate() const +{ + if (m_components.empty()) return 0; + return m_components.begin()->model->getSampleRate(); +} + +Model * +AggregateWaveModel::clone() const +{ + return new AggregateWaveModel(m_components); +} + +size_t +AggregateWaveModel::getValues(int channel, size_t start, size_t end, + float *buffer) const +{ + int ch0 = channel, ch1 = channel; + bool mixing = false; + if (channel == -1) { + ch0 = 0; + ch1 = getChannelCount()-1; + mixing = true; + } + + float *readbuf = buffer; + if (mixing) { + readbuf = new float[end - start]; + for (size_t i = 0; i < end - start; ++i) { + buffer[i] = 0.f; + } + } + + size_t sz = end - start; + + for (int c = ch0; c <= ch1; ++c) { + size_t szHere = + m_components[c].model->getValues(m_components[c].channel, + start, end, + readbuf); + if (szHere < sz) sz = szHere; + if (mixing) { + for (size_t i = 0; i < end - start; ++i) { + buffer[i] += readbuf[i]; + } + } + } + + if (mixing) delete[] readbuf; + return sz; +} + +size_t +AggregateWaveModel::getValues(int channel, size_t start, size_t end, + double *buffer) const +{ + int ch0 = channel, ch1 = channel; + bool mixing = false; + if (channel == -1) { + ch0 = 0; + ch1 = getChannelCount()-1; + mixing = true; + } + + double *readbuf = buffer; + if (mixing) { + readbuf = new double[end - start]; + for (size_t i = 0; i < end - start; ++i) { + buffer[i] = 0.f; + } + } + + size_t sz = end - start; + + for (int c = ch0; c <= ch1; ++c) { + size_t szHere = + m_components[c].model->getValues(m_components[c].channel, + start, end, + readbuf); + if (szHere < sz) sz = szHere; + if (mixing) { + for (size_t i = 0; i < end - start; ++i) { + buffer[i] += readbuf[i]; + } + } + } + + if (mixing) delete[] readbuf; + return sz; +} + +void +AggregateWaveModel::getRanges(size_t channel, size_t start, size_t end, + RangeBlock &ranges, size_t &blockSize) const +{ + //!!! complete +} + +AggregateWaveModel::Range +AggregateWaveModel::getRange(size_t channel, size_t start, size_t end) const +{ + //!!! complete + return Range(); +} + +size_t +AggregateWaveModel::getComponentCount() const +{ + return m_components.size(); +} + +AggregateWaveModel::ModelChannelSpec +AggregateWaveModel::getComponent(size_t c) const +{ + return m_components[c]; +} + +void +AggregateWaveModel::componentModelChanged() +{ + emit modelChanged(); +} + +void +AggregateWaveModel::componentModelChanged(size_t start, size_t end) +{ + emit modelChanged(start, end); +} + +void +AggregateWaveModel::componentModelCompletionChanged() +{ + emit completionChanged(); +} + +void +AggregateWaveModel::toXml(QTextStream &out, + QString indent, + QString extraAttributes) const +{ + //!!! complete +} +