changeset 1791:c2388289fce8 time-frequency-boxes

Rename TimeFrequencyBoxModel to simply BoxModel
author Chris Cannam
date Wed, 25 Sep 2019 09:44:02 +0100 (2019-09-25)
parents dd51797e528e
children cb45c0a1dfe1
files data/model/BoxModel.h data/model/TimeFrequencyBoxModel.h files.pri
diffstat 3 files changed, 382 insertions(+), 377 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/data/model/BoxModel.h	Wed Sep 25 09:44:02 2019 +0100
@@ -0,0 +1,381 @@
+/* -*- 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 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.
+*/
+
+#ifndef SV_BOX_MODEL_H
+#define SV_BOX_MODEL_H
+
+#include "EventCommands.h"
+#include "TabularModel.h"
+#include "Model.h"
+#include "DeferredNotifier.h"
+
+#include "base/RealTime.h"
+#include "base/EventSeries.h"
+#include "base/UnitDatabase.h"
+
+#include "system/System.h"
+
+#include <QMutex>
+
+/**
+ * BoxModel -- a model for annotations having start time, duration,
+ * and a value range. We use Events as usual for these, but treat the
+ * "value" as the lower value and "level" as the difference between
+ * lower and upper values, which is expected to be non-negative (if it
+ * is negative, abs(level) will be used).
+ *
+ * This is expected to be used most often for time-frequency boxes.
+ */
+class BoxModel : public Model,
+                 public TabularModel,
+                 public EventEditable
+{
+    Q_OBJECT
+    
+public:
+    BoxModel(sv_samplerate_t sampleRate,
+                          int resolution,
+                          bool notifyOnAdd = true) :
+        m_sampleRate(sampleRate),
+        m_resolution(resolution),
+        m_valueMinimum(0.f),
+        m_valueMaximum(0.f),
+        m_haveExtents(false),
+        m_notifier(this,
+                   getId(),
+                   notifyOnAdd ?
+                   DeferredNotifier::NOTIFY_ALWAYS :
+                   DeferredNotifier::NOTIFY_DEFERRED),
+        m_completion(100) {
+    }
+
+    BoxModel(sv_samplerate_t sampleRate, int resolution,
+                          float valueMinimum, float valueMaximum,
+                          bool notifyOnAdd = true) :
+        m_sampleRate(sampleRate),
+        m_resolution(resolution),
+        m_valueMinimum(valueMinimum),
+        m_valueMaximum(valueMaximum),
+        m_haveExtents(true),
+        m_notifier(this,
+                   getId(),
+                   notifyOnAdd ?
+                   DeferredNotifier::NOTIFY_ALWAYS :
+                   DeferredNotifier::NOTIFY_DEFERRED),
+        m_completion(100) {
+    }
+
+    virtual ~BoxModel() {
+    }
+
+    QString getTypeName() const override { return tr("Box"); }
+    bool isSparse() const override { return true; }
+    bool isOK() const override { return true; }
+
+    sv_frame_t getStartFrame() const override {
+        return m_events.getStartFrame();
+    }
+    sv_frame_t getTrueEndFrame() const override {
+        if (m_events.isEmpty()) return 0;
+        sv_frame_t e = m_events.getEndFrame();
+        if (e % m_resolution == 0) return e;
+        else return (e / m_resolution + 1) * m_resolution;
+    }
+
+    sv_samplerate_t getSampleRate() const override { return m_sampleRate; }
+    int getResolution() const { return m_resolution; }
+
+    QString getScaleUnits() const { return m_units; }
+    void setScaleUnits(QString units) {
+        m_units = units;
+        UnitDatabase::getInstance()->registerUnit(units);
+    }
+
+    float getValueMinimum() const { return m_valueMinimum; }
+    float getValueMaximum() const { return m_valueMaximum; }
+    
+    int getCompletion() const override { return m_completion; }
+
+    void setCompletion(int completion, bool update = true) {
+
+        {   QMutexLocker locker(&m_mutex);
+            if (m_completion == completion) return;
+            m_completion = completion;
+        }
+
+        if (update) {
+            m_notifier.makeDeferredNotifications();
+        }
+        
+        emit completionChanged(getId());
+
+        if (completion == 100) {
+            // henceforth:
+            m_notifier.switchMode(DeferredNotifier::NOTIFY_ALWAYS);
+            emit modelChanged(getId());
+        }
+    }
+
+    /**
+     * Query methods.
+     */
+    int getEventCount() const {
+        return m_events.count();
+    }
+    bool isEmpty() const {
+        return m_events.isEmpty();
+    }
+    bool containsEvent(const Event &e) const {
+        return m_events.contains(e);
+    }
+    EventVector getAllEvents() const {
+        return m_events.getAllEvents();
+    }
+    EventVector getEventsSpanning(sv_frame_t f, sv_frame_t duration) const {
+        return m_events.getEventsSpanning(f, duration);
+    }
+    EventVector getEventsCovering(sv_frame_t f) const {
+        return m_events.getEventsCovering(f);
+    }
+    EventVector getEventsWithin(sv_frame_t f, sv_frame_t duration) const {
+        return m_events.getEventsWithin(f, duration);
+    }
+    EventVector getEventsStartingWithin(sv_frame_t f, sv_frame_t duration) const {
+        return m_events.getEventsStartingWithin(f, duration);
+    }
+    EventVector getEventsStartingAt(sv_frame_t f) const {
+        return m_events.getEventsStartingAt(f);
+    }
+    bool getNearestEventMatching(sv_frame_t startSearchAt,
+                                 std::function<bool(Event)> predicate,
+                                 EventSeries::Direction direction,
+                                 Event &found) const {
+        return m_events.getNearestEventMatching
+            (startSearchAt, predicate, direction, found);
+    }
+
+    /**
+     * Editing methods.
+     */
+    void add(Event e) override {
+
+        bool allChange = false;
+
+        {
+            QMutexLocker locker(&m_mutex);
+            m_events.add(e);
+
+            float f0 = e.getValue();
+            float f1 = f0 + fabsf(e.getLevel());
+            
+            if (!m_haveExtents || f0 < m_valueMinimum) {
+                m_valueMinimum = f0; allChange = true;
+            }
+            if (!m_haveExtents || f1 > m_valueMaximum) {
+                m_valueMaximum = f1; allChange = true;
+            }
+            m_haveExtents = true;
+        }
+        
+        m_notifier.update(e.getFrame(), e.getDuration() + m_resolution);
+
+        if (allChange) {
+            emit modelChanged(getId());
+        }
+    }
+    
+    void remove(Event e) override {
+        {
+            QMutexLocker locker(&m_mutex);
+            m_events.remove(e);
+        }
+        emit modelChangedWithin(getId(),
+                                e.getFrame(),
+                                e.getFrame() + e.getDuration() + m_resolution);
+    }
+    
+    /**
+     * TabularModel methods.  
+     */
+
+    int getRowCount() const override {
+        return m_events.count();
+    }
+
+    int getColumnCount() const override {
+        return 6;
+    }
+
+    bool isColumnTimeValue(int column) const override {
+        // NB duration is not a "time value" -- that's for columns
+        // whose sort ordering is exactly that of the frame time
+        return (column < 2);
+    }
+
+    sv_frame_t getFrameForRow(int row) const override {
+        if (row < 0 || row >= m_events.count()) {
+            return 0;
+        }
+        Event e = m_events.getEventByIndex(row);
+        return e.getFrame();
+    }
+
+    int getRowForFrame(sv_frame_t frame) const override {
+        return m_events.getIndexForEvent(Event(frame));
+    }
+    
+    QString getHeading(int column) const override {
+        switch (column) {
+        case 0: return tr("Time");
+        case 1: return tr("Frame");
+        case 2: return tr("Duration");
+        case 3: return tr("Min Freq");
+        case 4: return tr("Max Freq");
+        case 5: return tr("Label");
+        default: return tr("Unknown");
+        }
+    }
+
+    SortType getSortType(int column) const override {
+        if (column == 5) return SortAlphabetical;
+        return SortNumeric;
+    }
+
+    QVariant getData(int row, int column, int role) const override {
+
+        if (row < 0 || row >= m_events.count()) {
+            return QVariant();
+        }
+
+        Event e = m_events.getEventByIndex(row);
+
+        switch (column) {
+        case 0: return adaptFrameForRole(e.getFrame(), getSampleRate(), role);
+        case 1: return int(e.getFrame());
+        case 2: return int(e.getDuration());
+        case 3: return adaptValueForRole(e.getValue(), getScaleUnits(), role);
+        case 4: return adaptValueForRole(e.getValue() + fabsf(e.getLevel()),
+                                         getScaleUnits(), role);
+        case 5: return e.getLabel();
+        default: return QVariant();
+        }
+    }
+
+    Command *getSetDataCommand(int row, int column, const QVariant &value,
+                               int role) override {
+        
+        if (row < 0 || row >= m_events.count()) return nullptr;
+        if (role != Qt::EditRole) return nullptr;
+
+        Event e0 = m_events.getEventByIndex(row);
+        Event e1;
+
+        switch (column) {
+        case 0: e1 = e0.withFrame(sv_frame_t(round(value.toDouble() *
+                                                   getSampleRate()))); break;
+        case 1: e1 = e0.withFrame(value.toInt()); break;
+        case 2: e1 = e0.withDuration(value.toInt()); break;
+        case 3: e1 = e0.withValue(float(value.toDouble())); break;
+        case 4: e1 = e0.withLevel(fabsf(float(value.toDouble()) -
+                                        e0.getValue())); break;
+        case 5: e1 = e0.withLabel(value.toString()); break;
+        }
+
+        auto command = new ChangeEventsCommand(getId().untyped, tr("Edit Data"));
+        command->remove(e0);
+        command->add(e1);
+        return command->finish();
+    }
+
+    
+    /**
+     * XmlExportable methods.
+     */
+    void toXml(QTextStream &out,
+               QString indent = "",
+               QString extraAttributes = "") const override {
+
+        Model::toXml
+            (out,
+             indent,
+             QString("type=\"sparse\" dimensions=\"2\" resolution=\"%1\" "
+                     "notifyOnAdd=\"%2\" dataset=\"%3\" subtype=\"%4\" "
+                     "minimum=\"%5\" maximum=\"%6\" units=\"%7\" %8")
+             .arg(m_resolution)
+             .arg("true") // always true after model reaches 100% -
+                          // subsequent events are always notified
+             .arg(m_events.getExportId())
+             .arg("box")
+             .arg(m_valueMinimum)
+             .arg(m_valueMaximum)
+             .arg(encodeEntities(m_units))
+             .arg(extraAttributes));
+
+        Event::ExportNameOptions options;
+        options.levelAttributeName = "extent";
+        
+        m_events.toXml(out, indent, QString("dimensions=\"2\""), options);
+    }
+
+    QString toDelimitedDataString(QString delimiter,
+                                  DataExportOptions,
+                                  sv_frame_t startFrame,
+                                  sv_frame_t duration) const override {
+
+        // We need a custom format here
+
+        EventVector ee = m_events.getEventsSpanning(startFrame, duration);
+
+        QString s;
+        
+        for (auto e: ee) {
+
+            QStringList list;
+
+            list << RealTime::frame2RealTime
+                (e.getFrame(), getSampleRate())
+                .toString().c_str()
+                 << RealTime::frame2RealTime
+                (e.getFrame() + e.getDuration(), getSampleRate())
+                .toString().c_str()
+                 << QString("%1").arg(e.getValue())
+                 << QString("%1").arg(e.getValue() + fabsf(e.getLevel()));
+            
+            if (e.getLabel() != "") {
+                list << e.getLabel();
+            }
+
+            s += list.join(delimiter) + "\n";
+        }
+
+        return s;
+    }
+
+protected:
+    sv_samplerate_t m_sampleRate;
+    int m_resolution;
+
+    float m_valueMinimum;
+    float m_valueMaximum;
+    bool m_haveExtents;
+    QString m_units;
+    DeferredNotifier m_notifier;
+    int m_completion;
+
+    EventSeries m_events;
+
+    mutable QMutex m_mutex;
+};
+
+#endif
--- a/data/model/TimeFrequencyBoxModel.h	Wed Sep 25 09:43:34 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,376 +0,0 @@
-/* -*- 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 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.
-*/
-
-#ifndef SV_TIME_FREQUENCY_BOX_MODEL_H
-#define SV_TIME_FREQUENCY_BOX_MODEL_H
-
-#include "EventCommands.h"
-#include "TabularModel.h"
-#include "Model.h"
-#include "DeferredNotifier.h"
-
-#include "base/RealTime.h"
-#include "base/EventSeries.h"
-#include "base/UnitDatabase.h"
-
-#include "system/System.h"
-
-#include <QMutex>
-
-/**
- * TimeFrequencyBoxModel -- a model for annotations having start time,
- * duration, and a frequency range. We use Events as usual for these,
- * but treat the "value" as the lower frequency and "level" as the
- * difference between lower and upper frequencies, which is expected
- * to be non-negative (if it is negative, abs(level) will be used).
- */
-class TimeFrequencyBoxModel : public Model,
-                              public TabularModel,
-                              public EventEditable
-{
-    Q_OBJECT
-    
-public:
-    TimeFrequencyBoxModel(sv_samplerate_t sampleRate,
-                          int resolution,
-                          bool notifyOnAdd = true) :
-        m_sampleRate(sampleRate),
-        m_resolution(resolution),
-        m_frequencyMinimum(0.f),
-        m_frequencyMaximum(0.f),
-        m_haveExtents(false),
-        m_notifier(this,
-                   getId(),
-                   notifyOnAdd ?
-                   DeferredNotifier::NOTIFY_ALWAYS :
-                   DeferredNotifier::NOTIFY_DEFERRED),
-        m_completion(100) {
-    }
-
-    TimeFrequencyBoxModel(sv_samplerate_t sampleRate, int resolution,
-                          float frequencyMinimum, float frequencyMaximum,
-                          bool notifyOnAdd = true) :
-        m_sampleRate(sampleRate),
-        m_resolution(resolution),
-        m_frequencyMinimum(frequencyMinimum),
-        m_frequencyMaximum(frequencyMaximum),
-        m_haveExtents(true),
-        m_notifier(this,
-                   getId(),
-                   notifyOnAdd ?
-                   DeferredNotifier::NOTIFY_ALWAYS :
-                   DeferredNotifier::NOTIFY_DEFERRED),
-        m_completion(100) {
-    }
-
-    virtual ~TimeFrequencyBoxModel() {
-    }
-
-    QString getTypeName() const override { return tr("Time-Frequency Box"); }
-    bool isSparse() const override { return true; }
-    bool isOK() const override { return true; }
-
-    sv_frame_t getStartFrame() const override {
-        return m_events.getStartFrame();
-    }
-    sv_frame_t getTrueEndFrame() const override {
-        if (m_events.isEmpty()) return 0;
-        sv_frame_t e = m_events.getEndFrame();
-        if (e % m_resolution == 0) return e;
-        else return (e / m_resolution + 1) * m_resolution;
-    }
-
-    sv_samplerate_t getSampleRate() const override { return m_sampleRate; }
-    int getResolution() const { return m_resolution; }
-
-    QString getScaleUnits() const { return "Hz"; }
-
-    float getFrequencyMinimum() const { return m_frequencyMinimum; }
-    float getFrequencyMaximum() const { return m_frequencyMaximum; }
-    
-    int getCompletion() const override { return m_completion; }
-
-    void setCompletion(int completion, bool update = true) {
-
-        {   QMutexLocker locker(&m_mutex);
-            if (m_completion == completion) return;
-            m_completion = completion;
-        }
-
-        if (update) {
-            m_notifier.makeDeferredNotifications();
-        }
-        
-        emit completionChanged(getId());
-
-        if (completion == 100) {
-            // henceforth:
-            m_notifier.switchMode(DeferredNotifier::NOTIFY_ALWAYS);
-            emit modelChanged(getId());
-        }
-    }
-
-    /**
-     * Query methods.
-     */
-    int getEventCount() const {
-        return m_events.count();
-    }
-    bool isEmpty() const {
-        return m_events.isEmpty();
-    }
-    bool containsEvent(const Event &e) const {
-        return m_events.contains(e);
-    }
-    EventVector getAllEvents() const {
-        return m_events.getAllEvents();
-    }
-    EventVector getEventsSpanning(sv_frame_t f, sv_frame_t duration) const {
-        return m_events.getEventsSpanning(f, duration);
-    }
-    EventVector getEventsCovering(sv_frame_t f) const {
-        return m_events.getEventsCovering(f);
-    }
-    EventVector getEventsWithin(sv_frame_t f, sv_frame_t duration) const {
-        return m_events.getEventsWithin(f, duration);
-    }
-    EventVector getEventsStartingWithin(sv_frame_t f, sv_frame_t duration) const {
-        return m_events.getEventsStartingWithin(f, duration);
-    }
-    EventVector getEventsStartingAt(sv_frame_t f) const {
-        return m_events.getEventsStartingAt(f);
-    }
-    bool getNearestEventMatching(sv_frame_t startSearchAt,
-                                 std::function<bool(Event)> predicate,
-                                 EventSeries::Direction direction,
-                                 Event &found) const {
-        return m_events.getNearestEventMatching
-            (startSearchAt, predicate, direction, found);
-    }
-
-    /**
-     * Editing methods.
-     */
-    void add(Event e) override {
-
-        bool allChange = false;
-
-        {
-            QMutexLocker locker(&m_mutex);
-            m_events.add(e);
-
-            float f0 = e.getValue();
-            float f1 = f0 + fabsf(e.getLevel());
-            
-            if (!m_haveExtents || f0 < m_frequencyMinimum) {
-                m_frequencyMinimum = f0; allChange = true;
-            }
-            if (!m_haveExtents || f1 > m_frequencyMaximum) {
-                m_frequencyMaximum = f1; allChange = true;
-            }
-            m_haveExtents = true;
-        }
-        
-        m_notifier.update(e.getFrame(), e.getDuration() + m_resolution);
-
-        if (allChange) {
-            emit modelChanged(getId());
-        }
-    }
-    
-    void remove(Event e) override {
-        {
-            QMutexLocker locker(&m_mutex);
-            m_events.remove(e);
-        }
-        emit modelChangedWithin(getId(),
-                                e.getFrame(),
-                                e.getFrame() + e.getDuration() + m_resolution);
-    }
-    
-    /**
-     * TabularModel methods.  
-     */
-
-    int getRowCount() const override {
-        return m_events.count();
-    }
-
-    int getColumnCount() const override {
-        return 6;
-    }
-
-    bool isColumnTimeValue(int column) const override {
-        // NB duration is not a "time value" -- that's for columns
-        // whose sort ordering is exactly that of the frame time
-        return (column < 2);
-    }
-
-    sv_frame_t getFrameForRow(int row) const override {
-        if (row < 0 || row >= m_events.count()) {
-            return 0;
-        }
-        Event e = m_events.getEventByIndex(row);
-        return e.getFrame();
-    }
-
-    int getRowForFrame(sv_frame_t frame) const override {
-        return m_events.getIndexForEvent(Event(frame));
-    }
-    
-    QString getHeading(int column) const override {
-        switch (column) {
-        case 0: return tr("Time");
-        case 1: return tr("Frame");
-        case 2: return tr("Duration");
-        case 3: return tr("Min Freq");
-        case 4: return tr("Max Freq");
-        case 5: return tr("Label");
-        default: return tr("Unknown");
-        }
-    }
-
-    SortType getSortType(int column) const override {
-        if (column == 5) return SortAlphabetical;
-        return SortNumeric;
-    }
-
-    QVariant getData(int row, int column, int role) const override {
-
-        if (row < 0 || row >= m_events.count()) {
-            return QVariant();
-        }
-
-        Event e = m_events.getEventByIndex(row);
-
-        switch (column) {
-        case 0: return adaptFrameForRole(e.getFrame(), getSampleRate(), role);
-        case 1: return int(e.getFrame());
-        case 2: return int(e.getDuration());
-        case 3: return adaptValueForRole(e.getValue(), getScaleUnits(), role);
-        case 4: return adaptValueForRole(e.getValue() + fabsf(e.getLevel()),
-                                         getScaleUnits(), role);
-        case 5: return e.getLabel();
-        default: return QVariant();
-        }
-    }
-
-    Command *getSetDataCommand(int row, int column, const QVariant &value,
-                               int role) override {
-        
-        if (row < 0 || row >= m_events.count()) return nullptr;
-        if (role != Qt::EditRole) return nullptr;
-
-        Event e0 = m_events.getEventByIndex(row);
-        Event e1;
-
-        switch (column) {
-        case 0: e1 = e0.withFrame(sv_frame_t(round(value.toDouble() *
-                                                   getSampleRate()))); break;
-        case 1: e1 = e0.withFrame(value.toInt()); break;
-        case 2: e1 = e0.withDuration(value.toInt()); break;
-        case 3: e1 = e0.withValue(float(value.toDouble())); break;
-        case 4: e1 = e0.withLevel(fabsf(float(value.toDouble()) -
-                                        e0.getValue())); break;
-        case 5: e1 = e0.withLabel(value.toString()); break;
-        }
-
-        auto command = new ChangeEventsCommand(getId().untyped, tr("Edit Data"));
-        command->remove(e0);
-        command->add(e1);
-        return command->finish();
-    }
-
-    
-    /**
-     * XmlExportable methods.
-     */
-    void toXml(QTextStream &out,
-               QString indent = "",
-               QString extraAttributes = "") const override {
-
-        Model::toXml
-            (out,
-             indent,
-             QString("type=\"sparse\" dimensions=\"2\" resolution=\"%1\" "
-                     "notifyOnAdd=\"%2\" dataset=\"%3\" subtype=\"%4\" "
-                     "minimum=\"%5\" maximum=\"%6\" units=\"%7\" %8")
-             .arg(m_resolution)
-             .arg("true") // always true after model reaches 100% -
-                          // subsequent events are always notified
-             .arg(m_events.getExportId())
-             .arg("timefrequencybox")
-             .arg(m_frequencyMinimum)
-             .arg(m_frequencyMaximum)
-             .arg(encodeEntities(m_units))
-             .arg(extraAttributes));
-
-        Event::ExportNameOptions options;
-        options.valueAttributeName = "frequency";
-        options.levelAttributeName = "extent";
-        
-        m_events.toXml(out, indent, QString("dimensions=\"2\""), options);
-    }
-
-    QString toDelimitedDataString(QString delimiter,
-                                  DataExportOptions,
-                                  sv_frame_t startFrame,
-                                  sv_frame_t duration) const override {
-
-        // We need a custom format here
-
-        EventVector ee = m_events.getEventsSpanning(startFrame, duration);
-
-        QString s;
-        
-        for (auto e: ee) {
-
-            QStringList list;
-
-            list << RealTime::frame2RealTime
-                (e.getFrame(), getSampleRate())
-                .toString().c_str()
-                 << RealTime::frame2RealTime
-                (e.getFrame() + e.getDuration(), getSampleRate())
-                .toString().c_str()
-                 << QString("%1").arg(e.getValue())
-                 << QString("%1").arg(e.getValue() + fabsf(e.getLevel()));
-            
-            if (e.getLabel() != "") {
-                list << e.getLabel();
-            }
-
-            s += list.join(delimiter) + "\n";
-        }
-
-        return s;
-    }
-
-protected:
-    sv_samplerate_t m_sampleRate;
-    int m_resolution;
-
-    float m_frequencyMinimum;
-    float m_frequencyMaximum;
-    bool m_haveExtents;
-    QString m_units;
-    DeferredNotifier m_notifier;
-    int m_completion;
-
-    EventSeries m_events;
-
-    mutable QMutex m_mutex;
-};
-
-#endif
--- a/files.pri	Wed Sep 25 09:43:34 2019 +0100
+++ b/files.pri	Wed Sep 25 09:44:02 2019 +0100
@@ -101,7 +101,7 @@
            data/model/SparseTimeValueModel.h \
            data/model/TabularModel.h \
            data/model/TextModel.h \
-           data/model/TimeFrequencyBoxModel.h \
+           data/model/BoxModel.h \
            data/model/WaveformOversampler.h \
            data/model/WaveFileModel.h \
            data/model/ReadOnlyWaveFileModel.h \