EditableDenseThreeDimensionalModel.cpp

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     This file copyright 2006 Chris Cannam and QMUL.
00008     
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of the
00012     License, or (at your option) any later version.  See the file
00013     COPYING included with this distribution for more information.
00014 */
00015 
00016 #include "EditableDenseThreeDimensionalModel.h"
00017 
00018 #include <QTextStream>
00019 
00020 #include <iostream>
00021 
00022 #include <cmath>
00023 
00024 EditableDenseThreeDimensionalModel::EditableDenseThreeDimensionalModel(size_t sampleRate,
00025                                                                        size_t resolution,
00026                                                                        size_t yBinCount,
00027                                                                        bool notifyOnAdd) :
00028     m_sampleRate(sampleRate),
00029     m_resolution(resolution),
00030     m_yBinCount(yBinCount),
00031     m_minimum(0.0),
00032     m_maximum(0.0),
00033     m_haveExtents(false),
00034     m_notifyOnAdd(notifyOnAdd),
00035     m_sinceLastNotifyMin(-1),
00036     m_sinceLastNotifyMax(-1),
00037     m_completion(100)
00038 {
00039 }    
00040 
00041 bool
00042 EditableDenseThreeDimensionalModel::isOK() const
00043 {
00044     return true;
00045 }
00046 
00047 size_t
00048 EditableDenseThreeDimensionalModel::getSampleRate() const
00049 {
00050     return m_sampleRate;
00051 }
00052 
00053 size_t
00054 EditableDenseThreeDimensionalModel::getStartFrame() const
00055 {
00056     return 0;
00057 }
00058 
00059 size_t
00060 EditableDenseThreeDimensionalModel::getEndFrame() const
00061 {
00062     return m_resolution * m_data.size() + (m_resolution - 1);
00063 }
00064 
00065 Model *
00066 EditableDenseThreeDimensionalModel::clone() const
00067 {
00068     EditableDenseThreeDimensionalModel *model =
00069         new EditableDenseThreeDimensionalModel
00070         (m_sampleRate, m_resolution, m_yBinCount);
00071 
00072     model->m_minimum = m_minimum;
00073     model->m_maximum = m_maximum;
00074     model->m_haveExtents = m_haveExtents;
00075 
00076     for (size_t i = 0; i < m_data.size(); ++i) {
00077         model->setColumn(i, m_data[i]);
00078     }
00079 
00080     return model;
00081 }
00082 
00083 size_t
00084 EditableDenseThreeDimensionalModel::getResolution() const
00085 {
00086     return m_resolution;
00087 }
00088 
00089 void
00090 EditableDenseThreeDimensionalModel::setResolution(size_t sz)
00091 {
00092     m_resolution = sz;
00093 }
00094 
00095 size_t
00096 EditableDenseThreeDimensionalModel::getWidth() const
00097 {
00098     return m_data.size();
00099 }
00100 
00101 size_t
00102 EditableDenseThreeDimensionalModel::getHeight() const
00103 {
00104     return m_yBinCount;
00105 }
00106 
00107 void
00108 EditableDenseThreeDimensionalModel::setHeight(size_t sz)
00109 {
00110     m_yBinCount = sz;
00111 }
00112 
00113 float
00114 EditableDenseThreeDimensionalModel::getMinimumLevel() const
00115 {
00116     return m_minimum;
00117 }
00118 
00119 void
00120 EditableDenseThreeDimensionalModel::setMinimumLevel(float level)
00121 {
00122     m_minimum = level;
00123 }
00124 
00125 float
00126 EditableDenseThreeDimensionalModel::getMaximumLevel() const
00127 {
00128     return m_maximum;
00129 }
00130 
00131 void
00132 EditableDenseThreeDimensionalModel::setMaximumLevel(float level)
00133 {
00134     m_maximum = level;
00135 }
00136 
00137 void
00138 EditableDenseThreeDimensionalModel::getColumn(size_t index,
00139                                               Column &result) const
00140 {
00141     QMutexLocker locker(&m_mutex);
00142 
00143     if (index < m_data.size()) {
00144         result = m_data[index];
00145     } else {
00146         result.clear();
00147     }
00148 
00149     while (result.size() < m_yBinCount) result.push_back(m_minimum);
00150 }
00151 
00152 float
00153 EditableDenseThreeDimensionalModel::getValueAt(size_t index, size_t n) const
00154 {
00155     QMutexLocker locker(&m_mutex);
00156 
00157     if (index < m_data.size()) {
00158         const Column &s = m_data[index];
00159 //        std::cerr << "index " << index << ", n " << n << ", res " << m_resolution << ", size " << s.size()
00160 //                  << std::endl;
00161         if (n < s.size()) return s[n];
00162     }
00163 
00164     return m_minimum;
00165 }
00166 
00167 void
00168 EditableDenseThreeDimensionalModel::setColumn(size_t index,
00169                                               const Column &values)
00170 {
00171     QMutexLocker locker(&m_mutex);
00172 
00173     while (index >= m_data.size()) {
00174         m_data.push_back(Column());
00175     }
00176 
00177     bool allChange = false;
00178 
00179     for (size_t i = 0; i < values.size(); ++i) {
00180         float value = values[i];
00181         if (std::isnan(value) || std::isinf(value)) {
00182             continue;
00183         }
00184         if (!m_haveExtents || value < m_minimum) {
00185             m_minimum = value;
00186             allChange = true;
00187         }
00188         if (!m_haveExtents || value > m_maximum) {
00189             m_maximum = value;
00190             allChange = true;
00191         }
00192         m_haveExtents = true;
00193     }
00194 
00195     m_data[index] = values;
00196 
00197     long windowStart = index;
00198     windowStart *= m_resolution;
00199 
00200     if (m_notifyOnAdd) {
00201         if (allChange) {
00202             emit modelChanged();
00203         } else {
00204             emit modelChanged(windowStart, windowStart + m_resolution);
00205         }
00206     } else {
00207         if (allChange) {
00208             m_sinceLastNotifyMin = -1;
00209             m_sinceLastNotifyMax = -1;
00210             emit modelChanged();
00211         } else {
00212             if (m_sinceLastNotifyMin == -1 ||
00213                 windowStart < m_sinceLastNotifyMin) {
00214                 m_sinceLastNotifyMin = windowStart;
00215             }
00216             if (m_sinceLastNotifyMax == -1 ||
00217                 windowStart > m_sinceLastNotifyMax) {
00218                 m_sinceLastNotifyMax = windowStart;
00219             }
00220         }
00221     }
00222 }
00223 
00224 QString
00225 EditableDenseThreeDimensionalModel::getBinName(size_t n) const
00226 {
00227     if (m_binNames.size() > n) return m_binNames[n];
00228     else return "";
00229 }
00230 
00231 void
00232 EditableDenseThreeDimensionalModel::setBinName(size_t n, QString name)
00233 {
00234     while (m_binNames.size() <= n) m_binNames.push_back("");
00235     m_binNames[n] = name;
00236     emit modelChanged();
00237 }
00238 
00239 void
00240 EditableDenseThreeDimensionalModel::setBinNames(std::vector<QString> names)
00241 {
00242     m_binNames = names;
00243     emit modelChanged();
00244 }
00245 
00246 void
00247 EditableDenseThreeDimensionalModel::setCompletion(int completion, bool update)
00248 {
00249     if (m_completion != completion) {
00250         m_completion = completion;
00251 
00252         if (completion == 100) {
00253 
00254             m_notifyOnAdd = true; // henceforth
00255             emit modelChanged();
00256 
00257         } else if (!m_notifyOnAdd) {
00258 
00259             if (update &&
00260                 m_sinceLastNotifyMin >= 0 &&
00261                 m_sinceLastNotifyMax >= 0) {
00262                 emit modelChanged(m_sinceLastNotifyMin,
00263                                   m_sinceLastNotifyMax + m_resolution);
00264                 m_sinceLastNotifyMin = m_sinceLastNotifyMax = -1;
00265             } else {
00266                 emit completionChanged();
00267             }
00268         } else {
00269             emit completionChanged();
00270         }           
00271     }
00272 }
00273 
00274 QString
00275 EditableDenseThreeDimensionalModel::toDelimitedDataString(QString delimiter) const
00276 {
00277     QString s;
00278     for (size_t i = 0; i < m_data.size(); ++i) {
00279         QStringList list;
00280         for (size_t j = 0; j < m_data[i].size(); ++j) {
00281             list << QString("%1").arg(m_data[i][j]);
00282         }
00283         s += list.join(delimiter) + "\n";
00284     }
00285     return s;
00286 }
00287 
00288 void
00289 EditableDenseThreeDimensionalModel::toXml(QTextStream &out,
00290                                           QString indent,
00291                                           QString extraAttributes) const
00292 {
00293     // For historical reasons we read and write "resolution" as "windowSize"
00294 
00295     std::cerr << "EditableDenseThreeDimensionalModel::toXml" << std::endl;
00296 
00297     Model::toXml
00298         (out, indent,
00299          QString("type=\"dense\" dimensions=\"3\" windowSize=\"%1\" yBinCount=\"%2\" minimum=\"%3\" maximum=\"%4\" dataset=\"%5\" %6")
00300          .arg(m_resolution)
00301          .arg(m_yBinCount)
00302          .arg(m_minimum)
00303          .arg(m_maximum)
00304          .arg(getObjectExportId(&m_data))
00305          .arg(extraAttributes));
00306 
00307     out << indent;
00308     out << QString("<dataset id=\"%1\" dimensions=\"3\" separator=\" \">\n")
00309         .arg(getObjectExportId(&m_data));
00310 
00311     for (size_t i = 0; i < m_binNames.size(); ++i) {
00312         if (m_binNames[i] != "") {
00313             out << indent + "  ";
00314             out << QString("<bin number=\"%1\" name=\"%2\"/>\n")
00315                 .arg(i).arg(m_binNames[i]);
00316         }
00317     }
00318 
00319     for (size_t i = 0; i < m_data.size(); ++i) {
00320         out << indent + "  ";
00321         out << QString("<row n=\"%1\">").arg(i);
00322         for (size_t j = 0; j < m_data[i].size(); ++j) {
00323             if (j > 0) out << " ";
00324             out << m_data[i][j];
00325         }
00326         out << QString("</row>\n");
00327         out.flush();
00328     }
00329 
00330     out << indent + "</dataset>\n";
00331 }
00332 
00333 

Generated on Wed Feb 20 15:45:25 2008 for SonicVisualiser by  doxygen 1.5.1