Thread: [Sv1-commits] SF.net SVN: sv1:[1195] sonic-visualiser/trunk
Brought to you by:
cannam
From: <ca...@us...> - 2008-08-07 15:59:24
|
Revision: 1195 http://sv1.svn.sourceforge.net/sv1/?rev=1195&view=rev Author: cannam Date: 2008-08-07 15:59:20 +0000 (Thu, 07 Aug 2008) Log Message: ----------- * Add IntervalModel as base class for NoteModel (and other, further models, hopefully) Modified Paths: -------------- sonic-visualiser/trunk/data/data.pro sonic-visualiser/trunk/data/model/ModelDataTableModel.cpp sonic-visualiser/trunk/data/model/NoteModel.h sonic-visualiser/trunk/sv.prf Added Paths: ----------- sonic-visualiser/trunk/data/model/IntervalModel.h Removed Paths: ------------- sonic-visualiser/trunk/data/model/NoteModel.cpp Modified: sonic-visualiser/trunk/data/data.pro =================================================================== --- sonic-visualiser/trunk/data/data.pro 2008-08-06 15:15:30 UTC (rev 1194) +++ sonic-visualiser/trunk/data/data.pro 2008-08-07 15:59:20 UTC (rev 1195) @@ -50,6 +50,7 @@ model/EditableDenseThreeDimensionalModel.h \ model/FFTModel.h \ model/ImageModel.h \ + model/IntervalModel.h \ model/Labeller.h \ model/Model.h \ model/ModelDataTableModel.h \ @@ -100,7 +101,6 @@ model/FFTModel.cpp \ model/Model.cpp \ model/ModelDataTableModel.cpp \ - model/NoteModel.cpp \ model/PowerOfSqrtTwoZoomConstraint.cpp \ model/PowerOfTwoZoomConstraint.cpp \ model/RangeSummarisableTimeValueModel.cpp \ Added: sonic-visualiser/trunk/data/model/IntervalModel.h =================================================================== --- sonic-visualiser/trunk/data/model/IntervalModel.h (rev 0) +++ sonic-visualiser/trunk/data/model/IntervalModel.h 2008-08-07 15:59:20 UTC (rev 1195) @@ -0,0 +1,188 @@ +/* -*- 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 2006-2008 Chris Cannam and 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. +*/ + +#ifndef _INTERVAL_MODEL_H_ +#define _INTERVAL_MODEL_H_ + +#include "SparseValueModel.h" +#include "base/RealTime.h" + +/** + * Model containing sparse data (points with some properties) of which + * the properties include a duration and an arbitrary float value. + * The other properties depend on the point type. + */ + +template <typename PointType> +class IntervalModel : public SparseValueModel<PointType> +{ +public: + IntervalModel(size_t sampleRate, size_t resolution, + bool notifyOnAdd = true) : + SparseValueModel<PointType>(sampleRate, resolution, notifyOnAdd) + { } + + IntervalModel(size_t sampleRate, size_t resolution, + float valueMinimum, float valueMaximum, + bool notifyOnAdd = true) : + SparseValueModel<PointType>(sampleRate, resolution, + valueMinimum, valueMaximum, + notifyOnAdd) + { } + + /** + * PointTypes have a duration, so this returns all points that span any + * of the given range (as well as the usual additional few before + * and after). Consequently this can be very slow (optimised data + * structures still to be done!). + */ + virtual typename SparseValueModel<PointType>::PointList getPoints(long start, long end) const; + + /** + * PointTypes have a duration, so this returns all points that span the + * given frame. Consequently this can be very slow (optimised + * data structures still to be done!). + */ + virtual typename SparseValueModel<PointType>::PointList getPoints(long frame) const; + + /** + * TabularModel methods. + */ + + virtual QVariant getData(int row, int column, int role) const + { + if (column < 2) { + return SparseValueModel<PointType>::getData + (row, column, role); + } + + typename SparseModel<PointType>::PointList::const_iterator i + = SparseModel<PointType>::getPointListIteratorForRow(row); + if (i == SparseModel<PointType>::m_points.end()) return QVariant(); + + switch (column) { + case 2: + if (role == Qt::EditRole || role == TabularModel::SortRole) return i->value; + else return QString("%1 %2").arg(i->value).arg + (IntervalModel<PointType>::getScaleUnits()); + case 3: return int(i->duration); //!!! could be better presented + default: return QVariant(); + } + } + + virtual Command *getSetDataCommand(int row, int column, const QVariant &value, int role) + { + if (column < 2) { + return SparseValueModel<PointType>::getSetDataCommand + (row, column, value, role); + } + + if (role != Qt::EditRole) return false; + // gah. This is such garbage. Thank you, C++! I love you too + typename SparseModel<PointType>::PointList::const_iterator i + = SparseModel<PointType>::getPointListIteratorForRow(row); + if (i == SparseModel<PointType>::m_points.end()) return false; + typename IntervalModel<PointType>::EditCommand *command + = new typename IntervalModel<PointType>::EditCommand + (this, IntervalModel<PointType>::tr("Edit Data")); + + PointType point(*i); + command->deletePoint(point); + + switch (column) { + case 0: case 1: point.frame = value.toInt(); break; + case 2: point.value = value.toDouble(); break; + case 3: point.duration = value.toInt(); break; + } + + command->addPoint(point); + return command->finish(); + } + + virtual bool isColumnTimeValue(int column) const + { + return (column < 2 || column == 3); + } +}; + +template <typename PointType> +typename SparseValueModel<PointType>::PointList +IntervalModel<PointType>::getPoints(long start, long end) const +{ + typedef IntervalModel<PointType> I; + + if (start > end) return typename I::PointList(); + + QMutex &mutex(I::m_mutex); + QMutexLocker locker(&mutex); + + PointType endPoint(end); + + typename I::PointListIterator endItr = I::m_points.upper_bound(endPoint); + + if (endItr != I::m_points.end()) ++endItr; + if (endItr != I::m_points.end()) ++endItr; + + typename I::PointList rv; + + for (typename I::PointListIterator i = endItr; i != I::m_points.begin(); ) { + --i; + if (i->frame < start) { + if (i->frame + long(i->duration) >= start) { + rv.insert(*i); + } + } else if (i->frame <= end) { + rv.insert(*i); + } + } + + return rv; +} + +template <typename PointType> +typename SparseValueModel<PointType>::PointList +IntervalModel<PointType>::getPoints(long frame) const +{ + typedef IntervalModel<PointType> I; + + QMutex &mutex(I::m_mutex); + QMutexLocker locker(&mutex); + + if (I::m_resolution == 0) return typename I::PointList(); + + long start = (frame / I::m_resolution) * I::m_resolution; + long end = start + I::m_resolution; + + PointType endPoint(end); + + typename I::PointListIterator endItr = I::m_points.upper_bound(endPoint); + + typename I::PointList rv; + + for (typename I::PointListIterator i = endItr; i != I::m_points.begin(); ) { + --i; + if (i->frame < start) { + if (i->frame + long(i->duration) >= start) { + rv.insert(*i); + } + } else if (i->frame <= end) { + rv.insert(*i); + } + } + + return rv; +} + +#endif Modified: sonic-visualiser/trunk/data/model/ModelDataTableModel.cpp =================================================================== --- sonic-visualiser/trunk/data/model/ModelDataTableModel.cpp 2008-08-06 15:15:30 UTC (rev 1194) +++ sonic-visualiser/trunk/data/model/ModelDataTableModel.cpp 2008-08-07 15:59:20 UTC (rev 1195) @@ -160,8 +160,8 @@ void ModelDataTableModel::sort(int column, Qt::SortOrder sortOrder) { - std::cerr << "ModelDataTableModel::sort(" << column << ", " << sortOrder - << ")" << std::endl; +// std::cerr << "ModelDataTableModel::sort(" << column << ", " << sortOrder +// << ")" << std::endl; int prevCurrent = getCurrentRow(); if (m_sortColumn != column) { clearSort(); @@ -170,7 +170,7 @@ m_sortOrdering = sortOrder; int current = getCurrentRow(); if (current != prevCurrent) { - std::cerr << "Current row changed from " << prevCurrent << " to " << current << " for underlying row " << m_currentRow << std::endl; +// std::cerr << "Current row changed from " << prevCurrent << " to " << current << " for underlying row " << m_currentRow << std::endl; emit currentChanged(createIndex(current, 0, 0)); } emit layoutChanged(); Deleted: sonic-visualiser/trunk/data/model/NoteModel.cpp =================================================================== --- sonic-visualiser/trunk/data/model/NoteModel.cpp 2008-08-06 15:15:30 UTC (rev 1194) +++ sonic-visualiser/trunk/data/model/NoteModel.cpp 2008-08-07 15:59:20 UTC (rev 1195) @@ -1,75 +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 file copyright 2006 Chris Cannam. - - 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 "NoteModel.h" - -NoteModel::PointList -NoteModel::getPoints(long start, long end) const -{ - if (start > end) return PointList(); - QMutexLocker locker(&m_mutex); - - Note endPoint(end); - - PointListIterator endItr = m_points.upper_bound(endPoint); - - if (endItr != m_points.end()) ++endItr; - if (endItr != m_points.end()) ++endItr; - - PointList rv; - - for (PointListIterator i = endItr; i != m_points.begin(); ) { - --i; - if (i->frame < start) { - if (i->frame + long(i->duration) >= start) { - rv.insert(*i); - } - } else if (i->frame <= end) { - rv.insert(*i); - } - } - - return rv; -} - -NoteModel::PointList -NoteModel::getPoints(long frame) const -{ - QMutexLocker locker(&m_mutex); - - if (m_resolution == 0) return PointList(); - - long start = (frame / m_resolution) * m_resolution; - long end = start + m_resolution; - - Note endPoint(end); - - PointListIterator endItr = m_points.upper_bound(endPoint); - - PointList rv; - - for (PointListIterator i = endItr; i != m_points.begin(); ) { - --i; - if (i->frame < start) { - if (i->frame + long(i->duration) >= start) { - rv.insert(*i); - } - } else if (i->frame <= end) { - rv.insert(*i); - } - } - - return rv; -} Modified: sonic-visualiser/trunk/data/model/NoteModel.h =================================================================== --- sonic-visualiser/trunk/data/model/NoteModel.h 2008-08-06 15:15:30 UTC (rev 1194) +++ sonic-visualiser/trunk/data/model/NoteModel.h 2008-08-07 15:59:20 UTC (rev 1195) @@ -16,7 +16,7 @@ #ifndef _NOTE_MODEL_H_ #define _NOTE_MODEL_H_ -#include "SparseValueModel.h" +#include "IntervalModel.h" #include "base/RealTime.h" #include "base/PlayParameterRepository.h" @@ -86,15 +86,14 @@ }; -class NoteModel : public SparseValueModel<Note> +class NoteModel : public IntervalModel<Note> { Q_OBJECT public: NoteModel(size_t sampleRate, size_t resolution, bool notifyOnAdd = true) : - SparseValueModel<Note>(sampleRate, resolution, - notifyOnAdd), + IntervalModel<Note>(sampleRate, resolution, notifyOnAdd), m_valueQuantization(0) { PlayParameterRepository::getInstance()->addPlayable(this); @@ -103,9 +102,9 @@ NoteModel(size_t sampleRate, size_t resolution, float valueMinimum, float valueMaximum, bool notifyOnAdd = true) : - SparseValueModel<Note>(sampleRate, resolution, - valueMinimum, valueMaximum, - notifyOnAdd), + IntervalModel<Note>(sampleRate, resolution, + valueMinimum, valueMaximum, + notifyOnAdd), m_valueQuantization(0) { PlayParameterRepository::getInstance()->addPlayable(this); @@ -119,21 +118,6 @@ float getValueQuantization() const { return m_valueQuantization; } void setValueQuantization(float q) { m_valueQuantization = q; } - /** - * Notes have a duration, so this returns all points that span any - * of the given range (as well as the usual additional few before - * and after). Consequently this can be very slow (optimised data - * structures still to be done!). - */ - virtual PointList getPoints(long start, long end) const; - - /** - * Notes have a duration, so this returns all points that span the - * given frame. Consequently this can be very slow (optimised - * data structures still to be done!). - */ - virtual PointList getPoints(long frame) const; - QString getTypeName() const { return tr("Note"); } virtual bool canPlay() const { return true; } @@ -155,7 +139,7 @@ std::cerr << "NoteModel::toXml: extraAttributes = \"" << extraAttributes.toStdString() << std::endl; - SparseValueModel<Note>::toXml + IntervalModel<Note>::toXml (out, indent, QString("%1 valueQuantization=\"%2\"") @@ -186,19 +170,14 @@ virtual QVariant getData(int row, int column, int role) const { - if (column < 2) { - return SparseValueModel<Note>::getData - (row, column, role); + if (column < 4) { + return IntervalModel<Note>::getData(row, column, role); } PointListIterator i = getPointListIteratorForRow(row); if (i == m_points.end()) return QVariant(); switch (column) { - case 2: - if (role == Qt::EditRole || role == SortRole) return i->value; - else return QString("%1 %2").arg(i->value).arg(getScaleUnits()); - case 3: return int(i->duration); case 4: return i->level; case 5: return i->label; default: return QVariant(); @@ -207,8 +186,8 @@ virtual Command *getSetDataCommand(int row, int column, const QVariant &value, int role) { - if (column < 2) { - return SparseValueModel<Note>::getSetDataCommand + if (column < 4) { + return IntervalModel<Note>::getSetDataCommand (row, column, value, role); } @@ -221,9 +200,6 @@ command->deletePoint(point); switch (column) { - case 0: case 1: point.frame = value.toInt(); break; - case 2: point.value = value.toDouble(); break; - case 3: point.duration = value.toInt(); break; case 4: point.level = value.toDouble(); break; case 5: point.label = value.toString(); break; } @@ -232,11 +208,6 @@ return command->finish(); } - virtual bool isColumnTimeValue(int column) const - { - return (column < 2); - } - virtual SortType getSortType(int column) const { if (column == 5) return SortAlphabetical; Modified: sonic-visualiser/trunk/sv.prf =================================================================== --- sonic-visualiser/trunk/sv.prf 2008-08-06 15:15:30 UTC (rev 1194) +++ sonic-visualiser/trunk/sv.prf 2008-08-07 15:59:20 UTC (rev 1195) @@ -22,8 +22,8 @@ # To do a static build with gcc on Linux # -#linux-g++:LIBS += -Wl,-Bstatic -#linux-g++:DEFINES += BUILD_STATIC +linux-g++:LIBS += -Wl,-Bstatic +linux-g++:DEFINES += BUILD_STATIC # These are testable on platforms with pkg-config. If you don't have @@ -186,12 +186,14 @@ QMAKE_CXXFLAGS_DEBUG += -DBUILD_DEBUG $$VERSION_CFLAGS QMAKE_CXXFLAGS_RELEASE += -DBUILD_RELEASE $$VERSION_CFLAGS +LIBS -= -lpthread + linux-g++ { contains(DEFINES, BUILD_STATIC) { - LIBS += -lFLAC + LIBS += -lFLAC -lxslt -lxml2 } } # Restore dynamic linkage, in case we went static earlier -linux-g++:LIBS += -Wl,-Bdynamic +linux-g++:LIBS += -Wl,-Bdynamic -lcurl -lpthread -ldl This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-09-18 05:09:40
|
Revision: 1204 http://sv1.svn.sourceforge.net/sv1/?rev=1204&view=rev Author: cannam Date: 2008-09-18 12:09:32 +0000 (Thu, 18 Sep 2008) Log Message: ----------- * Merge revisions 1041 to 1130 from sv-rdf-import branch Modified Paths: -------------- sonic-visualiser/trunk/base/ProgressPrinter.cpp sonic-visualiser/trunk/base/ProgressPrinter.h sonic-visualiser/trunk/base/ProgressReporter.h sonic-visualiser/trunk/base/RealTime.cpp sonic-visualiser/trunk/base/RealTime.h sonic-visualiser/trunk/data/fileio/FileSource.cpp sonic-visualiser/trunk/data/model/EditableDenseThreeDimensionalModel.cpp sonic-visualiser/trunk/framework/MainWindowBase.cpp sonic-visualiser/trunk/sonic-visualiser.pro sonic-visualiser/trunk/sv/sv.pro sonic-visualiser/trunk/sv.prf sonic-visualiser/trunk/transform/TransformFactory.cpp sonic-visualiser/trunk/widgets/FileFinder.cpp sonic-visualiser/trunk/widgets/ProgressDialog.cpp sonic-visualiser/trunk/widgets/ProgressDialog.h Added Paths: ----------- sonic-visualiser/trunk/rdf/ sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp sonic-visualiser/trunk/rdf/PluginRDFDescription.h sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp sonic-visualiser/trunk/rdf/PluginRDFIndexer.h sonic-visualiser/trunk/rdf/RDFImporter.cpp sonic-visualiser/trunk/rdf/RDFImporter.h sonic-visualiser/trunk/rdf/RDFTransformFactory.cpp sonic-visualiser/trunk/rdf/RDFTransformFactory.h sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.cpp sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.h sonic-visualiser/trunk/rdf/rdf.pro sonic-visualiser/trunk/sparql-test sonic-visualiser/trunk/sparql-test-2 sonic-visualiser/trunk/sparql-test-3 sonic-visualiser/trunk/sparql-test-4 sonic-visualiser/trunk/sparql-test-5 sonic-visualiser/trunk/sparql-test-8 Removed Paths: ------------- sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp sonic-visualiser/trunk/rdf/PluginRDFDescription.h sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp sonic-visualiser/trunk/rdf/PluginRDFIndexer.h sonic-visualiser/trunk/rdf/RDFImporter.cpp sonic-visualiser/trunk/rdf/RDFImporter.h sonic-visualiser/trunk/rdf/RDFTransformFactory.cpp sonic-visualiser/trunk/rdf/RDFTransformFactory.h sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.cpp sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.h sonic-visualiser/trunk/rdf/rdf.pro Modified: sonic-visualiser/trunk/base/ProgressPrinter.cpp =================================================================== --- sonic-visualiser/trunk/base/ProgressPrinter.cpp 2008-09-12 16:27:22 UTC (rev 1203) +++ sonic-visualiser/trunk/base/ProgressPrinter.cpp 2008-09-18 12:09:32 UTC (rev 1204) @@ -20,7 +20,8 @@ ProgressPrinter::ProgressPrinter(QString message, QObject *parent) : ProgressReporter(parent), m_prefix(message), - m_lastProgress(0) + m_lastProgress(0), + m_definite(true) { } @@ -32,7 +33,19 @@ // std::cerr << "(progress printer dtor)" << std::endl; } +bool +ProgressPrinter::isDefinite() const +{ + return m_definite; +} + void +ProgressPrinter::setDefinite(bool definite) +{ + m_definite = definite; +} + +void ProgressPrinter::setMessage(QString message) { m_prefix = message; @@ -46,8 +59,12 @@ else { std::cerr << "\r" << m_prefix.toStdString() - << (m_prefix == "" ? "" : " ") - << progress << "%"; + << (m_prefix == "" ? "" : " "); + if (m_definite) { + std::cerr << progress << "%"; + } else { + std::cerr << "|/-\\"[progress % 4]; + } } m_lastProgress = progress; } Modified: sonic-visualiser/trunk/base/ProgressPrinter.h =================================================================== --- sonic-visualiser/trunk/base/ProgressPrinter.h 2008-09-12 16:27:22 UTC (rev 1203) +++ sonic-visualiser/trunk/base/ProgressPrinter.h 2008-09-18 12:09:32 UTC (rev 1204) @@ -26,6 +26,11 @@ ProgressPrinter(QString message, QObject *parent = 0); virtual ~ProgressPrinter(); + virtual bool isDefinite() const; + virtual void setDefinite(bool definite); + + virtual bool wasCancelled() const { return false; } // no mechanism + public slots: virtual void setMessage(QString); virtual void setProgress(int); @@ -33,6 +38,7 @@ protected: QString m_prefix; int m_lastProgress; + bool m_definite; }; #endif Modified: sonic-visualiser/trunk/base/ProgressReporter.h =================================================================== --- sonic-visualiser/trunk/base/ProgressReporter.h 2008-09-12 16:27:22 UTC (rev 1203) +++ sonic-visualiser/trunk/base/ProgressReporter.h 2008-09-18 12:09:32 UTC (rev 1204) @@ -14,6 +14,7 @@ */ #ifndef _PROGRESS_REPORTER_H_ +#define _PROGRESS_REPORTER_H_ #include <QObject> #include <QString> @@ -26,6 +27,11 @@ ProgressReporter(QObject *parent = 0); virtual ~ProgressReporter(); + virtual bool isDefinite() const = 0; + virtual void setDefinite(bool definite) = 0; // default should be definite + + virtual bool wasCancelled() const = 0; + signals: void cancelled(); Modified: sonic-visualiser/trunk/base/RealTime.cpp =================================================================== --- sonic-visualiser/trunk/base/RealTime.cpp 2008-09-12 16:27:22 UTC (rev 1203) +++ sonic-visualiser/trunk/base/RealTime.cpp 2008-09-18 12:09:32 UTC (rev 1204) @@ -79,6 +79,94 @@ return RealTime(tv.tv_sec, tv.tv_usec * 1000); } +RealTime +RealTime::fromXsdDuration(std::string xsdd) +{ + RealTime t; + + int year = 0, month = 0, day = 0, hour = 0, minute = 0; + double second = 0.0; + + int i = 0; + + const char *s = xsdd.c_str(); + int len = xsdd.length(); + + bool negative = false, afterT = false; + + int valstart = 0; + + while (i < len) { + + if (s[i] == '-') { + if (i == 0) negative = true; + ++i; + continue; + } + + double value = 0.0; + char *eptr = 0; + + if (isdigit(s[i]) || s[i] == '.') { + valstart = i; + value = strtod(&s[i], &eptr); + i = eptr - s; + } + + if (i == len) break; + + switch (s[i]) { + case 'Y': year = int(value + 0.1); break; + case 'D': day = int(value + 0.1); break; + case 'H': hour = int(value + 0.1); break; + case 'M': + if (afterT) minute = int(value + 0.1); + else month = int(value + 0.1); + break; + case 'S': + second = value; + break; + case 'T': afterT = true; break; + }; + + ++i; + } + + if (year > 0) { + std::cerr << "WARNING: This xsd:duration (\"" << xsdd << "\") contains a non-zero year.\nWith no origin and a limited data size, I will treat a year as exactly 31556952\nseconds and you should expect overflow and/or poor results." << std::endl; + t = t + RealTime(year * 31556952, 0); + } + + if (month > 0) { + std::cerr << "WARNING: This xsd:duration (\"" << xsdd << "\") contains a non-zero month.\nWith no origin and a limited data size, I will treat a month as exactly 2629746\nseconds and you should expect overflow and/or poor results." << std::endl; + t = t + RealTime(month * 2629746, 0); + } + + if (day > 0) { + t = t + RealTime(day * 86400, 0); + } + + if (hour > 0) { + t = t + RealTime(hour * 3600, 0); + } + + if (minute > 0) { + t = t + RealTime(minute * 60, 0); + } + + t = t + fromSeconds(second); + + return t; +} + +double +RealTime::toDouble() const +{ + double d = sec; + d += double(nsec) / double(ONE_BILLION); + return d; +} + std::ostream &operator<<(std::ostream &out, const RealTime &rt) { if (rt < RealTime::zeroTime) { @@ -128,7 +216,6 @@ RealTime::fromString(std::string s) { bool negative = false; - bool faulty = false; bool section = 0; std::string ssec, snsec; Modified: sonic-visualiser/trunk/base/RealTime.h =================================================================== --- sonic-visualiser/trunk/base/RealTime.h 2008-09-12 16:27:22 UTC (rev 1203) +++ sonic-visualiser/trunk/base/RealTime.h 2008-09-18 12:09:32 UTC (rev 1204) @@ -49,7 +49,10 @@ static RealTime fromSeconds(double sec); static RealTime fromMilliseconds(int msec); static RealTime fromTimeval(const struct timeval &); + static RealTime fromXsdDuration(std::string xsdd); + double toDouble() const; + RealTime &operator=(const RealTime &r) { sec = r.sec; nsec = r.nsec; return *this; } Modified: sonic-visualiser/trunk/data/fileio/FileSource.cpp =================================================================== --- sonic-visualiser/trunk/data/fileio/FileSource.cpp 2008-09-12 16:27:22 UTC (rev 1203) +++ sonic-visualiser/trunk/data/fileio/FileSource.cpp 2008-09-18 12:09:32 UTC (rev 1204) @@ -209,6 +209,8 @@ m_localFilename = m_url.toString(); literal = true; } + m_localFilename = QFileInfo(m_localFilename).absoluteFilePath(); + #ifdef DEBUG_FILE_SOURCE std::cerr << "FileSource::init: URL translates to local filename \"" << m_localFilename.toStdString() << "\"" << std::endl; Modified: sonic-visualiser/trunk/data/model/EditableDenseThreeDimensionalModel.cpp =================================================================== --- sonic-visualiser/trunk/data/model/EditableDenseThreeDimensionalModel.cpp 2008-09-12 16:27:22 UTC (rev 1203) +++ sonic-visualiser/trunk/data/model/EditableDenseThreeDimensionalModel.cpp 2008-09-18 12:09:32 UTC (rev 1204) @@ -178,6 +178,8 @@ bool allChange = false; + if (values.size() > m_yBinCount) m_yBinCount = values.size(); + for (size_t i = 0; i < values.size(); ++i) { float value = values[i]; if (std::isnan(value) || std::isinf(value)) { Modified: sonic-visualiser/trunk/framework/MainWindowBase.cpp =================================================================== --- sonic-visualiser/trunk/framework/MainWindowBase.cpp 2008-09-12 16:27:22 UTC (rev 1203) +++ sonic-visualiser/trunk/framework/MainWindowBase.cpp 2008-09-18 12:09:32 UTC (rev 1204) @@ -53,6 +53,7 @@ #include "data/fileio/MIDIFileWriter.h" #include "data/fileio/BZipFileDevice.h" #include "data/fileio/FileSource.h" +#include "rdf/RDFImporter.h" #include "data/fft/FFTDataServer.h" @@ -837,7 +838,8 @@ MainWindowBase::FileOpenStatus MainWindowBase::open(QString fileOrUrl, AudioFileOpenMode mode) { - ProgressDialog dialog(tr("Opening file or URL..."), true, 2000); + ProgressDialog dialog(tr("Opening file or URL..."), true, 2000, this); + connect(&dialog, SIGNAL(showing()), this, SIGNAL(hideSplash())); return open(FileSource(fileOrUrl, &dialog), mode); } @@ -1080,7 +1082,8 @@ for (PlaylistFileReader::Playlist::const_iterator i = playlist.begin(); i != playlist.end(); ++i) { - ProgressDialog dialog(tr("Opening playlist..."), true, 2000); + ProgressDialog dialog(tr("Opening playlist..."), true, 2000, this); + connect(&dialog, SIGNAL(showing()), this, SIGNAL(hideSplash())); FileOpenStatus status = openAudio(FileSource(*i, &dialog), mode); if (status == FileOpenCancelled) { @@ -1119,8 +1122,31 @@ QString path = source.getLocalFilename(); - if (source.getExtension() == "svl" || source.getExtension() == "xml") { + if (source.getExtension() == "rdf" || source.getExtension() == "n3" || + source.getExtension() == "ttl") { + RDFImporter importer("file://" + path, getMainModel()->getSampleRate()); + if (importer.isOK()) { + + ProgressDialog dialog(tr("Importing from RDF..."), true, 2000, this); + connect(&dialog, SIGNAL(showing()), this, SIGNAL(hideSplash())); + std::vector<Model *> models = importer.getDataModels(&dialog); + + for (int i = 0; i < models.size(); ++i) { + Layer *newLayer = m_document->createImportedLayer(models[i]); + if (newLayer) { + m_document->addLayerToView(pane, newLayer); + } + } + + m_recentFiles.addFile(source.getLocation()); + return FileOpenSucceeded; + } + + return FileOpenFailed; + + } else if (source.getExtension() == "svl" || source.getExtension() == "xml") { + PaneCallback callback(this); QFile file(path); @@ -1263,7 +1289,8 @@ MainWindowBase::FileOpenStatus MainWindowBase::openSessionFile(QString fileOrUrl) { - ProgressDialog dialog(tr("Opening session..."), true, 2000); + ProgressDialog dialog(tr("Opening session..."), true, 2000, this); + connect(&dialog, SIGNAL(showing()), this, SIGNAL(hideSplash())); return openSession(FileSource(fileOrUrl, &dialog)); } Deleted: sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp =================================================================== --- sonic-visualiser/branches/rdf-import/rdf/PluginRDFDescription.cpp 2008-06-25 10:35:16 UTC (rev 1130) +++ sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp 2008-09-18 12:09:32 UTC (rev 1204) @@ -1,221 +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 file copyright 2008 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 "PluginRDFDescription.h" - -#include "PluginRDFIndexer.h" -#include "SimpleSPARQLQuery.h" - -#include "plugin/PluginIdentifier.h" - -#include <iostream> -using std::cerr; -using std::endl; - -PluginRDFDescription::PluginRDFDescription(QString pluginId) : - m_pluginId(pluginId), - m_haveDescription(false) -{ - PluginRDFIndexer *indexer = PluginRDFIndexer::getInstance(); - QString url = indexer->getDescriptionURLForPluginId(pluginId); - if (url == "") { - cerr << "PluginRDFDescription: WARNING: No RDF description available for plugin ID \"" - << pluginId.toStdString() << "\"" << endl; - } else { - if (!indexURL(url)) { - cerr << "PluginRDFDescription: ERROR: Failed to query RDF description for plugin ID \"" - << pluginId.toStdString() << "\"" << endl; - } else { - m_haveDescription = true; - } - } -} - -PluginRDFDescription::~PluginRDFDescription() -{ -} - -bool -PluginRDFDescription::haveDescription() const -{ - return m_haveDescription; -} - -PluginRDFDescription::OutputType -PluginRDFDescription::getOutputType(QString outputId) const -{ - if (m_outputTypes.find(outputId) == m_outputTypes.end()) { - return OutputTypeUnknown; - } - return m_outputTypes.find(outputId)->second; -} - -PluginRDFDescription::OutputDisposition -PluginRDFDescription::getOutputDisposition(QString outputId) const -{ - if (m_outputDispositions.find(outputId) == m_outputDispositions.end()) { - return OutputDispositionUnknown; - } - return m_outputDispositions.find(outputId)->second; -} - -QString -PluginRDFDescription::getOutputFeatureTypeURI(QString outputId) const -{ - if (m_outputFeatureTypeURIMap.find(outputId) == - m_outputFeatureTypeURIMap.end()) { - return ""; - } - return m_outputFeatureTypeURIMap.find(outputId)->second; -} - -QString -PluginRDFDescription::getOutputEventTypeURI(QString outputId) const -{ - if (m_outputEventTypeURIMap.find(outputId) == - m_outputEventTypeURIMap.end()) { - return ""; - } - return m_outputEventTypeURIMap.find(outputId)->second; -} - -QString -PluginRDFDescription::getOutputUnit(QString outputId) const -{ - if (m_outputUnitMap.find(outputId) == m_outputUnitMap.end()) { - return ""; - } - return m_outputUnitMap.find(outputId)->second; -} - -bool -PluginRDFDescription::indexURL(QString url) -{ - QString type, soname, label; - PluginIdentifier::parseIdentifier(m_pluginId, type, soname, label); - - SimpleSPARQLQuery query - (QString - ( - " PREFIX vamp: <http://purl.org/ontology/vamp/> " - - " SELECT ?output_id ?output_type ?feature_type ?event_type ?unit " - " FROM <%1> " - - " WHERE { " - - " ?plugin a vamp:Plugin ; " - " vamp:identifier \"%2\" ; " - " vamp:output_descriptor ?output . " - - " ?output vamp:identifier ?output_id ; " - " a ?output_type . " - - " OPTIONAL { " - " ?output vamp:computes_feature_type ?feature_type " - " } . " - - " OPTIONAL { " - " ?output vamp:computes_event_type ?event_type " - " } . " - - " OPTIONAL { " - " ?output vamp:unit ?unit " - " } . " - - " } " - ) - .arg(url) - .arg(label)); - - SimpleSPARQLQuery::ResultList results = query.execute(); - - if (!query.isOK()) { - cerr << "ERROR: PluginRDFDescription::indexURL: ERROR: Failed to query document at <" - << url.toStdString() << ">: " - << query.getErrorString().toStdString() << endl; - return false; - } - - if (results.empty()) { - cerr << "ERROR: PluginRDFDescription::indexURL: NOTE: Document at <" - << url.toStdString() - << "> does not appear to describe any plugin outputs" << endl; - return false; - } - - // Note that an output may appear more than once, if it inherits - // more than one type (e.g. DenseOutput and QuantizedOutput). So - // these results must accumulate - - for (int i = 0; i < results.size(); ++i) { - - QString outputId = results[i]["output_id"].value; - - if (m_outputTypes.find(outputId) == m_outputTypes.end()) { - m_outputTypes[outputId] = OutputTypeUnknown; - } - - QString outputType = results[i]["output_type"].value; - - if (outputType.contains("DenseOutput")) { - m_outputDispositions[outputId] = OutputDense; - } else if (outputType.contains("SparseOutput")) { - m_outputDispositions[outputId] = OutputSparse; - } else if (outputType.contains("TrackLevelOutput")) { - m_outputDispositions[outputId] = OutputTrackLevel; - } - - if (results[i]["feature_type"].type == SimpleSPARQLQuery::URIValue) { - - QString featureType = results[i]["feature_type"].value; - - if (featureType != "") { - if (m_outputTypes[outputId] == OutputEvents) { - m_outputTypes[outputId] = OutputFeaturesAndEvents; - } else { - m_outputTypes[outputId] = OutputFeatures; - } - m_outputFeatureTypeURIMap[outputId] = featureType; - } - } - - if (results[i]["event_type"].type == SimpleSPARQLQuery::URIValue) { - - QString eventType = results[i]["event_type"].value; - - if (eventType != "") { - if (m_outputTypes[outputId] == OutputFeatures) { - m_outputTypes[outputId] = OutputFeaturesAndEvents; - } else { - m_outputTypes[outputId] = OutputEvents; - } - m_outputEventTypeURIMap[outputId] = eventType; - } - } - - if (results[i]["unit"].type == SimpleSPARQLQuery::LiteralValue) { - - QString unit = results[i]["unit"].value; - - if (unit != "") { - m_outputUnitMap[outputId] = unit; - } - } - } - - return true; -} - Copied: sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp (from rev 1130, sonic-visualiser/branches/rdf-import/rdf/PluginRDFDescription.cpp) =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp (rev 0) +++ sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp 2008-09-18 12:09:32 UTC (rev 1204) @@ -0,0 +1,221 @@ +/* -*- 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 2008 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 "PluginRDFDescription.h" + +#include "PluginRDFIndexer.h" +#include "SimpleSPARQLQuery.h" + +#include "plugin/PluginIdentifier.h" + +#include <iostream> +using std::cerr; +using std::endl; + +PluginRDFDescription::PluginRDFDescription(QString pluginId) : + m_pluginId(pluginId), + m_haveDescription(false) +{ + PluginRDFIndexer *indexer = PluginRDFIndexer::getInstance(); + QString url = indexer->getDescriptionURLForPluginId(pluginId); + if (url == "") { + cerr << "PluginRDFDescription: WARNING: No RDF description available for plugin ID \"" + << pluginId.toStdString() << "\"" << endl; + } else { + if (!indexURL(url)) { + cerr << "PluginRDFDescription: ERROR: Failed to query RDF description for plugin ID \"" + << pluginId.toStdString() << "\"" << endl; + } else { + m_haveDescription = true; + } + } +} + +PluginRDFDescription::~PluginRDFDescription() +{ +} + +bool +PluginRDFDescription::haveDescription() const +{ + return m_haveDescription; +} + +PluginRDFDescription::OutputType +PluginRDFDescription::getOutputType(QString outputId) const +{ + if (m_outputTypes.find(outputId) == m_outputTypes.end()) { + return OutputTypeUnknown; + } + return m_outputTypes.find(outputId)->second; +} + +PluginRDFDescription::OutputDisposition +PluginRDFDescription::getOutputDisposition(QString outputId) const +{ + if (m_outputDispositions.find(outputId) == m_outputDispositions.end()) { + return OutputDispositionUnknown; + } + return m_outputDispositions.find(outputId)->second; +} + +QString +PluginRDFDescription::getOutputFeatureTypeURI(QString outputId) const +{ + if (m_outputFeatureTypeURIMap.find(outputId) == + m_outputFeatureTypeURIMap.end()) { + return ""; + } + return m_outputFeatureTypeURIMap.find(outputId)->second; +} + +QString +PluginRDFDescription::getOutputEventTypeURI(QString outputId) const +{ + if (m_outputEventTypeURIMap.find(outputId) == + m_outputEventTypeURIMap.end()) { + return ""; + } + return m_outputEventTypeURIMap.find(outputId)->second; +} + +QString +PluginRDFDescription::getOutputUnit(QString outputId) const +{ + if (m_outputUnitMap.find(outputId) == m_outputUnitMap.end()) { + return ""; + } + return m_outputUnitMap.find(outputId)->second; +} + +bool +PluginRDFDescription::indexURL(QString url) +{ + QString type, soname, label; + PluginIdentifier::parseIdentifier(m_pluginId, type, soname, label); + + SimpleSPARQLQuery query + (QString + ( + " PREFIX vamp: <http://purl.org/ontology/vamp/> " + + " SELECT ?output_id ?output_type ?feature_type ?event_type ?unit " + " FROM <%1> " + + " WHERE { " + + " ?plugin a vamp:Plugin ; " + " vamp:identifier \"%2\" ; " + " vamp:output_descriptor ?output . " + + " ?output vamp:identifier ?output_id ; " + " a ?output_type . " + + " OPTIONAL { " + " ?output vamp:computes_feature_type ?feature_type " + " } . " + + " OPTIONAL { " + " ?output vamp:computes_event_type ?event_type " + " } . " + + " OPTIONAL { " + " ?output vamp:unit ?unit " + " } . " + + " } " + ) + .arg(url) + .arg(label)); + + SimpleSPARQLQuery::ResultList results = query.execute(); + + if (!query.isOK()) { + cerr << "ERROR: PluginRDFDescription::indexURL: ERROR: Failed to query document at <" + << url.toStdString() << ">: " + << query.getErrorString().toStdString() << endl; + return false; + } + + if (results.empty()) { + cerr << "ERROR: PluginRDFDescription::indexURL: NOTE: Document at <" + << url.toStdString() + << "> does not appear to describe any plugin outputs" << endl; + return false; + } + + // Note that an output may appear more than once, if it inherits + // more than one type (e.g. DenseOutput and QuantizedOutput). So + // these results must accumulate + + for (int i = 0; i < results.size(); ++i) { + + QString outputId = results[i]["output_id"].value; + + if (m_outputTypes.find(outputId) == m_outputTypes.end()) { + m_outputTypes[outputId] = OutputTypeUnknown; + } + + QString outputType = results[i]["output_type"].value; + + if (outputType.contains("DenseOutput")) { + m_outputDispositions[outputId] = OutputDense; + } else if (outputType.contains("SparseOutput")) { + m_outputDispositions[outputId] = OutputSparse; + } else if (outputType.contains("TrackLevelOutput")) { + m_outputDispositions[outputId] = OutputTrackLevel; + } + + if (results[i]["feature_type"].type == SimpleSPARQLQuery::URIValue) { + + QString featureType = results[i]["feature_type"].value; + + if (featureType != "") { + if (m_outputTypes[outputId] == OutputEvents) { + m_outputTypes[outputId] = OutputFeaturesAndEvents; + } else { + m_outputTypes[outputId] = OutputFeatures; + } + m_outputFeatureTypeURIMap[outputId] = featureType; + } + } + + if (results[i]["event_type"].type == SimpleSPARQLQuery::URIValue) { + + QString eventType = results[i]["event_type"].value; + + if (eventType != "") { + if (m_outputTypes[outputId] == OutputFeatures) { + m_outputTypes[outputId] = OutputFeaturesAndEvents; + } else { + m_outputTypes[outputId] = OutputEvents; + } + m_outputEventTypeURIMap[outputId] = eventType; + } + } + + if (results[i]["unit"].type == SimpleSPARQLQuery::LiteralValue) { + + QString unit = results[i]["unit"].value; + + if (unit != "") { + m_outputUnitMap[outputId] = unit; + } + } + } + + return true; +} + Deleted: sonic-visualiser/trunk/rdf/PluginRDFDescription.h =================================================================== --- sonic-visualiser/branches/rdf-import/rdf/PluginRDFDescription.h 2008-06-25 10:35:16 UTC (rev 1130) +++ sonic-visualiser/trunk/rdf/PluginRDFDescription.h 2008-09-18 12:09:32 UTC (rev 1204) @@ -1,70 +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 file copyright 2008 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. -*/ - -#ifndef _PLUGIN_RDF_DESCRIPTION_H_ -#define _PLUGIN_RDF_DESCRIPTION_H_ - -#include <QString> -#include <map> - -class FileSource; - -class PluginRDFDescription -{ -public: - PluginRDFDescription() : m_haveDescription(false) { } - PluginRDFDescription(QString pluginId); - ~PluginRDFDescription(); - - enum OutputType - { - OutputTypeUnknown, - OutputFeatures, - OutputEvents, - OutputFeaturesAndEvents - }; - - enum OutputDisposition - { - OutputDispositionUnknown, - OutputSparse, - OutputDense, - OutputTrackLevel - }; - - bool haveDescription() const; - OutputType getOutputType(QString outputId) const; - OutputDisposition getOutputDisposition(QString outputId) const; - QString getOutputFeatureTypeURI(QString outputId) const; - QString getOutputEventTypeURI(QString outputId) const; - QString getOutputUnit(QString outputId) const; - -protected: - typedef std::map<QString, OutputType> OutputTypeMap; - typedef std::map<QString, OutputDisposition> OutputDispositionMap; - typedef std::map<QString, QString> OutputStringMap; - - QString m_pluginId; - bool m_haveDescription; - OutputTypeMap m_outputTypes; - OutputDispositionMap m_outputDispositions; - OutputStringMap m_outputFeatureTypeURIMap; - OutputStringMap m_outputEventTypeURIMap; - OutputStringMap m_outputUnitMap; - bool indexURL(QString url); -}; - -#endif - Copied: sonic-visualiser/trunk/rdf/PluginRDFDescription.h (from rev 1130, sonic-visualiser/branches/rdf-import/rdf/PluginRDFDescription.h) =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFDescription.h (rev 0) +++ sonic-visualiser/trunk/rdf/PluginRDFDescription.h 2008-09-18 12:09:32 UTC (rev 1204) @@ -0,0 +1,70 @@ +/* -*- 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 2008 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. +*/ + +#ifndef _PLUGIN_RDF_DESCRIPTION_H_ +#define _PLUGIN_RDF_DESCRIPTION_H_ + +#include <QString> +#include <map> + +class FileSource; + +class PluginRDFDescription +{ +public: + PluginRDFDescription() : m_haveDescription(false) { } + PluginRDFDescription(QString pluginId); + ~PluginRDFDescription(); + + enum OutputType + { + OutputTypeUnknown, + OutputFeatures, + OutputEvents, + OutputFeaturesAndEvents + }; + + enum OutputDisposition + { + OutputDispositionUnknown, + OutputSparse, + OutputDense, + OutputTrackLevel + }; + + bool haveDescription() const; + OutputType getOutputType(QString outputId) const; + OutputDisposition getOutputDisposition(QString outputId) const; + QString getOutputFeatureTypeURI(QString outputId) const; + QString getOutputEventTypeURI(QString outputId) const; + QString getOutputUnit(QString outputId) const; + +protected: + typedef std::map<QString, OutputType> OutputTypeMap; + typedef std::map<QString, OutputDisposition> OutputDispositionMap; + typedef std::map<QString, QString> OutputStringMap; + + QString m_pluginId; + bool m_haveDescription; + OutputTypeMap m_outputTypes; + OutputDispositionMap m_outputDispositions; + OutputStringMap m_outputFeatureTypeURIMap; + OutputStringMap m_outputEventTypeURIMap; + OutputStringMap m_outputUnitMap; + bool indexURL(QString url); +}; + +#endif + Deleted: sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp =================================================================== --- sonic-visualiser/branches/rdf-import/rdf/PluginRDFIndexer.cpp 2008-06-25 10:35:16 UTC (rev 1130) +++ sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp 2008-09-18 12:09:32 UTC (rev 1204) @@ -1,286 +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 file copyright 2008 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 "PluginRDFIndexer.h" - -#include "SimpleSPARQLQuery.h" - -#include "data/fileio/FileSource.h" -#include "plugin/PluginIdentifier.h" - -#include <vamp-sdk/PluginHostAdapter.h> - -#include <QFileInfo> -#include <QDir> -#include <QUrl> - -#include <iostream> -using std::cerr; -using std::endl; -using std::vector; -using std::string; -using Vamp::PluginHostAdapter; - -PluginRDFIndexer * -PluginRDFIndexer::m_instance = 0; - -PluginRDFIndexer * -PluginRDFIndexer::getInstance() -{ - if (!m_instance) m_instance = new PluginRDFIndexer(); - return m_instance; -} - -PluginRDFIndexer::PluginRDFIndexer() -{ - vector<string> paths = PluginHostAdapter::getPluginPath(); - - QStringList filters; - filters << "*.n3"; - filters << "*.N3"; - filters << "*.rdf"; - filters << "*.RDF"; - - // Search each Vamp plugin path for a .rdf file that either has - // name "soname", "soname:label" or "soname/label" plus RDF - // extension. Use that order of preference, and prefer n3 over - // rdf extension. - - for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) { - - QDir dir(i->c_str()); - if (!dir.exists()) continue; - - QStringList entries = dir.entryList - (filters, QDir::Files | QDir::Readable); - - for (QStringList::const_iterator j = entries.begin(); - j != entries.end(); ++j) { - QFileInfo fi(dir.filePath(*j)); - indexFile(fi.absoluteFilePath()); - } - - QStringList subdirs = dir.entryList - (QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Readable); - - for (QStringList::const_iterator j = subdirs.begin(); - j != subdirs.end(); ++j) { - QDir subdir(dir.filePath(*j)); - if (subdir.exists()) { - entries = subdir.entryList - (filters, QDir::Files | QDir::Readable); - for (QStringList::const_iterator k = entries.begin(); - k != entries.end(); ++k) { - QFileInfo fi(subdir.filePath(*k)); - indexFile(fi.absoluteFilePath()); - } - } - } - } -} - -PluginRDFIndexer::~PluginRDFIndexer() -{ - while (!m_cache.empty()) { - delete *m_cache.begin(); - m_cache.erase(m_cache.begin()); - } -} - -QString -PluginRDFIndexer::getURIForPluginId(QString pluginId) -{ - if (m_idToUriMap.find(pluginId) == m_idToUriMap.end()) return ""; - return m_idToUriMap[pluginId]; -} - -QString -PluginRDFIndexer::getIdForPluginURI(QString uri) -{ - if (m_uriToIdMap.find(uri) == m_uriToIdMap.end()) { - - // Haven't found this uri referenced in any document on the - // local filesystem; try resolving the pre-fragment part of - // the uri as a document URL and reading that if possible. - - // Because we may want to refer to this document again, we - // cache it locally if it turns out to exist. - - cerr << "PluginRDFIndexer::getIdForPluginURI: NOTE: Failed to find a local RDF document describing plugin <" << uri.toStdString() << ">: attempting to retrieve one remotely by guesswork" << endl; - - QString baseUrl = QUrl(uri).toString(QUrl::RemoveFragment); - - FileSource source(baseUrl); - if (source.isAvailable()) { - source.waitForData(); - if (indexFile(source.getLocalFilename())) { - m_cache.insert(new FileSource(source)); - } - } - - if (m_uriToIdMap.find(uri) == m_uriToIdMap.end()) { - m_uriToIdMap[uri] = ""; - } - } - - return m_uriToIdMap[uri]; -} - -QString -PluginRDFIndexer::getDescriptionURLForPluginId(QString pluginId) -{ - if (m_idToDescriptionMap.find(pluginId) == m_idToDescriptionMap.end()) return ""; - return m_idToDescriptionMap[pluginId]; -} - -QString -PluginRDFIndexer::getDescriptionURLForPluginURI(QString uri) -{ - QString id = getIdForPluginURI(uri); - if (id == "") return ""; - return getDescriptionURLForPluginId(id); -} - -bool -PluginRDFIndexer::indexFile(QString filepath) -{ - QUrl url = QUrl::fromLocalFile(filepath); - QString urlString = url.toString(); - return indexURL(urlString); -} - -bool -PluginRDFIndexer::indexURL(QString urlString) -{ -// cerr << "PluginRDFIndexer::indexURL: url = <" << urlString.toStdString() << ">" << endl; - - SimpleSPARQLQuery query - (QString - ( - " PREFIX vamp: <http://purl.org/ontology/vamp/> " - - " SELECT ?plugin ?library_id ?plugin_id " - " FROM <%1> " - - " WHERE { " - " ?plugin a vamp:Plugin . " - - // Make the identifier and library parts optional, so - // that we can check and report helpfully if one or both - // is absent instead of just getting no results - - " OPTIONAL { ?plugin vamp:identifier ?plugin_id } . " - - " OPTIONAL { " - " ?library a vamp:PluginLibrary ; " - " vamp:available_plugin ?plugin ; " - " vamp:identifier ?library_id " - " } " - " } " - ) - .arg(urlString)); - - SimpleSPARQLQuery::ResultList results = query.execute(); - - if (!query.isOK()) { - cerr << "ERROR: PluginRDFIndexer::indexURL: ERROR: Failed to index document at <" - << urlString.toStdString() << ">: " - << query.getErrorString().toStdString() << endl; - return false; - } - - if (results.empty()) { - cerr << "PluginRDFIndexer::indexURL: NOTE: Document at <" - << urlString.toStdString() - << "> does not describe any vamp:Plugin resources" << endl; - return false; - } - - bool foundSomething = false; - bool addedSomething = false; - - for (SimpleSPARQLQuery::ResultList::iterator i = results.begin(); - i != results.end(); ++i) { - - QString pluginUri = (*i)["plugin"].value; - QString soname = (*i)["library_id"].value; - QString identifier = (*i)["plugin_id"].value; - - if (identifier == "") { - cerr << "PluginRDFIndexer::indexURL: NOTE: Document at <" - << urlString.toStdString() - << "> fails to define any vamp:identifier for plugin <" - << pluginUri.toStdString() << ">" - << endl; - continue; - } - if (soname == "") { - cerr << "PluginRDFIndexer::indexURL: NOTE: Document at <" - << urlString.toStdString() << "> does not associate plugin <" - << pluginUri.toStdString() << "> with any implementation library" - << endl; - continue; - } -/* - cerr << "PluginRDFIndexer::indexURL: Document for plugin \"" - << soname.toStdString() << ":" << identifier.toStdString() - << "\" (uri <" << pluginUri.toStdString() << ">) is at url <" - << urlString.toStdString() << ">" << endl; -*/ - QString pluginId = PluginIdentifier::createIdentifier - ("vamp", soname, identifier); - - foundSomething = true; - - if (m_idToDescriptionMap.find(pluginId) != m_idToDescriptionMap.end()) { - cerr << "PluginRDFIndexer::indexURL: NOTE: Plugin id \"" - << pluginId.toStdString() << "\", described in document at <" - << urlString.toStdString() - << ">, has already been described in document <" - << m_idToDescriptionMap[pluginId].toStdString() - << ">: ignoring this new description" << endl; - continue; - } - - m_idToDescriptionMap[pluginId] = urlString; - m_idToUriMap[pluginId] = pluginUri; - - addedSomething = true; - - if (pluginUri != "") { - if (m_uriToIdMap.find(pluginUri) != m_uriToIdMap.end()) { - cerr << "PluginRDFIndexer::indexURL: WARNING: Found multiple plugins with the same URI:" << endl; - cerr << " 1. Plugin id \"" << m_uriToIdMap[pluginUri].toStdString() << "\"" << endl; - cerr << " described in <" << m_idToDescriptionMap[m_uriToIdMap[pluginUri]].toStdString() << ">" << endl; - cerr << " 2. Plugin id \"" << pluginId.toStdString() << "\"" << endl; - cerr << " described in <" << urlString.toStdString() << ">" << endl; - cerr << "both claim URI <" << pluginUri.toStdString() << ">" << endl; - } else { - m_uriToIdMap[pluginUri] = pluginId; - } - } - } - - if (!foundSomething) { - cerr << "PluginRDFIndexer::indexURL: NOTE: Document at <" - << urlString.toStdString() - << "> does not sufficiently describe any plugins" << endl; - } - - return addedSomething; -} - - - Copied: sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp (from rev 1130, sonic-visualiser/branches/rdf-import/rdf/PluginRDFIndexer.cpp) =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp (rev 0) +++ sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp 2008-09-18 12:09:32 UTC (rev 1204) @@ -0,0 +1,286 @@ +/* -*- 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 2008 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 "PluginRDFIndexer.h" + +#include "SimpleSPARQLQuery.h" + +#include "data/fileio/FileSource.h" +#include "plugin/PluginIdentifier.h" + +#include <vamp-sdk/PluginHostAdapter.h> + +#include <QFileInfo> +#include <QDir> +#include <QUrl> + +#include <iostream> +using std::cerr; +using std::endl; +using std::vector; +using std::string; +using Vamp::PluginHostAdapter; + +PluginRDFIndexer * +PluginRDFIndexer::m_instance = 0; + +PluginRDFIndexer * +PluginRDFIndexer::getInstance() +{ + if (!m_instance) m_instance = new PluginRDFIndexer(); + return m_instance; +} + +PluginRDFIndexer::PluginRDFIndexer() +{ + vector<string> paths = PluginHostAdapter::getPluginPath(); + + QStringList filters; + filters << "*.n3"; + filters << "*.N3"; + filters << "*.rdf"; + filters << "*.RDF"; + + // Search each Vamp plugin path for a .rdf file that either has + // name "soname", "soname:label" or "soname/label" plus RDF + // extension. Use that order of preference, and prefer n3 over + // rdf extension. + + for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) { + + QDir dir(i->c_str()); + if (!dir.exists()) continue; + + QStringList entries = dir.entryList + (filters, QDir::Files | QDir::Readable); + + for (QStringList::const_iterator j = entries.begin(); + j != entries.end(); ++j) { + QFileInfo fi(dir.filePath(*j)); + indexFile(fi.absoluteFilePath()); + } + + QStringList subdirs = dir.entryList + (QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Readable); + + for (QStringList::const_iterator j = subdirs.begin(); + j != subdirs.end(); ++j) { + QDir subdir(dir.filePath(*j)); + if (subdir.exists()) { + entries = subdir.entryList + (filters, QDir::Files | QDir::Readable); + for (QStringList::const_iterator k = entries.begin(); + k != entries.end(); ++k) { + QFileInfo fi(subdir.filePath(*k)); + indexFile(fi.absoluteFilePath()); + } + } + } + } +} + +PluginRDFIndexer::~PluginRDFIndexer() +{ + while (!m_cache.empty()) { + delete *m_cache.begin(); + m_cache.erase(m_cache.begin()); + } +} + +QString +PluginRDFIndexer::getURIForPluginId(QString pluginId) +{ + if (m_idToUriMap.find(pluginId) == m_idToUriMap.end()) return ""; + return m_idToUriMap[pluginId]; +} + +QString +PluginRDFIndexer::getIdForPluginURI(QString uri) +{ + if (m_uriToIdMap.find(uri) == m_uriToIdMap.end()) { + + // Haven't found this uri referenced in any document on the + // local filesystem; try resolving the pre-fragment part of + // the uri as a document URL and reading that if possible. + + // Because we may want to refer to this document again, we + // cache it locally if it turns out to exist. + + cerr << "PluginRDFIndexer::getIdForPluginURI: NOTE: Failed to find a local RDF document describing plugin <" << uri.toStdString() << ">: attempting to retrieve one remotely by guesswork" << endl; + + QString baseUrl = QUrl(uri).toString(QUrl::RemoveFragment); + + FileSource source(baseUrl); + if (source.isAvailable()) { + source.waitForData(); + if (indexFile(source.getLocalFilename())) { + m_cache.insert(new FileSource(source)); + } + } + + if (m_uriToIdMap.find(uri) == m_uriToIdMap.end()) { + m_uriToIdMap[uri] = ""; + } + } + + return m_uriToIdMap[uri]; +} + +QString +PluginRDFIndexer::getDescriptionURLForPluginId(QString pluginId) +{ + if (m_idToDescriptionMap.find(pluginId) == m_idToDescriptionMap.end()) return ""; + return m_idToDescriptionMap[pluginId]; +} + +QString +PluginRDFIndexer::getDescriptionURLForPluginURI(QString uri) +{ + QString id = getIdForPluginURI(uri); + if (id == "") return ""; + return getDescriptionURLForPluginId(id); +} + +bool +PluginRDFIndexer::indexFile(QString filepath) +{ + QUrl url = QUrl::fromLocalFile(filepath); + QString urlString = url.toString(); + return indexURL(urlString); +} + +bool +PluginRDFIndexer::indexURL(QString urlString) +{ +// cerr << "PluginRDFIndexer::indexURL: url = <" << urlString.toStdString() << ">" << endl; + + SimpleSPARQLQuery query + (QString + ( + " PREFIX vamp: <http://purl.org/ontology/vamp/> " + + " SELECT ?plugin ?library_id ?plugin_id " + " FROM <%1> " + + " WHERE { " + " ?plugin a vamp:Plugin . " + + // Make the identifier and library parts optional, so + // that we can check and report helpfully if one or both + // is absent instead of just getting no results + + " OPTIONAL { ?plugin vamp:identifier ?plugin_id } . " + + " OPTIONAL { " + " ?library a vamp:PluginLibrary ; " + " vamp:available_plugin ?plugin ; " + " vamp:identifier ?library_id " + " } " + " } " + ) + .arg(urlString)); + + SimpleSPARQLQuery::ResultList results = query.execute(); + + if (!query.isOK()) { + cerr << "ERROR: PluginRDFIndexer::indexURL: ERROR: Failed to index document at <" + << urlString.toStdString() << ">: " + << query.getErrorString().toStdString() << endl; + return false; + } + + if (results.empty()) { + cerr << "PluginRDFIndexer::indexURL: NOTE: Document at <" + << urlString.toStdString() + << "> does not describe any vamp:Plugin resources" << endl; + return false; + } + + bool foundSomething = false; + bool addedSomething = false; + + for (SimpleSPARQLQuery::ResultList::iterator i = results.begin(); + i != results.end(); ++i) { + + QString pluginUri = (*i)["plugin"].value; + QString soname = (*i)["library_id"].value; + QString identifier = (*i)["plugin_id"].value; + + if (identifier == "") { + cerr << "PluginRDFIndexer::indexURL: NOTE: Document at <" + << urlString.toStdString() + << "> fails to define any vamp:identifier for plugin <" + << pluginUri.toStdString() << ">" + << endl; + continue; + } + if (soname == "") { + cerr << "PluginRDFIndexer::indexURL: NOTE: Document at <" + << urlString.toStdString() << "> does not associate plugin <" + << pluginUri.toStdString() << "> with any implementation library" + << endl; + continue; + } +/* + cerr << "PluginRDFIndexer::indexURL: Document for plugin \"" + << soname.toStdString() << ":" << identifier.toStdString() + << "\" (uri <" << pluginUri.toStdString() << ">) is at url <" + << urlString.toStdString() << ">" << endl; +*/ + QString pluginId = PluginIdentifier::createIdentifier + ("vamp", soname, identifier); + + foundSomething = true; + + if (m_idToDescriptionMap.find(pluginId) != m_idToDescriptionMap.end()) { + cerr << "PluginRDFIndexer::indexURL: NOTE: Plugin id \"" + << pluginId.toStdString() << "\", described in document at <" + << urlString.toStdString() + << ">, has already been described in document <" + << m_idToDescriptionMap[pluginId].toStdString() + << ">: ignoring this new description" << endl; + continue; + } + + m_idToDescriptionMap[pluginId] = urlString; + m_idToUriMap[pluginId] = pluginUri; + + addedSomething = true; + + if (pluginUri != "") { + if (m_uriToIdMap.find(pluginUri) != m_uriToIdMap.end()) { + cerr << "PluginRDFIndexer::indexURL: WARNING: Found multiple plugins with the same URI:" << endl; + cerr << " 1. Plugin id \"" << m_uriToIdMap[pluginUri].toStdString() << "\"" << endl; + cerr << " described in <" << m_idToDescriptionMap[m_uriToIdMap[pluginUri]].toStdString() << ">" << endl; + cerr << " 2. Plugin id \"" << pluginId.toStdString() << "\"" << endl; + cerr << " described in <" << urlString.toStdString() << ">" << endl; + cerr << "both claim URI <" << pluginUri.toStdString() << ">" << endl; + } else { + m_uriToIdMap[pluginUri] = pluginId; + } + } + } + + if (!foundSomething) { + cerr << "PluginRDFIndexer::indexURL: NOTE: Document at <" + << urlString.toStdString() + << "> does not sufficiently describe any plugins" << endl; + } + + return addedSomething; +} + + + Deleted: sonic-visualiser/trunk/rdf/PluginRDFIndexer.h =================================================================== --- sonic-visualiser/branches/rdf-import/rdf/PluginRDFIndexer.h 2008-06-25 10:35:16 UTC (rev 1130) +++ sonic-visualiser/trunk/rdf/PluginRDFIndexer.h 2008-09-18 12:09:32 UTC (rev 1204) @@ -1,50 +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 file copyright 2008 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. -*/ - -#ifndef _PLUGIN_RDF_INDEXER_H_ -#define _PLUGIN_RDF_INDEXER_H_ - -#include <QString> -#include <map> -#include <set> - -class FileSource; - -class PluginRDFIndexer -{ -public: - static PluginRDFIndexer *getInstance(); - - QString getURIForPluginId(QString pluginId); - QString getIdForPluginURI(QString uri); - QString getDescriptionURLForPluginId(QString pluginId); - QString getDescriptionURLForPluginURI(QString uri); - - ~PluginRDFIndexer(); - -protected: - PluginRDFIndexer(); - typedef std::map<QString, QString> StringMap; - StringMap m_uriToIdMap; - StringMap m_idToUriMap; - StringMap m_idToDescriptionMap; - bool indexFile(QString path); - bool indexURL(QString url); - std::set<FileSource *> m_cache; - static PluginRDFIndexer *m_instance; -}; - -#endif - Copied: sonic-visualiser/trunk/rdf/PluginRDFIndexer.h (from rev 1130, sonic-visualiser/branches/rdf-import/rdf/PluginRDFIndexer.h) =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFIndexer.h (rev 0) +++ sonic-visualiser/trunk/rdf/PluginRDFIndexer.h 2008-09-18 12:09:32 UTC (rev 1204) @@ -0,0 +1,50 @@ +/* -*- 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 2008 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. +*/ + +#ifndef _PLUGIN_RDF_INDEXER_H_ +#define _PLUGIN_RDF_INDEXER_H_ + +#include <QString> +#include <map> +#include <set> + +class FileSource; + +class PluginRDFIndexer +{ +public: + static PluginRDFIndexer *getInstance(); + + QString getURIForPluginId(QString pluginId); + QString getIdForPluginURI(QString uri); + QString getDescriptionURLForPluginId(QString pluginId); + QString getDescriptionURLForPluginURI(QString uri); + + ~PluginRDFIndexer(); + +protected: + PluginRDFIndexer(); + typedef std::map<QString, QString> StringMap; + StringMap m_uriToIdMap; + StringMap m_idToUriMap; + StringMap m_idToDescriptionMap; + bool indexFile(QString path); + bool indexURL(QString url); + std::set<FileSource *> m_cache; + static PluginRDFIndexer *m_instance; +}; + +#endif + Deleted: sonic-visualiser/trunk/rdf/RDFImporter.cpp =================================================================== --- sonic-visualiser/branches/rdf-import/rdf/RDFImporter.cpp 2008-06-25 10:35:16 UTC (rev 1130) +++ sonic-visualiser/trunk/rdf/RDFImporter.cpp 2008-09-18 12:09:32 UTC (rev 1204) @@ -1,435 +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 file copyright 2008 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 "RDFImporter.h" - -#include <map> -#include <vector> - -#include <iostream> -#include <cmath> - -#include "SimpleSPARQLQuery.h" - -#include "base/ProgressReporter.h" -#include "base/RealTime.h" - -#include "data/model/SparseOneDimensionalModel.h" -#include "data/model/SparseTimeValueModel.h" -#include "data/model/EditableDenseThreeDimensionalModel.h" - -using std::cerr; -using std::endl; - -class RDFImporterImpl -{ -public: - RDFImporterImpl(QString url, int sampleRate); - virtual ~RDFImporterImpl(); - - bool isOK(); - QString getErrorString() const; - - std::vector<Model *> getDataModels(ProgressReporter *); - -protected: - QString m_uristring; - QString m_errorString; - int m_sampleRate; - - typedef std::vector<float> ValueList; - typedef std::map<RealTime, ValueList> TimeValueMap; - typedef std::map<QString, TimeValueMap> TypeTimeValueMap; - typedef std::map<QString, TypeTimeValueMap> SourceTypeTimeValueMap; - - void extractStructure(const TimeValueMap &map, bool &sparse, - int &minValueCount, int &maxValueCount); - - void fillModel(SparseOneDimensionalModel *, const TimeValueMap &); - void fillModel(SparseTimeValueModel *, const TimeValueMap &); - void fillModel(EditableDenseThreeDimensionalModel *, const TimeValueMap &); -}; - - -QString -RDFImporter::getKnownExtensions() -{ - return "*.rdf *.n3 *.ttl"; -} - -RDFImporter::RDFImporter(QString url, int sampleRate) : - m_d(new RDFImporterImpl(url, sampleRate)) -{ -} - -RDFImporter::~RDFImporter() -{ - delete m_d; -} - -bool -RDFImporter::isOK() -{ - return m_d->isOK(); -} - -QString -RDFImporter::getErrorString() const -{ - return m_d->getErrorString(); -} - -std::vector<Model *> -RDFImporter::getDataModels(ProgressReporter *r) -{ - return m_d->getDataModels(r); -} - -RDFImporterImpl::RDFImporterImpl(QString uri, int sampleRate) : - m_uristring(uri), - m_sampleRate(sampleRate) -{ -} - -RDFImporterImpl::~RDFImporterImpl() -{ -} - -bool -RDFImporterImpl::isOK() -{ - return (m_errorString == ""); -} - -QString -RDFImporterImpl::getErrorString() const -{ - return m_errorString; -} - -std::vector<Model *> -RDFImporterImpl::getDataModels(ProgressReporter *reporter) -{ - std::vector<Model *> models; - - // Our query is intended to retrieve every thing that has a time, - // and every feature type and value associated with a thing that - // has a time. - - // We will then need to refine this big bag of results into a set - // of data models. - - // Results that have different source signals should go into - // different models. - - // Results that have different feature types should go into - // different models. - - // Results that are sparse should go into different models from - // those that are dense (we need to examine the timestamps to - // establish this -- if the timestamps are regular, the results - // are dense -- so we can't do it as we go along, only after - // collecting all results). - - // Timed things that have features associated with them should not - // appear directly in any model -- their features should appear - // instead -- and these should be different models from those used - // for timed things that do not have features. - - // As we load the results, we'll push them into a partially - // structured container that maps from source signal (URI as - // string) -> feature type (likewise) -> time -> list of values. - // If the source signal or feature type is unavailable, the empty - // string will do. - - SourceTypeTimeValueMap m; - - QString queryString = QString( - - " PREFIX event: <http://purl.org/NET/c4dm/event.owl#>" - ... [truncated message content] |
From: <ca...@us...> - 2008-09-18 05:33:33
|
Revision: 1205 http://sv1.svn.sourceforge.net/sv1/?rev=1205&view=rev Author: cannam Date: 2008-09-18 12:33:30 +0000 (Thu, 18 Sep 2008) Log Message: ----------- * Merge revisions 1131 to 1201 from sv-rdf-import branch Modified Paths: -------------- sonic-visualiser/trunk/data/fileio/AudioFileReaderFactory.cpp sonic-visualiser/trunk/data/fileio/PlaylistFileReader.cpp sonic-visualiser/trunk/data/fileio/PlaylistFileReader.h sonic-visualiser/trunk/framework/MainWindowBase.cpp sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp sonic-visualiser/trunk/rdf/PluginRDFDescription.h sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp sonic-visualiser/trunk/rdf/RDFImporter.cpp sonic-visualiser/trunk/rdf/RDFTransformFactory.cpp sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.cpp sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.h sonic-visualiser/trunk/rdf/rdf.pro sonic-visualiser/trunk/sv/main/main.cpp sonic-visualiser/trunk/sv/sv.pro sonic-visualiser/trunk/sv.prf Modified: sonic-visualiser/trunk/data/fileio/AudioFileReaderFactory.cpp =================================================================== --- sonic-visualiser/trunk/data/fileio/AudioFileReaderFactory.cpp 2008-09-18 12:09:32 UTC (rev 1204) +++ sonic-visualiser/trunk/data/fileio/AudioFileReaderFactory.cpp 2008-09-18 12:33:30 UTC (rev 1205) @@ -104,6 +104,10 @@ ResamplingWavFileReader::CacheInTemporaryFile, targetRate, reporter); + if (!reader->isOK()) { + delete reader; + reader = 0; + } } } @@ -119,6 +123,10 @@ OggVorbisFileReader::CacheInTemporaryFile, targetRate, reporter); + if (!reader->isOK()) { + delete reader; + reader = 0; + } } } #endif @@ -135,6 +143,10 @@ MP3FileReader::CacheInTemporaryFile, targetRate, reporter); + if (!reader->isOK()) { + delete reader; + reader = 0; + } } } #endif @@ -150,10 +162,103 @@ QuickTimeFileReader::CacheInTemporaryFile, targetRate, reporter); + if (!reader->isOK()) { + delete reader; + reader = 0; + } } } #endif + // If none of the readers claimed to support this file extension, + // perhaps the extension is missing or misleading. Try again, + // ignoring it. We have to be confident that the reader won't + // open just any old text file or whatever and pretend it's + // succeeded + + if (!reader) { + + reader = new WavFileReader(source); + + if (targetRate != 0 && + reader->isOK() && + reader->getSampleRate() != targetRate) { + + std::cerr << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", creating resampling reader" << std::endl; + + delete reader; + reader = new ResamplingWavFileReader + (source, + threading ? + ResamplingWavFileReader::ResampleThreaded : + ResamplingWavFileReader::ResampleAtOnce, + ResamplingWavFileReader::CacheInTemporaryFile, + targetRate, + reporter); + } + + if (!reader->isOK()) { + delete reader; + reader = 0; + } + } + +#ifdef HAVE_OGGZ +#ifdef HAVE_FISHSOUND + if (!reader) { + reader = new OggVorbisFileReader + (source, + threading ? + OggVorbisFileReader::DecodeThreaded : + OggVorbisFileReader::DecodeAtOnce, + OggVorbisFileReader::CacheInTemporaryFile, + targetRate, + reporter); + + if (!reader->isOK()) { + delete reader; + reader = 0; + } + } +#endif +#endif + +#ifdef HAVE_MAD + if (!reader) { + reader = new MP3FileReader + (source, + threading ? + MP3FileReader::DecodeThreaded : + MP3FileReader::DecodeAtOnce, + MP3FileReader::CacheInTemporaryFile, + targetRate, + reporter); + + if (!reader->isOK()) { + delete reader; + reader = 0; + } + } +#endif + +#ifdef HAVE_QUICKTIME + if (!reader) { + reader = new QuickTimeFileReader + (source, + threading ? + QuickTimeFileReader::DecodeThreaded : + QuickTimeFileReader::DecodeAtOnce, + QuickTimeFileReader::CacheInTemporaryFile, + targetRate, + reporter); + + if (!reader->isOK()) { + delete reader; + reader = 0; + } + } +#endif + if (reader) { if (reader->isOK()) { // std::cerr << "AudioFileReaderFactory: Reader is OK" << std::endl; Modified: sonic-visualiser/trunk/data/fileio/PlaylistFileReader.cpp =================================================================== --- sonic-visualiser/trunk/data/fileio/PlaylistFileReader.cpp 2008-09-18 12:09:32 UTC (rev 1204) +++ sonic-visualiser/trunk/data/fileio/PlaylistFileReader.cpp 2008-09-18 12:33:30 UTC (rev 1205) @@ -18,7 +18,11 @@ #include <QFile> #include <QTextStream> #include <QStringList> +#include <QFileInfo> +#include <QDir> +#include <iostream> + PlaylistFileReader::PlaylistFileReader(QString path) : m_source(path), m_file(0) @@ -56,7 +60,9 @@ m_source.waitForData(); - m_file = new QFile(m_source.getLocalFilename()); + QString filename = m_source.getLocalFilename(); + + m_file = new QFile(filename); bool good = false; if (!m_file->exists()) { @@ -69,6 +75,12 @@ good = true; } + if (good) { + if (!m_source.isRemote()) { + m_basedir = QFileInfo(filename).dir().canonicalPath(); + } + } + if (!good) { delete m_file; m_file = 0; @@ -105,12 +117,31 @@ QString chunk = in.readLine(); QStringList lines = chunk.split('\r', QString::SkipEmptyParts); - for (size_t li = 0; li < lines.size(); ++li) { + for (int li = 0; li < lines.size(); ++li) { QString line = lines[li]; if (line.startsWith("#")) continue; + // line is expected to be a URL or a file path. If it + // appears to be a local relative file path, then we + // should check whether it can be resolved relative to the + // location of the playlist file and, if so, do so. + + if (!FileSource::isRemote(line)) { + if (QFileInfo(line).isRelative() && m_basedir != "") { + QString testpath = QDir(m_basedir).filePath(line); + if (QFileInfo(testpath).exists() && + QFileInfo(testpath).isFile()) { + std::cerr << "Path \"" << line.toStdString() + << "\" is relative, resolving to \"" + << testpath.toStdString() << "\"" + << std::endl; + line = testpath; + } + } + } + playlist.push_back(line); } } Modified: sonic-visualiser/trunk/data/fileio/PlaylistFileReader.h =================================================================== --- sonic-visualiser/trunk/data/fileio/PlaylistFileReader.h 2008-09-18 12:09:32 UTC (rev 1204) +++ sonic-visualiser/trunk/data/fileio/PlaylistFileReader.h 2008-09-18 12:33:30 UTC (rev 1205) @@ -45,6 +45,7 @@ FileSource m_source; QFile *m_file; + QString m_basedir; QString m_error; }; Modified: sonic-visualiser/trunk/framework/MainWindowBase.cpp =================================================================== --- sonic-visualiser/trunk/framework/MainWindowBase.cpp 2008-09-18 12:09:32 UTC (rev 1204) +++ sonic-visualiser/trunk/framework/MainWindowBase.cpp 2008-09-18 12:33:30 UTC (rev 1205) @@ -1064,6 +1064,8 @@ MainWindowBase::FileOpenStatus MainWindowBase::openPlaylist(FileSource source, AudioFileOpenMode mode) { + std::cerr << "MainWindowBase::openPlaylist(" << source.getLocation().toStdString() << ")" << std::endl; + std::set<QString> extensions; PlaylistFileReader::getSupportedExtensions(extensions); QString extension = source.getExtension(); @@ -1103,6 +1105,8 @@ MainWindowBase::FileOpenStatus MainWindowBase::openLayer(FileSource source) { + std::cerr << "MainWindowBase::openLayer(" << source.getLocation().toStdString() << ")" << std::endl; + Pane *pane = m_paneStack->getCurrentPane(); if (!pane) { @@ -1128,10 +1132,18 @@ RDFImporter importer("file://" + path, getMainModel()->getSampleRate()); if (importer.isOK()) { - ProgressDialog dialog(tr("Importing from RDF..."), true, 2000, this); - connect(&dialog, SIGNAL(showing()), this, SIGNAL(hideSplash())); - std::vector<Model *> models = importer.getDataModels(&dialog); + std::vector<Model *> models; + { + ProgressDialog dialog(tr("Importing from RDF..."), true, 2000, this); + connect(&dialog, SIGNAL(showing()), this, SIGNAL(hideSplash())); + models = importer.getDataModels(&dialog); + } + + if (models.empty()) { + return FileOpenFailed; + } + for (int i = 0; i < models.size(); ++i) { Layer *newLayer = m_document->createImportedLayer(models[i]); if (newLayer) { @@ -1239,6 +1251,8 @@ MainWindowBase::FileOpenStatus MainWindowBase::openImage(FileSource source) { + std::cerr << "MainWindowBase::openImage(" << source.getLocation().toStdString() << ")" << std::endl; + Pane *pane = m_paneStack->getCurrentPane(); if (!pane) { @@ -1297,6 +1311,8 @@ MainWindowBase::FileOpenStatus MainWindowBase::openSession(FileSource source) { + std::cerr << "MainWindowBase::openSession(" << source.getLocation().toStdString() << ")" << std::endl; + if (!source.isAvailable()) return FileOpenFailed; if (source.getExtension() != "sv") return FileOpenFailed; source.waitForData(); Modified: sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp 2008-09-18 12:09:32 UTC (rev 1204) +++ sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp 2008-09-18 12:33:30 UTC (rev 1205) @@ -53,15 +53,6 @@ return m_haveDescription; } -PluginRDFDescription::OutputType -PluginRDFDescription::getOutputType(QString outputId) const -{ - if (m_outputTypes.find(outputId) == m_outputTypes.end()) { - return OutputTypeUnknown; - } - return m_outputTypes.find(outputId)->second; -} - PluginRDFDescription::OutputDisposition PluginRDFDescription::getOutputDisposition(QString outputId) const { @@ -72,26 +63,36 @@ } QString -PluginRDFDescription::getOutputFeatureTypeURI(QString outputId) const +PluginRDFDescription::getOutputEventTypeURI(QString outputId) const { - if (m_outputFeatureTypeURIMap.find(outputId) == - m_outputFeatureTypeURIMap.end()) { + if (m_outputEventTypeURIMap.find(outputId) == + m_outputEventTypeURIMap.end()) { return ""; } - return m_outputFeatureTypeURIMap.find(outputId)->second; + return m_outputEventTypeURIMap.find(outputId)->second; } QString -PluginRDFDescription::getOutputEventTypeURI(QString outputId) const +PluginRDFDescription::getOutputFeatureAttributeURI(QString outputId) const { - if (m_outputEventTypeURIMap.find(outputId) == - m_outputEventTypeURIMap.end()) { + if (m_outputFeatureAttributeURIMap.find(outputId) == + m_outputFeatureAttributeURIMap.end()) { return ""; } - return m_outputEventTypeURIMap.find(outputId)->second; + return m_outputFeatureAttributeURIMap.find(outputId)->second; } QString +PluginRDFDescription::getOutputSignalTypeURI(QString outputId) const +{ + if (m_outputSignalTypeURIMap.find(outputId) == + m_outputSignalTypeURIMap.end()) { + return ""; + } + return m_outputSignalTypeURIMap.find(outputId)->second; +} + +QString PluginRDFDescription::getOutputUnit(QString outputId) const { if (m_outputUnitMap.find(outputId) == m_outputUnitMap.end()) { @@ -111,27 +112,19 @@ ( " PREFIX vamp: <http://purl.org/ontology/vamp/> " - " SELECT ?output_id ?output_type ?feature_type ?event_type ?unit " + " SELECT ?output ?output_id ?output_type ?unit " " FROM <%1> " " WHERE { " " ?plugin a vamp:Plugin ; " " vamp:identifier \"%2\" ; " - " vamp:output_descriptor ?output . " + " vamp:output ?output . " " ?output vamp:identifier ?output_id ; " " a ?output_type . " " OPTIONAL { " - " ?output vamp:computes_feature_type ?feature_type " - " } . " - - " OPTIONAL { " - " ?output vamp:computes_event_type ?event_type " - " } . " - - " OPTIONAL { " " ?output vamp:unit ?unit " " } . " @@ -152,7 +145,8 @@ if (results.empty()) { cerr << "ERROR: PluginRDFDescription::indexURL: NOTE: Document at <" << url.toStdString() - << "> does not appear to describe any plugin outputs" << endl; + << "> does not appear to describe any outputs for plugin with id \"" + << label.toStdString() << "\"" << endl; return false; } @@ -162,12 +156,8 @@ for (int i = 0; i < results.size(); ++i) { + QString outputUri = results[i]["output"].value; QString outputId = results[i]["output_id"].value; - - if (m_outputTypes.find(outputId) == m_outputTypes.end()) { - m_outputTypes[outputId] = OutputTypeUnknown; - } - QString outputType = results[i]["output_type"].value; if (outputType.contains("DenseOutput")) { @@ -177,34 +167,6 @@ } else if (outputType.contains("TrackLevelOutput")) { m_outputDispositions[outputId] = OutputTrackLevel; } - - if (results[i]["feature_type"].type == SimpleSPARQLQuery::URIValue) { - - QString featureType = results[i]["feature_type"].value; - - if (featureType != "") { - if (m_outputTypes[outputId] == OutputEvents) { - m_outputTypes[outputId] = OutputFeaturesAndEvents; - } else { - m_outputTypes[outputId] = OutputFeatures; - } - m_outputFeatureTypeURIMap[outputId] = featureType; - } - } - - if (results[i]["event_type"].type == SimpleSPARQLQuery::URIValue) { - - QString eventType = results[i]["event_type"].value; - - if (eventType != "") { - if (m_outputTypes[outputId] == OutputFeatures) { - m_outputTypes[outputId] = OutputFeaturesAndEvents; - } else { - m_outputTypes[outputId] = OutputEvents; - } - m_outputEventTypeURIMap[outputId] = eventType; - } - } if (results[i]["unit"].type == SimpleSPARQLQuery::LiteralValue) { @@ -214,6 +176,35 @@ m_outputUnitMap[outputId] = unit; } } + + QString queryTemplate = + QString(" PREFIX vamp: <http://purl.org/ontology/vamp/> " + " SELECT ?%3 FROM <%1> " + " WHERE { <%2> vamp:computes_%3 ?%3 } ") + .arg(url).arg(outputUri); + + SimpleSPARQLQuery::Value v; + + v = SimpleSPARQLQuery::singleResultQuery + (queryTemplate.arg("event_type"), "event_type"); + + if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") { + m_outputEventTypeURIMap[outputId] = v.value; + } + + v = SimpleSPARQLQuery::singleResultQuery + (queryTemplate.arg("feature_attribute"), "feature_attribute"); + + if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") { + m_outputFeatureAttributeURIMap[outputId] = v.value; + } + + v = SimpleSPARQLQuery::singleResultQuery + (queryTemplate.arg("signal_type"), "signal_type"); + + if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") { + m_outputSignalTypeURIMap[outputId] = v.value; + } } return true; Modified: sonic-visualiser/trunk/rdf/PluginRDFDescription.h =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFDescription.h 2008-09-18 12:09:32 UTC (rev 1204) +++ sonic-visualiser/trunk/rdf/PluginRDFDescription.h 2008-09-18 12:33:30 UTC (rev 1205) @@ -28,14 +28,6 @@ PluginRDFDescription(QString pluginId); ~PluginRDFDescription(); - enum OutputType - { - OutputTypeUnknown, - OutputFeatures, - OutputEvents, - OutputFeaturesAndEvents - }; - enum OutputDisposition { OutputDispositionUnknown, @@ -45,23 +37,22 @@ }; bool haveDescription() const; - OutputType getOutputType(QString outputId) const; OutputDisposition getOutputDisposition(QString outputId) const; - QString getOutputFeatureTypeURI(QString outputId) const; QString getOutputEventTypeURI(QString outputId) const; + QString getOutputFeatureAttributeURI(QString outputId) const; + QString getOutputSignalTypeURI(QString outputId) const; QString getOutputUnit(QString outputId) const; protected: - typedef std::map<QString, OutputType> OutputTypeMap; typedef std::map<QString, OutputDisposition> OutputDispositionMap; typedef std::map<QString, QString> OutputStringMap; QString m_pluginId; bool m_haveDescription; - OutputTypeMap m_outputTypes; OutputDispositionMap m_outputDispositions; - OutputStringMap m_outputFeatureTypeURIMap; OutputStringMap m_outputEventTypeURIMap; + OutputStringMap m_outputFeatureAttributeURIMap; + OutputStringMap m_outputSignalTypeURIMap; OutputStringMap m_outputUnitMap; bool indexURL(QString url); }; Modified: sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp 2008-09-18 12:09:32 UTC (rev 1204) +++ sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp 2008-09-18 12:33:30 UTC (rev 1205) @@ -181,8 +181,13 @@ // that we can check and report helpfully if one or both // is absent instead of just getting no results - " OPTIONAL { ?plugin vamp:identifier ?plugin_id } . " + //!!! No -- because of rasqal's inability to correctly + // handle more than one OPTIONAL graph in a query, let's + // make identifier compulsory after all + //" OPTIONAL { ?plugin vamp:identifier ?plugin_id } . " + " ?plugin vamp:identifier ?plugin_id . " + " OPTIONAL { " " ?library a vamp:PluginLibrary ; " " vamp:available_plugin ?plugin ; " Modified: sonic-visualiser/trunk/rdf/RDFImporter.cpp =================================================================== --- sonic-visualiser/trunk/rdf/RDFImporter.cpp 2008-09-18 12:09:32 UTC (rev 1204) +++ sonic-visualiser/trunk/rdf/RDFImporter.cpp 2008-09-18 12:33:30 UTC (rev 1205) @@ -54,6 +54,13 @@ typedef std::map<QString, TimeValueMap> TypeTimeValueMap; typedef std::map<QString, TypeTimeValueMap> SourceTypeTimeValueMap; + void getDataModelsSparse(std::vector<Model *> &, ProgressReporter *); + void getDataModelsDense(std::vector<Model *> &, ProgressReporter *); + + void getDenseFeatureProperties(QString featureUri, + int &sampleRate, int &windowLength, + int &hopSize, int &width, int &height); + void extractStructure(const TimeValueMap &map, bool &sparse, int &minValueCount, int &maxValueCount); @@ -124,6 +131,229 @@ { std::vector<Model *> models; + getDataModelsDense(models, reporter); + + QString error; + if (!isOK()) error = m_errorString; + m_errorString = ""; + + getDataModelsSparse(models, reporter); + + if (isOK()) m_errorString = error; + + return models; +} + +void +RDFImporterImpl::getDataModelsDense(std::vector<Model *> &models, + ProgressReporter *reporter) +{ + SimpleSPARQLQuery query = SimpleSPARQLQuery + (QString + ( + " PREFIX mo: <http://purl.org/ontology/mo/>" + " PREFIX af: <http://purl.org/ontology/af/>" + + " SELECT ?feature ?signal_source ?feature_signal_type ?value " + " FROM <%1> " + + " WHERE { " + + " ?signal a mo:Signal ; " + " mo:available_as ?signal_source ; " + " af:signal_feature ?feature . " + + " ?feature a ?feature_signal_type ; " + " af:value ?value . " + + " } " + ) + .arg(m_uristring)); + + SimpleSPARQLQuery::ResultList results = query.execute(); + + if (!query.isOK()) { + m_errorString = query.getErrorString(); + return; + } + + if (query.wasCancelled()) { + m_errorString = "Query cancelled"; + return; + } + + for (int i = 0; i < results.size(); ++i) { + + QString feature = results[i]["feature"].value; + QString source = results[i]["signal_source"].value; + QString type = results[i]["feature_signal_type"].value; + QString value = results[i]["value"].value; + + int sampleRate = 0; + int windowLength = 0; + int hopSize = 0; + int width = 0; + int height = 0; + getDenseFeatureProperties + (feature, sampleRate, windowLength, hopSize, width, height); + + if (sampleRate != 0 && sampleRate != m_sampleRate) { + cerr << "WARNING: Sample rate in dense feature description does not match our underlying rate -- using rate from feature description" << endl; + } + if (sampleRate == 0) sampleRate = m_sampleRate; + + if (hopSize == 0) { + cerr << "WARNING: Dense feature description does not specify a hop size -- assuming 1" << endl; + hopSize = 1; + } + + if (height == 0) { + cerr << "WARNING: Dense feature description does not specify feature signal dimensions -- assuming one-dimensional (height = 1)" << endl; + height = 1; + } + + QStringList values = value.split(' ', QString::SkipEmptyParts); + + if (values.empty()) { + cerr << "WARNING: Dense feature description does not specify any values!" << endl; + continue; + } + + if (height == 1) { + + SparseTimeValueModel *m = new SparseTimeValueModel + (sampleRate, hopSize, false); + + for (int j = 0; j < values.size(); ++j) { + float f = values[j].toFloat(); + SparseTimeValueModel::Point point(j * hopSize, f, ""); + m->addPoint(point); + } + + models.push_back(m); + + } else { + + EditableDenseThreeDimensionalModel *m = + new EditableDenseThreeDimensionalModel(sampleRate, hopSize, + height, false); + + EditableDenseThreeDimensionalModel::Column column; + + int x = 0; + + for (int j = 0; j < values.size(); ++j) { + if (j % height == 0 && !column.empty()) { + m->setColumn(x++, column); + column.clear(); + } + column.push_back(values[j].toFloat()); + } + + if (!column.empty()) { + m->setColumn(x++, column); + } + + models.push_back(m); + } + } +} + +void +RDFImporterImpl::getDenseFeatureProperties(QString featureUri, + int &sampleRate, int &windowLength, + int &hopSize, int &width, int &height) +{ + QString dimensionsQuery + ( + " PREFIX mo: <http://purl.org/ontology/mo/>" + " PREFIX af: <http://purl.org/ontology/af/>" + + " SELECT ?dimensions " + " FROM <%1> " + + " WHERE { " + + " <%2> af:dimensions ?dimensions . " + + " } " + ); + + SimpleSPARQLQuery::Value dimensionsValue = + SimpleSPARQLQuery::singleResultQuery(dimensionsQuery + .arg(m_uristring).arg(featureUri), + "dimensions"); + + cerr << "Dimensions = \"" << dimensionsValue.value.toStdString() << "\"" + << endl; + + if (dimensionsValue.value != "") { + QStringList dl = dimensionsValue.value.split(" "); + if (dl.empty()) dl.push_back(dimensionsValue.value); + if (dl.size() > 0) height = dl[0].toInt(); + if (dl.size() > 1) width = dl[1].toInt(); + } + + QString queryTemplate + ( + " PREFIX mo: <http://purl.org/ontology/mo/>" + " PREFIX af: <http://purl.org/ontology/af/>" + " PREFIX tl: <http://purl.org/NET/c4dm/timeline.owl#>" + + " SELECT ?%3 " + " FROM <%1> " + + " WHERE { " + + " <%2> mo:time ?time . " + + " ?time a tl:Interval ; " + " tl:onTimeLine ?timeline . " + + " ?map tl:rangeTimeLine ?timeline . " + + " ?map tl:%3 ?%3 . " + + " } " + ); + + // Another laborious workaround for rasqal's failure to handle + // multiple optionals properly + + SimpleSPARQLQuery::Value srValue = + SimpleSPARQLQuery::singleResultQuery(queryTemplate + .arg(m_uristring).arg(featureUri) + .arg("sampleRate"), + "sampleRate"); + if (srValue.value != "") { + sampleRate = srValue.value.toInt(); + } + + SimpleSPARQLQuery::Value hopValue = + SimpleSPARQLQuery::singleResultQuery(queryTemplate + .arg(m_uristring).arg(featureUri) + .arg("hopSize"), + "hopSize"); + if (srValue.value != "") { + hopSize = hopValue.value.toInt(); + } + + SimpleSPARQLQuery::Value winValue = + SimpleSPARQLQuery::singleResultQuery(queryTemplate + .arg(m_uristring).arg(featureUri) + .arg("windowLength"), + "windowLength"); + if (winValue.value != "") { + windowLength = winValue.value.toInt(); + } + + cerr << "sr = " << sampleRate << ", hop = " << hopSize << ", win = " << windowLength << endl; +} + +void +RDFImporterImpl::getDataModelsSparse(std::vector<Model *> &models, + ProgressReporter *reporter) +{ // Our query is intended to retrieve every thing that has a time, // and every feature type and value associated with a thing that // has a time. @@ -163,20 +393,23 @@ " PREFIX mo: <http://purl.org/ontology/mo/>" " PREFIX af: <http://purl.org/ontology/af/>" - " SELECT ?signalSource ?time ?eventType ?value" + " SELECT ?signal_source ?time ?event_type ?value" " FROM <%1>" " WHERE {" - " ?signal mo:available_as ?signalSource ." + + " ?signal mo:available_as ?signal_source ." + " ?signal a mo:Signal ." + " ?signal mo:time ?interval ." " ?interval time:onTimeLine ?tl ." " ?t time:onTimeLine ?tl ." " ?t time:at ?time ." - " ?timedThing event:time ?t ." - " ?timedThing a ?eventType ." + " ?timed_thing event:time ?t ." + " ?timed_thing a ?event_type ." + " OPTIONAL {" - " ?timedThing af:hasFeature ?feature ." - " ?feature af:value ?value" + " ?timed_thing af:feature ?value" " }" " }" @@ -191,17 +424,17 @@ if (!query.isOK()) { m_errorString = query.getErrorString(); - return models; + return; } if (query.wasCancelled()) { m_errorString = "Query cancelled"; - return models; + return; } for (int i = 0; i < results.size(); ++i) { - QString source = results[i]["signalSource"].value; + QString source = results[i]["signal_source"].value; QString timestring = results[i]["time"].value; RealTime time; @@ -209,12 +442,13 @@ cerr << "time = " << time.toString() << " (from xsd:duration \"" << timestring.toStdString() << "\")" << endl; - QString type = results[i]["eventType"].value; + QString type = results[i]["event_type"].value; QString valuestring = results[i]["value"].value; float value = 0.f; bool haveValue = false; if (valuestring != "") { + //!!! no -- runner actually writes a "CSV literal" value = valuestring.toFloat(&haveValue); cerr << "value = " << value << endl; } @@ -322,9 +556,6 @@ } } } - - - return models; } void Modified: sonic-visualiser/trunk/rdf/RDFTransformFactory.cpp =================================================================== --- sonic-visualiser/trunk/rdf/RDFTransformFactory.cpp 2008-09-18 12:09:32 UTC (rev 1204) +++ sonic-visualiser/trunk/rdf/RDFTransformFactory.cpp 2008-09-18 12:33:30 UTC (rev 1205) @@ -18,9 +18,6 @@ #include <map> #include <vector> -#include <redland.h> -#include <rasqal.h> - #include <iostream> #include <cmath> @@ -50,6 +47,8 @@ protected: QString m_urlString; QString m_errorString; + bool setOutput(Transform &, QString, QString); + bool setParameters(Transform &, QString, QString); }; @@ -113,140 +112,156 @@ { std::vector<Transform> transforms; - SimpleSPARQLQuery query - (QString - ( - " PREFIX vamp: <http://purl.org/ontology/vamp/> " + // We have to do this a very long way round, to work around + // rasqal's current inability to handle correctly more than one + // OPTIONAL graph in a query - " SELECT ?transform ?plugin ?output ?program " - " ?step_size ?block_size ?window_type " - " ?sample_rate ?start ?duration " + const char *optionals[] = { + "output", + "program", + "step_size", + "block_size", + "window_type", + "sample_rate", + "start", + "duration" + }; - " FROM <%1> " + std::map<QString, Transform> uriTransformMap; - " WHERE { " - " ?transform a vamp:Transform ; " - " vamp:plugin ?plugin . " - " OPTIONAL { ?transform vamp:output ?output } . " - " OPTIONAL { ?transform vamp:program ?program } . " - " OPTIONAL { ?transform vamp:step_size ?step_size } . " - " OPTIONAL { ?transform vamp:block_size ?block_size } . " - " OPTIONAL { ?transform vamp:window_type ?window_type } . " - " OPTIONAL { ?transform vamp:sample_rate ?sample_rate } . " - " OPTIONAL { ?transform vamp:start ?start } . " - " OPTIONAL { ?transform vamp:duration ?duration } " - " } " - ) - .arg(m_urlString)); + QString queryTemplate = + " PREFIX vamp: <http://purl.org/ontology/vamp/> " - SimpleSPARQLQuery::ResultList results = query.execute(); + " SELECT ?transform ?plugin %1 " + + " FROM <%2> " - if (!query.isOK()) { - m_errorString = query.getErrorString(); + " WHERE { " + " ?transform a vamp:Transform ; " + " vamp:plugin ?plugin . " + " %3 " + " } "; + + SimpleSPARQLQuery transformsQuery + (queryTemplate.arg("").arg(m_urlString).arg("")); + + SimpleSPARQLQuery::ResultList transformResults = transformsQuery.execute(); + + if (!transformsQuery.isOK()) { + m_errorString = transformsQuery.getErrorString(); return transforms; } - if (query.wasCancelled()) { - m_errorString = "Query cancelled"; + if (transformResults.empty()) { + cerr << "RDFTransformFactory: NOTE: No RDF/TTL transform descriptions found in document at <" << m_urlString.toStdString() << ">" << endl; return transforms; } PluginRDFIndexer *indexer = PluginRDFIndexer::getInstance(); - for (int i = 0; i < results.size(); ++i) { + for (int i = 0; i < transformResults.size(); ++i) { - SimpleSPARQLQuery::KeyValueMap &result = results[i]; + SimpleSPARQLQuery::KeyValueMap &result = transformResults[i]; QString transformUri = result["transform"].value; QString pluginUri = result["plugin"].value; QString pluginId = indexer->getIdForPluginURI(pluginUri); - if (pluginId == "") { cerr << "RDFTransformFactory: WARNING: Unknown plugin <" << pluginUri.toStdString() << "> for transform <" + << transformUri.toStdString() << ">, skipping this transform" + << endl; + continue; + } + + QString pluginDescriptionURL = + indexer->getDescriptionURLForPluginId(pluginId); + if (pluginDescriptionURL == "") { + cerr << "RDFTransformFactory: WARNING: No RDF description available for plugin <" + << pluginUri.toStdString() << ">, skipping transform <" << transformUri.toStdString() << ">" << endl; continue; } Transform transform; transform.setPluginIdentifier(pluginId); - - if (result["output"].type == SimpleSPARQLQuery::LiteralValue) { - transform.setOutput(result["output"].value); - } - if (result["program"].type == SimpleSPARQLQuery::LiteralValue) { - transform.setProgram(result["program"].value); + if (!setOutput(transform, transformUri, pluginDescriptionURL)) { + return transforms; } - - if (result["step_size"].type == SimpleSPARQLQuery::LiteralValue) { - transform.setStepSize(result["step_size"].value.toUInt()); - } - - if (result["block_size"].type == SimpleSPARQLQuery::LiteralValue) { - transform.setBlockSize(result["block_size"].value.toUInt()); - } - - if (result["window_type"].type == SimpleSPARQLQuery::LiteralValue) { - cerr << "NOTE: can't handle window type yet (value is \"" - << result["window_type"].value.toStdString() << "\")" << endl; - } - - if (result["sample_rate"].type == SimpleSPARQLQuery::LiteralValue) { - transform.setStepSize(result["sample_rate"].value.toFloat()); - } - if (result["start"].type == SimpleSPARQLQuery::LiteralValue) { - transform.setStartTime(RealTime::fromXsdDuration - (result["start"].value.toStdString())); + if (!setParameters(transform, transformUri, pluginDescriptionURL)) { + return transforms; } - if (result["duration"].type == SimpleSPARQLQuery::LiteralValue) { - transform.setDuration(RealTime::fromXsdDuration - (result["duration"].value.toStdString())); - } + uriTransformMap[transformUri] = transform; + } - SimpleSPARQLQuery paramQuery - (QString - ( - " PREFIX vamp: <http://purl.org/ontology/vamp/> " + for (int i = 0; i < sizeof(optionals)/sizeof(optionals[0]); ++i) { - " SELECT ?param_id ?param_value " + QString optional = optionals[i]; - " FROM <%1> " - - " WHERE { " - " <%2> vamp:parameter ?param . " - " ?param vamp:identifier ?param_id ; " - " vamp:value ?param_value " - " } " - ) + SimpleSPARQLQuery query + (queryTemplate + .arg(QString("?%1").arg(optional)) .arg(m_urlString) - .arg(transformUri)); + .arg(QString("?transform vamp:%1 ?%2") + .arg(optionals[i]).arg(optional))); - SimpleSPARQLQuery::ResultList paramResults = paramQuery.execute(); + SimpleSPARQLQuery::ResultList results = query.execute(); - if (!paramQuery.isOK()) { - m_errorString = paramQuery.getErrorString(); + if (!query.isOK()) { + m_errorString = query.getErrorString(); return transforms; } - if (paramQuery.wasCancelled()) { - m_errorString = "Query cancelled"; - return transforms; - } + if (results.empty()) continue; - for (int j = 0; j < paramResults.size(); ++j) { + for (int j = 0; j < results.size(); ++j) { - QString paramId = paramResults[j]["param_id"].value; - QString paramValue = paramResults[j]["param_value"].value; + QString transformUri = results[j]["transform"].value; + + if (uriTransformMap.find(transformUri) == uriTransformMap.end()) { + cerr << "RDFTransformFactory: ERROR: Transform URI <" + << transformUri.toStdString() << "> not found in internal map!" << endl; + continue; + } - if (paramId == "" || paramValue == "") continue; + Transform &transform = uriTransformMap[transformUri]; + const SimpleSPARQLQuery::Value &v = results[j][optional]; - transform.setParameter(paramId, paramValue.toFloat()); + if (v.type == SimpleSPARQLQuery::LiteralValue) { + + if (optional == "program") { + transform.setProgram(v.value); + } else if (optional == "step_size") { + transform.setStepSize(v.value.toUInt()); + } else if (optional == "block_size") { + transform.setBlockSize(v.value.toUInt()); + } else if (optional == "window_type") { + cerr << "NOTE: can't handle window type yet (value is \"" + << v.value.toStdString() << "\")" << endl; + } else if (optional == "sample_rate") { + transform.setSampleRate(v.value.toFloat()); + } else if (optional == "start") { + transform.setStartTime + (RealTime::fromXsdDuration(v.value.toStdString())); + } else if (optional == "duration") { + transform.setDuration + (RealTime::fromXsdDuration(v.value.toStdString())); + } else { + cerr << "RDFTransformFactory: ERROR: Inconsistent optionals lists (unexpected optional \"" << optional.toStdString() << "\"" << endl; + } + } } + } + for (std::map<QString, Transform>::iterator i = uriTransformMap.begin(); + i != uriTransformMap.end(); ++i) { + + Transform &transform = i->second; + cerr << "RDFTransformFactory: NOTE: Transform is: " << endl; cerr << transform.toXmlString().toStdString() << endl; @@ -256,3 +271,99 @@ return transforms; } +bool +RDFTransformFactoryImpl::setOutput(Transform &transform, + QString transformUri, + QString pluginDescriptionURL) +{ + SimpleSPARQLQuery outputQuery + (QString + ( + " PREFIX vamp: <http://purl.org/ontology/vamp/> " + + " SELECT ?output_id " + + " FROM <%1> " + " FROM <%2> " + + " WHERE { " + " <%3> vamp:output ?output . " + " ?output vamp:identifier ?output_id " + " } " + ) + .arg(m_urlString) + .arg(pluginDescriptionURL) + .arg(transformUri)); + + SimpleSPARQLQuery::ResultList outputResults = outputQuery.execute(); + + if (!outputQuery.isOK()) { + m_errorString = outputQuery.getErrorString(); + return false; + } + + if (outputQuery.wasCancelled()) { + m_errorString = "Query cancelled"; + return false; + } + + for (int j = 0; j < outputResults.size(); ++j) { + QString outputId = outputResults[j]["output_id"].value; + transform.setOutput(outputId); + } + + return true; +} + + +bool +RDFTransformFactoryImpl::setParameters(Transform &transform, + QString transformUri, + QString pluginDescriptionURL) +{ + SimpleSPARQLQuery paramQuery + (QString + ( + " PREFIX vamp: <http://purl.org/ontology/vamp/> " + + " SELECT ?param_id ?param_value " + + " FROM <%1> " + " FROM <%2> " + + " WHERE { " + " <%3> vamp:parameter_binding ?binding . " + " ?binding vamp:parameter ?param ; " + " vamp:value ?param_value . " + " ?param vamp:identifier ?param_id " + " } " + ) + .arg(m_urlString) + .arg(pluginDescriptionURL) + .arg(transformUri)); + + SimpleSPARQLQuery::ResultList paramResults = paramQuery.execute(); + + if (!paramQuery.isOK()) { + m_errorString = paramQuery.getErrorString(); + return false; + } + + if (paramQuery.wasCancelled()) { + m_errorString = "Query cancelled"; + return false; + } + + for (int j = 0; j < paramResults.size(); ++j) { + + QString paramId = paramResults[j]["param_id"].value; + QString paramValue = paramResults[j]["param_value"].value; + + if (paramId == "" || paramValue == "") continue; + + transform.setParameter(paramId, paramValue.toFloat()); + } + + return true; +} + Modified: sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.cpp =================================================================== --- sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.cpp 2008-09-18 12:09:32 UTC (rev 1204) +++ sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.cpp 2008-09-18 12:33:30 UTC (rev 1205) @@ -16,13 +16,31 @@ #include "SimpleSPARQLQuery.h" #include "base/ProgressReporter.h" +#ifdef USE_NEW_RASQAL_API +#include <rasqal/rasqal.h> +#else #include <rasqal.h> +#endif #include <iostream> using std::cerr; using std::endl; +#ifdef USE_NEW_RASQAL_API +class WrasqalWorldWrapper // wrong but wromantic, etc +{ +public: + WrasqalWorldWrapper() : m_world(rasqal_new_world()) { } + ~WrasqalWorldWrapper() { rasqal_free_world(m_world); } + + rasqal_world *getWorld() const { return m_world; } + +private: + rasqal_world *m_world; +}; +#endif + class SimpleSPARQLQuery::Impl { public: @@ -40,7 +58,11 @@ protected: static void errorHandler(void *, raptor_locator *, const char *); +#ifdef USE_NEW_RASQAL_API + static WrasqalWorldWrapper m_www; +#else static bool m_initialised; +#endif QString m_query; QString m_errorString; @@ -48,6 +70,14 @@ bool m_cancelled; }; +#ifdef USE_NEW_RASQAL_API +WrasqalWorldWrapper +SimpleSPARQLQuery::Impl::m_www; +#else +bool +SimpleSPARQLQuery::Impl::m_initialised = false; +#endif + SimpleSPARQLQuery::SimpleSPARQLQuery(QString query) : m_impl(new Impl(query)) { } @@ -86,23 +116,15 @@ return m_impl->getErrorString(); } -bool -SimpleSPARQLQuery::Impl::m_initialised = false; - SimpleSPARQLQuery::Impl::Impl(QString query) : m_query(query), m_reporter(0), m_cancelled(false) { - //!!! fortunately this global stuff goes away in future rasqal versions - if (!m_initialised) { - rasqal_init(); - } } SimpleSPARQLQuery::Impl::~Impl() { -//!!! rasqal_finish(); } bool @@ -138,7 +160,15 @@ { ResultList list; +#ifdef USE_NEW_RASQAL_API + rasqal_query *query = rasqal_new_query(m_www.getWorld(), "sparql", NULL); +#else + if (!m_initialised) { + m_initialised = true; + rasqal_init(); + } rasqal_query *query = rasqal_new_query("sparql", NULL); +#endif if (!query) { m_errorString = "Failed to construct query"; cerr << "SimpleSPARQLQuery: ERROR: " << m_errorString.toStdString() << endl; @@ -232,4 +262,28 @@ return list; } - + +SimpleSPARQLQuery::Value +SimpleSPARQLQuery::singleResultQuery(QString query, QString binding) +{ + SimpleSPARQLQuery q(query); + ResultList results = q.execute(); + if (!q.isOK()) { + cerr << "SimpleSPARQLQuery::singleResultQuery: ERROR: " + << q.getErrorString().toStdString() << endl; + return Value(); + } + if (results.empty()) { + return Value(); + } + for (int i = 0; i < results.size(); ++i) { + if (results[i].find(binding) != results[i].end() && + results[i][binding].type != NoValue) { + return results[i][binding]; + } + } + return Value(); +} + + + Modified: sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.h =================================================================== --- sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.h 2008-09-18 12:09:32 UTC (rev 1204) +++ sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.h 2008-09-18 12:33:30 UTC (rev 1205) @@ -48,6 +48,10 @@ bool isOK() const; QString getErrorString() const; + // Do a query and return the value for the given binding, from the + // first result that has a value for it + static Value singleResultQuery(QString query, QString binding); + protected: class Impl; Impl *m_impl; Modified: sonic-visualiser/trunk/rdf/rdf.pro =================================================================== --- sonic-visualiser/trunk/rdf/rdf.pro 2008-09-18 12:09:32 UTC (rev 1204) +++ sonic-visualiser/trunk/rdf/rdf.pro 2008-09-18 12:33:30 UTC (rev 1205) @@ -1,6 +1,6 @@ TEMPLATE = lib -SV_UNIT_PACKAGES = redland +SV_UNIT_PACKAGES = rasqal raptor load(../sv.prf) CONFIG += sv staticlib qt thread warn_on stl rtti exceptions Modified: sonic-visualiser/trunk/sv/main/main.cpp =================================================================== --- sonic-visualiser/trunk/sv/main/main.cpp 2008-09-18 12:09:32 UTC (rev 1204) +++ sonic-visualiser/trunk/sv/main/main.cpp 2008-09-18 12:33:30 UTC (rev 1205) @@ -358,9 +358,15 @@ } } if (status == MainWindow::FileOpenFailed) { + splash.hide(); QMessageBox::critical (gui, QMessageBox::tr("Failed to open file"), QMessageBox::tr("File or URL \"%1\" could not be opened").arg(path)); + } else if (status == MainWindow::FileOpenWrongMode) { + splash.hide(); + QMessageBox::critical + (gui, QMessageBox::tr("Failed to open file"), + QMessageBox::tr("<b>Audio required</b><p>Please load at least one audio file before importing annotation data")); } } Modified: sonic-visualiser/trunk/sv/sv.pro =================================================================== --- sonic-visualiser/trunk/sv/sv.pro 2008-09-18 12:09:32 UTC (rev 1204) +++ sonic-visualiser/trunk/sv/sv.pro 2008-09-18 12:33:30 UTC (rev 1205) @@ -1,7 +1,8 @@ TEMPLATE = app -SV_UNIT_PACKAGES = vamp vamp-hostsdk rubberband fftw3 fftw3f samplerate jack libpulse portaudio-2.0 mad id3tag oggz fishsound lrdf sndfile liblo redland +SV_UNIT_PACKAGES = vamp vamp-hostsdk rubberband fftw3 fftw3f samplerate jack libpulse portaudio-2.0 mad id3tag oggz fishsound lrdf rasqal raptor sndfile liblo + load(../sv.prf) CONFIG += sv qt thread warn_on stl rtti exceptions Modified: sonic-visualiser/trunk/sv.prf =================================================================== --- sonic-visualiser/trunk/sv.prf 2008-09-18 12:09:32 UTC (rev 1204) +++ sonic-visualiser/trunk/sv.prf 2008-09-18 12:33:30 UTC (rev 1205) @@ -26,11 +26,15 @@ linux-g++:DEFINES += BUILD_STATIC +#LIBPATH += /usr/local/lib +#INCLUDEPATH += /usr/local/include + + # These are testable on platforms with pkg-config. If you don't have # pkg-config, edit the "If you don't have pkg-config" block below (see # comments). # -PKGCONFIG_PACKAGES = vamp vamp-hostsdk oggz fishsound mad id3tag rubberband fftw3 fftw3f sndfile samplerate lrdf portaudio-2.0 libpulse jack liblo redland +PKGCONFIG_PACKAGES = vamp vamp-hostsdk oggz fishsound mad id3tag rubberband fftw3 fftw3f sndfile samplerate lrdf rasqal raptor portaudio-2.0 libpulse jack liblo # No pkg-config test for the bzip2 library. This library is required. @@ -83,18 +87,18 @@ DEFINES += HAVE_SNDFILE # Required -- to import and export .wav files DEFINES += HAVE_SAMPLERATE # Required -- for resampling DEFINES += HAVE_RUBBERBAND # Required -- for time stretching - DEFINES += HAVE_REDLAND # Required -- for RDF + DEFINES += HAVE_RASQAL # Required -- for RDF # INCLUDEPATH += ../../vamp-plugin-sdk LIBPATH += ../../vamp-plugin-sdk/vamp-sdk # - LIBS += -lvamp-hostsdk -lsndfile -lrubberband -lrdf -lsamplerate + LIBS += -lvamp-hostsdk -lsndfile -lrubberband -lrasqal -lraptor -lsamplerate } ##!!! - DEFINES += HAVE_REDLAND # Required -- for RDF - LIBS += -lrdf +# DEFINES += HAVE_RASQAL # Required -- for RDF +# LIBS += -lrasqal -lraptor ### ### END CONFIGURABLE STUFF @@ -185,7 +189,7 @@ contains(SV_UNIT_PACKAGES, sndfile):!contains(DEFINES, HAVE_SNDFILE):error("sndfile library required") contains(SV_UNIT_PACKAGES, samplerate):!contains(DEFINES, HAVE_SAMPLERATE):error("libsamplerate required") contains(SV_UNIT_PACKAGES, rubberband):!contains(DEFINES, HAVE_RUBBERBAND):error("Rubber Band library required") -contains(SV_UNIT_PACKAGES, redland):!contains(DEFINES, HAVE_REDLAND):error("Redland RDF library required") +contains(SV_UNIT_PACKAGES, redland):!contains(DEFINES, HAVE_RASQAL):error("Rasqal RDF query library required") VERSION_CFLAGS += -D"'"SVNREV='"'$$system(svnversion -n .)'"'"'" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-09-22 15:44:16
|
Revision: 1215 http://sv1.svn.sourceforge.net/sv1/?rev=1215&view=rev Author: cannam Date: 2008-09-22 15:44:03 +0000 (Mon, 22 Sep 2008) Log Message: ----------- * Add beginnings of transform-search-by-text function Modified Paths: -------------- sonic-visualiser/trunk/layer/RegionLayer.cpp sonic-visualiser/trunk/sv/main/MainWindow.cpp sonic-visualiser/trunk/sv/main/MainWindow.h sonic-visualiser/trunk/transform/TransformDescription.h sonic-visualiser/trunk/transform/TransformFactory.cpp sonic-visualiser/trunk/transform/TransformFactory.h Modified: sonic-visualiser/trunk/layer/RegionLayer.cpp =================================================================== --- sonic-visualiser/trunk/layer/RegionLayer.cpp 2008-09-22 13:06:01 UTC (rev 1214) +++ sonic-visualiser/trunk/layer/RegionLayer.cpp 2008-09-22 15:44:03 UTC (rev 1215) @@ -26,8 +26,6 @@ #include "widgets/ItemEditDialog.h" -#include "SpectrogramLayer.h" // for optional frequency alignment - #include <QPainter> #include <QPainterPath> #include <QMouseEvent> Modified: sonic-visualiser/trunk/sv/main/MainWindow.cpp =================================================================== --- sonic-visualiser/trunk/sv/main/MainWindow.cpp 2008-09-22 13:06:01 UTC (rev 1214) +++ sonic-visualiser/trunk/sv/main/MainWindow.cpp 2008-09-22 15:44:03 UTC (rev 1215) @@ -1217,11 +1217,37 @@ } else { m_transformsMenu = menuBar()->addMenu(tr("&Transform")); m_transformsMenu->setTearOffEnabled(true); - } + } TransformList transforms = TransformFactory::getInstance()->getAllTransformDescriptions(); - +/*!!! + std::cerr << "Testing transform search..." << std::endl; + QStringList terms; + terms << "onset"; + terms << "detector"; + TransformFactory::SearchResults results = TransformFactory::getInstance()-> + search(terms); + std::cerr << results.size() << " result(s)..." << std::endl; + int i = 0; + std::set<TransformFactory::Match> sortedResults; + for (TransformFactory::SearchResults::const_iterator j = + results.begin(); + j != results.end(); ++j) { + sortedResults.insert(j->second); + } + for (std::set<TransformFactory::Match>::const_iterator j = + sortedResults.begin(); + j != sortedResults.end(); ++j) { + std::cerr << i << ": " << j->transform.toStdString() + << ": "; + for (int k = 0; k < j->fragments.size(); ++k) { + std::cerr << j->fragments[k].toStdString() << " "; + } + std::cerr << "(" << j->score << ")" << std::endl; + ++i; + } +*/ vector<QString> types = TransformFactory::getInstance()->getAllTransformTypes(); @@ -1239,6 +1265,13 @@ connect(&m_recentTransforms, SIGNAL(recentChanged()), this, SLOT(setupRecentTransformsMenu())); + QAction *action = new QAction(tr("Find Transform..."), this); + action->setStatusTip(tr("Search for a transform by name or description")); + connect(action, SIGNAL(triggered()), this, SLOT(findTransform())); + connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); + m_transformsMenu->addAction(action); + m_rightButtonTransformsMenu->addAction(action); + m_transformsMenu->addSeparator(); m_rightButtonTransformsMenu->addSeparator(); @@ -1375,7 +1408,7 @@ m_transformActionsReverse[transforms[i].identifier] = action; connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); - action->setStatusTip(transforms[i].description); + action->setStatusTip(transforms[i].longDescription); if (categoryMenus[type].find(category) == categoryMenus[type].end()) { std::cerr << "WARNING: MainWindow::setupMenus: Internal error: " @@ -1399,7 +1432,7 @@ connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); m_transformActions[action] = transforms[i].identifier; connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); - action->setStatusTip(transforms[i].description); + action->setStatusTip(transforms[i].longDescription); // cerr << "Transform: \"" << name.toStdString() << "\": plugin name \"" << pluginName.toStdString() << "\"" << endl; @@ -3062,6 +3095,12 @@ } void +MainWindow::findTransform() +{ + //!!! implement me! +} + +void MainWindow::playSoloToggled() { MainWindowBase::playSoloToggled(); Modified: sonic-visualiser/trunk/sv/main/MainWindow.h =================================================================== --- sonic-visualiser/trunk/sv/main/MainWindow.h 2008-09-22 13:06:01 UTC (rev 1214) +++ sonic-visualiser/trunk/sv/main/MainWindow.h 2008-09-22 15:44:03 UTC (rev 1215) @@ -128,6 +128,8 @@ virtual void addLayer(); virtual void renameCurrentLayer(); + virtual void findTransform(); + virtual void paneAdded(Pane *); virtual void paneHidden(Pane *); virtual void paneAboutToBeDeleted(Pane *); Modified: sonic-visualiser/trunk/transform/TransformDescription.h =================================================================== --- sonic-visualiser/trunk/transform/TransformDescription.h 2008-09-22 13:06:01 UTC (rev 1214) +++ sonic-visualiser/trunk/transform/TransformDescription.h 2008-09-22 15:44:03 UTC (rev 1215) @@ -49,10 +49,12 @@ TransformDescription(QString _type, QString _category, TransformId _identifier, QString _name, QString _friendlyName, QString _description, + QString _longDescription, QString _maker, QString _units, bool _configurable) : type(_type), category(_category), identifier(_identifier), name(_name), friendlyName(_friendlyName), description(_description), + longDescription(_longDescription), maker(_maker), units(_units), configurable(_configurable) { } QString type; // e.g. feature extraction plugin @@ -61,6 +63,7 @@ QString name; // plugin's name if 1 output, else "name: output" QString friendlyName; // short text for layer name QString description; // sentence describing transform + QString longDescription; // description "using" plugin name "by" maker QString maker; QString units; bool configurable; Modified: sonic-visualiser/trunk/transform/TransformFactory.cpp =================================================================== --- sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-09-22 13:06:01 UTC (rev 1214) +++ sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-09-22 15:44:03 UTC (rev 1215) @@ -30,6 +30,9 @@ #include <QRegExp> #include <QTextStream> +using std::cerr; +using std::endl; + TransformFactory * TransformFactory::m_instance = new TransformFactory; @@ -51,14 +54,14 @@ std::set<TransformDescription> dset; for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); i != m_transforms.end(); ++i) { -// std::cerr << "inserting transform into set: id = " << i->second.identifier.toStdString() << std::endl; +// cerr << "inserting transform into set: id = " << i->second.identifier.toStdString() << endl; dset.insert(i->second); } TransformList list; for (std::set<TransformDescription>::const_iterator i = dset.begin(); i != dset.end(); ++i) { -// std::cerr << "inserting transform into list: id = " << i->identifier.toStdString() << std::endl; +// cerr << "inserting transform into list: id = " << i->identifier.toStdString() << endl; list.push_back(*i); } @@ -227,7 +230,7 @@ FeatureExtractionPluginFactory::instanceFor(pluginId); if (!factory) { - std::cerr << "WARNING: TransformFactory::populateTransforms: No feature extraction plugin factory for instance " << pluginId.toLocal8Bit().data() << std::endl; + cerr << "WARNING: TransformFactory::populateTransforms: No feature extraction plugin factory for instance " << pluginId.toLocal8Bit().data() << endl; continue; } @@ -235,7 +238,7 @@ factory->instantiatePlugin(pluginId, 44100); if (!plugin) { - std::cerr << "WARNING: TransformFactory::populateTransforms: Failed to instantiate plugin " << pluginId.toLocal8Bit().data() << std::endl; + cerr << "WARNING: TransformFactory::populateTransforms: Failed to instantiate plugin " << pluginId.toLocal8Bit().data() << endl; continue; } @@ -257,21 +260,23 @@ QString maker = plugin->getMaker().c_str(); if (maker == "") maker = tr("<unknown maker>"); - if (description == "") { + QString longDescription = description; + + if (longDescription == "") { if (outputs.size() == 1) { - description = tr("Extract features using \"%1\" plugin (from %2)") + longDescription = tr("Extract features using \"%1\" plugin (from %2)") .arg(pluginName).arg(maker); } else { - description = tr("Extract features using \"%1\" output of \"%2\" plugin (from %3)") + longDescription = tr("Extract features using \"%1\" output of \"%2\" plugin (from %3)") .arg(outputs[j].name.c_str()).arg(pluginName).arg(maker); } } else { if (outputs.size() == 1) { - description = tr("%1 using \"%2\" plugin (from %3)") - .arg(description).arg(pluginName).arg(maker); + longDescription = tr("%1 using \"%2\" plugin (from %3)") + .arg(longDescription).arg(pluginName).arg(maker); } else { - description = tr("%1 using \"%2\" output of \"%3\" plugin (from %4)") - .arg(description).arg(outputs[j].name.c_str()).arg(pluginName).arg(maker); + longDescription = tr("%1 using \"%2\" output of \"%3\" plugin (from %4)") + .arg(longDescription).arg(outputs[j].name.c_str()).arg(pluginName).arg(maker); } } @@ -288,7 +293,7 @@ bool configurable = (!plugin->getPrograms().empty() || !plugin->getParameterDescriptors().empty()); -// std::cerr << "Feature extraction plugin transform: " << transformId.toStdString() << " friendly name: " << friendlyName.toStdString() << std::endl; +// cerr << "Feature extraction plugin transform: " << transformId.toStdString() << " friendly name: " << friendlyName.toStdString() << endl; transforms[transformId] = TransformDescription(tr("Analysis"), @@ -297,6 +302,7 @@ userName, friendlyName, description, + longDescription, maker, units, configurable); @@ -322,7 +328,7 @@ RealTimePluginFactory::instanceFor(pluginId); if (!factory) { - std::cerr << "WARNING: TransformFactory::populateTransforms: No real time plugin factory for instance " << pluginId.toLocal8Bit().data() << std::endl; + cerr << "WARNING: TransformFactory::populateTransforms: No real time plugin factory for instance " << pluginId.toLocal8Bit().data() << endl; continue; } @@ -330,14 +336,14 @@ factory->getPluginDescriptor(pluginId); if (!descriptor) { - std::cerr << "WARNING: TransformFactory::populateTransforms: Failed to query plugin " << pluginId.toLocal8Bit().data() << std::endl; + cerr << "WARNING: TransformFactory::populateTransforms: Failed to query plugin " << pluginId.toLocal8Bit().data() << endl; continue; } //!!! if (descriptor->controlOutputPortCount == 0 || // descriptor->audioInputPortCount == 0) continue; -// std::cout << "TransformFactory::populateRealTimePlugins: plugin " << pluginId.toStdString() << " has " << descriptor->controlOutputPortCount << " control output ports, " << descriptor->audioOutputPortCount << " audio outputs, " << descriptor->audioInputPortCount << " audio inputs" << std::endl; +// std::cout << "TransformFactory::populateRealTimePlugins: plugin " << pluginId.toStdString() << " has " << descriptor->controlOutputPortCount << " control output ports, " << descriptor->audioOutputPortCount << " audio outputs, " << descriptor->audioInputPortCount << " audio inputs" << endl; QString pluginName = descriptor->name.c_str(); QString category = factory->getPluginCategory(pluginId); @@ -398,6 +404,7 @@ transformId, userName, userName, + "", description, maker, units, @@ -429,6 +436,7 @@ transformId, pluginName, pluginName, + "", description, maker, "", @@ -506,15 +514,15 @@ { Vamp::Plugin *vp = dynamic_cast<Vamp::Plugin *>(plugin); if (!vp) { -// std::cerr << "makeConsistentWithPlugin: not a Vamp::Plugin" << std::endl; +// cerr << "makeConsistentWithPlugin: not a Vamp::Plugin" << endl; vp = dynamic_cast<Vamp::PluginHostAdapter *>(plugin); //!!! why? } if (!vp) { -// std::cerr << "makeConsistentWithPlugin: not a Vamp::PluginHostAdapter" << std::endl; +// cerr << "makeConsistentWithPlugin: not a Vamp::PluginHostAdapter" << endl; vp = dynamic_cast<Vamp::HostExt::PluginWrapper *>(plugin); //!!! no, I mean really why? } if (!vp) { -// std::cerr << "makeConsistentWithPlugin: not a Vamp::HostExt::PluginWrapper" << std::endl; +// cerr << "makeConsistentWithPlugin: not a Vamp::HostExt::PluginWrapper" << endl; } return vp; } @@ -727,10 +735,10 @@ } if (!transform.getStepSize()) { if (domain == Vamp::Plugin::FrequencyDomain) { -// std::cerr << "frequency domain, step = " << blockSize/2 << std::endl; +// cerr << "frequency domain, step = " << blockSize/2 << endl; transform.setStepSize(transform.getBlockSize()/2); } else { -// std::cerr << "time domain, step = " << blockSize/2 << std::endl; +// cerr << "time domain, step = " << blockSize/2 << endl; transform.setStepSize(transform.getBlockSize()); } } @@ -745,9 +753,9 @@ Vamp::PluginBase *plugin = instantiateDefaultPluginFor (t.getIdentifier(), 0); if (!plugin) { - std::cerr << "TransformFactory::getPluginConfigurationXml: " + cerr << "TransformFactory::getPluginConfigurationXml: " << "Unable to instantiate plugin for transform \"" - << t.getIdentifier().toStdString() << "\"" << std::endl; + << t.getIdentifier().toStdString() << "\"" << endl; return xml; } @@ -767,9 +775,9 @@ Vamp::PluginBase *plugin = instantiateDefaultPluginFor (t.getIdentifier(), 0); if (!plugin) { - std::cerr << "TransformFactory::setParametersFromPluginConfigurationXml: " + cerr << "TransformFactory::setParametersFromPluginConfigurationXml: " << "Unable to instantiate plugin for transform \"" - << t.getIdentifier().toStdString() << "\"" << std::endl; + << t.getIdentifier().toStdString() << "\"" << endl; return; } @@ -777,4 +785,137 @@ setParametersFromPlugin(t, plugin); delete plugin; } +/* +TransformFactory::SearchResults +TransformFactory::search(QStringList keywords) +{ + SearchResults results; + SearchResults partial; + for (int i = 0; i < keywords.size(); ++i) { + partial = search(keywords[i]); + for (SearchResults::const_iterator j = partial.begin(); + j != partial.end(); ++j) { + if (results.find(j->first) == results.end()) { + results[j->first] = j->second; + } else { + results[j->first].score += j->second.score; + results[j->first].fragments << j->second.fragments; + } + } + } + return results; +} +*/ +TransformFactory::SearchResults +TransformFactory::search(QString keyword) +{ + QStringList keywords; + keywords << keyword; + return search(keywords); +} + +TransformFactory::SearchResults +TransformFactory::search(QStringList keywords) +{ + if (m_transforms.empty()) populateTransforms(); + + SearchResults results; + + for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); + i != m_transforms.end(); ++i) { + + Match match; + + match.transform = i->first; + + searchTest(match, keywords, i->second.type, tr("Plugin type"), 10); + searchTest(match, keywords, i->second.category, tr("Category"), 20); + searchTest(match, keywords, i->second.identifier, tr("System Identifier"), 5); + searchTest(match, keywords, i->second.name, tr("Name"), 30); + searchTest(match, keywords, i->second.description, tr("Description"), 20); + searchTest(match, keywords, i->second.maker, tr("Maker"), 10); + searchTest(match, keywords, i->second.units, tr("Units"), 10); + + if (match.score > 0) results[i->first] = match; + } + + return results; +} + +void +TransformFactory::searchTest(Match &match, QStringList keywords, QString text, + QString textType, int score) +{ +/* + if (text.toLower() == keyword.toLower()) { + match.score += score * 1.5; + match.fragments << tr("%1: <b>%2</b>").arg(textType).arg(text); + return; + } +*/ + int len = text.length(); + int prevEnd = 0; + QString fragment; + + while (1) { + + bool first = (prevEnd == 0); + + int idx = -1; + QString keyword; + + for (int ki = 0; ki < keywords.size(); ++ki) { + int midx = text.indexOf(keywords[ki], prevEnd, Qt::CaseInsensitive); + if (midx >= 0 && midx < len) { + if (midx < idx || idx == -1) { + idx = midx; + keyword = keywords[ki]; + } + } + } + + if (idx < 0 || idx >= len) break; + + int klen = keyword.length(); + + if (first) { + match.score += score; + } else { + match.score += score / 4; + } + + int start = idx; + int end = start + klen; + + if (start == 0) match.score += 1; + if (end == len) match.score += 1; + + if (start > prevEnd + 14) { +// cerr << "start = " << start << ", prevEnd = " <<prevEnd << ", length = " << len << ", text = " << text.toStdString() << endl; + QString s = text.right((len - start) + 10); +// cerr << "s = " << s.toStdString() << endl; + s = s.left(10) + "<b>" + s.left(klen + 10).right(klen) + "</b>"; +// cerr << "s = " << s.toStdString() << endl; + fragment += tr("...%1").arg(s); +// cerr << "fragment = " << fragment.toStdString() << endl; + } else { + QString s = text.right(len - prevEnd); + s = s.left(start - prevEnd) + "<b>" + s.left(end - prevEnd).right(klen) + "</b>"; + fragment += s; + } + + prevEnd = end; + } + + if (prevEnd > 0 && prevEnd < len) { + int n = len - prevEnd; + fragment += text.right(n).left(n < 8 ? n : 8); + } + + if (fragment != "") { + fragment = tr("%1: %2").arg(textType).arg(fragment); + match.fragments << fragment; + } +} + Modified: sonic-visualiser/trunk/transform/TransformFactory.h =================================================================== --- sonic-visualiser/trunk/transform/TransformFactory.h 2008-09-22 13:06:01 UTC (rev 1214) +++ sonic-visualiser/trunk/transform/TransformFactory.h 2008-09-22 15:44:03 UTC (rev 1215) @@ -21,6 +21,7 @@ #include <vamp-sdk/Plugin.h> #include <QObject> +#include <QStringList> #include <map> #include <set> @@ -41,6 +42,38 @@ std::vector<QString> getTransformCategories(QString transformType); std::vector<QString> getTransformMakers(QString transformType); + struct Match + { + TransformId transform; + int score; + QStringList fragments; + + Match() : score(0) { } + Match(const Match &m) : transform(m.transform), + score(m.score), fragments(m.fragments) { } + + bool operator<(const Match &m) { + if (score != m.score) { + return score < m.score; + } else if (transform != m.transform) { + return transform < m.transform; + } else if (fragments.size() != m.fragments.size()) { + return fragments.size() < m.fragments.size(); + } else { + for (int i = 0; i < fragments.size(); ++i) { + if (fragments[i] != m.fragments[i]) { + return fragments[i] < m.fragments[i]; + } + } + } + return false; + } + }; + + typedef std::map<TransformId, Match> SearchResults; + SearchResults search(QString keyword); + SearchResults search(QStringList keywords); + /** * Return true if the given transform is known. */ @@ -165,6 +198,9 @@ void populateFeatureExtractionPlugins(TransformDescriptionMap &); void populateRealTimePlugins(TransformDescriptionMap &); + void searchTest(Match &match, QStringList keywords, QString text, + QString textType, int score); + Vamp::PluginBase *instantiateDefaultPluginFor(TransformId id, size_t rate); static TransformFactory *m_instance; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-09-23 13:39:36
|
Revision: 1217 http://sv1.svn.sourceforge.net/sv1/?rev=1217&view=rev Author: cannam Date: 2008-09-23 13:39:25 +0000 (Tue, 23 Sep 2008) Log Message: ----------- * Start work on TransformFinder dialog Modified Paths: -------------- sonic-visualiser/trunk/sv/main/MainWindow.cpp sonic-visualiser/trunk/sv.prf sonic-visualiser/trunk/transform/TransformFactory.cpp sonic-visualiser/trunk/transform/TransformFactory.h sonic-visualiser/trunk/widgets/widgets.pro Added Paths: ----------- sonic-visualiser/trunk/widgets/TransformFinder.cpp sonic-visualiser/trunk/widgets/TransformFinder.h Modified: sonic-visualiser/trunk/sv/main/MainWindow.cpp =================================================================== --- sonic-visualiser/trunk/sv/main/MainWindow.cpp 2008-09-22 15:46:37 UTC (rev 1216) +++ sonic-visualiser/trunk/sv/main/MainWindow.cpp 2008-09-23 13:39:25 UTC (rev 1217) @@ -47,6 +47,7 @@ #include "widgets/SubdividingMenu.h" #include "widgets/NotifyingPushButton.h" #include "widgets/KeyReference.h" +#include "widgets/TransformFinder.h" #include "widgets/LabelCounterInputDialog.h" #include "audioio/AudioCallbackPlaySource.h" #include "audioio/AudioCallbackPlayTarget.h" @@ -1241,8 +1242,11 @@ j != sortedResults.end(); ++j) { std::cerr << i << ": " << j->transform.toStdString() << ": "; - for (int k = 0; k < j->fragments.size(); ++k) { - std::cerr << j->fragments[k].toStdString() << " "; + for (TransformFactory::Match::FragmentMap::const_iterator k = + j->fragments.begin(); + k != j->fragments.end(); ++k) { + std::cerr << k->first.toStdString() << ": " + << k->second.toStdString() << " "; } std::cerr << "(" << j->score << ")" << std::endl; ++i; @@ -1265,13 +1269,6 @@ connect(&m_recentTransforms, SIGNAL(recentChanged()), this, SLOT(setupRecentTransformsMenu())); - QAction *action = new QAction(tr("Find Transform..."), this); - action->setStatusTip(tr("Search for a transform by name or description")); - connect(action, SIGNAL(triggered()), this, SLOT(findTransform())); - connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); - m_transformsMenu->addAction(action); - m_rightButtonTransformsMenu->addAction(action); - m_transformsMenu->addSeparator(); m_rightButtonTransformsMenu->addSeparator(); @@ -1464,6 +1461,16 @@ (*i)->entriesAdded(); } + m_transformsMenu->addSeparator(); + m_rightButtonTransformsMenu->addSeparator(); + + QAction *action = new QAction(tr("Find a Transform..."), this); + action->setStatusTip(tr("Search for a transform from the installed plugins, by name or description")); + connect(action, SIGNAL(triggered()), this, SLOT(findTransform())); + connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); + m_transformsMenu->addAction(action); + m_rightButtonTransformsMenu->addAction(action); + setupRecentTransformsMenu(); } @@ -3097,7 +3104,12 @@ void MainWindow::findTransform() { - //!!! implement me! + TransformFinder finder(this); + if (finder.exec()) { + std::cerr << "Yes! transform is " << finder.getTransform().toStdString() << std::endl; + } else { + std::cerr << "No" << std::endl; + } } void Modified: sonic-visualiser/trunk/sv.prf =================================================================== --- sonic-visualiser/trunk/sv.prf 2008-09-22 15:46:37 UTC (rev 1216) +++ sonic-visualiser/trunk/sv.prf 2008-09-23 13:39:25 UTC (rev 1217) @@ -3,9 +3,13 @@ ### BEGIN CONFIGURABLE STUFF ### -CONFIG += debug +CONFIG += release +# Temporarily +DEFINES += USE_NEW_RASQAL_API + + # Put your favourite optimization flags here. # # Don't use -ffast-math -- it does make things faster, but it Modified: sonic-visualiser/trunk/transform/TransformFactory.cpp =================================================================== --- sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-09-22 15:46:37 UTC (rev 1216) +++ sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-09-23 13:39:25 UTC (rev 1217) @@ -914,8 +914,31 @@ } if (fragment != "") { - fragment = tr("%1: %2").arg(textType).arg(fragment); - match.fragments << fragment; + match.fragments[textType] = fragment; } } +bool +TransformFactory::Match::operator<(const Match &m) const +{ + if (score != m.score) { + return score < m.score; + } + if (transform != m.transform) { + return transform < m.transform; + } + if (fragments.size() != m.fragments.size()) { + return fragments.size() < m.fragments.size(); + } + + for (FragmentMap::const_iterator + i = fragments.begin(), + j = m.fragments.begin(); + i != fragments.end(); ++i, ++j) { + if (i->first != j->first) return i->first < j->first; + if (i->second != j->second) return i->second < j->second; + } + + return false; +} + Modified: sonic-visualiser/trunk/transform/TransformFactory.h =================================================================== --- sonic-visualiser/trunk/transform/TransformFactory.h 2008-09-22 15:46:37 UTC (rev 1216) +++ sonic-visualiser/trunk/transform/TransformFactory.h 2008-09-23 13:39:25 UTC (rev 1217) @@ -46,28 +46,14 @@ { TransformId transform; int score; - QStringList fragments; + typedef std::map<QString, QString> FragmentMap; + FragmentMap fragments; Match() : score(0) { } - Match(const Match &m) : transform(m.transform), - score(m.score), fragments(m.fragments) { } + Match(const Match &m) : + transform(m.transform), score(m.score), fragments(m.fragments) { } - bool operator<(const Match &m) { - if (score != m.score) { - return score < m.score; - } else if (transform != m.transform) { - return transform < m.transform; - } else if (fragments.size() != m.fragments.size()) { - return fragments.size() < m.fragments.size(); - } else { - for (int i = 0; i < fragments.size(); ++i) { - if (fragments[i] != m.fragments[i]) { - return fragments[i] < m.fragments[i]; - } - } - } - return false; - } + bool operator<(const Match &m) const; }; typedef std::map<TransformId, Match> SearchResults; Added: sonic-visualiser/trunk/widgets/TransformFinder.cpp =================================================================== --- sonic-visualiser/trunk/widgets/TransformFinder.cpp (rev 0) +++ sonic-visualiser/trunk/widgets/TransformFinder.cpp 2008-09-23 13:39:25 UTC (rev 1217) @@ -0,0 +1,126 @@ +/* -*- 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 2008 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 "TransformFinder.h" + +#include "transform/TransformFactory.h" + +#include <QVBoxLayout> +#include <QGridLayout> +#include <QLineEdit> +#include <QLabel> +#include <QDialogButtonBox> +#include <QScrollArea> + +TransformFinder::TransformFinder(QWidget *parent) : + QDialog(parent) +{ + setWindowTitle(tr("Find a Transform")); + + QGridLayout *mainGrid = new QGridLayout; + setLayout(mainGrid); + + mainGrid->addWidget(new QLabel(tr("Find:")), 0, 0); + + QLineEdit *searchField = new QLineEdit; + mainGrid->addWidget(searchField, 0, 1); + connect(searchField, SIGNAL(textChanged(const QString &)), + this, SLOT(searchTextChanged(const QString &))); + + m_resultsScroll = new QScrollArea; + mainGrid->addWidget(m_resultsScroll, 1, 0, 1, 2); + mainGrid->setRowStretch(1, 10); + + QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok | + QDialogButtonBox::Cancel); + mainGrid->addWidget(bb, 2, 0, 1, 2); + connect(bb, SIGNAL(accepted()), this, SLOT(accept())); + connect(bb, SIGNAL(rejected()), this, SLOT(reject())); + + resize(500, 400); //!!! +} + +TransformFinder::~TransformFinder() +{ +} + +void +TransformFinder::searchTextChanged(const QString &text) +{ + std::cerr << "text is " << text.toStdString() << std::endl; + + QStringList keywords = text.split(' ', QString::SkipEmptyParts); + TransformFactory::SearchResults results = + TransformFactory::getInstance()->search(keywords); + + std::cerr << results.size() << " result(s)..." << std::endl; + + std::set<TransformFactory::Match> sorted; + for (TransformFactory::SearchResults::const_iterator j = results.begin(); + j != results.end(); ++j) { + sorted.insert(j->second); + } + + int i = 0; +/* + for (std::set<TransformFactory::Match>::const_iterator j = sorted.begin(); + j != sorted.end(); ++j) { + std::cerr << i++ << ": " << j->transform.toStdString() << ": "; + for (TransformFactory::Match::FragmentMap::const_iterator k = + j->fragments.begin(); + k != j->fragments.end(); ++k) { + std::cerr << k->first.toStdString() << ": " + << k->second.toStdString() << " "; + } + std::cerr << "(" << j->score << ")" << std::endl; + } +*/ + QFrame *resultsFrame = new QFrame; + QVBoxLayout *resultsLayout = new QVBoxLayout; + resultsFrame->setLayout(resultsLayout); + + i = 0; + int maxResults = 40; + + for (std::set<TransformFactory::Match>::const_iterator j = sorted.end(); + j != sorted.begin(); ) { + --j; + QString labelText; + TransformDescription desc = + TransformFactory::getInstance()->getTransformDescription(j->transform); + labelText += tr("%2<br><small>").arg(desc.name); + labelText += "..."; + for (TransformFactory::Match::FragmentMap::const_iterator k = + j->fragments.begin(); + k != j->fragments.end(); ++k) { + labelText += k->second; + labelText += "... "; + } + labelText += tr("</small>"); + resultsLayout->addWidget(new QLabel(labelText)); + if (++i == maxResults) break; + } + + QWidget *oldWidget = m_resultsScroll->takeWidget(); + m_resultsScroll->setWidget(resultsFrame); + delete oldWidget; +} + +TransformId +TransformFinder::getTransform() const +{ + return ""; +} + Added: sonic-visualiser/trunk/widgets/TransformFinder.h =================================================================== --- sonic-visualiser/trunk/widgets/TransformFinder.h (rev 0) +++ sonic-visualiser/trunk/widgets/TransformFinder.h 2008-09-23 13:39:25 UTC (rev 1217) @@ -0,0 +1,45 @@ +/* -*- 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 2008 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. +*/ + +#ifndef _TRANSFORM_FINDER_H_ +#define _TRANSFORM_FINDER_H_ + +#include <QDialog> + +#include "transform/Transform.h" + +class QVBoxLayout; +class QScrollArea; + +class TransformFinder : public QDialog +{ + Q_OBJECT + +public: + TransformFinder(QWidget *parent = 0); + ~TransformFinder(); + + TransformId getTransform() const; + +protected slots: + void searchTextChanged(const QString &); + +protected: + QScrollArea *m_resultsScroll; + QVBoxLayout *m_resultsLayout; +}; + +#endif + Modified: sonic-visualiser/trunk/widgets/widgets.pro =================================================================== --- sonic-visualiser/trunk/widgets/widgets.pro 2008-09-22 15:46:37 UTC (rev 1216) +++ sonic-visualiser/trunk/widgets/widgets.pro 2008-09-23 13:39:25 UTC (rev 1217) @@ -46,6 +46,7 @@ TextAbbrev.h \ Thumbwheel.h \ TipDialog.h \ + TransformFinder.h \ WindowShapePreview.h \ WindowTypeSelector.h SOURCES += AudioDial.cpp \ @@ -80,5 +81,6 @@ TextAbbrev.cpp \ Thumbwheel.cpp \ TipDialog.cpp \ + TransformFinder.cpp \ WindowShapePreview.cpp \ WindowTypeSelector.cpp This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-09-25 12:46:02
|
Revision: 1220 http://sv1.svn.sourceforge.net/sv1/?rev=1220&view=rev Author: cannam Date: 2008-09-25 12:44:23 +0000 (Thu, 25 Sep 2008) Log Message: ----------- * some work on transform finder Modified Paths: -------------- sonic-visualiser/trunk/transform/FeatureExtractionModelTransformer.cpp sonic-visualiser/trunk/widgets/TransformFinder.cpp sonic-visualiser/trunk/widgets/TransformFinder.h Modified: sonic-visualiser/trunk/transform/FeatureExtractionModelTransformer.cpp =================================================================== --- sonic-visualiser/trunk/transform/FeatureExtractionModelTransformer.cpp 2008-09-23 16:53:26 UTC (rev 1219) +++ sonic-visualiser/trunk/transform/FeatureExtractionModelTransformer.cpp 2008-09-25 12:44:23 UTC (rev 1220) @@ -212,6 +212,8 @@ if (binCount == 0 && (preDurationPlugin || !m_descriptor->hasDuration)) { + // Anything with no value and no duration is an instant + m_output = new SparseOneDimensionalModel(modelRate, modelResolution, false); Modified: sonic-visualiser/trunk/widgets/TransformFinder.cpp =================================================================== --- sonic-visualiser/trunk/widgets/TransformFinder.cpp 2008-09-23 16:53:26 UTC (rev 1219) +++ sonic-visualiser/trunk/widgets/TransformFinder.cpp 2008-09-25 12:44:23 UTC (rev 1220) @@ -17,13 +17,32 @@ #include "transform/TransformFactory.h" -#include <QVBoxLayout> #include <QGridLayout> +#include <QGridLayout> #include <QLineEdit> #include <QLabel> +//#include <SelectableLabel> #include <QDialogButtonBox> #include <QScrollArea> +void +SelectableLabel::setUnselectedText(QString text) +{ + setText(text); +} + +void +SelectableLabel::setSelectedText(QString text) +{ + setText(text); +} + +void +SelectableLabel::mousePressEvent(QMouseEvent *e) +{ + +} + TransformFinder::TransformFinder(QWidget *parent) : QDialog(parent), m_resultsFrame(0), @@ -94,7 +113,7 @@ std::cerr << "creating frame & layout" << std::endl; m_resultsFrame = new QWidget; // resultsFrame->setFrameStyle(QFrame::Sunken | QFrame::Box); - m_resultsLayout = new QVBoxLayout; + m_resultsLayout = new QGridLayout; m_resultsFrame->setLayout(m_resultsLayout); m_resultsScroll->setWidget(m_resultsFrame); m_resultsFrame->show(); @@ -109,9 +128,10 @@ j != sorted.begin(); ) { --j; - QString labelText; TransformDescription desc = TransformFactory::getInstance()->getTransformDescription(j->transform); + + QString labelText; labelText += tr("%2<br><small>").arg(desc.name); labelText += "..."; for (TransformFactory::Match::FragmentMap::const_iterator k = @@ -122,17 +142,37 @@ } labelText += tr("</small>"); + QString selectedText; + selectedText += tr("<b>%1</b><br>").arg(desc.name); + selectedText += tr("<small><i>%1</i></small>").arg(desc.longDescription); +/* + for (TransformFactory::Match::FragmentMap::const_iterator k = + j->fragments.begin(); + k != j->fragments.end(); ++k) { + selectedText += tr("<br><small>%1: %2</small>").arg(k->first).arg(k->second); + } +*/ + + selectedText += tr("<br><small>Plugin type: %1</small>").arg(desc.type); + selectedText += tr("<br><small>Category: %1</small>").arg(desc.category); + selectedText += tr("<br><small>System identifier: %1</small>").arg(desc.identifier); + if (i >= m_labels.size()) { - QLabel *label = new QLabel(m_resultsFrame); - label->setTextFormat(Qt::RichText); - m_resultsLayout->addWidget(label); + SelectableLabel *label = new SelectableLabel(m_resultsFrame); + m_resultsLayout->addWidget(label, i, 0); m_labels.push_back(label); } - m_labels[i]->setText(labelText); + m_labels[i]->setUnselectedText(labelText); + m_labels[i]->setSelectedText(selectedText); + +/* QSize sh = m_labels[i]->sizeHint(); std::cerr << "size hint for text \"" << labelText.toStdString() << "\" has height " << sh.height() << std::endl; height += sh.height(); if (sh.width() > width) width = sh.width(); +*/ +// m_labels[i]->resize(m_labels[i]->sizeHint()); +// m_labels[i]->updateGeometry(); m_labels[i]->show(); if (++i == maxResults) break; @@ -140,9 +180,10 @@ std::cerr << "m_labels.size() = " << m_labels.size() << ", i = " << i << ", height = " << height << std::endl; - while (i < m_labels.size()) m_labels[i++]->hide(); + for (int j = m_labels.size(); j > i; ) m_labels[--j]->hide(); - m_resultsFrame->resize(height, width); + m_resultsFrame->resize(m_resultsFrame->sizeHint()); +// m_resultsFrame->resize(height, width); } TransformId Modified: sonic-visualiser/trunk/widgets/TransformFinder.h =================================================================== --- sonic-visualiser/trunk/widgets/TransformFinder.h 2008-09-23 16:53:26 UTC (rev 1219) +++ sonic-visualiser/trunk/widgets/TransformFinder.h 2008-09-25 12:44:23 UTC (rev 1220) @@ -22,11 +22,31 @@ #include "transform/Transform.h" -class QVBoxLayout; +class QGridLayout; class QScrollArea; class QLabel; +class SelectableLabel; class QWidget; + +#include <QLabel> +class SelectableLabel : public QLabel +{ + Q_OBJECT + +public: + SelectableLabel(QWidget *parent = 0) : QLabel(parent) { + setTextFormat(Qt::RichText); + } + virtual ~SelectableLabel() { } + + void setSelectedText(QString); + void setUnselectedText(QString); + +protected: + virtual void mousePressEvent(QMouseEvent *e); +}; + class TransformFinder : public QDialog { Q_OBJECT @@ -43,8 +63,8 @@ protected: QScrollArea *m_resultsScroll; QWidget *m_resultsFrame; - QVBoxLayout *m_resultsLayout; - std::vector<QLabel *> m_labels; + QGridLayout *m_resultsLayout; + std::vector<SelectableLabel *> m_labels; }; #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-09-29 15:06:54
|
Revision: 1225 http://sv1.svn.sourceforge.net/sv1/?rev=1225&view=rev Author: cannam Date: 2008-09-29 15:06:43 +0000 (Mon, 29 Sep 2008) Log Message: ----------- * More SelectableLabel and TransformFinder tweaking Modified Paths: -------------- sonic-visualiser/trunk/sv/main/MainWindow.cpp sonic-visualiser/trunk/sv/main/MainWindow.h sonic-visualiser/trunk/sv.prf sonic-visualiser/trunk/transform/TransformFactory.cpp sonic-visualiser/trunk/transform/TransformFactory.h sonic-visualiser/trunk/widgets/TransformFinder.cpp sonic-visualiser/trunk/widgets/TransformFinder.h sonic-visualiser/trunk/widgets/widgets.pro Added Paths: ----------- sonic-visualiser/trunk/widgets/SelectableLabel.cpp sonic-visualiser/trunk/widgets/SelectableLabel.h Modified: sonic-visualiser/trunk/sv/main/MainWindow.cpp =================================================================== --- sonic-visualiser/trunk/sv/main/MainWindow.cpp 2008-09-29 11:11:42 UTC (rev 1224) +++ sonic-visualiser/trunk/sv/main/MainWindow.cpp 2008-09-29 15:06:43 UTC (rev 1225) @@ -1222,36 +1222,7 @@ TransformList transforms = TransformFactory::getInstance()->getAllTransformDescriptions(); -/*!!! - std::cerr << "Testing transform search..." << std::endl; - QStringList terms; - terms << "onset"; - terms << "detector"; - TransformFactory::SearchResults results = TransformFactory::getInstance()-> - search(terms); - std::cerr << results.size() << " result(s)..." << std::endl; - int i = 0; - std::set<TransformFactory::Match> sortedResults; - for (TransformFactory::SearchResults::const_iterator j = - results.begin(); - j != results.end(); ++j) { - sortedResults.insert(j->second); - } - for (std::set<TransformFactory::Match>::const_iterator j = - sortedResults.begin(); - j != sortedResults.end(); ++j) { - std::cerr << i << ": " << j->transform.toStdString() - << ": "; - for (TransformFactory::Match::FragmentMap::const_iterator k = - j->fragments.begin(); - k != j->fragments.end(); ++k) { - std::cerr << k->first.toStdString() << ": " - << k->second.toStdString() << " "; - } - std::cerr << "(" << j->score << ")" << std::endl; - ++i; - } -*/ + vector<QString> types = TransformFactory::getInstance()->getAllTransformTypes(); @@ -3026,6 +2997,19 @@ // change the execution context (block size etc). QString transformId = i->second; + + addLayer(transformId); +} + +void +MainWindow::addLayer(QString transformId) +{ + Pane *pane = m_paneStack->getCurrentPane(); + if (!pane) { + std::cerr << "WARNING: MainWindow::addLayer: no current pane" << std::endl; + return; + } + Transform transform = TransformFactory::getInstance()-> getDefaultTransformFor(transformId); @@ -3104,12 +3088,14 @@ void MainWindow::findTransform() { - TransformFinder finder(this); - if (finder.exec()) { - std::cerr << "Yes! transform is " << finder.getTransform().toStdString() << std::endl; - } else { - std::cerr << "No" << std::endl; + TransformFinder *finder = new TransformFinder(this); + if (!finder->exec()) { + delete finder; + return; } + TransformId transform = finder->getTransform(); + delete finder; + addLayer(transform); } void Modified: sonic-visualiser/trunk/sv/main/MainWindow.h =================================================================== --- sonic-visualiser/trunk/sv/main/MainWindow.h 2008-09-29 11:11:42 UTC (rev 1224) +++ sonic-visualiser/trunk/sv/main/MainWindow.h 2008-09-29 15:06:43 UTC (rev 1225) @@ -126,6 +126,7 @@ virtual void addPane(); virtual void addLayer(); + virtual void addLayer(QString transformId); virtual void renameCurrentLayer(); virtual void findTransform(); Modified: sonic-visualiser/trunk/sv.prf =================================================================== --- sonic-visualiser/trunk/sv.prf 2008-09-29 11:11:42 UTC (rev 1224) +++ sonic-visualiser/trunk/sv.prf 2008-09-29 15:06:43 UTC (rev 1225) @@ -3,7 +3,7 @@ ### BEGIN CONFIGURABLE STUFF ### -CONFIG += release +CONFIG += debug # Temporarily Modified: sonic-visualiser/trunk/transform/TransformFactory.cpp =================================================================== --- sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-09-29 11:11:42 UTC (rev 1224) +++ sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-09-29 15:06:43 UTC (rev 1225) @@ -24,6 +24,8 @@ #include "vamp-sdk/PluginHostAdapter.h" #include "vamp-sdk/hostext/PluginWrapper.h" +#include "base/XmlExportable.h" + #include <iostream> #include <set> @@ -892,16 +894,16 @@ if (end == len) match.score += 1; if (start > prevEnd + 14) { -// cerr << "start = " << start << ", prevEnd = " <<prevEnd << ", length = " << len << ", text = " << text.toStdString() << endl; QString s = text.right((len - start) + 10); -// cerr << "s = " << s.toStdString() << endl; - s = s.left(10) + "<b>" + s.left(klen + 10).right(klen) + "</b>"; -// cerr << "s = " << s.toStdString() << endl; + s = XmlExportable::encodeEntities(s.left(10)) + "<b>" + + XmlExportable::encodeEntities(s.left(klen + 10).right(klen)) + + "</b>"; fragment += tr("...%1").arg(s); -// cerr << "fragment = " << fragment.toStdString() << endl; } else { QString s = text.right(len - prevEnd); - s = s.left(start - prevEnd) + "<b>" + s.left(end - prevEnd).right(klen) + "</b>"; + s = XmlExportable::encodeEntities(s.left(start - prevEnd)) + "<b>" + + XmlExportable::encodeEntities(s.left(end - prevEnd).right(klen)) + + "</b>"; fragment += s; } @@ -910,7 +912,8 @@ if (prevEnd > 0 && prevEnd < len) { int n = len - prevEnd; - fragment += text.right(n).left(n < 8 ? n : 8); + fragment += + XmlExportable::encodeEntities(text.right(n).left(n < 8 ? n : 8)); } if (fragment != "") { Modified: sonic-visualiser/trunk/transform/TransformFactory.h =================================================================== --- sonic-visualiser/trunk/transform/TransformFactory.h 2008-09-29 11:11:42 UTC (rev 1224) +++ sonic-visualiser/trunk/transform/TransformFactory.h 2008-09-29 15:06:43 UTC (rev 1225) @@ -53,7 +53,7 @@ Match(const Match &m) : transform(m.transform), score(m.score), fragments(m.fragments) { } - bool operator<(const Match &m) const; + bool operator<(const Match &m) const; // sort by score first }; typedef std::map<TransformId, Match> SearchResults; Added: sonic-visualiser/trunk/widgets/SelectableLabel.cpp =================================================================== --- sonic-visualiser/trunk/widgets/SelectableLabel.cpp (rev 0) +++ sonic-visualiser/trunk/widgets/SelectableLabel.cpp 2008-09-29 15:06:43 UTC (rev 1225) @@ -0,0 +1,135 @@ +/* -*- 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 2008 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 "SelectableLabel.h" + +#include <iostream> +#include <QApplication> + +SelectableLabel::SelectableLabel(QWidget *p) : + QLabel(p), + m_selected(false) +{ + setTextFormat(Qt::RichText); +// setLineWidth(2); +// setFixedWidth(480); + setupStyle(); +} + +SelectableLabel::~SelectableLabel() +{ +} + +void +SelectableLabel::setUnselectedText(QString text) +{ + m_unselectedText = text; + if (!m_selected) { + setText(m_unselectedText); + resize(sizeHint()); + } +} + +void +SelectableLabel::setSelectedText(QString text) +{ + m_selectedText = text; + if (m_selected) { + setText(m_selectedText); + resize(sizeHint()); + } +} + +void +SelectableLabel::setupStyle() +{ + QPalette palette = QApplication::palette(); + + if (m_selected) { + setWordWrap(true); + setStyleSheet + (QString("QLabel:hover { background: %1; color: %3; } " + "QLabel:!hover { background: %2; color: %3 } " + "QLabel { padding: 7px }") + .arg(palette.button().color().name()) + .arg(palette.mid().color().light().name()) + .arg(palette.text().color().name())); + } else { + setWordWrap(false); + setStyleSheet + (QString("QLabel:hover { background: %1; color: %3; } " + "QLabel:!hover { background: %2; color: %3 } " + "QLabel { padding: 7px }") + .arg(palette.button().color().name()) + .arg(palette.light().color().name()) + .arg(palette.text().color().name())); + +// setStyleSheet("QLabel:hover { background: #e0e0e0; color: black; } QLabel:!hover { background: white; color: black } QLabel { padding: 7px }"); + } +} + +void +SelectableLabel::setSelected(bool s) +{ + if (m_selected == s) return; + m_selected = s; + if (m_selected) { + setText(m_selectedText); + } else { + setText(m_unselectedText); + } + setupStyle(); + parentWidget()->resize(parentWidget()->sizeHint()); +} + +void +SelectableLabel::toggle() +{ + setSelected(!m_selected); +} + +void +SelectableLabel::mousePressEvent(QMouseEvent *e) +{ + setSelected(true); + emit selectionChanged(); +} + +void +SelectableLabel::mouseDoubleClickEvent(QMouseEvent *e) +{ + std::cerr << "mouseDoubleClickEvent" << std::endl; + emit doubleClicked(); +} + +void +SelectableLabel::enterEvent(QEvent *) +{ +// std::cerr << "enterEvent" << std::endl; +// QPalette palette = QApplication::palette(); +// palette.setColor(QPalette::Window, Qt::gray); +// setStyleSheet("background: gray"); +// setPalette(palette); +} + +void +SelectableLabel::leaveEvent(QEvent *) +{ +// std::cerr << "leaveEvent" << std::endl; +// setStyleSheet("background: white"); +// QPalette palette = QApplication::palette(); +// palette.setColor(QPalette::Window, Qt::gray); +// setPalette(palette); +} Added: sonic-visualiser/trunk/widgets/SelectableLabel.h =================================================================== --- sonic-visualiser/trunk/widgets/SelectableLabel.h (rev 0) +++ sonic-visualiser/trunk/widgets/SelectableLabel.h 2008-09-29 15:06:43 UTC (rev 1225) @@ -0,0 +1,53 @@ +/* -*- 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 2008 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. +*/ + +#ifndef _SELECTABLE_LABEL_H_ +#define _SELECTABLE_LABEL_H_ + +#include <QLabel> + +class SelectableLabel : public QLabel +{ + Q_OBJECT + +public: + SelectableLabel(QWidget *parent = 0); + virtual ~SelectableLabel(); + + void setSelectedText(QString); + void setUnselectedText(QString); + + bool isSelected() const { return m_selected; } + +signals: + void selectionChanged(); + void doubleClicked(); + +public slots: + void setSelected(bool); + void toggle(); + +protected: + virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseDoubleClickEvent(QMouseEvent *e); + virtual void enterEvent(QEvent *); + virtual void leaveEvent(QEvent *); + void setupStyle(); + QString m_selectedText; + QString m_unselectedText; + bool m_selected; +}; + +#endif Modified: sonic-visualiser/trunk/widgets/TransformFinder.cpp =================================================================== --- sonic-visualiser/trunk/widgets/TransformFinder.cpp 2008-09-29 11:11:42 UTC (rev 1224) +++ sonic-visualiser/trunk/widgets/TransformFinder.cpp 2008-09-29 15:06:43 UTC (rev 1225) @@ -15,117 +15,20 @@ #include "TransformFinder.h" +#include "base/XmlExportable.h" #include "transform/TransformFactory.h" +#include "SelectableLabel.h" #include <QVBoxLayout> #include <QGridLayout> #include <QLineEdit> #include <QLabel> -//#include <SelectableLabel> #include <QDialogButtonBox> #include <QScrollArea> #include <QApplication> #include <QDesktopWidget> +#include <QTimer> -SelectableLabel::SelectableLabel(QWidget *p) : - QLabel(p), - m_selected(false) -{ - setTextFormat(Qt::RichText); -// setLineWidth(2); -// setFixedWidth(480); - setupStyle(); -} - -void -SelectableLabel::setUnselectedText(QString text) -{ - m_unselectedText = text; - if (!m_selected) { - setText(m_unselectedText); - resize(sizeHint()); - } -} - -void -SelectableLabel::setSelectedText(QString text) -{ - m_selectedText = text; - if (m_selected) { - setText(m_selectedText); - resize(sizeHint()); - } -} - -void -SelectableLabel::setupStyle() -{ - if (m_selected) { - setWordWrap(true); - setStyleSheet("QLabel:hover { background: #e0e0e0; color: black; } QLabel:!hover { background: #f0f0f0; color: black } QLabel { padding: 7px }"); - -// setFrameStyle(QFrame::Box | QFrame::Plain); - } else { - setWordWrap(false); - setStyleSheet("QLabel:hover { background: #e0e0e0; color: black; } QLabel:!hover { background: white; color: black } QLabel { padding: 7px }"); - -// setFrameStyle(QFrame::NoFrame); - } -} - -void -SelectableLabel::setSelected(bool s) -{ - if (m_selected == s) return; - m_selected = s; - if (m_selected) { - setText(m_selectedText); - } else { - setText(m_unselectedText); - } - setupStyle(); - parentWidget()->resize(parentWidget()->sizeHint()); -} - -void -SelectableLabel::toggle() -{ - setSelected(!m_selected); -} - -void -SelectableLabel::mousePressEvent(QMouseEvent *e) -{ - setSelected(true); - emit selectionChanged(); -} - -void -SelectableLabel::mouseDoubleClickEvent(QMouseEvent *e) -{ - std::cerr << "mouseDoubleClickEvent" << std::endl; -} - -void -SelectableLabel::enterEvent(QEvent *) -{ -// std::cerr << "enterEvent" << std::endl; -// QPalette palette = QApplication::palette(); -// palette.setColor(QPalette::Window, Qt::gray); -// setStyleSheet("background: gray"); -// setPalette(palette); -} - -void -SelectableLabel::leaveEvent(QEvent *) -{ -// std::cerr << "leaveEvent" << std::endl; -// setStyleSheet("background: white"); -// QPalette palette = QApplication::palette(); -// palette.setColor(QPalette::Window, Qt::gray); -// setPalette(palette); -} - TransformFinder::TransformFinder(QWidget *parent) : QDialog(parent), m_resultsFrame(0), @@ -161,7 +64,6 @@ palette.setColor(QPalette::Window, palette.color(QPalette::Base)); m_resultsFrame->setPalette(palette); m_resultsScroll->setPalette(palette); -// resultsFrame->setFrameStyle(QFrame::Sunken | QFrame::Box); m_resultsLayout = new QVBoxLayout; m_resultsLayout->setSpacing(0); m_resultsLayout->setContentsMargins(0, 0, 0, 0); @@ -184,6 +86,11 @@ resize(width, height); raise(); + + m_upToDateCount = 0; + m_timer = new QTimer(this); + connect(m_timer, SIGNAL(timeout()), this, SLOT(timeout())); + m_timer->start(0); } TransformFinder::~TransformFinder() @@ -194,82 +101,98 @@ TransformFinder::searchTextChanged(const QString &text) { std::cerr << "text is " << text.toStdString() << std::endl; + m_newSearchText = text; +} - QStringList keywords = text.split(' ', QString::SkipEmptyParts); - TransformFactory::SearchResults results = - TransformFactory::getInstance()->search(keywords); +void +TransformFinder::timeout() +{ + int maxResults = 40; - std::cerr << results.size() << " result(s)..." << std::endl; + if (m_newSearchText != "") { - std::set<TransformFactory::Match> sorted; - for (TransformFactory::SearchResults::const_iterator j = results.begin(); - j != results.end(); ++j) { - sorted.insert(j->second); - } + QString text = m_newSearchText; + m_newSearchText = ""; - int i = 0; -/* - for (std::set<TransformFactory::Match>::const_iterator j = sorted.begin(); - j != sorted.end(); ++j) { - std::cerr << i++ << ": " << j->transform.toStdString() << ": "; - for (TransformFactory::Match::FragmentMap::const_iterator k = - j->fragments.begin(); - k != j->fragments.end(); ++k) { - std::cerr << k->first.toStdString() << ": " - << k->second.toStdString() << " "; + QStringList keywords = text.split(' ', QString::SkipEmptyParts); + TransformFactory::SearchResults results = + TransformFactory::getInstance()->search(keywords); + + std::cerr << results.size() << " result(s)..." << std::endl; + + std::set<TransformFactory::Match> sorted; + sorted.clear(); + for (TransformFactory::SearchResults::const_iterator j = results.begin(); + j != results.end(); ++j) { + sorted.insert(j->second); } - std::cerr << "(" << j->score << ")" << std::endl; + + m_sortedResults.clear(); + for (std::set<TransformFactory::Match>::const_iterator j = sorted.end(); + j != sorted.begin(); ) { + --j; + m_sortedResults.push_back(*j); + if (m_sortedResults.size() == maxResults) break; + } + + if (m_sortedResults.empty()) m_selectedTransform = ""; + else m_selectedTransform = m_sortedResults.begin()->transform; + + m_upToDateCount = 0; + + for (int j = m_labels.size(); j > m_sortedResults.size(); ) { + m_labels[--j]->hide(); + } + + return; } -*/ - i = 0; - int maxResults = 40; - int height = 0; - int width = 0; + if (m_upToDateCount < m_sortedResults.size()) { - if (sorted.empty()) m_selectedTransform = ""; + int i = m_upToDateCount; - for (std::set<TransformFactory::Match>::const_iterator j = sorted.end(); - j != sorted.begin(); ) { - --j; + std::cerr << "sorted size = " << m_sortedResults.size() << std::endl; TransformDescription desc = - TransformFactory::getInstance()->getTransformDescription(j->transform); + TransformFactory::getInstance()->getTransformDescription + (m_sortedResults[i].transform); QString labelText; - labelText += tr("%2<br><small>").arg(desc.name); + labelText += tr("%1: %2<br><small>") + .arg(m_sortedResults[i].score) + .arg(XmlExportable::encodeEntities(desc.name)); + labelText += "..."; for (TransformFactory::Match::FragmentMap::const_iterator k = - j->fragments.begin(); - k != j->fragments.end(); ++k) { + m_sortedResults[i].fragments.begin(); + k != m_sortedResults[i].fragments.end(); ++k) { labelText += k->second; labelText += "... "; } labelText += tr("</small>"); QString selectedText; - selectedText += tr("<b>%1</b><br>").arg(desc.name); - selectedText += tr("<small>%1</small>").arg(desc.longDescription); -/* - for (TransformFactory::Match::FragmentMap::const_iterator k = - j->fragments.begin(); - k != j->fragments.end(); ++k) { - selectedText += tr("<br><small>%1: %2</small>").arg(k->first).arg(k->second); - } -*/ + selectedText += tr("<b>%1</b><br>") + .arg(XmlExportable::encodeEntities(desc.name)); + selectedText += tr("<small>%1</small>") + .arg(XmlExportable::encodeEntities(desc.longDescription)); selectedText += tr("<ul><small>"); - selectedText += tr("<li>Plugin type: %1</li>").arg(desc.type); - selectedText += tr("<li>Category: %1</li>").arg(desc.category); - selectedText += tr("<li>System identifier: %1</li>").arg(desc.identifier); + selectedText += tr("<li>Plugin type: %1</li>") + .arg(XmlExportable::encodeEntities(desc.type)); + selectedText += tr("<li>Category: %1</li>") + .arg(XmlExportable::encodeEntities(desc.category)); + selectedText += tr("<li>System identifier: %1</li>") + .arg(XmlExportable::encodeEntities(desc.identifier)); selectedText += tr("</small></ul>"); if (i >= m_labels.size()) { SelectableLabel *label = new SelectableLabel(m_resultsFrame); -// m_resultsLayout->addWidget(label, i, 0); m_resultsLayout->addWidget(label); connect(label, SIGNAL(selectionChanged()), this, SLOT(selectedLabelChanged())); + connect(label, SIGNAL(doubleClicked()), this, + SLOT(accept())); QPalette palette = label->palette(); label->setPalette(palette); m_labels.push_back(label); @@ -280,35 +203,15 @@ m_labels[i]->setUnselectedText(labelText); m_labels[i]->setSelectedText(selectedText); - /* - m_labels[i]->setSelected(false); - m_selectedTransform = ""; - */ - - m_labels[i]->setSelected(i == 0); - if (i == 0) { - m_selectedTransform = desc.identifier; - } - -/* - QSize sh = m_labels[i]->sizeHint(); - std::cerr << "size hint for text \"" << labelText.toStdString() << "\" has height " << sh.height() << std::endl; - height += sh.height(); - if (sh.width() > width) width = sh.width(); -*/ -// m_labels[i]->resize(m_labels[i]->sizeHint()); -// m_labels[i]->updateGeometry(); + m_labels[i]->setSelected(m_selectedTransform == desc.identifier); m_labels[i]->show(); - if (++i == maxResults) break; - } + ++m_upToDateCount; - std::cerr << "m_labels.size() = " << m_labels.size() << ", i = " << i << ", height = " << height << std::endl; - - for (int j = m_labels.size(); j > i; ) m_labels[--j]->hide(); - - m_resultsFrame->resize(m_resultsFrame->sizeHint()); -// m_resultsFrame->resize(height, width); +// if (m_upToDateCount == m_sortedResults.size()) { + m_resultsFrame->resize(m_resultsFrame->sizeHint()); +// } + } } void @@ -335,6 +238,6 @@ TransformId TransformFinder::getTransform() const { - return ""; + return m_selectedTransform; } Modified: sonic-visualiser/trunk/widgets/TransformFinder.h =================================================================== --- sonic-visualiser/trunk/widgets/TransformFinder.h 2008-09-29 11:11:42 UTC (rev 1224) +++ sonic-visualiser/trunk/widgets/TransformFinder.h 2008-09-29 15:06:43 UTC (rev 1225) @@ -21,46 +21,15 @@ #include <vector> #include "transform/Transform.h" +#include "transform/TransformFactory.h" class QVBoxLayout; class QScrollArea; class QLabel; class SelectableLabel; class QWidget; +class QTimer; - -#include <QLabel> -class SelectableLabel : public QLabel -{ - Q_OBJECT - -public: - SelectableLabel(QWidget *parent = 0); - virtual ~SelectableLabel() { } - - void setSelectedText(QString); - void setUnselectedText(QString); - - bool isSelected() const { return m_selected; } - -signals: - void selectionChanged(); - -public slots: - void setSelected(bool); - void toggle(); - -protected: - virtual void mousePressEvent(QMouseEvent *e); - virtual void mouseDoubleClickEvent(QMouseEvent *e); - virtual void enterEvent(QEvent *); - virtual void leaveEvent(QEvent *); - void setupStyle(); - QString m_selectedText; - QString m_unselectedText; - bool m_selected; -}; - class TransformFinder : public QDialog { Q_OBJECT @@ -74,6 +43,7 @@ protected slots: void searchTextChanged(const QString &); void selectedLabelChanged(); + void timeout(); protected: QScrollArea *m_resultsScroll; @@ -81,6 +51,12 @@ QVBoxLayout *m_resultsLayout; std::vector<SelectableLabel *> m_labels; TransformId m_selectedTransform; + QTimer *m_timer; + + QString m_newSearchText; + typedef std::vector<TransformFactory::Match> SortedResults; + SortedResults m_sortedResults; + int m_upToDateCount; }; #endif Modified: sonic-visualiser/trunk/widgets/widgets.pro =================================================================== --- sonic-visualiser/trunk/widgets/widgets.pro 2008-09-29 11:11:42 UTC (rev 1224) +++ sonic-visualiser/trunk/widgets/widgets.pro 2008-09-29 15:06:43 UTC (rev 1225) @@ -42,6 +42,7 @@ PropertyBox.h \ PropertyStack.h \ RangeInputDialog.h \ + SelectableLabel.h \ SubdividingMenu.h \ TextAbbrev.h \ Thumbwheel.h \ @@ -77,6 +78,7 @@ PropertyBox.cpp \ PropertyStack.cpp \ RangeInputDialog.cpp \ + SelectableLabel.cpp \ SubdividingMenu.cpp \ TextAbbrev.cpp \ Thumbwheel.cpp \ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-09-29 16:32:23
|
Revision: 1226 http://sv1.svn.sourceforge.net/sv1/?rev=1226&view=rev Author: cannam Date: 2008-09-29 16:31:49 +0000 (Mon, 29 Sep 2008) Log Message: ----------- * More transform finder stuff Modified Paths: -------------- sonic-visualiser/trunk/sv/main/MainWindow.cpp sonic-visualiser/trunk/sv.prf sonic-visualiser/trunk/transform/TransformFactory.cpp sonic-visualiser/trunk/widgets/SelectableLabel.cpp sonic-visualiser/trunk/widgets/TransformFinder.cpp Modified: sonic-visualiser/trunk/sv/main/MainWindow.cpp =================================================================== --- sonic-visualiser/trunk/sv/main/MainWindow.cpp 2008-09-29 15:06:43 UTC (rev 1225) +++ sonic-visualiser/trunk/sv/main/MainWindow.cpp 2008-09-29 16:31:49 UTC (rev 1226) @@ -1437,8 +1437,10 @@ QAction *action = new QAction(tr("Find a Transform..."), this); action->setStatusTip(tr("Search for a transform from the installed plugins, by name or description")); + action->setShortcut(tr("Ctrl+M")); connect(action, SIGNAL(triggered()), this, SLOT(findTransform())); connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); + m_keyReference->registerShortcut(action); m_transformsMenu->addAction(action); m_rightButtonTransformsMenu->addAction(action); Modified: sonic-visualiser/trunk/sv.prf =================================================================== --- sonic-visualiser/trunk/sv.prf 2008-09-29 15:06:43 UTC (rev 1225) +++ sonic-visualiser/trunk/sv.prf 2008-09-29 16:31:49 UTC (rev 1226) @@ -3,7 +3,7 @@ ### BEGIN CONFIGURABLE STUFF ### -CONFIG += debug +CONFIG += release # Temporarily Modified: sonic-visualiser/trunk/transform/TransformFactory.cpp =================================================================== --- sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-09-29 15:06:43 UTC (rev 1225) +++ sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-09-29 16:31:49 UTC (rev 1226) @@ -822,6 +822,11 @@ { if (m_transforms.empty()) populateTransforms(); + if (keywords.size() > 1) { + // Additional score for all keywords in a row + keywords.push_back(keywords.join(" ")); + } + SearchResults results; for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); Modified: sonic-visualiser/trunk/widgets/SelectableLabel.cpp =================================================================== --- sonic-visualiser/trunk/widgets/SelectableLabel.cpp 2008-09-29 15:06:43 UTC (rev 1225) +++ sonic-visualiser/trunk/widgets/SelectableLabel.cpp 2008-09-29 16:31:49 UTC (rev 1226) @@ -35,6 +35,7 @@ void SelectableLabel::setUnselectedText(QString text) { + if (m_unselectedText == text) return; m_unselectedText = text; if (!m_selected) { setText(m_unselectedText); @@ -45,6 +46,7 @@ void SelectableLabel::setSelectedText(QString text) { + if (m_selectedText == text) return; m_selectedText = text; if (m_selected) { setText(m_selectedText); @@ -63,8 +65,8 @@ (QString("QLabel:hover { background: %1; color: %3; } " "QLabel:!hover { background: %2; color: %3 } " "QLabel { padding: 7px }") - .arg(palette.button().color().name()) - .arg(palette.mid().color().light().name()) + .arg(palette.mid().color().lighter(120).name()) + .arg(palette.mid().color().lighter(140).name()) .arg(palette.text().color().name())); } else { setWordWrap(false); Modified: sonic-visualiser/trunk/widgets/TransformFinder.cpp =================================================================== --- sonic-visualiser/trunk/widgets/TransformFinder.cpp 2008-09-29 15:06:43 UTC (rev 1225) +++ sonic-visualiser/trunk/widgets/TransformFinder.cpp 2008-09-29 16:31:49 UTC (rev 1226) @@ -90,7 +90,7 @@ m_upToDateCount = 0; m_timer = new QTimer(this); connect(m_timer, SIGNAL(timeout()), this, SLOT(timeout())); - m_timer->start(0); + m_timer->start(30); } TransformFinder::~TransformFinder() @@ -147,8 +147,10 @@ return; } - if (m_upToDateCount < m_sortedResults.size()) { + if (m_upToDateCount >= m_sortedResults.size()) return; + while (m_upToDateCount < m_sortedResults.size()) { + int i = m_upToDateCount; std::cerr << "sorted size = " << m_sortedResults.size() << std::endl; @@ -158,8 +160,7 @@ (m_sortedResults[i].transform); QString labelText; - labelText += tr("%1: %2<br><small>") - .arg(m_sortedResults[i].score) + labelText += tr("%1<br><small>") .arg(XmlExportable::encodeEntities(desc.name)); labelText += "..."; @@ -201,17 +202,20 @@ m_labels[i]->setObjectName(desc.identifier); m_labels[i]->setFixedWidth(this->width() - 40); m_labels[i]->setUnselectedText(labelText); + +// std::cerr << "selected text: " << selectedText.toStdString() << std::endl; m_labels[i]->setSelectedText(selectedText); m_labels[i]->setSelected(m_selectedTransform == desc.identifier); - m_labels[i]->show(); + if (!m_labels[i]->isVisible()) m_labels[i]->show(); + ++m_upToDateCount; -// if (m_upToDateCount == m_sortedResults.size()) { - m_resultsFrame->resize(m_resultsFrame->sizeHint()); -// } + if (i == 0) break; } + + m_resultsFrame->resize(m_resultsFrame->sizeHint()); } void This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-10-03 15:43:26
|
Revision: 1230 http://sv1.svn.sourceforge.net/sv1/?rev=1230&view=rev Author: cannam Date: 2008-10-03 15:43:15 +0000 (Fri, 03 Oct 2008) Log Message: ----------- nothing much! Modified Paths: -------------- sonic-visualiser/trunk/rdf/RDFImporter.cpp sonic-visualiser/trunk/sv.prf Modified: sonic-visualiser/trunk/rdf/RDFImporter.cpp =================================================================== --- sonic-visualiser/trunk/rdf/RDFImporter.cpp 2008-09-30 16:19:36 UTC (rev 1229) +++ sonic-visualiser/trunk/rdf/RDFImporter.cpp 2008-10-03 15:43:15 UTC (rev 1230) @@ -436,8 +436,8 @@ QString source = results[i]["signal_source"].value; + RealTime time; QString timestring = results[i]["time"].value; - RealTime time; time = RealTime::fromXsdDuration(timestring.toStdString()); cerr << "time = " << time.toString() << " (from xsd:duration \"" << timestring.toStdString() << "\")" << endl; Modified: sonic-visualiser/trunk/sv.prf =================================================================== --- sonic-visualiser/trunk/sv.prf 2008-09-30 16:19:36 UTC (rev 1229) +++ sonic-visualiser/trunk/sv.prf 2008-10-03 15:43:15 UTC (rev 1230) @@ -7,7 +7,7 @@ # Temporarily -DEFINES += USE_NEW_RASQAL_API +#DEFINES += USE_NEW_RASQAL_API # Put your favourite optimization flags here. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-10-07 12:42:24
|
Revision: 1231 http://sv1.svn.sourceforge.net/sv1/?rev=1231&view=rev Author: cannam Date: 2008-10-07 12:42:17 +0000 (Tue, 07 Oct 2008) Log Message: ----------- * Support importing features from RDF whose times are intervals rather than only instants; import them into region or note models. Sadly this makes RDF import much, much slower, because we need to work around Rasqal's single-OPTIONAL limitation by repeatedly querying each feature for time and range. * Add segmentation view to region layer, and display label texts Modified Paths: -------------- sonic-visualiser/trunk/layer/RegionLayer.cpp sonic-visualiser/trunk/layer/RegionLayer.h sonic-visualiser/trunk/layer/TimeValueLayer.cpp sonic-visualiser/trunk/rdf/RDFImporter.cpp sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.cpp Modified: sonic-visualiser/trunk/layer/RegionLayer.cpp =================================================================== --- sonic-visualiser/trunk/layer/RegionLayer.cpp 2008-10-03 15:43:15 UTC (rev 1230) +++ sonic-visualiser/trunk/layer/RegionLayer.cpp 2008-10-07 12:42:17 UTC (rev 1231) @@ -20,6 +20,7 @@ #include "base/Profiler.h" #include "base/LogRange.h" #include "ColourDatabase.h" +#include "ColourMapper.h" #include "view/View.h" #include "data/model/RegionModel.h" @@ -43,6 +44,7 @@ m_editingPoint(0, 0.0, 0, tr("New Point")), m_editingCommand(0), m_verticalScale(AutoAlignScale), + m_colourMap(0), m_plotStyle(PlotLines) { @@ -86,6 +88,7 @@ if (name == "Scale Units") return UnitsProperty; if (name == "Vertical Scale") return ValueProperty; if (name == "Plot Type") return ValueProperty; + if (name == "Colour" && m_plotStyle == PlotSegmentation) return ValueProperty; return SingleColourLayer::getPropertyType(name); } @@ -104,7 +107,15 @@ { int val = 0; - if (name == "Plot Type") { + if (name == "Colour" && m_plotStyle == PlotSegmentation) { + + if (min) *min = 0; + if (max) *max = ColourMapper::getColourMapCount() - 1; + if (deflt) *deflt = 0; + + val = m_colourMap; + + } else if (name == "Plot Type") { if (min) *min = 0; if (max) *max = 1; @@ -138,13 +149,15 @@ QString RegionLayer::getPropertyValueLabel(const PropertyName &name, - int value) const + int value) const { - if (name == "Plot Type") { + if (name == "Colour" && m_plotStyle == PlotSegmentation) { + return ColourMapper::getColourMapName(value); + } else if (name == "Plot Type") { switch (value) { default: - case 0: return tr("Lines"); + case 0: return tr("Bars"); case 1: return tr("Segmentation"); } @@ -162,7 +175,9 @@ void RegionLayer::setProperty(const PropertyName &name, int value) { - if (name == "Plot Type") { + if (name == "Colour" && m_plotStyle == PlotSegmentation) { + setFillColourMap(value); + } else if (name == "Plot Type") { setPlotStyle(PlotStyle(value)); } else if (name == "Vertical Scale") { setVerticalScale(VerticalScale(value)); @@ -178,10 +193,23 @@ } void +RegionLayer::setFillColourMap(int map) +{ + if (m_colourMap == map) return; + m_colourMap = map; + emit layerParametersChanged(); +} + +void RegionLayer::setPlotStyle(PlotStyle style) { if (m_plotStyle == style) return; + bool colourTypeChanged = (style == PlotSegmentation || + m_plotStyle == PlotSegmentation); m_plotStyle = style; + if (colourTypeChanged) { + emit layerParameterRangesChanged(); + } emit layerParametersChanged(); } @@ -487,6 +515,36 @@ return y; } +QColor +RegionLayer::getColourForValue(View *v, float val) const +{ + float min, max; + bool log; + getScaleExtents(v, min, max, log); + + if (min > max) std::swap(min, max); + if (max == min) max = min + 1; + + if (log) { + LogRange::mapRange(min, max); + val = LogRange::map(val); + } + +// std::cerr << "RegionLayer::getColourForValue: min " << min << ", max " +// << max << ", log " << log << ", value " << val << std::endl; + + QColor solid = ColourMapper(m_colourMap, min, max).map(val); + return QColor(solid.red(), solid.green(), solid.blue(), 120); +} + +int +RegionLayer::getDefaultColourHint(bool darkbg, bool &impose) +{ + impose = false; + return ColourDatabase::getInstance()->getColourIndex + (QString(darkbg ? "Bright Blue" : "Blue")); +} + float RegionLayer::getValueForY(View *v, int y) const { @@ -552,6 +610,11 @@ //!!! if it does have distinct values, we should still ensure y //!!! coord is never completely flat on the top or bottom + int textY = 0; + if (m_plotStyle == PlotSegmentation) { + textY = v->getTextLabelHeight(this, paint); + } + for (RegionModel::PointList::const_iterator i = points.begin(); i != points.end(); ++i) { @@ -562,30 +625,72 @@ int w = v->getXForFrame(p.frame + p.duration) - x; int h = 9; + bool haveNext = false; + int nx = v->getXForFrame(v->getModelsEndFrame()); + + RegionModel::PointList::const_iterator j = i; + ++j; + + if (j != points.end()) { + const RegionModel::Point &q(*j); + nx = v->getXForFrame(q.frame); + haveNext = true; + } + + if (m_plotStyle != PlotSegmentation) { + textY = y - paint.fontMetrics().height() + + paint.fontMetrics().ascent(); + if (textY < paint.fontMetrics().ascent() + 1) { + textY = paint.fontMetrics().ascent() + 1; + } + } + if (m_model->getValueQuantization() != 0.0) { h = y - getYForValue(v, p.value + m_model->getValueQuantization()); if (h < 3) h = 3; } if (w < 1) w = 1; - paint.setPen(getBaseQColor()); - paint.setBrush(brushColour); - if (illuminateFrame == p.frame) { - if (localPos.y() >= y - h && localPos.y() < y) { - paint.setPen(v->getForeground()); - paint.setBrush(v->getForeground()); + if (m_plotStyle == PlotSegmentation) { + paint.setPen(getForegroundQColor(v)); + paint.setBrush(getColourForValue(v, p.value)); + } else { + paint.setPen(getBaseQColor()); + paint.setBrush(brushColour); + } + + if (m_plotStyle == PlotSegmentation) { + + if (nx <= x) continue; + + if (illuminateFrame != p.frame && + (nx < x + 5 || x >= v->width() - 1)) { + paint.setPen(Qt::NoPen); } - } + + paint.drawRect(x, -1, nx - x, v->height() + 1); + + } else { + + if (illuminateFrame == p.frame) { + if (localPos.y() >= y - h && localPos.y() < y) { + paint.setPen(v->getForeground()); + paint.setBrush(v->getForeground()); + } + } - paint.drawLine(x, y-1, x + w, y-1); - paint.drawLine(x, y+1, x + w, y+1); - paint.drawLine(x, y - h/2, x, y + h/2); - paint.drawLine(x+w, y - h/2, x + w, y + h/2); + paint.drawLine(x, y-1, x + w, y-1); + paint.drawLine(x, y+1, x + w, y+1); + paint.drawLine(x, y - h/2, x, y + h/2); + paint.drawLine(x+w, y - h/2, x + w, y + h/2); + } -/// if (p.label != "") { -/// paint.drawText(x + 5, y - paint.fontMetrics().height() + paint.fontMetrics().ascent(), p.label); -/// } + if (p.label != "") { + if (!haveNext || nx > x + 6 + paint.fontMetrics().width(p.label)) { + paint.drawText(x + 5, textY, p.label); + } + } } paint.restore(); @@ -998,14 +1103,6 @@ return true; } -int -RegionLayer::getDefaultColourHint(bool darkbg, bool &impose) -{ - impose = false; - return ColourDatabase::getInstance()->getColourIndex - (QString(darkbg ? "White" : "Black")); -} - void RegionLayer::toXml(QTextStream &stream, QString indent, QString extraAttributes) const Modified: sonic-visualiser/trunk/layer/RegionLayer.h =================================================================== --- sonic-visualiser/trunk/layer/RegionLayer.h 2008-10-03 15:43:15 UTC (rev 1230) +++ sonic-visualiser/trunk/layer/RegionLayer.h 2008-10-07 12:42:17 UTC (rev 1231) @@ -75,6 +75,9 @@ int value) const; virtual void setProperty(const PropertyName &, int value); + void setFillColourMap(int); + int getFillColourMap() const { return m_colourMap; } + enum VerticalScale { AutoAlignScale, LinearScale, @@ -112,6 +115,7 @@ void getScaleExtents(View *, float &min, float &max, bool &log) const; int getYForValue(View *v, float value) const; float getValueForY(View *v, int y) const; + QColor getColourForValue(View *v, float value) const; virtual int getDefaultColourHint(bool dark, bool &impose); @@ -123,6 +127,7 @@ RegionModel::Point m_editingPoint; RegionModel::EditCommand *m_editingCommand; VerticalScale m_verticalScale; + int m_colourMap; PlotStyle m_plotStyle; void finish(RegionModel::EditCommand *command) { Modified: sonic-visualiser/trunk/layer/TimeValueLayer.cpp =================================================================== --- sonic-visualiser/trunk/layer/TimeValueLayer.cpp 2008-10-03 15:43:15 UTC (rev 1230) +++ sonic-visualiser/trunk/layer/TimeValueLayer.cpp 2008-10-07 12:42:17 UTC (rev 1231) @@ -611,7 +611,6 @@ bool haveNext = false; int nx = v->getXForFrame(v->getModelsEndFrame()); -// m_model->getEndFrame()); int ny = y; SparseTimeValueModel::PointList::const_iterator j = i; @@ -627,15 +626,12 @@ // std::cout << "frame = " << p.frame << ", x = " << x << ", haveNext = " << haveNext // << ", nx = " << nx << std::endl; - int labelY = y; - if (w < 1) w = 1; paint.setPen(getBaseQColor()); if (m_plotStyle == PlotSegmentation) { paint.setPen(getForegroundQColor(v)); paint.setBrush(getColourForValue(v, p.value)); - labelY = v->height(); } else if (m_plotStyle == PlotLines || m_plotStyle == PlotCurve) { paint.setBrush(Qt::NoBrush); Modified: sonic-visualiser/trunk/rdf/RDFImporter.cpp =================================================================== --- sonic-visualiser/trunk/rdf/RDFImporter.cpp 2008-10-03 15:43:15 UTC (rev 1230) +++ sonic-visualiser/trunk/rdf/RDFImporter.cpp 2008-10-07 12:42:17 UTC (rev 1231) @@ -29,6 +29,8 @@ #include "data/model/SparseOneDimensionalModel.h" #include "data/model/SparseTimeValueModel.h" #include "data/model/EditableDenseThreeDimensionalModel.h" +#include "data/model/NoteModel.h" +#include "data/model/RegionModel.h" using std::cerr; using std::endl; @@ -49,11 +51,6 @@ QString m_errorString; int m_sampleRate; - typedef std::vector<float> ValueList; - typedef std::map<RealTime, ValueList> TimeValueMap; - typedef std::map<QString, TimeValueMap> TypeTimeValueMap; - typedef std::map<QString, TypeTimeValueMap> SourceTypeTimeValueMap; - void getDataModelsSparse(std::vector<Model *> &, ProgressReporter *); void getDataModelsDense(std::vector<Model *> &, ProgressReporter *); @@ -61,12 +58,23 @@ int &sampleRate, int &windowLength, int &hopSize, int &width, int &height); - void extractStructure(const TimeValueMap &map, bool &sparse, + + void fillModel(Model *, long, long, bool, std::vector<float> &, QString); + +/* + + typedef std::vector<std::pair<RealTime, float> > DurationValueList; + typedef std::map<RealTime, DurationValueList> TimeDurationValueMap; + typedef std::map<QString, TimeDurationValueMap> TypeTimeDurationValueMap; + typedef std::map<QString, TypeTimeDurationValueMap> SourceTypeTimeDurationValueMap; + + void extractStructure(const TimeDurationValueMap &map, bool &sparse, int &minValueCount, int &maxValueCount); - void fillModel(SparseOneDimensionalModel *, const TimeValueMap &); - void fillModel(SparseTimeValueModel *, const TimeValueMap &); - void fillModel(EditableDenseThreeDimensionalModel *, const TimeValueMap &); + void fillModel(SparseOneDimensionalModel *, const TimeDurationValueMap &); + void fillModel(SparseTimeValueModel *, const TimeDurationValueMap &); + void fillModel(EditableDenseThreeDimensionalModel *, const TimeDurationValueMap &); +*/ }; @@ -384,16 +392,19 @@ // If the source signal or feature type is unavailable, the empty // string will do. - SourceTypeTimeValueMap m; +// SourceTypeTimeDurationValueMap m; - QString queryString = QString( - + QString prefixes = QString( " PREFIX event: <http://purl.org/NET/c4dm/event.owl#>" - " PREFIX time: <http://purl.org/NET/c4dm/timeline.owl#>" + " PREFIX tl: <http://purl.org/NET/c4dm/timeline.owl#>" " PREFIX mo: <http://purl.org/ontology/mo/>" " PREFIX af: <http://purl.org/ontology/af/>" + " PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>" + ); - " SELECT ?signal_source ?time ?event_type ?value" + QString queryString = prefixes + QString( + + " SELECT ?signal_source ?timed_thing ?event_type ?value" " FROM <%1>" " WHERE {" @@ -402,10 +413,9 @@ " ?signal a mo:Signal ." " ?signal mo:time ?interval ." - " ?interval time:onTimeLine ?tl ." - " ?t time:onTimeLine ?tl ." - " ?t time:at ?time ." - " ?timed_thing event:time ?t ." + " ?interval tl:onTimeLine ?tl ." + " ?time tl:onTimeLine ?tl ." + " ?timed_thing event:time ?time ." " ?timed_thing a ?event_type ." " OPTIONAL {" @@ -415,6 +425,36 @@ ).arg(m_uristring); + QString timeQueryString = prefixes + QString( + + " SELECT ?time FROM <%1> " + " WHERE { " + " <%2> event:time ?t . " + " ?t tl:at ?time . " + " } " + + ).arg(m_uristring); + + QString rangeQueryString = prefixes + QString( + + " SELECT ?time ?duration FROM <%1> " + " WHERE { " + " <%2> event:time ?t . " + " ?t tl:beginsAt ?time . " + " ?t tl:duration ?duration . " + " } " + + ).arg(m_uristring); + + QString labelQueryString = prefixes + QString( + + " SELECT ?label FROM <%1> " + " WHERE { " + " <%2> rdfs:label ?label . " + " } " + + ).arg(m_uristring); + SimpleSPARQLQuery query(queryString); query.setProgressReporter(reporter); @@ -432,40 +472,176 @@ return; } + + + /* + + This function is now only used for sparse data (for dense data + we would be in getDataModelsDense instead). + + For sparse data, the determining factors in deciding what model + to use are: Do the features have values? and Do the features + have duration? + + We can run through the results and check off whether we find + values and duration for each of the source+type keys, and then + run through the source+type keys pushing each of the results + into a suitable model. + + Unfortunately, at this point we do not yet have any actual + timing data (time/duration) -- just the time URI. + + What we _could_ do is to create one of each type of model at the + start, for each of the source+type keys, and then push each + feature into the relevant model depending on what we find out + about it. Then return only non-empty models. + + + */ + + // Map from signal source to event type to dimensionality to + // presence of duration to model ptr. Whee! + std::map<QString, std::map<QString, std::map<int, std::map<bool, Model *> > > > + modelMap; + for (int i = 0; i < results.size(); ++i) { QString source = results[i]["signal_source"].value; - + QString type = results[i]["event_type"].value; + QString thinguri = results[i]["timed_thing"].value; + RealTime time; - QString timestring = results[i]["time"].value; - time = RealTime::fromXsdDuration(timestring.toStdString()); - cerr << "time = " << time.toString() << " (from xsd:duration \"" - << timestring.toStdString() << "\")" << endl; + RealTime duration; - QString type = results[i]["event_type"].value; + bool haveTime = false; + bool haveDuration = false; + QString label = SimpleSPARQLQuery::singleResultQuery + (labelQueryString.arg(thinguri), "label").value; + + QString timestring = SimpleSPARQLQuery::singleResultQuery + (timeQueryString.arg(thinguri), "time").value; + + if (timestring != "") { + + time = RealTime::fromXsdDuration(timestring.toStdString()); + haveTime = true; + + } else { + + SimpleSPARQLQuery rangeQuery(rangeQueryString.arg(thinguri)); + SimpleSPARQLQuery::ResultList rangeResults = rangeQuery.execute(); + if (!rangeResults.empty()) { +// std::cerr << rangeResults.size() << " range results" << std::endl; + time = RealTime::fromXsdDuration + (rangeResults[0]["time"].value.toStdString()); + duration = RealTime::fromXsdDuration + (rangeResults[0]["duration"].value.toStdString()); +// std::cerr << "duration string " << rangeResults[0]["duration"].value.toStdString() << std::endl; + haveTime = true; + haveDuration = true; + } + } + QString valuestring = results[i]["value"].value; - float value = 0.f; - bool haveValue = false; + std::vector<float> values; + if (valuestring != "") { - //!!! no -- runner actually writes a "CSV literal" - value = valuestring.toFloat(&haveValue); - cerr << "value = " << value << endl; + QStringList vsl = valuestring.split(" ", QString::SkipEmptyParts); + for (int j = 0; j < vsl.size(); ++j) { + bool success = false; + float v = vsl[j].toFloat(&success); + if (success) values.push_back(v); + } } - if (haveValue) { - m[source][type][time].push_back(value); - } else if (m[source][type].find(time) == m[source][type].end()) { - m[source][type][time] = ValueList(); + int dimensions = 1; + if (values.size() == 1) dimensions = 2; + else if (values.size() > 1) dimensions = 3; + + Model *model = 0; + + if (modelMap[source][type][dimensions].find(haveDuration) == + modelMap[source][type][dimensions].end()) { + +/* + std::cerr << "Creating new model: source = " << source.toStdString() + << ", type = " << type.toStdString() << ", dimensions = " + << dimensions << ", haveDuration = " << haveDuration + << ", time = " << time << ", duration = " << duration + << std::endl; +*/ + + if (!haveDuration) { + + if (dimensions == 1) { + +// std::cerr << "SparseOneDimensionalModel" << std::endl; + model = new SparseOneDimensionalModel(m_sampleRate, 1, false); + + } else if (dimensions == 2) { + +// std::cerr << "SparseTimeValueModel" << std::endl; + model = new SparseTimeValueModel(m_sampleRate, 1, false); + + } else { + + // We don't have a three-dimensional sparse model, + // so use a note model. We do have some logic (in + // extractStructure below) for guessing whether + // this should after all have been a dense model, + // but it's hard to apply it because we don't have + // all the necessary timing data yet... hmm + +// std::cerr << "NoteModel" << std::endl; + model = new NoteModel(m_sampleRate, 1, false); + } + + } else { // haveDuration + + if (dimensions == 1 || dimensions == 2) { + + // If our units are frequency or midi pitch, we + // should be using a note model... hm + +// std::cerr << "RegionModel" << std::endl; + model = new RegionModel(m_sampleRate, 1, false); + + } else { + + // We don't have a three-dimensional sparse model, + // so use a note model. We do have some logic (in + // extractStructure below) for guessing whether + // this should after all have been a dense model, + // but it's hard to apply it because we don't have + // all the necessary timing data yet... hmm + +// std::cerr << "NoteModel" << std::endl; + model = new NoteModel(m_sampleRate, 1, false); + } + } + + modelMap[source][type][dimensions][haveDuration] = model; + models.push_back(model); } + + model = modelMap[source][type][dimensions][haveDuration]; + + if (model) { + long ftime = RealTime::realTime2Frame(time, m_sampleRate); + long fduration = RealTime::realTime2Frame(duration, m_sampleRate); + fillModel(model, ftime, fduration, haveDuration, values, label); + } } + - for (SourceTypeTimeValueMap::const_iterator mi = m.begin(); +/* + for (SourceTypeTimeDurationValueMap::const_iterator mi = m.begin(); mi != m.end(); ++mi) { QString source = mi->first; - for (TypeTimeValueMap::const_iterator ttvi = mi->second.begin(); + for (TypeTimeDurationValueMap::const_iterator ttvi = mi->second.begin(); ttvi != mi->second.end(); ++ttvi) { QString type = ttvi->first; @@ -556,10 +732,12 @@ } } } +*/ } +/* void -RDFImporterImpl::extractStructure(const TimeValueMap &tvm, +RDFImporterImpl::extractStructure(const TimeDurationValueMap &tvm, bool &sparse, int &minValueCount, int &maxValueCount) @@ -570,7 +748,7 @@ float timeStep = 0.f; bool haveTimeStep = false; - for (TimeValueMap::const_iterator tvi = tvm.begin(); tvi != tvm.end(); ++tvi) { + for (TimeDurationValueMap::const_iterator tvi = tvm.begin(); tvi != tvm.end(); ++tvi) { RealTime time = tvi->first; int valueCount = tvi->second.size(); @@ -607,14 +785,99 @@ } } } +*/ void +RDFImporterImpl::fillModel(Model *model, + long ftime, + long fduration, + bool haveDuration, + std::vector<float> &values, + QString label) +{ + SparseOneDimensionalModel *sodm = + dynamic_cast<SparseOneDimensionalModel *>(model); + if (sodm) { + SparseOneDimensionalModel::Point point(ftime, label); + sodm->addPoint(point); + return; + } + + SparseTimeValueModel *stvm = + dynamic_cast<SparseTimeValueModel *>(model); + if (stvm) { + SparseTimeValueModel::Point point + (ftime, values.empty() ? 0.f : values[0], label); + stvm->addPoint(point); + return; + } + + NoteModel *nm = + dynamic_cast<NoteModel *>(model); + if (nm) { + if (haveDuration) { + float value = 0.f, level = 1.f; + if (!values.empty()) { + value = values[0]; + if (values.size() > 1) { + level = values[1]; + } + } + NoteModel::Point point(ftime, value, fduration, level, label); + nm->addPoint(point); + } else { + float value = 0.f, duration = 1.f, level = 1.f; + if (!values.empty()) { + value = values[0]; + if (values.size() > 1) { + duration = values[1]; + if (values.size() > 2) { + level = values[2]; + } + } + } + NoteModel::Point point(ftime, value, duration, level, label); + nm->addPoint(point); + } + return; + } + + RegionModel *rm = + dynamic_cast<RegionModel *>(model); + if (rm) { + if (haveDuration) { + RegionModel::Point point + (ftime, values.empty() ? 0.f : values[0], fduration, label); + rm->addPoint(point); + } else { + // This won't actually happen -- we only create region models + // if we do have duration -- but just for completeness + float value = 0.f, duration = 1.f; + if (!values.empty()) { + value = values[0]; + if (values.size() > 1) { + duration = values[1]; + } + } + RegionModel::Point point(ftime, value, duration, label); + rm->addPoint(point); + } + return; + } + + std::cerr << "WARNING: RDFImporterImpl::fillModel: Unknown or unexpected model type" << std::endl; + return; +} + + +/* +void RDFImporterImpl::fillModel(SparseOneDimensionalModel *model, - const TimeValueMap &tvm) + const TimeDurationValueMap &tvm) { //!!! labels &c not yet handled - for (TimeValueMap::const_iterator tvi = tvm.begin(); + for (TimeDurationValueMap::const_iterator tvi = tvm.begin(); tvi != tvm.end(); ++tvi) { RealTime time = tvi->first; @@ -628,18 +891,18 @@ void RDFImporterImpl::fillModel(SparseTimeValueModel *model, - const TimeValueMap &tvm) + const TimeDurationValueMap &tvm) { //!!! labels &c not yet handled - for (TimeValueMap::const_iterator tvi = tvm.begin(); + for (TimeDurationValueMap::const_iterator tvi = tvm.begin(); tvi != tvm.end(); ++tvi) { RealTime time = tvi->first; long frame = RealTime::realTime2Frame(time, m_sampleRate); float value = 0.f; - if (!tvi->second.empty()) value = *tvi->second.begin(); + if (!tvi->second.empty()) value = *tvi->second.begin()->second; SparseTimeValueModel::Point point(frame, value, ""); @@ -649,7 +912,7 @@ void RDFImporterImpl::fillModel(EditableDenseThreeDimensionalModel *model, - const TimeValueMap &tvm) + const TimeDurationValueMap &tvm) { //!!! labels &c not yet handled @@ -657,10 +920,11 @@ size_t col = 0; - for (TimeValueMap::const_iterator tvi = tvm.begin(); + for (TimeDurationValueMap::const_iterator tvi = tvm.begin(); tvi != tvm.end(); ++tvi) { - model->setColumn(col++, tvi->second); + model->setColumn(col++, tvi->second.second); } } +*/ Modified: sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.cpp =================================================================== --- sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.cpp 2008-10-03 15:43:15 UTC (rev 1230) +++ sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.cpp 2008-10-07 12:42:17 UTC (rev 1231) @@ -121,6 +121,7 @@ m_reporter(0), m_cancelled(false) { + std::cerr << "SimpleSPARQLQuery::Impl: Query is: \"" << query.toStdString() << "\"" << std::endl; } SimpleSPARQLQuery::Impl::~Impl() @@ -233,6 +234,8 @@ QString text = (const char *)rasqal_literal_as_string(literal); + std::cerr << i << ". " << key.toStdString() << " -> " << text.toStdString() << " (type " << type << ")" << std::endl; + resultmap[key] = Value(type, text); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-10-09 12:04:27
|
Revision: 1234 http://sv1.svn.sourceforge.net/sv1/?rev=1234&view=rev Author: cannam Date: 2008-10-09 12:04:22 +0000 (Thu, 09 Oct 2008) Log Message: ----------- * Save/load of region models Modified Paths: -------------- sonic-visualiser/trunk/data/fft/FFTDataServer.cpp sonic-visualiser/trunk/data/model/NoteModel.h sonic-visualiser/trunk/data/model/RegionModel.h sonic-visualiser/trunk/framework/Document.cpp sonic-visualiser/trunk/framework/SVFileReader.cpp sonic-visualiser/trunk/sv.prf Modified: sonic-visualiser/trunk/data/fft/FFTDataServer.cpp =================================================================== --- sonic-visualiser/trunk/data/fft/FFTDataServer.cpp 2008-10-08 15:27:31 UTC (rev 1233) +++ sonic-visualiser/trunk/data/fft/FFTDataServer.cpp 2008-10-09 12:04:22 UTC (rev 1234) @@ -27,7 +27,7 @@ #include "base/Profiler.h" #include "base/Thread.h" // for debug mutex locker -//#define DEBUG_FFT_SERVER 1 +#define DEBUG_FFT_SERVER 1 //#define DEBUG_FFT_SERVER_FILL 1 #ifdef DEBUG_FFT_SERVER_FILL Modified: sonic-visualiser/trunk/data/model/NoteModel.h =================================================================== --- sonic-visualiser/trunk/data/model/NoteModel.h 2008-10-08 15:27:31 UTC (rev 1233) +++ sonic-visualiser/trunk/data/model/NoteModel.h 2008-10-09 12:04:22 UTC (rev 1234) @@ -146,7 +146,7 @@ IntervalModel<Note>::toXml (out, indent, - QString("%1 valueQuantization=\"%2\"") + QString("%1 subtype=\"note\" valueQuantization=\"%2\"") .arg(extraAttributes).arg(m_valueQuantization)); } Modified: sonic-visualiser/trunk/data/model/RegionModel.h =================================================================== --- sonic-visualiser/trunk/data/model/RegionModel.h 2008-10-08 15:27:31 UTC (rev 1233) +++ sonic-visualiser/trunk/data/model/RegionModel.h 2008-10-09 12:04:22 UTC (rev 1234) @@ -132,7 +132,7 @@ IntervalModel<RegionRec>::toXml (out, indent, - QString("%1 valueQuantization=\"%2\"") + QString("%1 subtype=\"region\" valueQuantization=\"%2\"") .arg(extraAttributes).arg(m_valueQuantization)); } Modified: sonic-visualiser/trunk/framework/Document.cpp =================================================================== --- sonic-visualiser/trunk/framework/Document.cpp 2008-10-08 15:27:31 UTC (rev 1233) +++ sonic-visualiser/trunk/framework/Document.cpp 2008-10-09 12:04:22 UTC (rev 1234) @@ -37,7 +37,7 @@ #include "data/model/SparseTimeValueModel.h" #include "data/model/AlignmentModel.h" -//#define DEBUG_DOCUMENT 1 +#define DEBUG_DOCUMENT 1 //!!! still need to handle command history, documentRestored/documentModified @@ -278,6 +278,11 @@ #ifdef DEBUG_DOCUMENT std::cerr << "Document::setMainModel: Have " << m_layers.size() << " layers" << std::endl; + std::cerr << "Models now: "; + for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) { + std::cerr << i->first << " "; + } + std::cerr << std::endl; #endif for (LayerSet::iterator i = m_layers.begin(); i != m_layers.end(); ++i) { @@ -299,10 +304,18 @@ continue; } - if (model && (m_models.find(model) == m_models.end())) { + if (!model) { + std::cerr << "WARNING: Document::setMainModel: Null model in layer " + << layer << std::endl; + // get rid of this hideous degenerate + obsoleteLayers.push_back(layer); + continue; + } + + if (m_models.find(model) == m_models.end()) { std::cerr << "WARNING: Document::setMainModel: Unknown model " << model << " in layer " << layer << std::endl; - // get rid of this hideous degenerate + // and this one obsoleteLayers.push_back(layer); continue; } @@ -361,7 +374,7 @@ if (rm) { std::cerr << "new model has " << rm->getChannelCount() << " channels " << std::endl; } else { - std::cerr << "new model is not a RangeSummarisableTimeValueModel!" << std::endl; + std::cerr << "new model " << replacementModel << " is not a RangeSummarisableTimeValueModel!" << std::endl; } #endif setModel(layer, replacementModel); @@ -375,14 +388,21 @@ for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { + Model *m = i->first; + +#ifdef DEBUG_DOCUMENT + std::cerr << "considering alignment for model " << m << " (name \"" + << m->objectName().toStdString() << "\")" << std::endl; +#endif + if (m_autoAlignment) { - alignModel(i->first); + alignModel(m); } else if (oldMainModel && - (i->first->getAlignmentReference() == oldMainModel)) { + (m->getAlignmentReference() == oldMainModel)) { - alignModel(i->first); + alignModel(m); } } @@ -425,6 +445,15 @@ m_models[outputModelToAdd] = rec; +#ifdef DEBUG_DOCUMENT + std::cerr << "Document::addDerivedModel: Added model " << outputModelToAdd << std::endl; + std::cerr << "Models now: "; + for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) { + std::cerr << i->first << " "; + } + std::cerr << std::endl; +#endif + emit modelAdded(outputModelToAdd); } @@ -444,6 +473,15 @@ m_models[model] = rec; +#ifdef DEBUG_DOCUMENT + std::cerr << "Document::addImportedModel: Added model " << model << std::endl; + std::cerr << "Models now: "; + for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) { + std::cerr << i->first << " "; + } + std::cerr << std::endl; +#endif + if (m_autoAlignment) alignModel(model); emit modelAdded(model); @@ -540,6 +578,16 @@ model->aboutToDelete(); emit modelAboutToBeDeleted(model); m_models.erase(model); + +#ifdef DEBUG_DOCUMENT + std::cerr << "Document::releaseModel: Deleted model " << model << std::endl; + std::cerr << "Models now: "; + for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) { + std::cerr << i->first << " "; + } + std::cerr << std::endl; +#endif + delete model; } } Modified: sonic-visualiser/trunk/framework/SVFileReader.cpp =================================================================== --- sonic-visualiser/trunk/framework/SVFileReader.cpp 2008-10-08 15:27:31 UTC (rev 1233) +++ sonic-visualiser/trunk/framework/SVFileReader.cpp 2008-10-09 12:04:22 UTC (rev 1234) @@ -31,6 +31,7 @@ #include "data/model/SparseOneDimensionalModel.h" #include "data/model/SparseTimeValueModel.h" #include "data/model/NoteModel.h" +#include "data/model/RegionModel.h" #include "data/model/TextModel.h" #include "data/model/ImageModel.h" #include "data/model/AlignmentModel.h" @@ -593,19 +594,36 @@ m_models[id] = model; } } else { - NoteModel *model; - if (haveMinMax) { - model = new NoteModel - (sampleRate, resolution, minimum, maximum, notifyOnAdd); + if (attributes.value("subtype") == "region") { + RegionModel *model; + if (haveMinMax) { + model = new RegionModel + (sampleRate, resolution, minimum, maximum, notifyOnAdd); + } else { + model = new RegionModel + (sampleRate, resolution, notifyOnAdd); + } + model->setValueQuantization(valueQuantization); + model->setScaleUnits(units); + model->setObjectName(name); + m_models[id] = model; } else { - model = new NoteModel - (sampleRate, resolution, notifyOnAdd); + // note models written out by SV 1.3 and earlier + // have no subtype, so we can't test that + NoteModel *model; + if (haveMinMax) { + model = new NoteModel + (sampleRate, resolution, minimum, maximum, notifyOnAdd); + } else { + model = new NoteModel + (sampleRate, resolution, notifyOnAdd); + } + model->setValueQuantization(valueQuantization); + model->setScaleUnits(units); + model->setObjectName(name); + m_models[id] = model; } - model->setValueQuantization(valueQuantization); - model->setScaleUnits(units); - model->setObjectName(name); - m_models[id] = model; - } + } int dataset = attributes.value("dataset").trimmed().toInt(&ok); if (ok) m_awaitingDatasets[dataset] = id; @@ -897,6 +915,7 @@ case 3: if (dynamic_cast<NoteModel *>(model)) good = true; + else if (dynamic_cast<RegionModel *>(model)) good = true; else if (dynamic_cast<EditableDenseThreeDimensionalModel *>(model)) { m_datasetSeparator = attributes.value("separator"); good = true; @@ -963,6 +982,19 @@ return ok; } + RegionModel *rm = dynamic_cast<RegionModel *>(m_currentDataset); + + if (rm) { +// std::cerr << "Current dataset is a note model" << std::endl; + float value = 0.0; + value = attributes.value("value").trimmed().toFloat(&ok); + size_t duration = 0; + duration = attributes.value("duration").trimmed().toUInt(&ok); + QString label = attributes.value("label"); + rm->addPoint(RegionModel::Point(frame, value, duration, label)); + return ok; + } + TextModel *tm = dynamic_cast<TextModel *>(m_currentDataset); if (tm) { Modified: sonic-visualiser/trunk/sv.prf =================================================================== --- sonic-visualiser/trunk/sv.prf 2008-10-08 15:27:31 UTC (rev 1233) +++ sonic-visualiser/trunk/sv.prf 2008-10-09 12:04:22 UTC (rev 1234) @@ -3,7 +3,7 @@ ### BEGIN CONFIGURABLE STUFF ### -CONFIG += release +CONFIG += debug # Temporarily This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-10-09 13:13:35
|
Revision: 1236 http://sv1.svn.sourceforge.net/sv1/?rev=1236&view=rev Author: cannam Date: 2008-10-09 13:13:33 +0000 (Thu, 09 Oct 2008) Log Message: ----------- * Support transforms that output regions with more than one bin (by creating more than one region) * When model displayed in the spreadsheet dialog is deleted, close the dialog in preference to crashing Modified Paths: -------------- sonic-visualiser/trunk/data/model/ModelDataTableModel.cpp sonic-visualiser/trunk/data/model/ModelDataTableModel.h sonic-visualiser/trunk/transform/FeatureExtractionModelTransformer.cpp sonic-visualiser/trunk/widgets/ModelDataTableDialog.cpp sonic-visualiser/trunk/widgets/ModelDataTableDialog.h Modified: sonic-visualiser/trunk/data/model/ModelDataTableModel.cpp =================================================================== --- sonic-visualiser/trunk/data/model/ModelDataTableModel.cpp 2008-10-09 12:22:02 UTC (rev 1235) +++ sonic-visualiser/trunk/data/model/ModelDataTableModel.cpp 2008-10-09 13:13:33 UTC (rev 1236) @@ -33,6 +33,8 @@ connect(baseModel, SIGNAL(modelChanged()), this, SLOT(modelChanged())); connect(baseModel, SIGNAL(modelChanged(size_t, size_t)), this, SLOT(modelChanged(size_t, size_t))); + connect(baseModel, SIGNAL(aboutToBeDeleted()), + this, SLOT(modelAboutToBeDeleted())); } ModelDataTableModel::~ModelDataTableModel() @@ -42,6 +44,7 @@ QVariant ModelDataTableModel::data(const QModelIndex &index, int role) const { + if (!m_model) return QVariant(); if (role != Qt::EditRole && role != Qt::DisplayRole) return QVariant(); if (!index.isValid()) return QVariant(); return m_model->getData(getUnsorted(index.row()), index.column(), role); @@ -50,6 +53,7 @@ bool ModelDataTableModel::setData(const QModelIndex &index, const QVariant &value, int role) { + if (!m_model) return false; if (!index.isValid()) return false; Command *command = m_model->getSetDataCommand(getUnsorted(index.row()), index.column(), @@ -65,6 +69,7 @@ bool ModelDataTableModel::insertRow(int row, const QModelIndex &parent) { + if (!m_model) return false; if (parent.isValid()) return false; emit beginInsertRows(parent, row, row); @@ -83,6 +88,7 @@ bool ModelDataTableModel::removeRow(int row, const QModelIndex &parent) { + if (!m_model) return false; if (parent.isValid()) return false; emit beginRemoveRows(parent, row, row); @@ -109,6 +115,8 @@ QVariant ModelDataTableModel::headerData(int section, Qt::Orientation orientation, int role) const { + if (!m_model) return QVariant(); + if (orientation == Qt::Vertical && role == Qt::DisplayRole) { return section + 1; } @@ -133,6 +141,7 @@ int ModelDataTableModel::rowCount(const QModelIndex &parent) const { + if (!m_model) return 0; if (parent.isValid()) return 0; return m_model->getRowCount(); } @@ -140,6 +149,7 @@ int ModelDataTableModel::columnCount(const QModelIndex &parent) const { + if (!m_model) return 0; if (parent.isValid()) return 0; return m_model->getColumnCount(); } @@ -147,6 +157,7 @@ QModelIndex ModelDataTableModel::getModelIndexForFrame(size_t frame) const { + if (!m_model) return createIndex(0, 0); int row = m_model->getRowForFrame(frame); return createIndex(getSorted(row), 0, 0); } @@ -154,6 +165,7 @@ size_t ModelDataTableModel::getFrameForModelIndex(const QModelIndex &index) const { + if (!m_model) return 0; return m_model->getFrameForRow(getUnsorted(index.row())); } @@ -191,9 +203,18 @@ emit layoutChanged(); } +void +ModelDataTableModel::modelAboutToBeDeleted() +{ + m_model = 0; + emit modelRemoved(); +} + int ModelDataTableModel::getSorted(int row) const { + if (!m_model) return row; + if (m_model->isColumnTimeValue(m_sortColumn)) { if (m_sortOrdering == Qt::AscendingOrder) { return row; @@ -219,6 +240,8 @@ int ModelDataTableModel::getUnsorted(int row) const { + if (!m_model) return row; + if (m_model->isColumnTimeValue(m_sortColumn)) { if (m_sortOrdering == Qt::AscendingOrder) { return row; @@ -246,6 +269,8 @@ void ModelDataTableModel::resort() const { + if (!m_model) return; + bool numeric = (m_model->getSortType(m_sortColumn) == TabularModel::SortNumeric); @@ -275,6 +300,8 @@ void ModelDataTableModel::resortNumeric() const { + if (!m_model) return; + typedef std::multimap<double, int> MapType; MapType rowMap; @@ -295,6 +322,8 @@ void ModelDataTableModel::resortAlphabetical() const { + if (!m_model) return; + typedef std::multimap<QString, int> MapType; MapType rowMap; Modified: sonic-visualiser/trunk/data/model/ModelDataTableModel.h =================================================================== --- sonic-visualiser/trunk/data/model/ModelDataTableModel.h 2008-10-09 12:22:02 UTC (rev 1235) +++ sonic-visualiser/trunk/data/model/ModelDataTableModel.h 2008-10-09 13:13:33 UTC (rev 1236) @@ -63,10 +63,12 @@ void frameSelected(size_t); void addCommand(Command *); void currentChanged(const QModelIndex &); + void modelRemoved(); protected slots: void modelChanged(); void modelChanged(size_t, size_t); + void modelAboutToBeDeleted(); protected: TabularModel *m_model; Modified: sonic-visualiser/trunk/transform/FeatureExtractionModelTransformer.cpp =================================================================== --- sonic-visualiser/trunk/transform/FeatureExtractionModelTransformer.cpp 2008-10-09 12:22:02 UTC (rev 1235) +++ sonic-visualiser/trunk/transform/FeatureExtractionModelTransformer.cpp 2008-10-09 13:13:33 UTC (rev 1236) @@ -633,16 +633,22 @@ } else if (isOutput<SparseTimeValueModel>()) { - float value = 0.0; - if (feature.values.size() > 0) value = feature.values[0]; - SparseTimeValueModel *model = getConformingOutput<SparseTimeValueModel>(); if (!model) return; - model->addPoint(SparseTimeValueModel::Point - (frame, value, feature.label.c_str())); + for (int i = 0; i < feature.values.size(); ++i) { + float value = feature.values[i]; + + QString label = feature.label.c_str(); + if (feature.values.size() > 1) { + label = QString("[%1] %2").arg(i+1).arg(label); + } + + model->addPoint(SparseTimeValueModel::Point(frame, value, label)); + } + } else if (isOutput<NoteModel>() || isOutput<RegionModel>()) { int index = 0; @@ -678,11 +684,29 @@ feature.label.c_str())); } else { RegionModel *model = getConformingOutput<RegionModel>(); - if (model) { + if (!model) return; + + if (feature.hasDuration) { + + for (int i = 0; i < feature.values.size(); ++i) { + + float value = feature.values[i]; + + QString label = feature.label.c_str(); + if (feature.values.size() > 1) { + label = QString("[%1] %2").arg(i+1).arg(label); + } + + model->addPoint(RegionModel::Point(frame, value, + lrintf(duration), + label)); + } + } else { + model->addPoint(RegionModel::Point(frame, value, lrintf(duration), feature.label.c_str())); - } else return; + } } } else if (isOutput<EditableDenseThreeDimensionalModel>()) { Modified: sonic-visualiser/trunk/widgets/ModelDataTableDialog.cpp =================================================================== --- sonic-visualiser/trunk/widgets/ModelDataTableDialog.cpp 2008-10-09 12:22:02 UTC (rev 1235) +++ sonic-visualiser/trunk/widgets/ModelDataTableDialog.cpp 2008-10-09 13:13:33 UTC (rev 1236) @@ -125,6 +125,8 @@ this, SLOT(addCommand(Command *))); connect(m_table, SIGNAL(currentChanged(const QModelIndex &)), this, SLOT(currentChangedThroughResort(const QModelIndex &))); + connect(m_table, SIGNAL(modelRemoved()), + this, SLOT(modelRemoved())); QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Close); connect(bb, SIGNAL(rejected()), this, SLOT(close())); @@ -268,5 +270,10 @@ makeCurrent(index.row()); } +void +ModelDataTableDialog::modelRemoved() +{ + close(); +} Modified: sonic-visualiser/trunk/widgets/ModelDataTableDialog.h =================================================================== --- sonic-visualiser/trunk/widgets/ModelDataTableDialog.h 2008-10-09 12:22:02 UTC (rev 1235) +++ sonic-visualiser/trunk/widgets/ModelDataTableDialog.h 2008-10-09 13:13:33 UTC (rev 1236) @@ -55,6 +55,8 @@ void editRow(); void togglePlayTracking(); + void modelRemoved(); + protected: void makeCurrent(int row); ModelDataTableModel *m_table; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-10-09 20:10:39
|
Revision: 1237 http://sv1.svn.sourceforge.net/sv1/?rev=1237&view=rev Author: cannam Date: 2008-10-09 20:10:28 +0000 (Thu, 09 Oct 2008) Log Message: ----------- * Fix a nasty and long-standing race condition in MatrixFile's use of FileReadThread that was causing crashes sometimes Modified Paths: -------------- sonic-visualiser/trunk/data/fft/FFTDataServer.cpp sonic-visualiser/trunk/data/fft/FFTFileCache.cpp sonic-visualiser/trunk/data/fileio/FileReadThread.cpp sonic-visualiser/trunk/data/fileio/FileReadThread.h sonic-visualiser/trunk/data/fileio/MatrixFile.cpp sonic-visualiser/trunk/data/fileio/MatrixFile.h sonic-visualiser/trunk/framework/Document.cpp sonic-visualiser/trunk/layer/TimeInstantLayer.cpp sonic-visualiser/trunk/sv.prf Modified: sonic-visualiser/trunk/data/fft/FFTDataServer.cpp =================================================================== --- sonic-visualiser/trunk/data/fft/FFTDataServer.cpp 2008-10-09 13:13:33 UTC (rev 1236) +++ sonic-visualiser/trunk/data/fft/FFTDataServer.cpp 2008-10-09 20:10:28 UTC (rev 1237) @@ -27,7 +27,7 @@ #include "base/Profiler.h" #include "base/Thread.h" // for debug mutex locker -#define DEBUG_FFT_SERVER 1 +//#define DEBUG_FFT_SERVER 1 //#define DEBUG_FFT_SERVER_FILL 1 #ifdef DEBUG_FFT_SERVER_FILL Modified: sonic-visualiser/trunk/data/fft/FFTFileCache.cpp =================================================================== --- sonic-visualiser/trunk/data/fft/FFTFileCache.cpp 2008-10-09 13:13:33 UTC (rev 1236) +++ sonic-visualiser/trunk/data/fft/FFTFileCache.cpp 2008-10-09 20:10:28 UTC (rev 1237) @@ -19,6 +19,7 @@ #include "base/Profiler.h" #include "base/Thread.h" +#include "base/Exceptions.h" #include <iostream> @@ -308,13 +309,19 @@ if (!m_readbuf) { m_readbuf = new char[m_mfc->getHeight() * 2 * m_mfc->getCellSize()]; } - m_mfc->getColumnAt(x, m_readbuf); - if (m_mfc->haveSetColumnAt(x + 1)) { - m_mfc->getColumnAt - (x + 1, m_readbuf + m_mfc->getCellSize() * m_mfc->getHeight()); - m_readbufWidth = 2; - } else { - m_readbufWidth = 1; + try { + m_mfc->getColumnAt(x, m_readbuf); + if (m_mfc->haveSetColumnAt(x + 1)) { + m_mfc->getColumnAt + (x + 1, m_readbuf + m_mfc->getCellSize() * m_mfc->getHeight()); + m_readbufWidth = 2; + } else { + m_readbufWidth = 1; + } + } catch (FileReadFailed f) { + std::cerr << "ERROR: FFTFileCache::populateReadBuf: File read failed: " + << f.what() << std::endl; + memset(m_readbuf, 0, m_mfc->getHeight() * 2 * m_mfc->getCellSize()); } m_readbufCol = x; } Modified: sonic-visualiser/trunk/data/fileio/FileReadThread.cpp =================================================================== --- sonic-visualiser/trunk/data/fileio/FileReadThread.cpp 2008-10-09 13:13:33 UTC (rev 1236) +++ sonic-visualiser/trunk/data/fileio/FileReadThread.cpp 2008-10-09 20:10:28 UTC (rev 1237) @@ -21,7 +21,7 @@ #include <iostream> #include <unistd.h> -#define DEBUG_FILE_READ_THREAD 1 +//#define DEBUG_FILE_READ_THREAD 1 FileReadThread::FileReadThread() : m_nextToken(0), @@ -141,6 +141,24 @@ } bool +FileReadThread::haveRequest(int token) +{ + MutexLocker locker(&m_mutex, "FileReadThread::haveRequest::m_mutex"); + + bool found = false; + + if (m_queue.find(token) != m_queue.end()) { + found = true; + } else if (m_cancelledRequests.find(token) != m_cancelledRequests.end()) { + found = true; + } else if (m_readyRequests.find(token) != m_readyRequests.end()) { + found = true; + } + + return found; +} + +bool FileReadThread::getRequest(int token, Request &request) { MutexLocker locker(&m_mutex, "FileReadThread::getRequest::m_mutex"); @@ -244,6 +262,9 @@ } else { if (r < 0) { ::perror("ERROR: FileReadThread::process: Read failed"); + std::cerr << "ERROR: FileReadThread::process: read of " + << request.size << " at " + << request.start << " failed" << std::endl; request.size = 0; } else if (r < ssize_t(request.size)) { std::cerr << "WARNING: FileReadThread::process: read " @@ -267,11 +288,15 @@ m_queue.erase(token); m_readyRequests[token] = request; #ifdef DEBUG_FILE_READ_THREAD - std::cerr << "FileReadThread::process: done, marking as ready" << std::endl; + std::cerr << "FileReadThread::process: done, marking as ready (success = " << m_readyRequests[token].successful << ")" << std::endl; #endif } else { #ifdef DEBUG_FILE_READ_THREAD - std::cerr << "FileReadThread::process: request disappeared or exiting" << std::endl; + if (m_exiting) { + std::cerr << "FileReadThread::process: exiting" << std::endl; + } else { + std::cerr << "FileReadThread::process: request disappeared" << std::endl; + } #endif } } Modified: sonic-visualiser/trunk/data/fileio/FileReadThread.h =================================================================== --- sonic-visualiser/trunk/data/fileio/FileReadThread.h 2008-10-09 13:13:33 UTC (rev 1236) +++ sonic-visualiser/trunk/data/fileio/FileReadThread.h 2008-10-09 20:10:28 UTC (rev 1237) @@ -50,6 +50,7 @@ virtual bool isReady(int token); virtual bool isCancelled(int token); // and safe to delete + virtual bool haveRequest(int token); virtual bool getRequest(int token, Request &request); virtual void done(int token); Modified: sonic-visualiser/trunk/data/fileio/MatrixFile.cpp =================================================================== --- sonic-visualiser/trunk/data/fileio/MatrixFile.cpp 2008-10-09 13:13:33 UTC (rev 1236) +++ sonic-visualiser/trunk/data/fileio/MatrixFile.cpp 2008-10-09 20:10:28 UTC (rev 1237) @@ -35,7 +35,7 @@ #include <QFileInfo> #include <QDir> -#define DEBUG_MATRIX_FILE 1 +//#define DEBUG_MATRIX_FILE 1 //#define DEBUG_MATRIX_FILE_READ_SET 1 #ifdef DEBUG_MATRIX_FILE_READ_SET @@ -521,8 +521,6 @@ #endif } -static int alloc = 0; - void MatrixFile::primeCache(size_t x, bool goingLeft) { @@ -565,16 +563,30 @@ MutexLocker locker(&m_cacheMutex, "MatrixFile::primeCache::m_cacheMutex"); - FileReadThread::Request request; + // Check for the existence of the request first; if it exists, + // check whether it's ready. Only when we know it's ready do we + // retrieve the actual request, because the reason we need the + // request is to check whether it was successful or not and + // extract data from it, and none of that can be relied upon if we + // retrieve the request before it's ready. (There used to be a + // race condition here, where we retrieved the request and only + // afterwards checked the ready status, pulling data from the + // request if it was found to be ready then.) if (m_requestToken >= 0 && - m_readThread->getRequest(m_requestToken, request)) { + m_readThread->haveRequest(m_requestToken)) { if (x >= m_requestingX && x < m_requestingX + m_requestingWidth) { if (m_readThread->isReady(m_requestToken)) { + FileReadThread::Request request; + if (!m_readThread->getRequest(m_requestToken, request)) { + std::cerr << "ERROR: MatrixFile::primeCache: File read thread has lost our request!" << std::endl; + throw FileReadFailed(m_fileName); + } + if (!request.successful) { std::cerr << "ERROR: MatrixFile::primeCache: Last request was unsuccessful" << std::endl; throw FileReadFailed(m_fileName); @@ -610,25 +622,32 @@ return; } - // the current request is no longer of any use - m_readThread->cancel(m_requestToken); + FileReadThread::Request dud; - // crude way to avoid leaking the data - while (!m_readThread->isCancelled(m_requestToken)) { - usleep(10000); - } + if (!m_readThread->getRequest(m_requestToken, dud)) { + std::cerr << "ERROR: MatrixFile::primeCache: Inconsistent replies from FileReadThread" << std::endl; + + } else { + + // current request is for the wrong area, so no longer of any use + m_readThread->cancel(m_requestToken); + + // crude way to avoid leaking the data + while (!m_readThread->isCancelled(m_requestToken)) { + usleep(10000); + } + #ifdef DEBUG_MATRIX_FILE_READ_SET - std::cerr << "cancelled " << m_requestToken << std::endl; + std::cerr << "cancelled " << m_requestToken << std::endl; #endif - if (m_spareData) { -// std::cerr << this << ": Freeing spare data" << std::endl; - free(m_spareData); + if (m_spareData) { + free(m_spareData); + } + m_spareData = dud.data; + m_readThread->done(m_requestToken); } -// std::cerr << this << ": Moving request data to spare" << std::endl; - m_spareData = request.data; - m_readThread->done(m_requestToken); m_requestToken = -1; } @@ -638,6 +657,8 @@ if (m_fd < 0) resume(); } + FileReadThread::Request request; + request.fd = m_fd; request.mutex = &m_fdMutex; request.start = m_headerSize + rx * m_height * m_cellSize; Modified: sonic-visualiser/trunk/data/fileio/MatrixFile.h =================================================================== --- sonic-visualiser/trunk/data/fileio/MatrixFile.h 2008-10-09 13:13:33 UTC (rev 1236) +++ sonic-visualiser/trunk/data/fileio/MatrixFile.h 2008-10-09 20:10:28 UTC (rev 1237) @@ -68,7 +68,7 @@ void reset(); bool haveSetColumnAt(size_t x) const { return m_columnBitset->get(x); } - void getColumnAt(size_t x, void *data); + void getColumnAt(size_t x, void *data); // may throw FileReadFailed void setColumnAt(size_t x, const void *data); void suspend(); Modified: sonic-visualiser/trunk/framework/Document.cpp =================================================================== --- sonic-visualiser/trunk/framework/Document.cpp 2008-10-09 13:13:33 UTC (rev 1236) +++ sonic-visualiser/trunk/framework/Document.cpp 2008-10-09 20:10:28 UTC (rev 1237) @@ -37,7 +37,7 @@ #include "data/model/SparseTimeValueModel.h" #include "data/model/AlignmentModel.h" -#define DEBUG_DOCUMENT 1 +//#define DEBUG_DOCUMENT 1 //!!! still need to handle command history, documentRestored/documentModified Modified: sonic-visualiser/trunk/layer/TimeInstantLayer.cpp =================================================================== --- sonic-visualiser/trunk/layer/TimeInstantLayer.cpp 2008-10-09 13:13:33 UTC (rev 1236) +++ sonic-visualiser/trunk/layer/TimeInstantLayer.cpp 2008-10-09 20:10:28 UTC (rev 1237) @@ -35,7 +35,7 @@ #include <iostream> #include <cmath> -#define DEBUG_TIME_INSTANT_LAYER 1 +//#define DEBUG_TIME_INSTANT_LAYER 1 TimeInstantLayer::TimeInstantLayer() : SingleColourLayer(), Modified: sonic-visualiser/trunk/sv.prf =================================================================== --- sonic-visualiser/trunk/sv.prf 2008-10-09 13:13:33 UTC (rev 1236) +++ sonic-visualiser/trunk/sv.prf 2008-10-09 20:10:28 UTC (rev 1237) @@ -3,7 +3,7 @@ ### BEGIN CONFIGURABLE STUFF ### -CONFIG += debug +CONFIG += release # Temporarily This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-10-14 16:36:51
|
Revision: 1240 http://sv1.svn.sourceforge.net/sv1/?rev=1240&view=rev Author: cannam Date: 2008-10-14 16:36:35 +0000 (Tue, 14 Oct 2008) Log Message: ----------- * Add beginnings of capability to search plugins that are not yet installed -- lots more work to do here, though Modified Paths: -------------- sonic-visualiser/trunk/base/base.pro sonic-visualiser/trunk/data/fileio/FileSource.cpp sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp sonic-visualiser/trunk/rdf/PluginRDFDescription.h sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp sonic-visualiser/trunk/rdf/PluginRDFIndexer.h sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.cpp sonic-visualiser/trunk/sv/main/MainWindow.cpp sonic-visualiser/trunk/sv/sv.pro sonic-visualiser/trunk/transform/TransformFactory.cpp sonic-visualiser/trunk/transform/TransformFactory.h sonic-visualiser/trunk/widgets/TransformFinder.cpp sonic-visualiser/trunk/widgets/TransformFinder.h Added Paths: ----------- sonic-visualiser/trunk/base/TextMatcher.cpp sonic-visualiser/trunk/base/TextMatcher.h Added: sonic-visualiser/trunk/base/TextMatcher.cpp =================================================================== --- sonic-visualiser/trunk/base/TextMatcher.cpp (rev 0) +++ sonic-visualiser/trunk/base/TextMatcher.cpp 2008-10-14 16:36:35 UTC (rev 1240) @@ -0,0 +1,124 @@ +/* -*- 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 2008 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 "TextMatcher.h" + +TextMatcher::TextMatcher() +{ +} + +TextMatcher::~TextMatcher() +{ +} + +void +TextMatcher::test(Match &match, QStringList keywords, QString text, + QString textType, int score) +{ +/* + if (text.toLower() == keyword.toLower()) { + match.score += score * 1.5; + match.fragments << tr("%1: <b>%2</b>").arg(textType).arg(text); + return; + } +*/ + int len = text.length(); + int prevEnd = 0; + QString fragment; + + while (1) { + + bool first = (prevEnd == 0); + + int idx = -1; + QString keyword; + + for (int ki = 0; ki < keywords.size(); ++ki) { + int midx = text.indexOf(keywords[ki], prevEnd, Qt::CaseInsensitive); + if (midx >= 0 && midx < len) { + if (midx < idx || idx == -1) { + idx = midx; + keyword = keywords[ki]; + } + } + } + + if (idx < 0 || idx >= len) break; + + int klen = keyword.length(); + + if (first) { + match.score += score; + } else { + match.score += score / 4; + } + + int start = idx; + int end = start + klen; + + if (start == 0) match.score += 1; + if (end == len) match.score += 1; + + if (start > prevEnd + 14) { + QString s = text.right((len - start) + 10); + s = XmlExportable::encodeEntities(s.left(10)) + "<b>" + + XmlExportable::encodeEntities(s.left(klen + 10).right(klen)) + + "</b>"; + fragment += QString("...%1").arg(s); + } else { + QString s = text.right(len - prevEnd); + s = XmlExportable::encodeEntities(s.left(start - prevEnd)) + "<b>" + + XmlExportable::encodeEntities(s.left(end - prevEnd).right(klen)) + + "</b>"; + fragment += s; + } + + prevEnd = end; + } + + if (prevEnd > 0 && prevEnd < len) { + int n = len - prevEnd; + fragment += + XmlExportable::encodeEntities(text.right(n).left(n < 8 ? n : 8)); + } + + if (fragment != "") { + match.fragments[textType] = fragment; + } +} + +bool +TextMatcher::Match::operator<(const Match &m) const +{ + if (score != m.score) { + return score < m.score; + } + if (key != m.key) { + return key < m.key; + } + if (fragments.size() != m.fragments.size()) { + return fragments.size() < m.fragments.size(); + } + + for (FragmentMap::const_iterator + i = fragments.begin(), + j = m.fragments.begin(); + i != fragments.end(); ++i, ++j) { + if (i->first != j->first) return i->first < j->first; + if (i->second != j->second) return i->second < j->second; + } + + return false; +} Added: sonic-visualiser/trunk/base/TextMatcher.h =================================================================== --- sonic-visualiser/trunk/base/TextMatcher.h (rev 0) +++ sonic-visualiser/trunk/base/TextMatcher.h 2008-10-14 16:36:35 UTC (rev 1240) @@ -0,0 +1,56 @@ +/* -*- 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 2008 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. +*/ + +#ifndef _TEXT_MATCHER_H_ +#define _TEXT_MATCHER_H_ + +#include <QString> +#include <QStringList> +#include "XmlExportable.h" + +#include <map> + +/// A rather eccentric interface for matching texts in differently-scored fields + +class TextMatcher +{ +public: + TextMatcher(); + virtual ~TextMatcher(); + + struct Match + { + QString key; // This field is not used by TextMatcher + int score; + typedef std::map<QString, QString> FragmentMap; // text type -> fragment + FragmentMap fragments; + + Match() : score(0) { } + Match(const Match &m) : + key(m.key), score(m.score), fragments(m.fragments) { } + + bool operator<(const Match &m) const; // sort by score first + }; + + void test(Match &match, // existing match record to be augmented + QStringList keywords, // search terms + QString text, // to search within + QString textType, // key to use for fragment map + int score); // relative weight for hits within this text type + +}; + + +#endif Modified: sonic-visualiser/trunk/base/base.pro =================================================================== --- sonic-visualiser/trunk/base/base.pro 2008-10-13 13:53:05 UTC (rev 1239) +++ sonic-visualiser/trunk/base/base.pro 2008-10-14 16:36:35 UTC (rev 1240) @@ -40,6 +40,7 @@ Serialiser.h \ StorageAdviser.h \ TempDirectory.h \ + TextMatcher.h \ Thread.h \ UnitDatabase.h \ ViewManagerBase.h \ @@ -67,6 +68,7 @@ Serialiser.cpp \ StorageAdviser.cpp \ TempDirectory.cpp \ + TextMatcher.cpp \ Thread.cpp \ UnitDatabase.cpp \ ViewManagerBase.cpp \ Modified: sonic-visualiser/trunk/data/fileio/FileSource.cpp =================================================================== --- sonic-visualiser/trunk/data/fileio/FileSource.cpp 2008-10-13 13:53:05 UTC (rev 1239) +++ sonic-visualiser/trunk/data/fileio/FileSource.cpp 2008-10-14 16:36:35 UTC (rev 1240) @@ -743,7 +743,9 @@ QString filepart = m_url.path().section('/', -1, -1, QString::SectionSkipEmpty); - QString extension = filepart.section('.', -1); + QString extension = ""; + if (filepart.contains('.')) extension = filepart.section('.', -1); + QString base = filepart; if (extension != "") { base = base.left(base.length() - extension.length() - 1); Modified: sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp 2008-10-13 13:53:05 UTC (rev 1239) +++ sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp 2008-10-14 16:36:35 UTC (rev 1240) @@ -18,6 +18,10 @@ #include "PluginRDFIndexer.h" #include "SimpleSPARQLQuery.h" +#include "data/fileio/FileSource.h" + +#include "base/Profiler.h" + #include "plugin/PluginIdentifier.h" #include <iostream> @@ -25,6 +29,7 @@ using std::endl; PluginRDFDescription::PluginRDFDescription(QString pluginId) : + m_source(0), m_pluginId(pluginId), m_haveDescription(false) { @@ -45,6 +50,7 @@ PluginRDFDescription::~PluginRDFDescription() { + delete m_source; } bool @@ -53,6 +59,44 @@ return m_haveDescription; } +QString +PluginRDFDescription::getPluginName() const +{ + return m_pluginName; +} + +QString +PluginRDFDescription::getPluginDescription() const +{ + return m_pluginDescription; +} + +QString +PluginRDFDescription::getPluginMaker() const +{ + return m_pluginMaker; +} + +QStringList +PluginRDFDescription::getOutputIds() const +{ + QStringList ids; + for (OutputDispositionMap::const_iterator i = m_outputDispositions.begin(); + i != m_outputDispositions.end(); ++i) { + ids.push_back(i->first); + } + return ids; +} + +QString +PluginRDFDescription::getOutputName(QString outputId) const +{ + if (m_outputNames.find(outputId) == m_outputNames.end()) { + return ""; + } + return m_outputNames.find(outputId)->second; +} + PluginRDFDescription::OutputDisposition PluginRDFDescription::getOutputDisposition(QString outputId) const { @@ -104,9 +148,95 @@ bool PluginRDFDescription::indexURL(QString url) { + Profiler profiler("PluginRDFDescription::indexURL"); + QString type, soname, label; PluginIdentifier::parseIdentifier(m_pluginId, type, soname, label); + bool success = true; + + QString local = url; + + if (FileSource::isRemote(url) && + FileSource::canHandleScheme(url)) { + + m_source = new FileSource(url); + if (!m_source->isAvailable()) { + delete m_source; + m_source = 0; + return false; + } + m_source->waitForData(); + local = QUrl::fromLocalFile(m_source->getLocalFilename()).toString(); + } + + if (!indexMetadata(local, label)) success = false; + if (!indexOutputs(local, label)) success = false; + + return success; +} + +bool +PluginRDFDescription::indexMetadata(QString url, QString label) +{ + Profiler profiler("PluginRDFDescription::indexMetadata"); + + QString queryTemplate = + QString( + " PREFIX vamp: <http://purl.org/ontology/vamp/> " + " PREFIX foaf: <http://xmlns.com/foaf/0.1/> " + " PREFIX dc: <http://purl.org/dc/elements/1.1/> " + " SELECT ?%4 FROM <%1> " + " WHERE { " + " ?plugin a vamp:Plugin ; " + " vamp:identifier \"%2\" ; " + " %3 ?%4 . " + " }") + .arg(url) + .arg(label); + + SimpleSPARQLQuery::Value v; + + v = SimpleSPARQLQuery::singleResultQuery + (queryTemplate.arg("vamp:name").arg("name"), "name"); + + if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") { + m_pluginName = v.value; + } + + v = SimpleSPARQLQuery::singleResultQuery + (queryTemplate.arg("dc:description").arg("description"), "description"); + + if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") { + m_pluginDescription = v.value; + } + + v = SimpleSPARQLQuery::singleResultQuery + (QString( + " PREFIX vamp: <http://purl.org/ontology/vamp/> " + " PREFIX foaf: <http://xmlns.com/foaf/0.1/> " + " SELECT ?name FROM <%1> " + " WHERE { " + " ?plugin a vamp:Plugin ; " + " vamp:identifier \"%2\" ; " + " foaf:maker ?maker . " + " ?maker foaf:name ?name . " + " }") + .arg(url) + .arg(label), "name"); + + if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") { + m_pluginMaker = v.value; + } + + return true; +} + +bool +PluginRDFDescription::indexOutputs(QString url, QString label) +{ + Profiler profiler("PluginRDFDescription::indexOutputs"); + SimpleSPARQLQuery query (QString ( @@ -166,6 +296,8 @@ m_outputDispositions[outputId] = OutputSparse; } else if (outputType.contains("TrackLevelOutput")) { m_outputDispositions[outputId] = OutputTrackLevel; + } else { + m_outputDispositions[outputId] = OutputDispositionUnknown; } if (results[i]["unit"].type == SimpleSPARQLQuery::LiteralValue) { @@ -177,14 +309,25 @@ } } + SimpleSPARQLQuery::Value v; + + v = SimpleSPARQLQuery::singleResultQuery + (QString(" PREFIX vamp: <http://purl.org/ontology/vamp/> " + " PREFIX dc: <http://purl.org/dc/elements/1.1/> " + " SELECT ?title FROM <%1> " + " WHERE { <%2> dc:title ?title } ") + .arg(url).arg(outputUri), "title"); + + if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") { + m_outputNames[outputId] = v.value; + } + QString queryTemplate = QString(" PREFIX vamp: <http://purl.org/ontology/vamp/> " " SELECT ?%3 FROM <%1> " " WHERE { <%2> vamp:computes_%3 ?%3 } ") .arg(url).arg(outputUri); - SimpleSPARQLQuery::Value v; - v = SimpleSPARQLQuery::singleResultQuery (queryTemplate.arg("event_type"), "event_type"); Modified: sonic-visualiser/trunk/rdf/PluginRDFDescription.h =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFDescription.h 2008-10-13 13:53:05 UTC (rev 1239) +++ sonic-visualiser/trunk/rdf/PluginRDFDescription.h 2008-10-14 16:36:35 UTC (rev 1240) @@ -17,6 +17,7 @@ #define _PLUGIN_RDF_DESCRIPTION_H_ #include <QString> +#include <QStringList> #include <map> class FileSource; @@ -37,6 +38,13 @@ }; bool haveDescription() const; + + QString getPluginName() const; + QString getPluginDescription() const; + QString getPluginMaker() const; + + QStringList getOutputIds() const; + QString getOutputName(QString outputId) const; OutputDisposition getOutputDisposition(QString outputId) const; QString getOutputEventTypeURI(QString outputId) const; QString getOutputFeatureAttributeURI(QString outputId) const; @@ -47,14 +55,21 @@ typedef std::map<QString, OutputDisposition> OutputDispositionMap; typedef std::map<QString, QString> OutputStringMap; + FileSource *m_source; QString m_pluginId; bool m_haveDescription; + QString m_pluginName; + QString m_pluginDescription; + QString m_pluginMaker; + OutputStringMap m_outputNames; OutputDispositionMap m_outputDispositions; OutputStringMap m_outputEventTypeURIMap; OutputStringMap m_outputFeatureAttributeURIMap; OutputStringMap m_outputSignalTypeURIMap; OutputStringMap m_outputUnitMap; bool indexURL(QString url); + bool indexMetadata(QString url, QString label); + bool indexOutputs(QString url, QString label); }; #endif Modified: sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp 2008-10-13 13:53:05 UTC (rev 1239) +++ sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp 2008-10-14 16:36:35 UTC (rev 1240) @@ -20,6 +20,8 @@ #include "data/fileio/FileSource.h" #include "plugin/PluginIdentifier.h" +#include "base/Profiler.h" + #include <vamp-sdk/PluginHostAdapter.h> #include <QFileInfo> @@ -93,9 +95,9 @@ PluginRDFIndexer::~PluginRDFIndexer() { - while (!m_cache.empty()) { - delete *m_cache.begin(); - m_cache.erase(m_cache.begin()); + while (!m_sources.empty()) { + delete *m_sources.begin(); + m_sources.erase(m_sources.begin()); } } @@ -122,13 +124,7 @@ QString baseUrl = QUrl(uri).toString(QUrl::RemoveFragment); - FileSource source(baseUrl); - if (source.isAvailable()) { - source.waitForData(); - if (indexFile(source.getLocalFilename())) { - m_cache.insert(new FileSource(source)); - } - } + indexURL(baseUrl); if (m_uriToIdMap.find(uri) == m_uriToIdMap.end()) { m_uriToIdMap[uri] = ""; @@ -175,6 +171,23 @@ bool PluginRDFIndexer::indexURL(QString urlString) { + Profiler profiler("PluginRDFIndexer::indexURL"); + + QString localString = urlString; + + if (FileSource::isRemote(urlString) && + FileSource::canHandleScheme(urlString)) { + + FileSource *source = new FileSource(urlString); + if (!source->isAvailable()) { + delete source; + return false; + } + source->waitForData(); + localString = QUrl::fromLocalFile(source->getLocalFilename()).toString(); + m_sources.insert(source); + } + // cerr << "PluginRDFIndexer::indexURL: url = <" << urlString.toStdString() << ">" << endl; SimpleSPARQLQuery query @@ -206,7 +219,7 @@ " } " " } " ) - .arg(urlString)); + .arg(localString)); SimpleSPARQLQuery::ResultList results = query.execute(); Modified: sonic-visualiser/trunk/rdf/PluginRDFIndexer.h =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFIndexer.h 2008-10-13 13:53:05 UTC (rev 1239) +++ sonic-visualiser/trunk/rdf/PluginRDFIndexer.h 2008-10-14 16:36:35 UTC (rev 1240) @@ -41,12 +41,12 @@ protected: PluginRDFIndexer(); + std::set<FileSource *> m_sources; typedef std::map<QString, QString> StringMap; StringMap m_uriToIdMap; StringMap m_idToUriMap; StringMap m_idToDescriptionMap; bool indexFile(QString path); - std::set<FileSource *> m_cache; static PluginRDFIndexer *m_instance; }; Modified: sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.cpp =================================================================== --- sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.cpp 2008-10-13 13:53:05 UTC (rev 1239) +++ sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.cpp 2008-10-14 16:36:35 UTC (rev 1240) @@ -121,7 +121,7 @@ m_reporter(0), m_cancelled(false) { - std::cerr << "SimpleSPARQLQuery::Impl: Query is: \"" << query.toStdString() << "\"" << std::endl; +// std::cerr << "SimpleSPARQLQuery::Impl: Query is: \"" << query.toStdString() << "\"" << std::endl; } SimpleSPARQLQuery::Impl::~Impl() Modified: sonic-visualiser/trunk/sv/main/MainWindow.cpp =================================================================== --- sonic-visualiser/trunk/sv/main/MainWindow.cpp 2008-10-13 13:53:05 UTC (rev 1239) +++ sonic-visualiser/trunk/sv/main/MainWindow.cpp 2008-10-14 16:36:35 UTC (rev 1240) @@ -73,6 +73,8 @@ #include "layer/ColourDatabase.h" #include "widgets/ModelDataTableDialog.h" +#include "rdf/PluginRDFIndexer.h" //!!! + // For version information #include "vamp/vamp.h" #include "vamp-sdk/PluginBase.h" @@ -1223,6 +1225,17 @@ TransformList transforms = TransformFactory::getInstance()->getAllTransformDescriptions(); + //!!! + + PluginRDFIndexer::getInstance()->indexURL("http://www.vamp-plugins.org/rdf/plugins/vamp-example-plugins"); + +// TransformList uninstalled = +// TransformFactory::getInstance()->getUninstalledTransformDescriptions(); +// for (int i = 0; i < uninstalled.size(); ++i) { +// std::cerr << "uninstalled transform: " << uninstalled[i].name.toStdString() << std::endl; +// } + + vector<QString> types = TransformFactory::getInstance()->getAllTransformTypes(); Modified: sonic-visualiser/trunk/sv/sv.pro =================================================================== --- sonic-visualiser/trunk/sv/sv.pro 2008-10-13 13:53:05 UTC (rev 1239) +++ sonic-visualiser/trunk/sv/sv.pro 2008-10-14 16:36:35 UTC (rev 1240) @@ -18,7 +18,7 @@ contains(DEFINES, BUILD_STATIC):LIBS -= -ljack -LIBS = -lsvframework -lsvaudioio -lsvview -lsvlayer -lsvrdf -lsvtransform -lsvwidgets -lsvdata -lsvplugin -lsvbase -lsvsystem $$LIBS +LIBS = -lsvframework -lsvaudioio -lsvview -lsvlayer -lsvrdf -lsvtransform -lsvrdf -lsvwidgets -lsvdata -lsvplugin -lsvbase -lsvsystem $$LIBS PRE_TARGETDEPS += ../view/libsvview.a \ ../layer/libsvlayer.a \ Modified: sonic-visualiser/trunk/transform/TransformFactory.cpp =================================================================== --- sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-10-13 13:53:05 UTC (rev 1239) +++ sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-10-14 16:36:35 UTC (rev 1240) @@ -24,6 +24,9 @@ #include "vamp-sdk/PluginHostAdapter.h" #include "vamp-sdk/hostext/PluginWrapper.h" +#include "rdf/PluginRDFIndexer.h" +#include "rdf/PluginRDFDescription.h" + #include "base/XmlExportable.h" #include <iostream> @@ -44,6 +47,12 @@ return m_instance; } +TransformFactory::TransformFactory() : + m_transformsPopulated(false), + m_uninstalledTransformsPopulated(false) +{ +} + TransformFactory::~TransformFactory() { } @@ -51,7 +60,7 @@ TransformList TransformFactory::getAllTransformDescriptions() { - if (m_transforms.empty()) populateTransforms(); + if (!m_transformsPopulated) populateTransforms(); std::set<TransformDescription> dset; for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); @@ -73,7 +82,7 @@ TransformDescription TransformFactory::getTransformDescription(TransformId id) { - if (m_transforms.empty()) populateTransforms(); + if (!m_transformsPopulated) populateTransforms(); if (m_transforms.find(id) == m_transforms.end()) { return TransformDescription(); @@ -82,10 +91,60 @@ return m_transforms[id]; } +TransformList +TransformFactory::getUninstalledTransformDescriptions() +{ + if (!m_uninstalledTransformsPopulated) populateUninstalledTransforms(); + + std::set<TransformDescription> dset; + for (TransformDescriptionMap::const_iterator i = m_uninstalledTransforms.begin(); + i != m_uninstalledTransforms.end(); ++i) { +// cerr << "inserting transform into set: id = " << i->second.identifier.toStdString() << endl; + dset.insert(i->second); + } + + TransformList list; + for (std::set<TransformDescription>::const_iterator i = dset.begin(); + i != dset.end(); ++i) { +// cerr << "inserting transform into list: id = " << i->identifier.toStdString() << endl; + list.push_back(*i); + } + + return list; +} + +TransformDescription +TransformFactory::getUninstalledTransformDescription(TransformId id) +{ + if (!m_uninstalledTransformsPopulated) populateUninstalledTransforms(); + + if (m_uninstalledTransforms.find(id) == m_uninstalledTransforms.end()) { + return TransformDescription(); + } + + return m_uninstalledTransforms[id]; +} + +TransformFactory::TransformInstallStatus +TransformFactory::getTransformInstallStatus(TransformId id) +{ + if (!m_transformsPopulated) populateTransforms(); + if (!m_uninstalledTransformsPopulated) populateUninstalledTransforms(); + + if (m_transforms.find(id) != m_transforms.end()) { + return TransformInstalled; + } + if (m_uninstalledTransforms.find(id) != m_uninstalledTransforms.end()) { + return TransformNotInstalled; + } + return TransformUnknown; +} + + std::vector<QString> TransformFactory::getAllTransformTypes() { - if (m_transforms.empty()) populateTransforms(); + if (!m_transformsPopulated) populateTransforms(); std::set<QString> types; for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); @@ -104,7 +163,7 @@ std::vector<QString> TransformFactory::getTransformCategories(QString transformType) { - if (m_transforms.empty()) populateTransforms(); + if (!m_transformsPopulated) populateTransforms(); std::set<QString> categories; for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); @@ -131,7 +190,7 @@ std::vector<QString> TransformFactory::getTransformMakers(QString transformType) { - if (m_transforms.empty()) populateTransforms(); + if (!m_transformsPopulated) populateTransforms(); std::set<QString> makers; for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); @@ -216,6 +275,8 @@ m_transforms[identifier] = desc; } + + m_transformsPopulated = true; } void @@ -448,7 +509,74 @@ } } +void +TransformFactory::populateUninstalledTransforms() +{ + if (!m_uninstalledTransforms.empty()) return; + if (m_transforms.empty()) populateTransforms(); + //!!! This will be amazingly slow + + QStringList ids = PluginRDFIndexer::getInstance()->getIndexedPluginIds(); + + for (QStringList::const_iterator i = ids.begin(); i != ids.end(); ++i) { + + PluginRDFDescription desc(*i); + + QString name = desc.getPluginName(); +// if (name == "") { +// std::cerr << "TransformFactory::populateUninstalledTransforms: " +// << "No name available for plugin " << i->toStdString() +// << ", skipping" << std::endl; +// continue; +// } + + QString description = desc.getPluginDescription(); + QString maker = desc.getPluginMaker(); + + QStringList oids = desc.getOutputIds(); + + for (QStringList::const_iterator j = oids.begin(); j != oids.end(); ++j) { + + TransformId tid = Transform::getIdentifierForPluginOutput(*i, *j); + + if (m_transforms.find(tid) != m_transforms.end()) { + std::cerr << "TransformFactory::populateUninstalledTransforms: " + << tid.toStdString() << " is installed, skipping" << std::endl; + continue; + } + + std::cerr << "TransformFactory::populateUninstalledTransforms: " + << "adding " << tid.toStdString() << std::endl; + + QString oname = desc.getOutputName(*j); + if (oname == "") oname = *j; + + TransformDescription td; + td.type = tr("Analysis"); //!!! should be enum or something + td.category = ""; + td.identifier = tid; + + if (oids.size() == 1) { + td.name = name; + } else if (name != "") { + td.name = tr("%1: %2").arg(name).arg(oname); + } + + td.friendlyName = name; //!!!??? + td.description = description; + td.longDescription = ""; //!!! + td.maker = maker; + td.units = ""; + td.configurable = false; + + m_uninstalledTransforms[tid] = td; + } + } + + m_uninstalledTransformsPopulated = true; +} + Transform TransformFactory::getDefaultTransformFor(TransformId id, size_t rate) { @@ -787,27 +915,6 @@ setParametersFromPlugin(t, plugin); delete plugin; } -/* -TransformFactory::SearchResults -TransformFactory::search(QStringList keywords) -{ - SearchResults results; - SearchResults partial; - for (int i = 0; i < keywords.size(); ++i) { - partial = search(keywords[i]); - for (SearchResults::const_iterator j = partial.begin(); - j != partial.end(); ++j) { - if (results.find(j->first) == results.end()) { - results[j->first] = j->second; - } else { - results[j->first].score += j->second.score; - results[j->first].fragments << j->second.fragments; - } - } - } - return results; -} -*/ TransformFactory::SearchResults TransformFactory::search(QString keyword) @@ -828,125 +935,46 @@ } SearchResults results; + TextMatcher matcher; for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); i != m_transforms.end(); ++i) { - Match match; + TextMatcher::Match match; - match.transform = i->first; + match.key = i->first; - searchTest(match, keywords, i->second.type, tr("Plugin type"), 10); - searchTest(match, keywords, i->second.category, tr("Category"), 20); - searchTest(match, keywords, i->second.identifier, tr("System Identifier"), 5); - searchTest(match, keywords, i->second.name, tr("Name"), 30); - searchTest(match, keywords, i->second.description, tr("Description"), 20); - searchTest(match, keywords, i->second.maker, tr("Maker"), 10); - searchTest(match, keywords, i->second.units, tr("Units"), 10); + matcher.test(match, keywords, i->second.type, tr("Plugin type"), 5); + matcher.test(match, keywords, i->second.category, tr("Category"), 20); + matcher.test(match, keywords, i->second.identifier, tr("System Identifier"), 6); + matcher.test(match, keywords, i->second.name, tr("Name"), 30); + matcher.test(match, keywords, i->second.description, tr("Description"), 20); + matcher.test(match, keywords, i->second.maker, tr("Maker"), 10); + matcher.test(match, keywords, i->second.units, tr("Units"), 10); if (match.score > 0) results[i->first] = match; } - return results; -} + if (m_uninstalledTransforms.empty()) populateUninstalledTransforms(); -void -TransformFactory::searchTest(Match &match, QStringList keywords, QString text, - QString textType, int score) -{ -/* - if (text.toLower() == keyword.toLower()) { - match.score += score * 1.5; - match.fragments << tr("%1: <b>%2</b>").arg(textType).arg(text); - return; - } -*/ - int len = text.length(); - int prevEnd = 0; - QString fragment; + for (TransformDescriptionMap::const_iterator i = m_uninstalledTransforms.begin(); + i != m_uninstalledTransforms.end(); ++i) { - while (1) { + TextMatcher::Match match; - bool first = (prevEnd == 0); + match.key = i->first; - int idx = -1; - QString keyword; + matcher.test(match, keywords, i->second.type, tr("Plugin type"), 2); + matcher.test(match, keywords, i->second.category, tr("Category"), 10); + matcher.test(match, keywords, i->second.identifier, tr("System Identifier"), 3); + matcher.test(match, keywords, i->second.name, tr("Name"), 15); + matcher.test(match, keywords, i->second.description, tr("Description"), 10); + matcher.test(match, keywords, i->second.maker, tr("Maker"), 5); + matcher.test(match, keywords, i->second.units, tr("Units"), 5); - for (int ki = 0; ki < keywords.size(); ++ki) { - int midx = text.indexOf(keywords[ki], prevEnd, Qt::CaseInsensitive); - if (midx >= 0 && midx < len) { - if (midx < idx || idx == -1) { - idx = midx; - keyword = keywords[ki]; - } - } - } - - if (idx < 0 || idx >= len) break; - - int klen = keyword.length(); - - if (first) { - match.score += score; - } else { - match.score += score / 4; - } - - int start = idx; - int end = start + klen; - - if (start == 0) match.score += 1; - if (end == len) match.score += 1; - - if (start > prevEnd + 14) { - QString s = text.right((len - start) + 10); - s = XmlExportable::encodeEntities(s.left(10)) + "<b>" + - XmlExportable::encodeEntities(s.left(klen + 10).right(klen)) - + "</b>"; - fragment += tr("...%1").arg(s); - } else { - QString s = text.right(len - prevEnd); - s = XmlExportable::encodeEntities(s.left(start - prevEnd)) + "<b>" + - XmlExportable::encodeEntities(s.left(end - prevEnd).right(klen)) - + "</b>"; - fragment += s; - } - - prevEnd = end; + if (match.score > 0) results[i->first] = match; } - if (prevEnd > 0 && prevEnd < len) { - int n = len - prevEnd; - fragment += - XmlExportable::encodeEntities(text.right(n).left(n < 8 ? n : 8)); - } - - if (fragment != "") { - match.fragments[textType] = fragment; - } + return results; } -bool -TransformFactory::Match::operator<(const Match &m) const -{ - if (score != m.score) { - return score < m.score; - } - if (transform != m.transform) { - return transform < m.transform; - } - if (fragments.size() != m.fragments.size()) { - return fragments.size() < m.fragments.size(); - } - - for (FragmentMap::const_iterator - i = fragments.begin(), - j = m.fragments.begin(); - i != fragments.end(); ++i, ++j) { - if (i->first != j->first) return i->first < j->first; - if (i->second != j->second) return i->second < j->second; - } - - return false; -} - Modified: sonic-visualiser/trunk/transform/TransformFactory.h =================================================================== --- sonic-visualiser/trunk/transform/TransformFactory.h 2008-10-13 13:53:05 UTC (rev 1239) +++ sonic-visualiser/trunk/transform/TransformFactory.h 2008-10-14 16:36:35 UTC (rev 1240) @@ -18,6 +18,8 @@ #include "TransformDescription.h" +#include "base/TextMatcher.h" + #include <vamp-sdk/Plugin.h> #include <QObject> @@ -31,6 +33,7 @@ Q_OBJECT public: + TransformFactory(); virtual ~TransformFactory(); static TransformFactory *getInstance(); @@ -38,25 +41,22 @@ TransformList getAllTransformDescriptions(); TransformDescription getTransformDescription(TransformId id); + TransformList getUninstalledTransformDescriptions(); + TransformDescription getUninstalledTransformDescription(TransformId id); + + typedef enum { + TransformUnknown, + TransformInstalled, + TransformNotInstalled + } TransformInstallStatus; + + TransformInstallStatus getTransformInstallStatus(TransformId id); + std::vector<QString> getAllTransformTypes(); std::vector<QString> getTransformCategories(QString transformType); std::vector<QString> getTransformMakers(QString transformType); - struct Match - { - TransformId transform; - int score; - typedef std::map<QString, QString> FragmentMap; - FragmentMap fragments; - - Match() : score(0) { } - Match(const Match &m) : - transform(m.transform), score(m.score), fragments(m.fragments) { } - - bool operator<(const Match &m) const; // sort by score first - }; - - typedef std::map<TransformId, Match> SearchResults; + typedef std::map<TransformId, TextMatcher::Match> SearchResults; SearchResults search(QString keyword); SearchResults search(QStringList keywords); @@ -178,15 +178,18 @@ protected: typedef std::map<TransformId, TransformDescription> TransformDescriptionMap; + TransformDescriptionMap m_transforms; + bool m_transformsPopulated; + TransformDescriptionMap m_uninstalledTransforms; + bool m_uninstalledTransformsPopulated; + void populateTransforms(); + void populateUninstalledTransforms(); void populateFeatureExtractionPlugins(TransformDescriptionMap &); void populateRealTimePlugins(TransformDescriptionMap &); - void searchTest(Match &match, QStringList keywords, QString text, - QString textType, int score); - Vamp::PluginBase *instantiateDefaultPluginFor(TransformId id, size_t rate); static TransformFactory *m_instance; Modified: sonic-visualiser/trunk/widgets/TransformFinder.cpp =================================================================== --- sonic-visualiser/trunk/widgets/TransformFinder.cpp 2008-10-13 13:53:05 UTC (rev 1239) +++ sonic-visualiser/trunk/widgets/TransformFinder.cpp 2008-10-14 16:36:35 UTC (rev 1240) @@ -131,7 +131,7 @@ std::cerr << results.size() << " result(s)..." << std::endl; - std::set<TransformFactory::Match> sorted; + std::set<TextMatcher::Match> sorted; sorted.clear(); for (TransformFactory::SearchResults::const_iterator j = results.begin(); j != results.end(); ++j) { @@ -139,7 +139,7 @@ } m_sortedResults.clear(); - for (std::set<TransformFactory::Match>::const_iterator j = sorted.end(); + for (std::set<TextMatcher::Match>::const_iterator j = sorted.end(); j != sorted.begin(); ) { --j; m_sortedResults.push_back(*j); @@ -147,7 +147,7 @@ } if (m_sortedResults.empty()) m_selectedTransform = ""; - else m_selectedTransform = m_sortedResults.begin()->transform; + else m_selectedTransform = m_sortedResults.begin()->key; m_upToDateCount = 0; @@ -164,18 +164,29 @@ int i = m_upToDateCount; - std::cerr << "sorted size = " << m_sortedResults.size() << std::endl; +// std::cerr << "sorted size = " << m_sortedResults.size() << std::endl; - TransformDescription desc = - TransformFactory::getInstance()->getTransformDescription - (m_sortedResults[i].transform); + TransformDescription desc; + TransformId tid = m_sortedResults[i].key; + TransformFactory *factory = TransformFactory::getInstance(); + TransformFactory::TransformInstallStatus status = + factory->getTransformInstallStatus(tid); + QString suffix; + if (status == TransformFactory::TransformInstalled) { + desc = factory->getTransformDescription(tid); + } else { + desc = factory->getUninstalledTransformDescription(tid); + suffix = tr("<i> (not installed)</i>"); + } + QString labelText; - labelText += tr("%1<br><small>") - .arg(XmlExportable::encodeEntities(desc.name)); + labelText += tr("%1%2<br><small>") + .arg(XmlExportable::encodeEntities(desc.name)) + .arg(suffix); labelText += "..."; - for (TransformFactory::Match::FragmentMap::const_iterator k = + for (TextMatcher::Match::FragmentMap::const_iterator k = m_sortedResults[i].fragments.begin(); k != m_sortedResults[i].fragments.end(); ++k) { labelText += k->second; @@ -184,16 +195,28 @@ labelText += tr("</small>"); QString selectedText; - selectedText += tr("<b>%1</b><br>") - .arg(XmlExportable::encodeEntities(desc.name)); - selectedText += tr("<small>%1</small>") - .arg(XmlExportable::encodeEntities(desc.longDescription)); + selectedText += tr("<b>%1</b>%2<br>") + .arg(XmlExportable::encodeEntities + (desc.name == "" ? desc.identifier : desc.name)) + .arg(suffix); + if (desc.longDescription != "") { + selectedText += tr("<small>%1</small>") + .arg(XmlExportable::encodeEntities(desc.longDescription)); + } else if (desc.description != "") { + selectedText += tr("<small>%1</small>") + .arg(XmlExportable::encodeEntities(desc.description)); + } + selectedText += tr("<br><small>"); - selectedText += tr(" — Plugin type: %1<br>") - .arg(XmlExportable::encodeEntities(desc.type)); - selectedText += tr(" — Category: %1<br>") - .arg(XmlExportable::encodeEntities(desc.category)); + if (desc.type != "") { + selectedText += tr(" — Plugin type: %1<br>") + .arg(XmlExportable::encodeEntities(desc.type)); + } + if (desc.category != "") { + selectedText += tr(" — Category: %1<br>") + .arg(XmlExportable::encodeEntities(desc.category)); + } selectedText += tr(" — System identifier: %1") .arg(XmlExportable::encodeEntities(desc.identifier)); selectedText += tr("</small>"); Modified: sonic-visualiser/trunk/widgets/TransformFinder.h =================================================================== --- sonic-visualiser/trunk/widgets/TransformFinder.h 2008-10-13 13:53:05 UTC (rev 1239) +++ sonic-visualiser/trunk/widgets/TransformFinder.h 2008-10-14 16:36:35 UTC (rev 1240) @@ -56,7 +56,7 @@ QTimer *m_timer; QString m_newSearchText; - typedef std::vector<TransformFactory::Match> SortedResults; + typedef std::vector<TextMatcher::Match> SortedResults; SortedResults m_sortedResults; int m_upToDateCount; }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-10-15 12:08:15
|
Revision: 1241 http://sv1.svn.sourceforge.net/sv1/?rev=1241&view=rev Author: cannam Date: 2008-10-15 12:08:02 +0000 (Wed, 15 Oct 2008) Log Message: ----------- * Fix race condition in FFTFileCache when reading from the same FFT model from multiple threads (e.g. when applying more than one plugin at once) Modified Paths: -------------- sonic-visualiser/trunk/data/fft/FFTFileCache.cpp sonic-visualiser/trunk/data/fft/FFTFileCache.h sonic-visualiser/trunk/layer/RegionLayer.cpp Modified: sonic-visualiser/trunk/data/fft/FFTFileCache.cpp =================================================================== --- sonic-visualiser/trunk/data/fft/FFTFileCache.cpp 2008-10-14 16:36:35 UTC (rev 1240) +++ sonic-visualiser/trunk/data/fft/FFTFileCache.cpp 2008-10-15 12:08:02 UTC (rev 1241) @@ -72,16 +72,21 @@ MutexLocker locker(&m_writeMutex, "FFTFileCache::resize::m_writeMutex"); m_mfc->resize(width, height * 2 + m_factorSize); - if (m_readbuf) { - delete[] m_readbuf; - m_readbuf = 0; + + { + MutexLocker locker(&m_readbufMutex, "FFTFileCache::resize::m_readMutex"); + if (m_readbuf) { + delete[] m_readbuf; + m_readbuf = 0; + } } + if (m_writebuf) { delete[] m_writebuf; } m_writebuf = new char[(height * 2 + m_factorSize) * m_mfc->getCellSize()]; } - + void FFTFileCache::reset() { @@ -302,7 +307,7 @@ } void -FFTFileCache::populateReadBuf(size_t x) const +FFTFileCache::populateReadBuf(size_t x) const // m_readbufMutex already held { Profiler profiler("FFTFileCache::populateReadBuf", false); Modified: sonic-visualiser/trunk/data/fft/FFTFileCache.h =================================================================== --- sonic-visualiser/trunk/data/fft/FFTFileCache.h 2008-10-14 16:36:35 UTC (rev 1240) +++ sonic-visualiser/trunk/data/fft/FFTFileCache.h 2008-10-15 12:08:02 UTC (rev 1241) @@ -62,31 +62,43 @@ mutable size_t m_readbufWidth; float getFromReadBufStandard(size_t x, size_t y) const { + m_readbufMutex.lock(); if (m_readbuf && (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) { - return ((float *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y]; + float v = ((float *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y]; + m_readbufMutex.unlock(); + return v; } else { populateReadBuf(x); + m_readbufMutex.unlock(); return getFromReadBufStandard(x, y); } } float getFromReadBufCompactUnsigned(size_t x, size_t y) const { + m_readbufMutex.lock(); if (m_readbuf && (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) { - return ((uint16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y]; + float v = ((uint16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y]; + m_readbufMutex.unlock(); + return v; } else { populateReadBuf(x); + m_readbufMutex.unlock(); return getFromReadBufCompactUnsigned(x, y); } } float getFromReadBufCompactSigned(size_t x, size_t y) const { + m_readbufMutex.lock(); if (m_readbuf && (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) { - return ((int16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y]; + float v = ((int16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y]; + m_readbufMutex.unlock(); + return v; } else { populateReadBuf(x); + m_readbufMutex.unlock(); return getFromReadBufCompactSigned(x, y); } } @@ -99,6 +111,7 @@ if (m_storageType != Compact) { return getFromReadBufStandard(col, h - 1); } else { + m_readbufMutex.lock(); union { float f; uint16_t u[2]; @@ -111,6 +124,7 @@ size_t ix = (col - m_readbufCol) * m_mfc->getHeight() + h; factor.u[0] = ((uint16_t *)m_readbuf)[ix - 2]; factor.u[1] = ((uint16_t *)m_readbuf)[ix - 1]; + m_readbufMutex.unlock(); return factor.f; } } @@ -133,6 +147,7 @@ MatrixFile *m_mfc; QMutex m_writeMutex; + mutable QMutex m_readbufMutex; StorageType m_storageType; size_t m_factorSize; }; Modified: sonic-visualiser/trunk/layer/RegionLayer.cpp =================================================================== --- sonic-visualiser/trunk/layer/RegionLayer.cpp 2008-10-14 16:36:35 UTC (rev 1240) +++ sonic-visualiser/trunk/layer/RegionLayer.cpp 2008-10-15 12:08:02 UTC (rev 1241) @@ -501,8 +501,8 @@ getScaleExtents(v, min, max, logarithmic); - std::cerr << "RegionLayer[" << this << "]::getYForValue(" << val << "): min = " << min << ", max = " << max << ", log = " << logarithmic << std::endl; - std::cerr << "h = " << h << ", margin = " << margin << std::endl; +// std::cerr << "RegionLayer[" << this << "]::getYForValue(" << val << "): min = " << min << ", max = " << max << ", log = " << logarithmic << std::endl; +// std::cerr << "h = " << h << ", margin = " << margin << std::endl; if (logarithmic) { val = LogRange::map(val); @@ -511,7 +511,7 @@ h -= margin * 2; int y = margin + int(h - ((val - min) * h) / (max - min)) - 1; - std::cerr << "y = " << y << std::endl; +// std::cerr << "y = " << y << std::endl; return y; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-10-16 13:38:47
|
Revision: 1242 http://sv1.svn.sourceforge.net/sv1/?rev=1242&view=rev Author: cannam Date: 2008-10-16 13:38:33 +0000 (Thu, 16 Oct 2008) Log Message: ----------- * somewhat clearer layout in region layer Modified Paths: -------------- sonic-visualiser/trunk/data/model/IntervalModel.h sonic-visualiser/trunk/data/model/RegionModel.h sonic-visualiser/trunk/data/model/SparseModel.h sonic-visualiser/trunk/layer/RegionLayer.cpp sonic-visualiser/trunk/layer/RegionLayer.h Modified: sonic-visualiser/trunk/data/model/IntervalModel.h =================================================================== --- sonic-visualiser/trunk/data/model/IntervalModel.h 2008-10-15 12:08:02 UTC (rev 1241) +++ sonic-visualiser/trunk/data/model/IntervalModel.h 2008-10-16 13:38:33 UTC (rev 1242) @@ -57,6 +57,10 @@ */ virtual typename SparseValueModel<PointType>::PointList getPoints(long frame) const; + virtual const typename SparseModel<PointType>::PointList &getPoints() const { + return SparseModel<PointType>::getPoints(); + } + /** * TabularModel methods. */ Modified: sonic-visualiser/trunk/data/model/RegionModel.h =================================================================== --- sonic-visualiser/trunk/data/model/RegionModel.h 2008-10-15 12:08:02 UTC (rev 1241) +++ sonic-visualiser/trunk/data/model/RegionModel.h 2008-10-16 13:38:33 UTC (rev 1242) @@ -101,8 +101,8 @@ } RegionModel(size_t sampleRate, size_t resolution, - float valueMinimum, float valueMaximum, - bool notifyOnAdd = true) : + float valueMinimum, float valueMaximum, + bool notifyOnAdd = true) : IntervalModel<RegionRec>(sampleRate, resolution, valueMinimum, valueMaximum, notifyOnAdd), Modified: sonic-visualiser/trunk/data/model/SparseModel.h =================================================================== --- sonic-visualiser/trunk/data/model/SparseModel.h 2008-10-15 12:08:02 UTC (rev 1241) +++ sonic-visualiser/trunk/data/model/SparseModel.h 2008-10-16 13:38:33 UTC (rev 1242) @@ -79,6 +79,11 @@ virtual size_t getPointCount() const; /** + * Get all points. + */ + virtual const PointList &getPoints() const; + + /** * Get all of the points in this model between the given * boundaries (in frames), as well as up to two points before and * after the boundaries. If you need exact boundaries, check the @@ -93,11 +98,6 @@ virtual PointList getPoints(long frame) const; /** - * Get all points. - */ - virtual const PointList &getPoints() const { return m_points; } - - /** * Return all points that share the nearest frame number prior to * the given one at which there are any points. */ @@ -477,6 +477,13 @@ } template <typename PointType> +const typename SparseModel<PointType>::PointList & +SparseModel<PointType>::getPoints() const +{ + return m_points; +} + +template <typename PointType> typename SparseModel<PointType>::PointList SparseModel<PointType>::getPoints(long start, long end) const { Modified: sonic-visualiser/trunk/layer/RegionLayer.cpp =================================================================== --- sonic-visualiser/trunk/layer/RegionLayer.cpp 2008-10-15 12:08:02 UTC (rev 1241) +++ sonic-visualiser/trunk/layer/RegionLayer.cpp 2008-10-16 13:38:33 UTC (rev 1242) @@ -43,7 +43,7 @@ m_originalPoint(0, 0.0, 0, tr("New Point")), m_editingPoint(0, 0.0, 0, tr("New Point")), m_editingCommand(0), - m_verticalScale(AutoAlignScale), + m_verticalScale(EqualSpaced), m_colourMap(0), m_plotStyle(PlotLines) { @@ -58,6 +58,9 @@ connectSignals(m_model); + connect(m_model, SIGNAL(modelChanged()), this, SLOT(recalcSpacing())); + recalcSpacing(); + // std::cerr << "RegionLayer::setModel(" << model << ")" << std::endl; emit modelReplaced(); @@ -127,7 +130,7 @@ if (min) *min = 0; if (max) *max = 3; - if (deflt) *deflt = int(AutoAlignScale); + if (deflt) *deflt = int(EqualSpaced); val = int(m_verticalScale); @@ -165,8 +168,9 @@ switch (value) { default: case 0: return tr("Auto-Align"); - case 1: return tr("Linear"); - case 2: return tr("Log"); + case 1: return tr("Equal Spaced"); + case 2: return tr("Linear"); + case 3: return tr("Log"); } } return SingleColourLayer::getPropertyValueLabel(name, value); @@ -228,6 +232,27 @@ return !v->shouldIlluminateLocalFeatures(this, discard); } +void +RegionLayer::recalcSpacing() +{ + m_spacingMap.clear(); + if (!m_model) return; + + std::set<float> values; + + for (RegionModel::PointList::const_iterator i = m_model->getPoints().begin(); + i != m_model->getPoints().end(); ++i) { + values.insert(i->value); + } + + int n = 0; + + for (std::set<float>::const_iterator i = values.begin(); + i != values.end(); ++i) { + m_spacingMap[*i] = n++; + } +} + bool RegionLayer::getValueExtents(float &min, float &max, bool &logarithmic, QString &unit) const @@ -245,7 +270,9 @@ bool RegionLayer::getDisplayExtents(float &min, float &max) const { - if (!m_model || m_verticalScale == AutoAlignScale) return false; + if (!m_model || + m_verticalScale == AutoAlignScale || + m_verticalScale == EqualSpaced) return false; min = m_model->getValueMinimum(); max = m_model->getValueMaximum(); @@ -476,6 +503,17 @@ } + } else if (m_verticalScale == EqualSpaced) { + + if (!m_spacingMap.empty()) { + SpacingMap::const_iterator i = m_spacingMap.begin(); + min = i->second; + i = m_spacingMap.end(); + --i; + max = i->second; + std::cerr << "RegionLayer[" << this << "]::getScaleExtents: equal spaced; min = " << min << ", max = " << max << ", log = " << log << std::endl; + } + } else { min = m_model->getValueMinimum(); @@ -496,23 +534,34 @@ float min = 0.0, max = 0.0; bool logarithmic = false; int h = v->height(); - int margin = 8; - if (h < margin * 8) margin = h / 8; - getScaleExtents(v, min, max, logarithmic); + if (m_verticalScale == EqualSpaced) { + if (m_spacingMap.empty()) return h/2; + + SpacingMap::const_iterator i = m_spacingMap.lower_bound(val); + //!!! what now, if i->first != v? + + int vh = i->second; + + SpacingMap::const_iterator j = m_spacingMap.end(); + --j; + + return h - (((h * vh) / (j->second + 1)) + (h / (2 * (j->second + 1)))); + + } else { + + getScaleExtents(v, min, max, logarithmic); + // std::cerr << "RegionLayer[" << this << "]::getYForValue(" << val << "): min = " << min << ", max = " << max << ", log = " << logarithmic << std::endl; // std::cerr << "h = " << h << ", margin = " << margin << std::endl; - if (logarithmic) { - val = LogRange::map(val); - std::cerr << "logarithmic true, val now = " << val << std::endl; + if (logarithmic) { + val = LogRange::map(val); + } + + return int(h - ((val - min) * h) / (max - min)); } - - h -= margin * 2; - int y = margin + int(h - ((val - min) * h) / (max - min)) - 1; -// std::cerr << "y = " << y << std::endl; - return y; } QColor @@ -624,17 +673,15 @@ int y = getYForValue(v, p.value); int w = v->getXForFrame(p.frame + p.duration) - x; int h = 9; - - bool haveNext = false; - int nx = v->getXForFrame(v->getModelsEndFrame()); + int ex = x + w; RegionModel::PointList::const_iterator j = i; ++j; if (j != points.end()) { const RegionModel::Point &q(*j); - nx = v->getXForFrame(q.frame); - haveNext = true; + int nx = v->getXForFrame(q.frame); + if (nx < ex) ex = nx; } if (m_plotStyle != PlotSegmentation) { @@ -662,14 +709,14 @@ if (m_plotStyle == PlotSegmentation) { - if (nx <= x) continue; + if (ex <= x) continue; if (illuminateFrame != p.frame && - (nx < x + 5 || x >= v->width() - 1)) { + (ex < x + 5 || x >= v->width() - 1)) { paint.setPen(Qt::NoPen); } - paint.drawRect(x, -1, nx - x, v->height() + 1); + paint.drawRect(x, -1, ex - x, v->height() + 1); } else { @@ -687,9 +734,9 @@ } if (p.label != "") { - if (!haveNext || nx > x + 6 + paint.fontMetrics().width(p.label)) { +// if (ex > x + 6 + paint.fontMetrics().width(p.label)) { paint.drawText(x + 5, textY, p.label); - } +// } } } Modified: sonic-visualiser/trunk/layer/RegionLayer.h =================================================================== --- sonic-visualiser/trunk/layer/RegionLayer.h 2008-10-15 12:08:02 UTC (rev 1241) +++ sonic-visualiser/trunk/layer/RegionLayer.h 2008-10-16 13:38:33 UTC (rev 1242) @@ -22,6 +22,8 @@ #include <QObject> #include <QColor> +#include <map> + class View; class QPainter; @@ -80,6 +82,7 @@ enum VerticalScale { AutoAlignScale, + EqualSpaced, LinearScale, LogScale, }; @@ -111,6 +114,9 @@ void setProperties(const QXmlAttributes &attributes); +protected slots: + void recalcSpacing(); + protected: void getScaleExtents(View *, float &min, float &max, bool &log) const; int getYForValue(View *v, float value) const; @@ -130,6 +136,9 @@ int m_colourMap; PlotStyle m_plotStyle; + typedef std::map<float, int> SpacingMap; + SpacingMap m_spacingMap; + void finish(RegionModel::EditCommand *command) { Command *c = command->finish(); if (c) CommandHistory::getInstance()->addCommand(c, false); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-10-17 13:33:01
|
Revision: 1244 http://sv1.svn.sourceforge.net/sv1/?rev=1244&view=rev Author: cannam Date: 2008-10-17 13:32:55 +0000 (Fri, 17 Oct 2008) Log Message: ----------- * Add persistent cache file support to FileSource (e.g. for RDF descriptions) * Query RDF plugin data in a background thread on startup Modified Paths: -------------- sonic-visualiser/trunk/INSTALL sonic-visualiser/trunk/base/TempDirectory.cpp sonic-visualiser/trunk/base/TempDirectory.h sonic-visualiser/trunk/data/fileio/FileSource.cpp sonic-visualiser/trunk/data/fileio/FileSource.h sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp sonic-visualiser/trunk/sv/main/MainWindow.cpp sonic-visualiser/trunk/transform/TransformFactory.cpp sonic-visualiser/trunk/transform/TransformFactory.h Modified: sonic-visualiser/trunk/INSTALL =================================================================== --- sonic-visualiser/trunk/INSTALL 2008-10-16 16:10:27 UTC (rev 1243) +++ sonic-visualiser/trunk/INSTALL 2008-10-17 13:32:55 UTC (rev 1244) @@ -60,8 +60,8 @@ Qt Library Version Requirements ------------------------------- -Sonic Visualiser requires Qt version 4.2 or newer. It can not be -built with Qt3 or with Qt 4.0.x or 4.1.x. +Sonic Visualiser requires Qt version 4.3 or newer. It can not be +built with Qt3 or with Qt 4.0.x, 4.1.x, or 4.2.x. A Note on SV Library Dependencies Modified: sonic-visualiser/trunk/base/TempDirectory.cpp =================================================================== --- sonic-visualiser/trunk/base/TempDirectory.cpp 2008-10-16 16:10:27 UTC (rev 1243) +++ sonic-visualiser/trunk/base/TempDirectory.cpp 2008-10-17 13:32:55 UTC (rev 1244) @@ -53,12 +53,10 @@ } QString -TempDirectory::getPath() +TempDirectory::getContainingPath() { QMutexLocker locker(&m_mutex); - if (m_tmpdir != "") return m_tmpdir; - QSettings settings; settings.beginGroup("TempDirectory"); QString svDirParent = settings.value("create-in", "$HOME").toString(); @@ -80,7 +78,15 @@ cleanupAbandonedDirectories(svDir); - return createTempDirectoryIn(svDir); + return svDir; +} + +QString +TempDirectory::getPath() +{ + if (m_tmpdir != "") return m_tmpdir; + + return createTempDirectoryIn(getContainingPath()); } QString Modified: sonic-visualiser/trunk/base/TempDirectory.h =================================================================== --- sonic-visualiser/trunk/base/TempDirectory.h 2008-10-16 16:10:27 UTC (rev 1243) +++ sonic-visualiser/trunk/base/TempDirectory.h 2008-10-17 13:32:55 UTC (rev 1244) @@ -38,17 +38,36 @@ virtual ~TempDirectory(); /** + * Return the path of the directory in which the temporary + * directory has been or will be created. This directory is + * particular to this application, although not to this instance + * of it, and it will not be removed when the application exits. + * Persistent cache data or similar may be placed in this + * directory or other, non-temporary subdirectories of it. + * + * If this directory does not exist, it will be created. Throw + * DirectoryCreationFailed if the directory cannot be created. + */ + QString getContainingPath(); + + /** * Create the root temporary directory if necessary, and return - * its path. Throw DirectoryCreationFailed if the directory - * cannot be created. + * its path. This directory will be removed when the application + * exits. + * + * Throw DirectoryCreationFailed if the directory cannot be + * created. */ QString getPath(); /** * Create an immediate subdirectory of the root temporary * directory of the given name, if it doesn't already exist, and - * return its path. Throw DirectoryCreationFailed if the - * directory cannot be created. + * return its path. This directory will be removed when the + * application exits. + * + * Throw DirectoryCreationFailed if the directory cannot be + * created. */ QString getSubDirectoryPath(QString subdir); Modified: sonic-visualiser/trunk/data/fileio/FileSource.cpp =================================================================== --- sonic-visualiser/trunk/data/fileio/FileSource.cpp 2008-10-16 16:10:27 UTC (rev 1243) +++ sonic-visualiser/trunk/data/fileio/FileSource.cpp 2008-10-17 13:32:55 UTC (rev 1244) @@ -24,12 +24,13 @@ #include <QFileInfo> #include <QDir> #include <QCoreApplication> +#include <QCryptographicHash> #include <QHttpResponseHeader> #include <iostream> #include <cstdlib> -//#define DEBUG_FILE_SOURCE 1 +#define DEBUG_FILE_SOURCE 1 int FileSource::m_count = 0; @@ -46,8 +47,10 @@ QMutex FileSource::m_mapMutex; -FileSource::FileSource(QString fileOrUrl, ProgressReporter *reporter) : +FileSource::FileSource(QString fileOrUrl, ProgressReporter *reporter, + LocalCacheMode cacheMode) : m_url(fileOrUrl), + m_cacheMode(cacheMode), m_ftp(0), m_http(0), m_localFile(0), @@ -60,7 +63,7 @@ m_refCounted(false) { #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::FileSource(" << fileOrUrl.toStdString() << ")" << std::endl; + std::cerr << "FileSource::FileSource(" << fileOrUrl.toStdString() << ", " << cacheMode << ")" << std::endl; #endif if (!canHandleScheme(m_url)) { @@ -110,8 +113,10 @@ } } -FileSource::FileSource(QUrl url, ProgressReporter *reporter) : +FileSource::FileSource(QUrl url, ProgressReporter *reporter, + LocalCacheMode cacheMode) : m_url(url), + m_cacheMode(cacheMode), m_ftp(0), m_http(0), m_localFile(0), @@ -139,6 +144,7 @@ FileSource::FileSource(const FileSource &rf) : QObject(), m_url(rf.m_url), + m_cacheMode(rf.m_cacheMode), m_ftp(0), m_http(0), m_localFile(0), @@ -160,8 +166,14 @@ return; } - if (!isRemote()) { + if (m_cacheMode == PersistentCache) { + m_localFilename = rf.m_localFilename; + + } else if (!isRemote()) { + + m_localFilename = rf.m_localFilename; + } else { QMutexLocker locker(&m_mapMutex); #ifdef DEBUG_FILE_SOURCE @@ -192,7 +204,9 @@ cleanup(); - if (isRemote() && !m_leaveLocalFile) deleteCacheFile(); + if (isRemote() && (m_cacheMode == TemporaryCache) && !m_leaveLocalFile) { + deleteCacheFile(); + } } void @@ -238,7 +252,8 @@ if (createCacheFile()) { #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::init: Already have this one" << std::endl; + std::cerr << "FileSource::init: Already have this one at " + << m_localFilename.toStdString() << std::endl; #endif m_ok = true; if (!QFileInfo(m_localFilename).exists()) { @@ -258,7 +273,8 @@ #ifdef DEBUG_FILE_SOURCE std::cerr << "FileSource::init: Don't have local copy of \"" - << m_url.toString().toStdString() << "\", retrieving" << std::endl; + << m_url.toString().toStdString() << "\", retrieving to " + << m_localFilename.toStdString() << std::endl; #endif if (scheme == "http") { @@ -693,10 +709,15 @@ m_fileCreationMutex.lock(); + // We always delete the file here, even in PersistentCache mode, + // because this function is also used if retrieval failed (in + // which case we want to delete the cache so that subsequent users + // won't trust it). It's up to the calling code to determine + // whether we actually want to delete the cache or not, e.g. on + // destruction. + if (!QFile(m_localFilename).remove()) { -#ifdef DEBUG_FILE_SOURCE std::cerr << "FileSource::deleteCacheFile: ERROR: Failed to delete file \"" << m_localFilename.toStdString() << "\"" << std::endl; -#endif } else { #ifdef DEBUG_FILE_SOURCE std::cerr << "FileSource::deleteCacheFile: Deleted cache file \"" << m_localFilename.toStdString() << "\"" << std::endl; @@ -709,9 +730,46 @@ m_done = true; } +QString +FileSource::getPersistentCacheDirectory() +{ + QDir dir = TempDirectory::getInstance()->getContainingPath(); + + QString cacheDirName("cache"); + + QFileInfo fi(dir.filePath(cacheDirName)); + + if ((fi.exists() && !fi.isDir()) || + (!fi.exists() && !dir.mkdir(cacheDirName))) { + + throw DirectoryCreationFailed(fi.filePath()); + } + + return fi.filePath(); +} + +QString +FileSource::getPersistentCacheFilePath(QUrl url) +{ + QDir dir(getPersistentCacheDirectory()); + + QString filename = + QString::fromLocal8Bit + (QCryptographicHash::hash(url.toString().toLocal8Bit(), + QCryptographicHash::Sha1).toBase64()); + + return dir.filePath(filename); +} + bool FileSource::createCacheFile() { + if (m_cacheMode == PersistentCache) { + m_localFilename = getPersistentCacheFilePath(m_url); + if (QFileInfo(m_localFilename).exists()) return true; + else return false; + } + { QMutexLocker locker(&m_mapMutex); Modified: sonic-visualiser/trunk/data/fileio/FileSource.h =================================================================== --- sonic-visualiser/trunk/data/fileio/FileSource.h 2008-10-16 16:10:27 UTC (rev 1243) +++ sonic-visualiser/trunk/data/fileio/FileSource.h 2008-10-17 13:32:55 UTC (rev 1244) @@ -51,10 +51,12 @@ * pass FileSource objects by value. FileSource only makes sense for * stateless URLs that result in the same data on each request. * - * Cached files share a lifetime with their "owning" FileSource - * objects; when the last FileSource referring to a given URL is - * deleted or goes out of scope, its cached file (if any) is also - * removed. + * Cached files (in their default temporary mode) share a lifetime + * with their "owning" FileSource objects. When the last FileSource + * referring to a given URL is deleted or goes out of scope, its + * cached file (if any) is also removed. You can change this + * behaviour by using persistent cache mode; \see LocalCacheMode for + * details and caveats. */ class FileSource : public QObject { @@ -62,6 +64,36 @@ public: /** + * Type of local cache to be used when retrieving remote files. + * + * Temporary cache files are created when a FileSource object is + * first created for a given URL, and removed when the last extant + * temporary cache mode FileSource object referring to a given URL + * is deleted (i.e. when its reference count is lowered to zero). + * They are also stored in a temporary directory that will be + * deleted when the program exits. + * + * Persistent cache files are created only when first retrieving a + * URL for which no persistent cache already exists, and are never + * deleted (by FileSource anyway). They are stored in a directory + * that is not deleted when the program exits. FileSource creates + * a unique local file name for each source URL, so as long as the + * local cache file remains on disc, the remote URL will not be + * retrieved again during any further run of the program. You can + * find out what local file name will be used for the persistent + * cache of a given URL by calling getPersistentCacheFilePath, if + * you want to do something such as delete it by hand. + * + * Note that FileSource does not cache local files (i.e. does not + * make a copy of files that already appear to be stored on the + * local filesystem) in either mode. + */ + enum LocalCacheMode { + TemporaryCache, + PersistentCache + }; + + /** * Construct a FileSource using the given local file path or URL. * The URL may be raw or encoded. * @@ -69,8 +101,13 @@ * progress status. Note that the progress() signal will also be * emitted regularly during retrieval, even if no reporter is * supplied here. Caller retains ownership of the reporter object. + * + * If LocalCacheMode is PersistentCache, a persistent cache file + * will be used. See LocalCacheMode documentation for details. */ - FileSource(QString fileOrUrl, ProgressReporter *reporter = 0); + FileSource(QString fileOrUrl, + ProgressReporter *reporter = 0, + LocalCacheMode mode = TemporaryCache); /** * Construct a FileSource using the given remote URL. @@ -79,8 +116,13 @@ * progress status. Note that the progress() signal will also be * emitted regularly during retrieval, even if no reporter is * supplied here. Caller retains ownership of the reporter object. + * + * If LocalCacheMode is PersistentCache, a persistent cache file + * will be used. See LocalCacheMode documentation for details. */ - FileSource(QUrl url, ProgressReporter *reporter = 0); + FileSource(QUrl url, + ProgressReporter *reporter = 0, + LocalCacheMode mode = TemporaryCache); FileSource(const FileSource &); @@ -158,7 +200,11 @@ /** * Specify whether any local, cached file should remain on disc * after this FileSource has been destroyed. The default is false - * (cached files share their FileSource owners' lifespans). + * (cached files share their FileSource owners' lifespans). This + * is only meaningful in TemporaryCache mode; even if this setting + * is true, the temporary cache will still be deleted when the + * program exits. Use PersistentCache mode if you want the cache + * to outlast the program. */ void setLeaveLocalFile(bool leave); @@ -174,6 +220,17 @@ */ static bool canHandleScheme(QUrl url); + /** + * Return the path that will be used for the cache file copy of + * the given remote URL by a FileSource object constructed in + * PersistentCache mode. + * + * This method also creates the containing directory for such + * cache files, if it does not already exist, and so may throw + * DirectoryCreationFailed. + */ + static QString getPersistentCacheFilePath(QUrl url); + signals: /** * Emitted during URL retrieval, when the retrieval progress @@ -206,6 +263,7 @@ FileSource &operator=(const FileSource &); // not provided QUrl m_url; + LocalCacheMode m_cacheMode; QFtp *m_ftp; QHttp *m_http; QFile *m_localFile; @@ -237,6 +295,8 @@ bool createCacheFile(); void deleteCacheFile(); + static QString getPersistentCacheDirectory(); + static QMutex m_fileCreationMutex; static int m_count; }; Modified: sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp 2008-10-16 16:10:27 UTC (rev 1243) +++ sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp 2008-10-17 13:32:55 UTC (rev 1244) @@ -178,7 +178,8 @@ if (FileSource::isRemote(urlString) && FileSource::canHandleScheme(urlString)) { - FileSource *source = new FileSource(urlString); + FileSource *source = new FileSource + (urlString, 0, FileSource::PersistentCache); if (!source->isAvailable()) { delete source; return false; Modified: sonic-visualiser/trunk/sv/main/MainWindow.cpp =================================================================== --- sonic-visualiser/trunk/sv/main/MainWindow.cpp 2008-10-16 16:10:27 UTC (rev 1243) +++ sonic-visualiser/trunk/sv/main/MainWindow.cpp 2008-10-17 13:32:55 UTC (rev 1244) @@ -1227,7 +1227,7 @@ //!!! - PluginRDFIndexer::getInstance()->indexURL("http://www.vamp-plugins.org/rdf/plugins/vamp-example-plugins"); +// PluginRDFIndexer::getInstance()->indexURL("http://www.vamp-plugins.org/rdf/plugins/vamp-example-plugins"); // TransformList uninstalled = // TransformFactory::getInstance()->getUninstalledTransformDescriptions(); Modified: sonic-visualiser/trunk/transform/TransformFactory.cpp =================================================================== --- sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-10-16 16:10:27 UTC (rev 1243) +++ sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-10-17 13:32:55 UTC (rev 1244) @@ -35,6 +35,8 @@ #include <QRegExp> #include <QTextStream> +#include "base/Thread.h" + using std::cerr; using std::endl; @@ -51,6 +53,9 @@ m_transformsPopulated(false), m_uninstalledTransformsPopulated(false) { + UninstalledTransformsPopulateThread *thread = + new UninstalledTransformsPopulateThread(this); + thread->start(); } TransformFactory::~TransformFactory() @@ -60,7 +65,7 @@ TransformList TransformFactory::getAllTransformDescriptions() { - if (!m_transformsPopulated) populateTransforms(); + populateTransforms(); std::set<TransformDescription> dset; for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); @@ -82,7 +87,7 @@ TransformDescription TransformFactory::getTransformDescription(TransformId id) { - if (!m_transformsPopulated) populateTransforms(); + populateTransforms(); if (m_transforms.find(id) == m_transforms.end()) { return TransformDescription(); @@ -94,7 +99,7 @@ TransformList TransformFactory::getUninstalledTransformDescriptions() { - if (!m_uninstalledTransformsPopulated) populateUninstalledTransforms(); + populateUninstalledTransforms(); std::set<TransformDescription> dset; for (TransformDescriptionMap::const_iterator i = m_uninstalledTransforms.begin(); @@ -106,7 +111,7 @@ TransformList list; for (std::set<TransformDescription>::const_iterator i = dset.begin(); i != dset.end(); ++i) { -// cerr << "inserting transform into list: id = " << i->identifier.toStdString() << endl; +// cerr << "inserting transform into uninstalled list: id = " << i->identifier.toStdString() << endl; list.push_back(*i); } @@ -116,7 +121,7 @@ TransformDescription TransformFactory::getUninstalledTransformDescription(TransformId id) { - if (!m_uninstalledTransformsPopulated) populateUninstalledTransforms(); + populateUninstalledTransforms(); if (m_uninstalledTransforms.find(id) == m_uninstalledTransforms.end()) { return TransformDescription(); @@ -128,8 +133,8 @@ TransformFactory::TransformInstallStatus TransformFactory::getTransformInstallStatus(TransformId id) { - if (!m_transformsPopulated) populateTransforms(); - if (!m_uninstalledTransformsPopulated) populateUninstalledTransforms(); + populateTransforms(); + populateUninstalledTransforms(); if (m_transforms.find(id) != m_transforms.end()) { return TransformInstalled; @@ -144,7 +149,7 @@ std::vector<QString> TransformFactory::getAllTransformTypes() { - if (!m_transformsPopulated) populateTransforms(); + populateTransforms(); std::set<QString> types; for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); @@ -163,7 +168,7 @@ std::vector<QString> TransformFactory::getTransformCategories(QString transformType) { - if (!m_transformsPopulated) populateTransforms(); + populateTransforms(); std::set<QString> categories; for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); @@ -190,7 +195,7 @@ std::vector<QString> TransformFactory::getTransformMakers(QString transformType) { - if (!m_transformsPopulated) populateTransforms(); + populateTransforms(); std::set<QString> makers; for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); @@ -217,6 +222,12 @@ void TransformFactory::populateTransforms() { + MutexLocker locker(&m_transformsMutex, + "TransformFactory::populateTransforms"); + if (m_transformsPopulated) { + return; + } + TransformDescriptionMap transforms; populateFeatureExtractionPlugins(transforms); @@ -512,9 +523,15 @@ void TransformFactory::populateUninstalledTransforms() { - if (!m_uninstalledTransforms.empty()) return; - if (m_transforms.empty()) populateTransforms(); + populateTransforms(); + MutexLocker locker(&m_uninstalledTransformsMutex, + "TransformFactory::populateUninstalledTransforms"); + if (m_uninstalledTransformsPopulated) return; + + PluginRDFIndexer::getInstance()->indexURL + ("http://www.vamp-plugins.org/rdf/plugins/vamp-example-plugins"); + //!!! This will be amazingly slow QStringList ids = PluginRDFIndexer::getInstance()->getIndexedPluginIds(); @@ -575,6 +592,8 @@ } m_uninstalledTransformsPopulated = true; + + std::cerr << "populateUninstalledTransforms exiting" << std::endl; } Transform @@ -660,7 +679,7 @@ bool TransformFactory::haveTransform(TransformId identifier) { - if (m_transforms.empty()) populateTransforms(); + populateTransforms(); return (m_transforms.find(identifier) != m_transforms.end()); } @@ -927,7 +946,7 @@ TransformFactory::SearchResults TransformFactory::search(QStringList keywords) { - if (m_transforms.empty()) populateTransforms(); + populateTransforms(); if (keywords.size() > 1) { // Additional score for all keywords in a row @@ -955,8 +974,22 @@ if (match.score > 0) results[i->first] = match; } - if (m_uninstalledTransforms.empty()) populateUninstalledTransforms(); + if (!m_uninstalledTransformsMutex.tryLock()) { + // uninstalled transforms are being populated; this may take some time, + // and they aren't critical + std::cerr << "TransformFactory::search: Uninstalled transforms mutex is held, skipping" << std::endl; + return results; + } + if (!m_uninstalledTransformsPopulated) { + std::cerr << "WARNING: TransformFactory::search: Uninstalled transforms are not populated yet" << endl + << "and are not being populated either -- was the thread not started correctly?" << endl; + m_uninstalledTransformsMutex.unlock(); + return results; + } + + m_uninstalledTransformsMutex.unlock(); + for (TransformDescriptionMap::const_iterator i = m_uninstalledTransforms.begin(); i != m_uninstalledTransforms.end(); ++i) { Modified: sonic-visualiser/trunk/transform/TransformFactory.h =================================================================== --- sonic-visualiser/trunk/transform/TransformFactory.h 2008-10-16 16:10:27 UTC (rev 1243) +++ sonic-visualiser/trunk/transform/TransformFactory.h 2008-10-17 13:32:55 UTC (rev 1244) @@ -24,6 +24,8 @@ #include <QObject> #include <QStringList> +#include <QThread> +#include <QMutex> #include <map> #include <set> @@ -192,6 +194,21 @@ Vamp::PluginBase *instantiateDefaultPluginFor(TransformId id, size_t rate); + QMutex m_transformsMutex; + QMutex m_uninstalledTransformsMutex; + + class UninstalledTransformsPopulateThread : public QThread + { + public: + UninstalledTransformsPopulateThread(TransformFactory *factory) : + m_factory(factory) { + } + virtual void run() { + m_factory->populateUninstalledTransforms(); + } + TransformFactory *m_factory; + }; + static TransformFactory *m_instance; }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-10-17 15:26:40
|
Revision: 1245 http://sv1.svn.sourceforge.net/sv1/?rev=1245&view=rev Author: cannam Date: 2008-10-17 15:26:29 +0000 (Fri, 17 Oct 2008) Log Message: ----------- * Some work on querying and cacheing plugin RDF from a central index Modified Paths: -------------- sonic-visualiser/trunk/data/fileio/FileSource.cpp sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp sonic-visualiser/trunk/rdf/PluginRDFIndexer.h sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.cpp sonic-visualiser/trunk/sv/main/main.cpp sonic-visualiser/trunk/transform/TransformFactory.cpp Modified: sonic-visualiser/trunk/data/fileio/FileSource.cpp =================================================================== --- sonic-visualiser/trunk/data/fileio/FileSource.cpp 2008-10-17 13:32:55 UTC (rev 1244) +++ sonic-visualiser/trunk/data/fileio/FileSource.cpp 2008-10-17 15:26:29 UTC (rev 1245) @@ -421,6 +421,10 @@ void FileSource::cleanup() { + if (m_done) { + delete m_localFile; // does not actually delete the file + m_localFile = 0; + } m_done = true; if (m_http) { QHttp *h = m_http; @@ -434,8 +438,10 @@ f->abort(); f->deleteLater(); } - delete m_localFile; // does not actually delete the file - m_localFile = 0; + if (m_localFile) { + delete m_localFile; // does not actually delete the file + m_localFile = 0; + } } bool @@ -660,7 +666,8 @@ if (error) { #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::done: error is " << error << ", deleting cache file" << std::endl; + std::cerr << "FileSource::done: error is " << error << " (\"" + << m_errorString.toStdString() << "\"), deleting cache file" << std::endl; #endif deleteCacheFile(); } @@ -756,7 +763,7 @@ QString filename = QString::fromLocal8Bit (QCryptographicHash::hash(url.toString().toLocal8Bit(), - QCryptographicHash::Sha1).toBase64()); + QCryptographicHash::Sha1).toHex()); return dir.filePath(filename); } Modified: sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp 2008-10-17 13:32:55 UTC (rev 1244) +++ sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp 2008-10-17 15:26:29 UTC (rev 1245) @@ -159,8 +159,11 @@ if (FileSource::isRemote(url) && FileSource::canHandleScheme(url)) { + + //!!! persistent with expiry - m_source = new FileSource(url); + m_source = new FileSource(url, 0, FileSource::PersistentCache); + if (!m_source->isAvailable()) { delete m_source; m_source = 0; Modified: sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp 2008-10-17 13:32:55 UTC (rev 1244) +++ sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp 2008-10-17 15:26:29 UTC (rev 1245) @@ -18,6 +18,7 @@ #include "SimpleSPARQLQuery.h" #include "data/fileio/FileSource.h" +#include "data/fileio/PlaylistFileReader.h" #include "plugin/PluginIdentifier.h" #include "base/Profiler.h" @@ -27,6 +28,9 @@ #include <QFileInfo> #include <QDir> #include <QUrl> +#include <QDateTime> +#include <QSettings> +#include <QFile> #include <iostream> using std::cerr; @@ -95,15 +99,66 @@ PluginRDFIndexer::~PluginRDFIndexer() { + QMutexLocker locker(&m_mutex); + while (!m_sources.empty()) { delete *m_sources.begin(); m_sources.erase(m_sources.begin()); } } +bool +PluginRDFIndexer::indexConfiguredURLs() +{ + std::cerr << "PluginRDFIndexer::indexConfiguredURLs" << std::endl; + + QSettings settings; + settings.beginGroup("RDF"); + + QString indexKey("rdf-indices"); + QStringList indices = settings.value(indexKey).toStringList(); + + for (int i = 0; i < indices.size(); ++i) { + + QString index = indices[i]; + + std::cerr << "PluginRDFIndexer::indexConfiguredURLs: index url is " + << index.toStdString() << std::endl; + + expireCacheMaybe(index); + + FileSource indexSource(index, 0, FileSource::PersistentCache); + if (!indexSource.isAvailable()) continue; + indexSource.waitForData(); + + PlaylistFileReader reader(indexSource); + if (!reader.isOK()) continue; + + PlaylistFileReader::Playlist list = reader.load(); + for (PlaylistFileReader::Playlist::const_iterator j = list.begin(); + j != list.end(); ++j) { + std::cerr << "PluginRDFIndexer::indexConfiguredURLs: url is " + << j->toStdString() << std::endl; + indexURL(*j); + } + } + + QString urlListKey("rdf-urls"); + QStringList urls = settings.value(urlListKey).toStringList(); + + for (int i = 0; i < urls.size(); ++i) { + indexURL(urls[i]); + } + + settings.endGroup(); + return true; +} + QString PluginRDFIndexer::getURIForPluginId(QString pluginId) { + QMutexLocker locker(&m_mutex); + if (m_idToUriMap.find(pluginId) == m_idToUriMap.end()) return ""; return m_idToUriMap[pluginId]; } @@ -111,6 +166,8 @@ QString PluginRDFIndexer::getIdForPluginURI(QString uri) { + QMutexLocker locker(&m_mutex); + if (m_uriToIdMap.find(uri) == m_uriToIdMap.end()) { // Haven't found this uri referenced in any document on the @@ -137,6 +194,8 @@ QString PluginRDFIndexer::getDescriptionURLForPluginId(QString pluginId) { + QMutexLocker locker(&m_mutex); + if (m_idToDescriptionMap.find(pluginId) == m_idToDescriptionMap.end()) return ""; return m_idToDescriptionMap[pluginId]; } @@ -144,6 +203,8 @@ QString PluginRDFIndexer::getDescriptionURLForPluginURI(QString uri) { + QMutexLocker locker(&m_mutex); + QString id = getIdForPluginURI(uri); if (id == "") return ""; return getDescriptionURLForPluginId(id); @@ -152,6 +213,8 @@ QStringList PluginRDFIndexer::getIndexedPluginIds() { + QMutexLocker locker(&m_mutex); + QStringList ids; for (StringMap::const_iterator i = m_idToDescriptionMap.begin(); i != m_idToDescriptionMap.end(); ++i) { @@ -168,16 +231,61 @@ return indexURL(urlString); } +void +PluginRDFIndexer::expireCacheMaybe(QString urlString) +{ + QString cacheFile = FileSource::getPersistentCacheFilePath(urlString); + + QSettings settings; + settings.beginGroup("RDF"); + + QString key("rdf-expiry-times"); + + QMap<QString, QVariant> expiryMap = settings.value(key).toMap(); + QDateTime lastExpiry = expiryMap[urlString].toDateTime(); + + if (!QFileInfo(cacheFile).exists()) { + expiryMap[urlString] = QDateTime::currentDateTime(); + settings.setValue(key, expiryMap); + settings.endGroup(); + return; + } + + if (!lastExpiry.isValid() || + (lastExpiry.addDays(2) < QDateTime::currentDateTime())) { + + std::cerr << "Expiring old cache file " << cacheFile.toStdString() + << std::endl; + + if (QFile(cacheFile).remove()) { + + expiryMap[urlString] = QDateTime::currentDateTime(); + settings.setValue(key, expiryMap); + } + } + + settings.endGroup(); +} + bool PluginRDFIndexer::indexURL(QString urlString) { Profiler profiler("PluginRDFIndexer::indexURL"); + std::cerr << "PluginRDFIndexer::indexURL(" << urlString.toStdString() << ")" << std::endl; + + QMutexLocker locker(&m_mutex); + QString localString = urlString; if (FileSource::isRemote(urlString) && FileSource::canHandleScheme(urlString)) { + //!!! how do we avoid hammering the server if it doesn't have + //!!! the file, and/or the network if it can't get through? + + expireCacheMaybe(urlString); + FileSource *source = new FileSource (urlString, 0, FileSource::PersistentCache); if (!source->isAvailable()) { Modified: sonic-visualiser/trunk/rdf/PluginRDFIndexer.h =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFIndexer.h 2008-10-17 13:32:55 UTC (rev 1244) +++ sonic-visualiser/trunk/rdf/PluginRDFIndexer.h 2008-10-17 15:26:29 UTC (rev 1245) @@ -18,6 +18,7 @@ #include <QString> #include <QStringList> +#include <QMutex> #include <map> #include <set> @@ -28,6 +29,18 @@ public: static PluginRDFIndexer *getInstance(); + /** + * Index all URLs obtained from index files defined in the current + * settings. This is not done automatically because it may incur + * significant processing and networking effort. It could be + * called from a background thread at startup, for example. + * + * Note that this class has a single mutex, so other functions + * will block if called from a different thread while this one is + * running. + */ + bool indexConfiguredURLs(); + bool indexURL(QString url); // in addition to "installed" URLs QString getURIForPluginId(QString pluginId); @@ -41,6 +54,7 @@ protected: PluginRDFIndexer(); + QMutex m_mutex; std::set<FileSource *> m_sources; typedef std::map<QString, QString> StringMap; StringMap m_uriToIdMap; @@ -48,6 +62,7 @@ StringMap m_idToDescriptionMap; bool indexFile(QString path); static PluginRDFIndexer *m_instance; + void expireCacheMaybe(QString); }; #endif Modified: sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.cpp =================================================================== --- sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.cpp 2008-10-17 13:32:55 UTC (rev 1244) +++ sonic-visualiser/trunk/rdf/SimpleSPARQLQuery.cpp 2008-10-17 15:26:29 UTC (rev 1245) @@ -22,6 +22,8 @@ #include <rasqal.h> #endif +//#define DEBUG_SIMPLE_SPARQL_QUERY 1 + #include <iostream> using std::cerr; @@ -121,7 +123,9 @@ m_reporter(0), m_cancelled(false) { -// std::cerr << "SimpleSPARQLQuery::Impl: Query is: \"" << query.toStdString() << "\"" << std::endl; +#ifdef DEBUG_SIMPLE_SPARQL_QUERY + std::cerr << "SimpleSPARQLQuery::Impl: Query is: \"" << query.toStdString() << "\"" << std::endl; +#endif } SimpleSPARQLQuery::Impl::~Impl() @@ -234,7 +238,9 @@ QString text = (const char *)rasqal_literal_as_string(literal); +#ifdef DEBUG_SIMPLE_SPARQL_QUERY std::cerr << i << ". " << key.toStdString() << " -> " << text.toStdString() << " (type " << type << ")" << std::endl; +#endif resultmap[key] = Value(type, text); } Modified: sonic-visualiser/trunk/sv/main/main.cpp =================================================================== --- sonic-visualiser/trunk/sv/main/main.cpp 2008-10-17 13:32:55 UTC (rev 1244) +++ sonic-visualiser/trunk/sv/main/main.cpp 2008-10-17 15:26:29 UTC (rev 1245) @@ -248,6 +248,14 @@ } settings.endGroup(); + settings.beginGroup("RDF"); + if (!settings.contains("rdf-indices")) { + QStringList list; + list << "http://www.vamp-plugins.org/rdf/plugins/index.txt"; + settings.setValue("rdf-indices", list); + } + settings.endGroup(); + QIcon icon; int sizes[] = { 16, 22, 24, 32, 48, 64, 128 }; for (int i = 0; i < sizeof(sizes)/sizeof(sizes[0]); ++i) { Modified: sonic-visualiser/trunk/transform/TransformFactory.cpp =================================================================== --- sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-10-17 13:32:55 UTC (rev 1244) +++ sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-10-17 15:26:29 UTC (rev 1245) @@ -529,9 +529,10 @@ "TransformFactory::populateUninstalledTransforms"); if (m_uninstalledTransformsPopulated) return; - PluginRDFIndexer::getInstance()->indexURL - ("http://www.vamp-plugins.org/rdf/plugins/vamp-example-plugins"); +// ("http://www.vamp-plugins.org/rdf/plugins/vamp-example-plugins"); + PluginRDFIndexer::getInstance()->indexConfiguredURLs(); + //!!! This will be amazingly slow QStringList ids = PluginRDFIndexer::getInstance()->getIndexedPluginIds(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-10-23 16:31:02
|
Revision: 1247 http://sv1.svn.sourceforge.net/sv1/?rev=1247&view=rev Author: cannam Date: 2008-10-23 16:30:48 +0000 (Thu, 23 Oct 2008) Log Message: ----------- * Add More Info URL to plugin finder Modified Paths: -------------- sonic-visualiser/trunk/data/model/TabularModel.h sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp sonic-visualiser/trunk/rdf/PluginRDFDescription.h sonic-visualiser/trunk/sv.prf sonic-visualiser/trunk/transform/TransformDescription.h sonic-visualiser/trunk/transform/TransformFactory.cpp sonic-visualiser/trunk/view/View.cpp sonic-visualiser/trunk/widgets/TransformFinder.cpp Modified: sonic-visualiser/trunk/data/model/TabularModel.h =================================================================== --- sonic-visualiser/trunk/data/model/TabularModel.h 2008-10-21 19:31:50 UTC (rev 1246) +++ sonic-visualiser/trunk/data/model/TabularModel.h 2008-10-23 16:30:48 UTC (rev 1247) @@ -34,6 +34,8 @@ class TabularModel { public: + virtual ~TabularModel() { } + virtual int getRowCount() const = 0; virtual int getColumnCount() const = 0; Modified: sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp 2008-10-21 19:31:50 UTC (rev 1246) +++ sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp 2008-10-23 16:30:48 UTC (rev 1247) @@ -77,6 +77,12 @@ return m_pluginMaker; } +QString +PluginRDFDescription::getPluginInfoURL() const +{ + return m_pluginInfoURL; +} + QStringList PluginRDFDescription::getOutputIds() const { @@ -232,6 +238,52 @@ m_pluginMaker = v.value; } + // If we have a more-information URL for this plugin, then we take + // that. Otherwise, a more-inforomation URL for the plugin + // library would do nicely. Failing that, we could perhaps use + // any foaf:page URL at all that appears in the file -- but + // perhaps that would be unwise + + v = SimpleSPARQLQuery::singleResultQuery + (QString( + " PREFIX vamp: <http://purl.org/ontology/vamp/> " + " PREFIX foaf: <http://xmlns.com/foaf/0.1/> " + " SELECT ?page from <%1> " + " WHERE { " + " ?plugin a vamp:Plugin ; " + " vamp:identifier \"%2\" ; " + " foaf:page ?page . " + " }") + .arg(url) + .arg(label), "page"); + + if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") { + + m_pluginInfoURL = v.value; + + } else { + + v = SimpleSPARQLQuery::singleResultQuery + (QString( + " PREFIX vamp: <http://purl.org/ontology/vamp/> " + " PREFIX foaf: <http://xmlns.com/foaf/0.1/> " + " SELECT ?page from <%1> " + " WHERE { " + " ?library a vamp:PluginLibrary ; " + " vamp:available_plugin ?plugin ; " + " foaf:page ?page . " + " ?plugin a vamp:Plugin ; " + " vamp:identifier \"%2\" . " + " }") + .arg(url) + .arg(label), "page"); + + if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") { + + m_pluginInfoURL = v.value; + } + } + return true; } Modified: sonic-visualiser/trunk/rdf/PluginRDFDescription.h =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFDescription.h 2008-10-21 19:31:50 UTC (rev 1246) +++ sonic-visualiser/trunk/rdf/PluginRDFDescription.h 2008-10-23 16:30:48 UTC (rev 1247) @@ -42,6 +42,7 @@ QString getPluginName() const; QString getPluginDescription() const; QString getPluginMaker() const; + QString getPluginInfoURL() const; QStringList getOutputIds() const; QString getOutputName(QString outputId) const; @@ -61,6 +62,7 @@ QString m_pluginName; QString m_pluginDescription; QString m_pluginMaker; + QString m_pluginInfoURL; OutputStringMap m_outputNames; OutputDispositionMap m_outputDispositions; OutputStringMap m_outputEventTypeURIMap; Modified: sonic-visualiser/trunk/sv.prf =================================================================== --- sonic-visualiser/trunk/sv.prf 2008-10-21 19:31:50 UTC (rev 1246) +++ sonic-visualiser/trunk/sv.prf 2008-10-23 16:30:48 UTC (rev 1247) @@ -3,7 +3,7 @@ ### BEGIN CONFIGURABLE STUFF ### -CONFIG += release +CONFIG += debug # Temporarily Modified: sonic-visualiser/trunk/transform/TransformDescription.h =================================================================== --- sonic-visualiser/trunk/transform/TransformDescription.h 2008-10-21 19:31:50 UTC (rev 1246) +++ sonic-visualiser/trunk/transform/TransformDescription.h 2008-10-23 16:30:48 UTC (rev 1247) @@ -65,6 +65,7 @@ QString description; // sentence describing transform QString longDescription; // description "using" plugin name "by" maker QString maker; + QString infoUrl; QString units; bool configurable; Modified: sonic-visualiser/trunk/transform/TransformFactory.cpp =================================================================== --- sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-10-21 19:31:50 UTC (rev 1246) +++ sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-10-23 16:30:48 UTC (rev 1247) @@ -551,6 +551,7 @@ QString description = desc.getPluginDescription(); QString maker = desc.getPluginMaker(); + QString infoUrl = desc.getPluginInfoURL(); QStringList oids = desc.getOutputIds(); @@ -581,14 +582,43 @@ td.name = tr("%1: %2").arg(name).arg(oname); } + QString longDescription = description; + //!!! basically duplicated from above + if (longDescription == "") { + if (oids.size() == 1) { + longDescription = tr("Extract features using \"%1\" plugin (from %2)") + .arg(name).arg(maker); + } else { + longDescription = tr("Extract features using \"%1\" output of \"%2\" plugin (from %3)") + .arg(oname).arg(name).arg(maker); + } + } else { + if (oids.size() == 1) { + longDescription = tr("%1 using \"%2\" plugin (from %3)") + .arg(longDescription).arg(name).arg(maker); + } else { + longDescription = tr("%1 using \"%2\" output of \"%3\" plugin (from %4)") + .arg(longDescription).arg(oname).arg(name).arg(maker); + } + } + td.friendlyName = name; //!!!??? td.description = description; - td.longDescription = ""; //!!! + td.longDescription = longDescription; td.maker = maker; + td.infoUrl = infoUrl; td.units = ""; td.configurable = false; m_uninstalledTransforms[tid] = td; + + if (td.infoUrl != "") { + if (m_transforms.find(tid) != m_transforms.end()) { + if (m_transforms[tid].infoUrl == "") { + m_transforms[tid].infoUrl = td.infoUrl; + } + } + } } } Modified: sonic-visualiser/trunk/view/View.cpp =================================================================== --- sonic-visualiser/trunk/view/View.cpp 2008-10-21 19:31:50 UTC (rev 1246) +++ sonic-visualiser/trunk/view/View.cpp 2008-10-23 16:30:48 UTC (rev 1247) @@ -1597,7 +1597,6 @@ paint.drawPixmap(dx, 0, *m_cache); paint.end(); #endif - if (dx < 0) { cacheRect = QRect(width() + dx, 0, -dx, height()); } else { Modified: sonic-visualiser/trunk/widgets/TransformFinder.cpp =================================================================== --- sonic-visualiser/trunk/widgets/TransformFinder.cpp 2008-10-21 19:31:50 UTC (rev 1246) +++ sonic-visualiser/trunk/widgets/TransformFinder.cpp 2008-10-23 16:30:48 UTC (rev 1247) @@ -208,17 +208,21 @@ .arg(XmlExportable::encodeEntities(desc.description)); } - selectedText += tr("<br><small>"); + selectedText += tr("<small>"); if (desc.type != "") { - selectedText += tr(" — Plugin type: %1<br>") + selectedText += tr("<br> — Plugin type: %1") .arg(XmlExportable::encodeEntities(desc.type)); } if (desc.category != "") { - selectedText += tr(" — Category: %1<br>") + selectedText += tr("<br> — Category: %1") .arg(XmlExportable::encodeEntities(desc.category)); } - selectedText += tr(" — System identifier: %1") + selectedText += tr("<br> — System identifier: %1") .arg(XmlExportable::encodeEntities(desc.identifier)); + if (desc.infoUrl != "") { + selectedText += tr("<br> — More information: <a href=\"%1\">%1</a>") + .arg(desc.infoUrl); + } selectedText += tr("</small>"); if (i >= m_labels.size()) { @@ -230,6 +234,10 @@ SLOT(accept())); QPalette palette = label->palette(); label->setPalette(palette); + label->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | + Qt::LinksAccessibleByMouse | + Qt::TextSelectableByMouse); + label->setOpenExternalLinks(true); m_labels.push_back(label); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-10-24 14:52:48
|
Revision: 1249 http://sv1.svn.sourceforge.net/sv1/?rev=1249&view=rev Author: cannam Date: 2008-10-24 14:52:40 +0000 (Fri, 24 Oct 2008) Log Message: ----------- * Add vertical zoom and pan to time-value layer. Still some defects, particularly in logarithmic mode. Now need to get this in note layer as well! * Some fixes to log colouring in segmentation mode of time-value layer. Modified Paths: -------------- sonic-visualiser/trunk/base/LogRange.cpp sonic-visualiser/trunk/base/RangeMapper.cpp sonic-visualiser/trunk/base/RangeMapper.h sonic-visualiser/trunk/layer/TimeValueLayer.cpp sonic-visualiser/trunk/layer/TimeValueLayer.h sonic-visualiser/trunk/sv.prf sonic-visualiser/trunk/transform/TransformFactory.h sonic-visualiser/trunk/view/Pane.cpp sonic-visualiser/trunk/view/Pane.h sonic-visualiser/trunk/widgets/Panner.cpp Modified: sonic-visualiser/trunk/base/LogRange.cpp =================================================================== --- sonic-visualiser/trunk/base/LogRange.cpp 2008-10-23 16:32:00 UTC (rev 1248) +++ sonic-visualiser/trunk/base/LogRange.cpp 2008-10-24 14:52:40 UTC (rev 1249) @@ -16,6 +16,7 @@ #include "LogRange.h" #include <algorithm> +#include <iostream> #include <cmath> void @@ -24,6 +25,8 @@ if (min > max) std::swap(min, max); if (max == min) max = min + 1; +// std::cerr << "LogRange::mapRange: min = " << min << ", max = " << max << std::endl; + if (min >= 0.f) { max = log10f(max); // we know max != 0 @@ -31,6 +34,8 @@ if (min == 0.f) min = std::min(logthresh, max); else min = log10f(min); +// std::cerr << "LogRange::mapRange: positive: min = " << min << ", max = " << max << std::endl; + } else if (max <= 0.f) { min = log10f(-min); // we know min != 0 @@ -40,12 +45,16 @@ std::swap(min, max); +// std::cerr << "LogRange::mapRange: negative: min = " << min << ", max = " << max << std::endl; + } else { // min < 0 and max > 0 max = log10f(std::max(max, -min)); min = std::min(logthresh, max); + +// std::cerr << "LogRange::mapRange: spanning: min = " << min << ", max = " << max << std::endl; } if (min == max) min = max - 1; Modified: sonic-visualiser/trunk/base/RangeMapper.cpp =================================================================== --- sonic-visualiser/trunk/base/RangeMapper.cpp 2008-10-23 16:32:00 UTC (rev 1248) +++ sonic-visualiser/trunk/base/RangeMapper.cpp 2008-10-24 14:52:40 UTC (rev 1249) @@ -22,12 +22,13 @@ LinearRangeMapper::LinearRangeMapper(int minpos, int maxpos, float minval, float maxval, - QString unit) : + QString unit, bool inverted) : m_minpos(minpos), m_maxpos(maxpos), m_minval(minval), m_maxval(maxval), - m_unit(unit) + m_unit(unit), + m_inverted(inverted) { assert(m_maxval != m_minval); assert(m_maxpos != m_minpos); @@ -43,12 +44,14 @@ if (position > m_maxpos) position = m_maxpos; // std::cerr << "LinearRangeMapper::getPositionForValue: " << value << " -> " // << position << " (minpos " << m_minpos << ", maxpos " << m_maxpos << ", minval " << m_minval << ", maxval " << m_maxval << ")" << std::endl; - return position; + if (m_inverted) return m_maxpos - position; + else return position; } float LinearRangeMapper::getValueForPosition(int position) const { + if (m_inverted) position = m_maxpos - position; float value = m_minval + ((float(position - m_minpos) / float(m_maxpos - m_minpos)) * (m_maxval - m_minval)); @@ -61,10 +64,11 @@ LogRangeMapper::LogRangeMapper(int minpos, int maxpos, float minval, float maxval, - QString unit) : + QString unit, bool inverted) : m_minpos(minpos), m_maxpos(maxpos), - m_unit(unit) + m_unit(unit), + m_inverted(inverted) { convertMinMax(minpos, maxpos, minval, maxval, m_minlog, m_ratio); @@ -104,17 +108,19 @@ int position = (log10(value) - m_minlog) * m_ratio + m_minpos; if (position < m_minpos) position = m_minpos; if (position > m_maxpos) position = m_maxpos; - std::cerr << "LogRangeMapper::getPositionForValue: " << value << " -> " - << position << " (minpos " << m_minpos << ", maxpos " << m_maxpos << ", ratio " << m_ratio << ", minlog " << m_minlog << ")" << std::endl; - return position; +// std::cerr << "LogRangeMapper::getPositionForValue: " << value << " -> " +// << position << " (minpos " << m_minpos << ", maxpos " << m_maxpos << ", ratio " << m_ratio << ", minlog " << m_minlog << ")" << std::endl; + if (m_inverted) return m_maxpos - position; + else return position; } float LogRangeMapper::getValueForPosition(int position) const { + if (m_inverted) position = m_maxpos - position; float value = powf(10, (position - m_minpos) / m_ratio + m_minlog); - std::cerr << "LogRangeMapper::getValueForPosition: " << position << " -> " - << value << " (minpos " << m_minpos << ", maxpos " << m_maxpos << ", ratio " << m_ratio << ", minlog " << m_minlog << ")" << std::endl; +// std::cerr << "LogRangeMapper::getValueForPosition: " << position << " -> " +// << value << " (minpos " << m_minpos << ", maxpos " << m_maxpos << ", ratio " << m_ratio << ", minlog " << m_minlog << ")" << std::endl; return value; } Modified: sonic-visualiser/trunk/base/RangeMapper.h =================================================================== --- sonic-visualiser/trunk/base/RangeMapper.h 2008-10-23 16:32:00 UTC (rev 1248) +++ sonic-visualiser/trunk/base/RangeMapper.h 2008-10-24 14:52:40 UTC (rev 1249) @@ -34,7 +34,7 @@ public: LinearRangeMapper(int minpos, int maxpos, float minval, float maxval, - QString unit = ""); + QString unit = "", bool inverted = false); virtual int getPositionForValue(float value) const; virtual float getValueForPosition(int position) const; @@ -47,6 +47,7 @@ float m_minval; float m_maxval; QString m_unit; + bool m_inverted; }; @@ -55,7 +56,7 @@ public: LogRangeMapper(int minpos, int maxpos, float minval, float maxval, - QString m_unit = ""); + QString m_unit = "", bool inverted = false); static void convertRatioMinLog(float ratio, float minlog, int minpos, int maxpos, @@ -77,6 +78,7 @@ float m_minlog; float m_maxlog; QString m_unit; + bool m_inverted; }; Modified: sonic-visualiser/trunk/layer/TimeValueLayer.cpp =================================================================== --- sonic-visualiser/trunk/layer/TimeValueLayer.cpp 2008-10-23 16:32:00 UTC (rev 1248) +++ sonic-visualiser/trunk/layer/TimeValueLayer.cpp 2008-10-24 14:52:40 UTC (rev 1249) @@ -19,6 +19,7 @@ #include "base/RealTime.h" #include "base/Profiler.h" #include "base/LogRange.h" +#include "base/RangeMapper.h" #include "ColourDatabase.h" #include "view/View.h" @@ -51,7 +52,9 @@ m_editingCommand(0), m_colourMap(0), m_plotStyle(PlotConnectedPoints), - m_verticalScale(AutoAlignScale) + m_verticalScale(AutoAlignScale), + m_scaleMinimum(0), + m_scaleMaximum(0) { } @@ -260,11 +263,149 @@ { if (!m_model || shouldAutoAlign()) return false; - min = m_model->getValueMinimum(); - max = m_model->getValueMaximum(); + if (m_scaleMinimum == m_scaleMaximum) { + m_scaleMinimum = m_model->getValueMinimum(); + m_scaleMaximum = m_model->getValueMaximum(); + } + + min = m_scaleMinimum; + max = m_scaleMaximum; + +// std::cerr << "TimeValueLayer::getDisplayExtents: min = " << min << ", max = " << max << std::endl; + return true; } +bool +TimeValueLayer::setDisplayExtents(float min, float max) +{ + if (!m_model) return false; + + if (min == max) { + if (min == 0.f) { + max = 1.f; + } else { + max = min * 1.0001; + } + } + + m_scaleMinimum = min; + m_scaleMaximum = max; + + std::cerr << "TimeValueLayer::setDisplayExtents: min = " << min << ", max = " << max << std::endl; + + emit layerParametersChanged(); + return true; +} + +int +TimeValueLayer::getVerticalZoomSteps(int &defaultStep) const +{ + if (shouldAutoAlign()) return 0; + if (!m_model) return 0; + + defaultStep = 100; + return 100; +} + +int +TimeValueLayer::getCurrentVerticalZoomStep() const +{ + if (shouldAutoAlign()) return 0; + if (!m_model) return 0; + + RangeMapper *mapper = getNewVerticalZoomRangeMapper(); + if (!mapper) return 0; + + float dmin, dmax; + getDisplayExtents(dmin, dmax); + + int nr = mapper->getPositionForValue(dmax - dmin); +/* + int n0 = mapper->getPositionForValue(dmax); + int n1 = mapper->getPositionForValue(dmin); + int nr = n1 - n0; + if (nr < 0) nr = -nr; + + std::cerr << "TimeValueLayer::getCurrentVerticalZoomStep: dmin = " << dmin << ", dmax = " << dmax << ", n0 = " << n0 << ", n1 = " << n1 << ", nr = " << nr << std::endl; +*/ + delete mapper; + + return 100 - nr; +} + +void +TimeValueLayer::setVerticalZoomStep(int step) +{ + if (shouldAutoAlign()) return; + if (!m_model) return; + + RangeMapper *mapper = getNewVerticalZoomRangeMapper(); + if (!mapper) return; + + float min, max; + bool logarithmic; + QString unit; + getValueExtents(min, max, logarithmic, unit); + + float dmin, dmax; + getDisplayExtents(dmin, dmax); + + float newdist = mapper->getValueForPosition(100 - step); + + float newmin, newmax; + + if (logarithmic) { + + // see SpectrogramLayer::setVerticalZoomStep + + newmax = (newdist + sqrtf(newdist*newdist + 4*dmin*dmax)) / 2; + newmin = newmax - newdist; + +// std::cerr << "newmin = " << newmin << ", newmax = " << newmax << std::endl; + + } else { + float dmid = (dmax + dmin) / 2; + newmin = dmid - newdist / 2; + newmax = dmid + newdist / 2; + } + + if (newmin < min) { + newmax += (min - newmin); + newmin = min; + } + if (newmax > max) { + newmax = max; + } + + std::cerr << "TimeValueLayer::setVerticalZoomStep: " << step << ": " << newmin << " -> " << newmax << " (range " << newdist << ")" << std::endl; + + setDisplayExtents(newmin, newmax); +} + +RangeMapper * +TimeValueLayer::getNewVerticalZoomRangeMapper() const +{ + if (!m_model) return 0; + + RangeMapper *mapper; + + float min, max; + bool logarithmic; + QString unit; + getValueExtents(min, max, logarithmic, unit); + + if (min == max) return 0; + + if (logarithmic) { + mapper = new LogRangeMapper(0, 100, min, max, unit); + } else { + mapper = new LinearRangeMapper(0, 100, min, max, unit); + } + + return mapper; +} + SparseTimeValueModel::PointList TimeValueLayer::getLocalPoints(View *v, int x) const { @@ -446,8 +587,7 @@ } else { - min = m_model->getValueMinimum(); - max = m_model->getValueMaximum(); + getDisplayExtents(min, max); if (m_verticalScale == LogScale) { LogRange::mapRange(min, max); @@ -489,7 +629,7 @@ float val = min + (float(h - y) * float(max - min)) / h; if (logarithmic) { - val = powf(10.f, val); + val = LogRange::map(val); } return val; @@ -514,7 +654,6 @@ if (max == min) max = min + 1; if (log) { - LogRange::mapRange(min, max); val = LogRange::map(val); } @@ -781,8 +920,18 @@ int n = 10; - float max = m_model->getValueMaximum(); - float min = m_model->getValueMinimum(); + float min, max; + bool logarithmic; + getScaleExtents(v, min, max, logarithmic); + + if (m_plotStyle == PlotSegmentation) { + QString unit; + getValueExtents(min, max, logarithmic, unit); + if (logarithmic) { + LogRange::mapRange(min, max); + } + } + float val = min; float inc = (max - val) / n; @@ -807,7 +956,11 @@ paint.save(); for (int y = 0; y < boxh; ++y) { float val = ((boxh - y) * (max - min)) / boxh + min; - paint.setPen(getColourForValue(v, val)); + if (logarithmic) { + paint.setPen(getColourForValue(v, LogRange::unmap(val))); + } else { + paint.setPen(getColourForValue(v, val)); + } paint.drawLine(boxx + 1, y + boxy + 1, boxx + boxw, y + boxy + 1); } paint.restore(); @@ -836,12 +989,17 @@ y = boxy + int(boxh - ((val - min) * boxh) / (max - min)); ty = y; } else { - if (i == n-1) { + if (i == n-1 && + v->height() < paint.fontMetrics().height() * (n*2)) { if (m_model->getScaleUnits() != "") drawText = false; } dispval = lrintf(val / round) * round; // std::cerr << "val = " << val << ", dispval = " << dispval << std::endl; - y = getYForValue(v, dispval); + if (logarithmic) { + y = getYForValue(v, LogRange::unmap(dispval)); + } else { + y = getYForValue(v, dispval); + } ty = y - paint.fontMetrics().height() + paint.fontMetrics().ascent() + 2; @@ -851,7 +1009,11 @@ } } - sprintf(buffer, "%.*f", dp, dispval); + if (logarithmic) { + sprintf(buffer, "%.*g", dp < 2 ? 2 : dp, LogRange::unmap(dispval)); + } else { + sprintf(buffer, "%.*f", dp, dispval); + } QString label = QString(buffer); if (m_plotStyle != PlotSegmentation) { Modified: sonic-visualiser/trunk/layer/TimeValueLayer.h =================================================================== --- sonic-visualiser/trunk/layer/TimeValueLayer.h 2008-10-23 16:32:00 UTC (rev 1248) +++ sonic-visualiser/trunk/layer/TimeValueLayer.h 2008-10-24 14:52:40 UTC (rev 1249) @@ -117,7 +117,13 @@ bool &logarithmic, QString &unit) const; virtual bool getDisplayExtents(float &min, float &max) const; + virtual bool setDisplayExtents(float min, float max); + virtual int getVerticalZoomSteps(int &defaultStep) const; + virtual int getCurrentVerticalZoomStep() const; + virtual void setVerticalZoomStep(int); + virtual RangeMapper *getNewVerticalZoomRangeMapper() const; + virtual void toXml(QTextStream &stream, QString indent = "", QString extraAttributes = "") const; @@ -143,6 +149,9 @@ PlotStyle m_plotStyle; VerticalScale m_verticalScale; + mutable float m_scaleMinimum; + mutable float m_scaleMaximum; + void finish(SparseTimeValueModel::EditCommand *command) { Command *c = command->finish(); if (c) CommandHistory::getInstance()->addCommand(c, false); Modified: sonic-visualiser/trunk/sv.prf =================================================================== --- sonic-visualiser/trunk/sv.prf 2008-10-23 16:32:00 UTC (rev 1248) +++ sonic-visualiser/trunk/sv.prf 2008-10-24 14:52:40 UTC (rev 1249) @@ -3,7 +3,7 @@ ### BEGIN CONFIGURABLE STUFF ### -CONFIG += debug +CONFIG += release # Temporarily Modified: sonic-visualiser/trunk/transform/TransformFactory.h =================================================================== --- sonic-visualiser/trunk/transform/TransformFactory.h 2008-10-23 16:32:00 UTC (rev 1248) +++ sonic-visualiser/trunk/transform/TransformFactory.h 2008-10-24 14:52:40 UTC (rev 1249) @@ -204,6 +204,7 @@ m_factory(factory) { } virtual void run() { + sleep(2); m_factory->populateUninstalledTransforms(); } TransformFactory *m_factory; Modified: sonic-visualiser/trunk/view/Pane.cpp =================================================================== --- sonic-visualiser/trunk/view/Pane.cpp 2008-10-23 16:32:00 UTC (rev 1248) +++ sonic-visualiser/trunk/view/Pane.cpp 2008-10-24 14:52:40 UTC (rev 1249) @@ -2168,6 +2168,13 @@ } void +Pane::layerParametersChanged() +{ + View::layerParametersChanged(); + updateHeadsUpDisplay(); +} + +void Pane::dragEnterEvent(QDragEnterEvent *e) { QStringList formats(e->mimeData()->formats()); Modified: sonic-visualiser/trunk/view/Pane.h =================================================================== --- sonic-visualiser/trunk/view/Pane.h 2008-10-23 16:32:00 UTC (rev 1248) +++ sonic-visualiser/trunk/view/Pane.h 2008-10-24 14:52:40 UTC (rev 1249) @@ -1,4 +1,3 @@ - /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ /* @@ -81,6 +80,8 @@ virtual void verticalPannerMoved(float x, float y, float w, float h); virtual void editVerticalPannerExtents(); + virtual void layerParametersChanged(); + virtual void propertyContainerSelected(View *, PropertyContainer *pc); void mouseEnteredWidget(); Modified: sonic-visualiser/trunk/widgets/Panner.cpp =================================================================== --- sonic-visualiser/trunk/widgets/Panner.cpp 2008-10-23 16:32:00 UTC (rev 1248) +++ sonic-visualiser/trunk/widgets/Panner.cpp 2008-10-24 14:52:40 UTC (rev 1249) @@ -163,10 +163,14 @@ paint.setBrush(hl); + int rw = lrintf(width() * m_rectWidth); + int rh = lrintf(height() * m_rectHeight); + if (rw < 2) rw = 2; + if (rh < 2) rh = 2; + paint.drawRect(lrintf(width() * m_rectX), lrintf(height() * m_rectY), - lrintf(width() * m_rectWidth), - lrintf(height() * m_rectHeight)); + rw, rh); } void This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-10-24 16:22:08
|
Revision: 1250 http://sv1.svn.sourceforge.net/sv1/?rev=1250&view=rev Author: cannam Date: 2008-10-24 16:21:57 +0000 (Fri, 24 Oct 2008) Log Message: ----------- * minor tidy Modified Paths: -------------- sonic-visualiser/trunk/layer/TimeValueLayer.cpp sonic-visualiser/trunk/view/Pane.cpp sonic-visualiser/trunk/widgets/Panner.cpp Modified: sonic-visualiser/trunk/layer/TimeValueLayer.cpp =================================================================== --- sonic-visualiser/trunk/layer/TimeValueLayer.cpp 2008-10-24 14:52:40 UTC (rev 1249) +++ sonic-visualiser/trunk/layer/TimeValueLayer.cpp 2008-10-24 16:21:57 UTC (rev 1250) @@ -67,6 +67,9 @@ connectSignals(m_model); + m_scaleMinimum = 0; + m_scaleMaximum = 0; + // std::cerr << "TimeValueLayer::setModel(" << model << ")" << std::endl; emit modelReplaced(); @@ -292,7 +295,7 @@ m_scaleMinimum = min; m_scaleMaximum = max; - std::cerr << "TimeValueLayer::setDisplayExtents: min = " << min << ", max = " << max << std::endl; +// std::cerr << "TimeValueLayer::setDisplayExtents: min = " << min << ", max = " << max << std::endl; emit layerParametersChanged(); return true; Modified: sonic-visualiser/trunk/view/Pane.cpp =================================================================== --- sonic-visualiser/trunk/view/Pane.cpp 2008-10-24 14:52:40 UTC (rev 1249) +++ sonic-visualiser/trunk/view/Pane.cpp 2008-10-24 16:21:57 UTC (rev 1250) @@ -2137,8 +2137,8 @@ float y1 = y0 + h; float newmax = vmin + ((1.0 - y0) * (vmax - vmin)); float newmin = vmin + ((1.0 - y1) * (vmax - vmin)); - std::cerr << "verticalPannerMoved: (" << x0 << "," << y0 << "," << w - << "," << h << ") -> (" << newmin << "," << newmax << ")" << std::endl; +// std::cerr << "verticalPannerMoved: (" << x0 << "," << y0 << "," << w +// << "," << h << ") -> (" << newmin << "," << newmax << ")" << std::endl; setTopLayerDisplayExtents(newmin, newmax); } Modified: sonic-visualiser/trunk/widgets/Panner.cpp =================================================================== --- sonic-visualiser/trunk/widgets/Panner.cpp 2008-10-24 14:52:40 UTC (rev 1249) +++ sonic-visualiser/trunk/widgets/Panner.cpp 2008-10-24 16:21:57 UTC (rev 1250) @@ -156,15 +156,15 @@ paint.setPen(palette().dark().color()); paint.setBrush(bg); - paint.drawRect(0, 0, width(), height()); + paint.drawRect(0, 0, width()-1, height()-1); QColor hl(m_thumbColour); hl.setAlpha(m_thumbAlpha); paint.setBrush(hl); - int rw = lrintf(width() * m_rectWidth); - int rh = lrintf(height() * m_rectHeight); + int rw = lrintf((width() - 1) * m_rectWidth); + int rh = lrintf((height() - 1) * m_rectHeight); if (rw < 2) rw = 2; if (rh < 2) rh = 2; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-10-27 18:18:10
|
Revision: 1254 http://sv1.svn.sourceforge.net/sv1/?rev=1254&view=rev Author: cannam Date: 2008-10-27 18:15:20 +0000 (Mon, 27 Oct 2008) Log Message: ----------- * make use of CachedFile (untested) Modified Paths: -------------- sonic-visualiser/trunk/data/fileio/CachedFile.cpp sonic-visualiser/trunk/data/fileio/CachedFile.h sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp sonic-visualiser/trunk/rdf/PluginRDFIndexer.h Modified: sonic-visualiser/trunk/data/fileio/CachedFile.cpp =================================================================== --- sonic-visualiser/trunk/data/fileio/CachedFile.cpp 2008-10-27 15:07:35 UTC (rev 1253) +++ sonic-visualiser/trunk/data/fileio/CachedFile.cpp 2008-10-27 18:15:20 UTC (rev 1254) @@ -61,15 +61,32 @@ return fi.filePath(); } +CachedFile::CachedFile(QString url, ProgressReporter *reporter) : + m_url(url), + m_localFilename(getLocalFilenameFor(m_url)), + m_reporter(reporter), + m_ok(false) +{ + std::cerr << "CachedFile::CachedFile: url is \"" + << url.toStdString() << "\"" << std::endl; + check(); +} + CachedFile::CachedFile(QUrl url, ProgressReporter *reporter) : m_url(url), - m_localFilename(getLocalFilenameFor(url)), + m_localFilename(getLocalFilenameFor(m_url)), m_reporter(reporter), m_ok(false) { - refresh(); + std::cerr << "CachedFile::CachedFile: url is \"" + << url.toString().toStdString() << "\"" << std::endl; + check(); } +CachedFile::~CachedFile() +{ +} + bool CachedFile::isOK() const { @@ -83,7 +100,7 @@ } void -CachedFile::refresh() +CachedFile::check() { //!!! n.b. obvious race condition here if different CachedFile // objects for same url used in more than one thread -- need to @@ -91,16 +108,20 @@ // separate instances of the program if (!QFileInfo(m_localFilename).exists()) { + std::cerr << "CachedFile::check: Local file does not exist, making a note that it hasn't been retrieved" << std::endl; updateLastRetrieval(false); // empirically! } QDateTime lastRetrieval = getLastRetrieval(); if (lastRetrieval.isValid()) { + std::cerr << "CachedFile::check: Valid last retrieval at " + << lastRetrieval.toString().toStdString() << std::endl; // this will not be the case if the file is missing, after // updateLastRetrieval(false) was called above m_ok = true; if (lastRetrieval.addDays(2) < QDateTime::currentDateTime()) { //!!! + std::cerr << "CachedFile::check: Out of date; trying to retrieve again" << std::endl; // doesn't matter if retrieval fails -- we just don't // update the last retrieval time @@ -109,15 +130,21 @@ // retrieval every single time if it isn't working if (retrieve()) { + std::cerr << "CachedFile::check: Retrieval succeeded" << std::endl; updateLastRetrieval(true); - } + } else { + std::cerr << "CachedFile::check: Retrieval failed, will try again later (using existing file for now)" << std::endl; + } } } else { + std::cerr << "CachedFile::check: No valid last retrieval" << std::endl; // there is no acceptable file if (retrieve()) { + std::cerr << "CachedFile::check: Retrieval succeeded" << std::endl; m_ok = true; updateLastRetrieval(true); } else { + std::cerr << "CachedFile::check: Retrieval failed, remaining in invalid state" << std::endl; // again, we don't need to do anything here -- the last // retrieval timestamp is already invalid } Modified: sonic-visualiser/trunk/data/fileio/CachedFile.h =================================================================== --- sonic-visualiser/trunk/data/fileio/CachedFile.h 2008-10-27 15:07:35 UTC (rev 1253) +++ sonic-visualiser/trunk/data/fileio/CachedFile.h 2008-10-27 18:15:20 UTC (rev 1254) @@ -25,6 +25,7 @@ class CachedFile { public: + CachedFile(QString fileOrUrl, ProgressReporter *reporter = 0); CachedFile(QUrl url, ProgressReporter *reporter = 0); virtual ~CachedFile(); @@ -39,7 +40,7 @@ ProgressReporter *m_reporter; bool m_ok; - void refresh(); + void check(); bool retrieve(); QDateTime getLastRetrieval(); Modified: sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp 2008-10-27 15:07:35 UTC (rev 1253) +++ sonic-visualiser/trunk/rdf/PluginRDFIndexer.cpp 2008-10-27 18:15:20 UTC (rev 1254) @@ -17,7 +17,8 @@ #include "SimpleSPARQLQuery.h" -#include "data/fileio/FileSource.h" +//!!!#include "data/fileio/FileSource.h" +#include "data/fileio/CachedFile.h" #include "data/fileio/PlaylistFileReader.h" #include "plugin/PluginIdentifier.h" @@ -100,11 +101,12 @@ PluginRDFIndexer::~PluginRDFIndexer() { QMutexLocker locker(&m_mutex); - +/*!!! while (!m_sources.empty()) { delete *m_sources.begin(); m_sources.erase(m_sources.begin()); } +*/ } bool @@ -125,12 +127,19 @@ std::cerr << "PluginRDFIndexer::indexConfiguredURLs: index url is " << index.toStdString() << std::endl; +/*!!! expireCacheMaybe(index); FileSource indexSource(index, 0, FileSource::PersistentCache); if (!indexSource.isAvailable()) continue; indexSource.waitForData(); +*/ + CachedFile cf(index); + if (!cf.isOK()) continue; + + FileSource indexSource(cf.getLocalFilename()); + PlaylistFileReader reader(indexSource); if (!reader.isOK()) continue; @@ -230,7 +239,7 @@ QString urlString = url.toString(); return indexURL(urlString); } - +/*!!! void PluginRDFIndexer::expireCacheMaybe(QString urlString) { @@ -266,7 +275,7 @@ settings.endGroup(); } - +*/ bool PluginRDFIndexer::indexURL(QString urlString) { @@ -284,6 +293,13 @@ //!!! how do we avoid hammering the server if it doesn't have //!!! the file, and/or the network if it can't get through? + CachedFile cf(urlString); + if (!cf.isOK()) { + return false; + } + + localString = cf.getLocalFilename(); +/*!!! expireCacheMaybe(urlString); FileSource *source = new FileSource @@ -295,6 +311,7 @@ source->waitForData(); localString = QUrl::fromLocalFile(source->getLocalFilename()).toString(); m_sources.insert(source); +*/ } // cerr << "PluginRDFIndexer::indexURL: url = <" << urlString.toStdString() << ">" << endl; Modified: sonic-visualiser/trunk/rdf/PluginRDFIndexer.h =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFIndexer.h 2008-10-27 15:07:35 UTC (rev 1253) +++ sonic-visualiser/trunk/rdf/PluginRDFIndexer.h 2008-10-27 18:15:20 UTC (rev 1254) @@ -22,7 +22,7 @@ #include <map> #include <set> -class FileSource; +//!!!class FileSource; class PluginRDFIndexer { @@ -55,14 +55,16 @@ protected: PluginRDFIndexer(); QMutex m_mutex; +/*!!! std::set<FileSource *> m_sources; +*/ typedef std::map<QString, QString> StringMap; StringMap m_uriToIdMap; StringMap m_idToUriMap; StringMap m_idToDescriptionMap; bool indexFile(QString path); static PluginRDFIndexer *m_instance; - void expireCacheMaybe(QString); +//!!! void expireCacheMaybe(QString); }; #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-10-27 20:30:04
|
Revision: 1255 http://sv1.svn.sourceforge.net/sv1/?rev=1255&view=rev Author: cannam Date: 2008-10-27 20:29:55 +0000 (Mon, 27 Oct 2008) Log Message: ----------- * complete switching the code to use CachedFile -- now to tidy & fix the remaining flaws... Modified Paths: -------------- sonic-visualiser/trunk/data/fileio/CachedFile.cpp sonic-visualiser/trunk/data/fileio/CachedFile.h sonic-visualiser/trunk/data/fileio/FileSource.cpp sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp sonic-visualiser/trunk/rdf/PluginRDFDescription.h sonic-visualiser/trunk/transform/TransformFactory.cpp Modified: sonic-visualiser/trunk/data/fileio/CachedFile.cpp =================================================================== --- sonic-visualiser/trunk/data/fileio/CachedFile.cpp 2008-10-27 18:15:20 UTC (rev 1254) +++ sonic-visualiser/trunk/data/fileio/CachedFile.cpp 2008-10-27 20:29:55 UTC (rev 1255) @@ -61,20 +61,20 @@ return fi.filePath(); } -CachedFile::CachedFile(QString url, ProgressReporter *reporter) : - m_url(url), - m_localFilename(getLocalFilenameFor(m_url)), +CachedFile::CachedFile(QString origin, ProgressReporter *reporter) : + m_origin(origin), + m_localFilename(getLocalFilenameFor(m_origin)), m_reporter(reporter), m_ok(false) { - std::cerr << "CachedFile::CachedFile: url is \"" - << url.toStdString() << "\"" << std::endl; + std::cerr << "CachedFile::CachedFile: origin is \"" + << origin.toStdString() << "\"" << std::endl; check(); } CachedFile::CachedFile(QUrl url, ProgressReporter *reporter) : - m_url(url), - m_localFilename(getLocalFilenameFor(m_url)), + m_origin(url.toString()), + m_localFilename(getLocalFilenameFor(m_origin)), m_reporter(reporter), m_ok(false) { @@ -160,15 +160,17 @@ //!!! using Qt classes, but a plain delete then copy is probably //!!! good enough) - FileSource fs(m_url, m_reporter); + FileSource fs(m_origin, m_reporter); if (!fs.isOK() || !fs.isAvailable()) { + std::cerr << "CachedFile::retrieve: ERROR: FileSource reported unavailable or failure" << std::endl; return false; } fs.waitForData(); if (!fs.isOK()) { + std::cerr << "CachedFile::retrieve: ERROR: FileSource reported failure during receive" << std::endl; return false; } @@ -196,6 +198,8 @@ return false; } + std::cerr << "CachedFile::retrieve: Successfully copied newly retrieved file \"" << tempName.toStdString() << "\" to its home at \"" << m_localFilename.toStdString() << "\"" << std::endl; + return true; } Modified: sonic-visualiser/trunk/data/fileio/CachedFile.h =================================================================== --- sonic-visualiser/trunk/data/fileio/CachedFile.h 2008-10-27 18:15:20 UTC (rev 1254) +++ sonic-visualiser/trunk/data/fileio/CachedFile.h 2008-10-27 20:29:55 UTC (rev 1255) @@ -35,7 +35,7 @@ QString getLocalFilename() const; protected: - QUrl m_url; + QString m_origin; QString m_localFilename; ProgressReporter *m_reporter; bool m_ok; Modified: sonic-visualiser/trunk/data/fileio/FileSource.cpp =================================================================== --- sonic-visualiser/trunk/data/fileio/FileSource.cpp 2008-10-27 18:15:20 UTC (rev 1254) +++ sonic-visualiser/trunk/data/fileio/FileSource.cpp 2008-10-27 20:29:55 UTC (rev 1255) @@ -62,6 +62,12 @@ m_reporter(reporter), m_refCounted(false) { + + if (cacheMode == PersistentCache) { + std::cerr << "FileSource::FileSource: Persistent cache mode used for \"" << fileOrUrl.toStdString() << "\"" << std::endl; + exit(1); + } + #ifdef DEBUG_FILE_SOURCE std::cerr << "FileSource::FileSource(" << fileOrUrl.toStdString() << ", " << cacheMode << ")" << std::endl; #endif @@ -128,6 +134,12 @@ m_reporter(reporter), m_refCounted(false) { + + if (cacheMode == PersistentCache) { + std::cerr << "FileSource::FileSource: Persistent cache mode used for \"" << url.toString().toStdString() << "\"" << std::endl; + exit(1); + } + #ifdef DEBUG_FILE_SOURCE std::cerr << "FileSource::FileSource(" << url.toString().toStdString() << ") [as url]" << std::endl; #endif Modified: sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp 2008-10-27 18:15:20 UTC (rev 1254) +++ sonic-visualiser/trunk/rdf/PluginRDFDescription.cpp 2008-10-27 20:29:55 UTC (rev 1255) @@ -19,6 +19,7 @@ #include "SimpleSPARQLQuery.h" #include "data/fileio/FileSource.h" +#include "data/fileio/CachedFile.h" #include "base/Profiler.h" @@ -29,7 +30,7 @@ using std::endl; PluginRDFDescription::PluginRDFDescription(QString pluginId) : - m_source(0), +//!!! m_source(0), m_pluginId(pluginId), m_haveDescription(false) { @@ -50,7 +51,7 @@ PluginRDFDescription::~PluginRDFDescription() { - delete m_source; +//!!! delete m_source; } bool @@ -168,6 +169,13 @@ //!!! persistent with expiry + CachedFile cf(url); + if (!cf.isOK()) { + return false; + } + + local = QUrl::fromLocalFile(cf.getLocalFilename()).toString(); +/*!!! m_source = new FileSource(url, 0, FileSource::PersistentCache); if (!m_source->isAvailable()) { @@ -177,6 +185,7 @@ } m_source->waitForData(); local = QUrl::fromLocalFile(m_source->getLocalFilename()).toString(); +*/ } if (!indexMetadata(local, label)) success = false; Modified: sonic-visualiser/trunk/rdf/PluginRDFDescription.h =================================================================== --- sonic-visualiser/trunk/rdf/PluginRDFDescription.h 2008-10-27 18:15:20 UTC (rev 1254) +++ sonic-visualiser/trunk/rdf/PluginRDFDescription.h 2008-10-27 20:29:55 UTC (rev 1255) @@ -20,7 +20,7 @@ #include <QStringList> #include <map> -class FileSource; +//!!!class FileSource; class PluginRDFDescription { @@ -56,7 +56,7 @@ typedef std::map<QString, OutputDisposition> OutputDispositionMap; typedef std::map<QString, QString> OutputStringMap; - FileSource *m_source; +//!!! FileSource *m_source; QString m_pluginId; bool m_haveDescription; QString m_pluginName; Modified: sonic-visualiser/trunk/transform/TransformFactory.cpp =================================================================== --- sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-10-27 18:15:20 UTC (rev 1254) +++ sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-10-27 20:29:55 UTC (rev 1255) @@ -561,7 +561,12 @@ if (m_transforms.find(tid) != m_transforms.end()) { std::cerr << "TransformFactory::populateUninstalledTransforms: " - << tid.toStdString() << " is installed, skipping" << std::endl; + << tid.toStdString() << " is installed; adding info url if appropriate, skipping rest" << std::endl; + if (infoUrl != "") { + if (m_transforms[tid].infoUrl == "") { + m_transforms[tid].infoUrl = infoUrl; + } + } continue; } @@ -611,14 +616,6 @@ td.configurable = false; m_uninstalledTransforms[tid] = td; - - if (td.infoUrl != "") { - if (m_transforms.find(tid) != m_transforms.end()) { - if (m_transforms[tid].infoUrl == "") { - m_transforms[tid].infoUrl = td.infoUrl; - } - } - } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-10-28 13:57:00
|
Revision: 1259 http://sv1.svn.sourceforge.net/sv1/?rev=1259&view=rev Author: cannam Date: 2008-10-28 12:39:53 +0000 (Tue, 28 Oct 2008) Log Message: ----------- * Add more info button to plugin dialog Modified Paths: -------------- sonic-visualiser/trunk/sv/sonic-visualiser.qrc sonic-visualiser/trunk/transform/ModelTransformerFactory.cpp sonic-visualiser/trunk/transform/TransformFactory.cpp sonic-visualiser/trunk/transform/TransformFactory.h sonic-visualiser/trunk/widgets/PluginParameterDialog.cpp sonic-visualiser/trunk/widgets/PluginParameterDialog.h Modified: sonic-visualiser/trunk/sv/sonic-visualiser.qrc =================================================================== --- sonic-visualiser/trunk/sv/sonic-visualiser.qrc 2008-10-28 11:38:43 UTC (rev 1258) +++ sonic-visualiser/trunk/sv/sonic-visualiser.qrc 2008-10-28 12:39:53 UTC (rev 1259) @@ -48,6 +48,7 @@ <file>icons/exit.png</file> <file>icons/speaker.png</file> <file>icons/annotation.png</file> + <file>icons/info.png</file> <file>icons/fileopen.png</file> <file>icons/fileopensession.png</file> <file>icons/fileopenaudio.png</file> Modified: sonic-visualiser/trunk/transform/ModelTransformerFactory.cpp =================================================================== --- sonic-visualiser/trunk/transform/ModelTransformerFactory.cpp 2008-10-28 11:38:43 UTC (rev 1258) +++ sonic-visualiser/trunk/transform/ModelTransformerFactory.cpp 2008-10-28 12:39:53 UTC (rev 1259) @@ -218,6 +218,9 @@ PluginParameterDialog *dialog = new PluginParameterDialog(plugin); + dialog->setMoreInfoUrl(TransformFactory::getInstance()-> + getTransformInfoUrl(transform.getIdentifier())); + if (candidateModelNames.size() > 1 && !generator) { dialog->setCandidateInputModels(candidateModelNames, defaultModelName); Modified: sonic-visualiser/trunk/transform/TransformFactory.cpp =================================================================== --- sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-10-28 11:38:43 UTC (rev 1258) +++ sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-10-28 12:39:53 UTC (rev 1259) @@ -735,6 +735,14 @@ } else return ""; } +QString +TransformFactory::getTransformInfoUrl(TransformId identifier) +{ + if (m_transforms.find(identifier) != m_transforms.end()) { + return m_transforms[identifier].infoUrl; + } else return ""; +} + Vamp::Plugin::InputDomain TransformFactory::getTransformInputDomain(TransformId identifier) { Modified: sonic-visualiser/trunk/transform/TransformFactory.h =================================================================== --- sonic-visualiser/trunk/transform/TransformFactory.h 2008-10-28 11:38:43 UTC (rev 1258) +++ sonic-visualiser/trunk/transform/TransformFactory.h 2008-10-28 12:39:53 UTC (rev 1259) @@ -87,6 +87,8 @@ QString getTransformUnits(TransformId identifier); + QString getTransformInfoUrl(TransformId identifier); + Vamp::Plugin::InputDomain getTransformInputDomain(TransformId identifier); /** Modified: sonic-visualiser/trunk/widgets/PluginParameterDialog.cpp =================================================================== --- sonic-visualiser/trunk/widgets/PluginParameterDialog.cpp 2008-10-28 11:38:43 UTC (rev 1258) +++ sonic-visualiser/trunk/widgets/PluginParameterDialog.cpp 2008-10-28 12:39:53 UTC (rev 1259) @@ -19,6 +19,7 @@ #include "WindowTypeSelector.h" #include "TextAbbrev.h" +#include "IconLoader.h" #include "vamp-sdk/Plugin.h" #include "vamp-sdk/PluginHostAdapter.h" @@ -36,6 +37,8 @@ #include <QCheckBox> #include <QSettings> #include <QDialogButtonBox> +#include <QDesktopServices> +#include <QUrl> PluginParameterDialog::PluginParameterDialog(Vamp::PluginBase *plugin, QWidget *parent) : @@ -100,18 +103,25 @@ label->setAlignment(Qt::AlignTop | Qt::AlignLeft); subgrid->addWidget(label, row, 0); subgrid->addWidget(nameLabel, row, 1); + + m_moreInfo = new QPushButton; + m_moreInfo->setIcon(IconLoader().load("info")); + m_moreInfo->setFixedSize(QSize(16, 16)); + connect(m_moreInfo, SIGNAL(clicked()), this, SLOT(moreInfo())); + subgrid->addWidget(m_moreInfo, row, 2, Qt::AlignTop | Qt::AlignRight); + m_moreInfo->hide(); + row++; if (descriptionLabel) { // label = new QLabel(tr("Description:")); // label->setAlignment(Qt::AlignTop | Qt::AlignLeft); // subgrid->addWidget(label, row, 0); - subgrid->addWidget(descriptionLabel, row, 1); + subgrid->addWidget(descriptionLabel, row, 1, 1, 2); row++; } - Vamp::PluginHostAdapter *fePlugin = - dynamic_cast<Vamp::PluginHostAdapter *>(m_plugin); + Vamp::Plugin *fePlugin = dynamic_cast<Vamp::Plugin *>(m_plugin); if (fePlugin) { label = new QLabel(tr("Version:")); @@ -119,6 +129,8 @@ subgrid->addWidget(label, row, 0); subgrid->addWidget(versionLabel, row, 1); row++; + } else { + std::cerr << "PluginParameterDialog: Note: not a feature extraction plugin (type is " << typeid(*m_plugin).name() << ")" << std::endl; } // label = new QLabel(tr("Type:")); @@ -276,6 +288,17 @@ } void +PluginParameterDialog::setMoreInfoUrl(QString moreInfoUrl) +{ + m_moreInfoUrl = moreInfoUrl; + if (m_moreInfoUrl != "") { + m_moreInfo->show(); + } else { + m_moreInfo->hide(); + } +} + +void PluginParameterDialog::setChannelArrangement(int sourceChannels, int targetChannels, int defaultChannel) @@ -549,6 +572,14 @@ } void +PluginParameterDialog::moreInfo() +{ + if (m_moreInfoUrl != "") { + QDesktopServices::openUrl(QUrl(m_moreInfoUrl)); + } +} + +void PluginParameterDialog::advancedToggled() { setAdvancedVisible(!m_advancedVisible); Modified: sonic-visualiser/trunk/widgets/PluginParameterDialog.h =================================================================== --- sonic-visualiser/trunk/widgets/PluginParameterDialog.h 2008-10-28 11:38:43 UTC (rev 1258) +++ sonic-visualiser/trunk/widgets/PluginParameterDialog.h 2008-10-28 12:39:53 UTC (rev 1259) @@ -51,6 +51,8 @@ void setOutputLabel(QString output, QString description); + void setMoreInfoUrl(QString url); + void setShowProcessingOptions(bool showWindowSize, bool showFrequencyDomainOptions); @@ -81,6 +83,7 @@ void incrementComboChanged(const QString &); void windowTypeChanged(WindowType type); void advancedToggled(); + void moreInfo(); void setAdvancedVisible(bool); void inputModelComboChanged(int); void selectionOnlyChanged(int); @@ -101,6 +104,9 @@ QLabel *m_outputDescription; QLabel *m_outputSpacer; + QPushButton *m_moreInfo; + QString m_moreInfoUrl; + QGroupBox *m_channelBox; bool m_haveChannelBoxData; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ca...@us...> - 2008-10-28 18:06:12
|
Revision: 1260 http://sv1.svn.sourceforge.net/sv1/?rev=1260&view=rev Author: cannam Date: 2008-10-28 18:06:06 +0000 (Tue, 28 Oct 2008) Log Message: ----------- * Avoid waiting on uninstalled transforms mutex in TransformFactory:: getTransformInstallStatus -- we can return TransformUnknown * Don't follow link in SelectableLabel when clicking to select it * Restore lost version number in plugin param dialog Modified Paths: -------------- sonic-visualiser/trunk/plugin/DSSIPluginInstance.cpp sonic-visualiser/trunk/plugin/LADSPAPluginInstance.cpp sonic-visualiser/trunk/transform/TransformFactory.cpp sonic-visualiser/trunk/widgets/PluginParameterDialog.cpp sonic-visualiser/trunk/widgets/SelectableLabel.cpp sonic-visualiser/trunk/widgets/SelectableLabel.h sonic-visualiser/trunk/widgets/TransformFinder.cpp Modified: sonic-visualiser/trunk/plugin/DSSIPluginInstance.cpp =================================================================== --- sonic-visualiser/trunk/plugin/DSSIPluginInstance.cpp 2008-10-28 12:39:53 UTC (rev 1259) +++ sonic-visualiser/trunk/plugin/DSSIPluginInstance.cpp 2008-10-28 18:06:06 UTC (rev 1260) @@ -126,7 +126,7 @@ int DSSIPluginInstance::getPluginVersion() const { - return 1; + return -1; } std::string Modified: sonic-visualiser/trunk/plugin/LADSPAPluginInstance.cpp =================================================================== --- sonic-visualiser/trunk/plugin/LADSPAPluginInstance.cpp 2008-10-28 12:39:53 UTC (rev 1259) +++ sonic-visualiser/trunk/plugin/LADSPAPluginInstance.cpp 2008-10-28 18:06:06 UTC (rev 1260) @@ -109,7 +109,7 @@ int LADSPAPluginInstance::getPluginVersion() const { - return 1; + return -1; } std::string Modified: sonic-visualiser/trunk/transform/TransformFactory.cpp =================================================================== --- sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-10-28 12:39:53 UTC (rev 1259) +++ sonic-visualiser/trunk/transform/TransformFactory.cpp 2008-10-28 18:06:06 UTC (rev 1260) @@ -134,14 +134,29 @@ TransformFactory::getTransformInstallStatus(TransformId id) { populateTransforms(); - populateUninstalledTransforms(); if (m_transforms.find(id) != m_transforms.end()) { return TransformInstalled; } + + if (!m_uninstalledTransformsMutex.tryLock()) { + // uninstalled transforms are being populated; this may take some time, + // and they aren't critical + return TransformUnknown; + } + + if (!m_uninstalledTransformsPopulated) { + m_uninstalledTransformsMutex.unlock(); + populateUninstalledTransforms(); + m_uninstalledTransformsMutex.lock(); + } + if (m_uninstalledTransforms.find(id) != m_uninstalledTransforms.end()) { return TransformNotInstalled; } + + m_uninstalledTransformsMutex.unlock(); + return TransformUnknown; } Modified: sonic-visualiser/trunk/widgets/PluginParameterDialog.cpp =================================================================== --- sonic-visualiser/trunk/widgets/PluginParameterDialog.cpp 2008-10-28 12:39:53 UTC (rev 1259) +++ sonic-visualiser/trunk/widgets/PluginParameterDialog.cpp 2008-10-28 18:06:06 UTC (rev 1260) @@ -79,8 +79,8 @@ QLabel *makerLabel = new QLabel(plugin->getMaker().c_str()); makerLabel->setWordWrap(true); - QLabel *versionLabel = new QLabel(QString("%1") - .arg(plugin->getPluginVersion())); + int version = plugin->getPluginVersion(); + QLabel *versionLabel = new QLabel(QString("%1").arg(version)); versionLabel->setWordWrap(true); QLabel *copyrightLabel = new QLabel(plugin->getCopyright().c_str()); @@ -121,16 +121,12 @@ row++; } - Vamp::Plugin *fePlugin = dynamic_cast<Vamp::Plugin *>(m_plugin); - - if (fePlugin) { + if (version >= 0) { label = new QLabel(tr("Version:")); label->setAlignment(Qt::AlignTop | Qt::AlignLeft); subgrid->addWidget(label, row, 0); subgrid->addWidget(versionLabel, row, 1); row++; - } else { - std::cerr << "PluginParameterDialog: Note: not a feature extraction plugin (type is " << typeid(*m_plugin).name() << ")" << std::endl; } // label = new QLabel(tr("Type:")); Modified: sonic-visualiser/trunk/widgets/SelectableLabel.cpp =================================================================== --- sonic-visualiser/trunk/widgets/SelectableLabel.cpp 2008-10-28 12:39:53 UTC (rev 1259) +++ sonic-visualiser/trunk/widgets/SelectableLabel.cpp 2008-10-28 18:06:06 UTC (rev 1260) @@ -26,6 +26,7 @@ // setLineWidth(2); // setFixedWidth(480); setupStyle(); + setOpenExternalLinks(true); } SelectableLabel::~SelectableLabel() @@ -59,6 +60,10 @@ { QPalette palette = QApplication::palette(); + setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | + Qt::LinksAccessibleByMouse | + Qt::TextSelectableByMouse); + if (m_selected) { setWordWrap(true); setStyleSheet @@ -77,8 +82,6 @@ .arg(palette.button().color().name()) .arg(palette.light().color().name()) .arg(palette.text().color().name())); - -// setStyleSheet("QLabel:hover { background: #e0e0e0; color: black; } QLabel:!hover { background: white; color: black } QLabel { padding: 7px }"); } } @@ -105,18 +108,27 @@ void SelectableLabel::mousePressEvent(QMouseEvent *e) { + m_swallowRelease = !m_selected; setSelected(true); + QLabel::mousePressEvent(e); emit selectionChanged(); } void SelectableLabel::mouseDoubleClickEvent(QMouseEvent *e) { - std::cerr << "mouseDoubleClickEvent" << std::endl; + QLabel::mouseDoubleClickEvent(e); emit doubleClicked(); } void +SelectableLabel::mouseReleaseEvent(QMouseEvent *e) +{ + if (!m_swallowRelease) QLabel::mouseReleaseEvent(e); + m_swallowRelease = false; +} + +void SelectableLabel::enterEvent(QEvent *) { // std::cerr << "enterEvent" << std::endl; Modified: sonic-visualiser/trunk/widgets/SelectableLabel.h =================================================================== --- sonic-visualiser/trunk/widgets/SelectableLabel.h 2008-10-28 12:39:53 UTC (rev 1259) +++ sonic-visualiser/trunk/widgets/SelectableLabel.h 2008-10-28 18:06:06 UTC (rev 1260) @@ -41,6 +41,7 @@ protected: virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseReleaseEvent(QMouseEvent *e); virtual void mouseDoubleClickEvent(QMouseEvent *e); virtual void enterEvent(QEvent *); virtual void leaveEvent(QEvent *); @@ -48,6 +49,7 @@ QString m_selectedText; QString m_unselectedText; bool m_selected; + bool m_swallowRelease; }; #endif Modified: sonic-visualiser/trunk/widgets/TransformFinder.cpp =================================================================== --- sonic-visualiser/trunk/widgets/TransformFinder.cpp 2008-10-28 12:39:53 UTC (rev 1259) +++ sonic-visualiser/trunk/widgets/TransformFinder.cpp 2008-10-28 18:06:06 UTC (rev 1260) @@ -234,10 +234,6 @@ SLOT(accept())); QPalette palette = label->palette(); label->setPalette(palette); - label->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | - Qt::LinksAccessibleByMouse | - Qt::TextSelectableByMouse); - label->setOpenExternalLinks(true); m_labels.push_back(label); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |