# HG changeset patch # User Chris Cannam # Date 1536063560 -3600 # Node ID fe579dc6a71385c385491d6125f1f6518ffdd17c # Parent f0c2b8b31609a2b6a77252ecf25a741f0e9a6a7e# Parent a250a54c11cc4350475096002076b7a6899ec792 Merge from default branch diff -r f0c2b8b31609 -r fe579dc6a713 data/fileio/test/CSVStreamWriterTest.h --- a/data/fileio/test/CSVStreamWriterTest.h Fri Jun 29 13:52:36 2018 +0100 +++ b/data/fileio/test/CSVStreamWriterTest.h Tue Sep 04 13:19:20 2018 +0100 @@ -256,7 +256,7 @@ regions.addSelection({0, 2}); regions.addSelection({4, 6}); regions.addSelection({16, 18}); - qDebug("End frame: %lld", (long long int)mwm.getEndFrame()); +// qDebug("End frame: %lld", (long long int)mwm.getEndFrame()); const std::string expectedOutput { "0,0,0\n" "1,0,0\n" @@ -278,7 +278,7 @@ QVERIFY( reporter.getCallCount() == 3 ); const std::vector expectedCallLog { 33, 66, 100 }; QVERIFY( reporter.getPercentageLog() == expectedCallLog ); - qDebug("%s", oss.str().c_str()); +// qDebug("%s", oss.str().c_str()); QVERIFY( oss.str() == expectedOutput ); } @@ -300,15 +300,15 @@ notes.addPoint({startFrame, note, 4, 1.f, ""}); startFrame += 8; } - qDebug("Create Expected Output\n"); +// qDebug("Create Expected Output\n"); // NB. removed end line break const auto expectedOutput = notes.toDelimitedDataString(",").trimmed(); StubReporter reporter { []() -> bool { return false; } }; std::ostringstream oss; - qDebug("End frame: %lld", (long long int)notes.getEndFrame()); - qDebug("Write streaming\n"); +// qDebug("End frame: %lld", (long long int)notes.getEndFrame()); +// qDebug("Write streaming\n"); const auto wroteSparseModel = CSVStreamWriter::writeInChunks( oss, notes, @@ -318,8 +318,8 @@ 2 ); - qDebug("\n%s\n", expectedOutput.toLocal8Bit().data()); - qDebug("\n%s\n", oss.str().c_str()); +// qDebug("\n%s\n", expectedOutput.toLocal8Bit().data()); +// qDebug("\n%s\n", oss.str().c_str()); QVERIFY( wroteSparseModel == true ); QVERIFY( oss.str() == expectedOutput.toStdString() ); } diff -r f0c2b8b31609 -r fe579dc6a713 data/fileio/test/svcore-data-fileio-test.cpp --- a/data/fileio/test/svcore-data-fileio-test.cpp Fri Jun 29 13:52:36 2018 +0100 +++ b/data/fileio/test/svcore-data-fileio-test.cpp Tue Sep 04 13:19:20 2018 +0100 @@ -35,18 +35,17 @@ #endif if (argc > 1) { - SVCERR << "argc = " << argc << endl; testDir = argv[1]; } - if (testDir != "") { - SVCERR << "Setting test directory base path to \"" << testDir << "\"" << endl; - } - QCoreApplication app(argc, argv); app.setOrganizationName("sonic-visualiser"); app.setApplicationName("test-fileio"); + if (testDir != "") { + SVCERR << "Setting test directory base path to \"" << testDir << "\"" << endl; + } + { AudioFileReaderTest t(testDir); if (QTest::qExec(&t, argc, argv) == 0) ++good; diff -r f0c2b8b31609 -r fe579dc6a713 data/model/DenseTimeValueModel.cpp --- a/data/model/DenseTimeValueModel.cpp Fri Jun 29 13:52:36 2018 +0100 +++ b/data/model/DenseTimeValueModel.cpp Tue Sep 04 13:19:20 2018 +0100 @@ -33,7 +33,7 @@ { int ch = getChannelCount(); - cerr << "f0 = " << f0 << ", f1 = " << f1 << endl; +// cerr << "f0 = " << f0 << ", f1 = " << f1 << endl; if (f1 <= f0) return ""; diff -r f0c2b8b31609 -r fe579dc6a713 data/model/Model.cpp --- a/data/model/Model.cpp Fri Jun 29 13:52:36 2018 +0100 +++ b/data/model/Model.cpp Tue Sep 04 13:19:20 2018 +0100 @@ -40,6 +40,20 @@ } } +int +Model::getNextId() +{ + static int nextId = 0; + static QMutex mutex; + QMutexLocker locker(&mutex); + int i = nextId; + if (nextId == INT_MAX) { + nextId = INT_MIN; + } + ++nextId; + return i; +} + void Model::setSourceModel(Model *model) { diff -r f0c2b8b31609 -r fe579dc6a713 data/model/Model.h --- a/data/model/Model.h Fri Jun 29 13:52:36 2018 +0100 +++ b/data/model/Model.h Tue Sep 04 13:19:20 2018 +0100 @@ -13,8 +13,8 @@ COPYING included with this distribution for more information. */ -#ifndef _MODEL_H_ -#define _MODEL_H_ +#ifndef SV_MODEL_H +#define SV_MODEL_H #include #include @@ -27,6 +27,8 @@ class ZoomConstraint; class AlignmentModel; +typedef int ModelId; + /** * Model is the base class for all data models that represent any sort * of data on a time scale based on an audio frame rate. @@ -98,6 +100,13 @@ * Return true if this is a sparse model. */ virtual bool isSparse() const { return false; } + + /** + * Return an id for this model. The id is guaranteed to be a + * unique identifier for this model among all models that may ever + * exist within this single run of the application. + */ + ModelId getId() const { return m_id; } /** * Mark the model as abandoning. This means that the application @@ -291,7 +300,8 @@ void aboutToBeDeleted(); protected: - Model() : + Model() : + m_id(getNextId()), m_sourceModel(0), m_alignment(0), m_abandoning(false), @@ -301,11 +311,14 @@ Model(const Model &); Model &operator=(const Model &); + const ModelId m_id; Model *m_sourceModel; AlignmentModel *m_alignment; QString m_typeUri; bool m_abandoning; bool m_aboutToDelete; + + int getNextId(); }; #endif diff -r f0c2b8b31609 -r fe579dc6a713 data/model/NoteData.h --- a/data/model/NoteData.h Fri Jun 29 13:52:36 2018 +0100 +++ b/data/model/NoteData.h Tue Sep 04 13:19:20 2018 +0100 @@ -12,8 +12,8 @@ COPYING included with this distribution for more information. */ -#ifndef NOTE_DATA_H -#define NOTE_DATA_H +#ifndef SV_NOTE_DATA_H +#define SV_NOTE_DATA_H #include diff -r f0c2b8b31609 -r fe579dc6a713 data/model/NoteModel.h --- a/data/model/NoteModel.h Fri Jun 29 13:52:36 2018 +0100 +++ b/data/model/NoteModel.h Tue Sep 04 13:19:20 2018 +0100 @@ -13,8 +13,8 @@ COPYING included with this distribution for more information. */ -#ifndef _NOTE_MODEL_H_ -#define _NOTE_MODEL_H_ +#ifndef SV_NOTE_MODEL_H +#define SV_NOTE_MODEL_H #include "IntervalModel.h" #include "NoteData.h" diff -r f0c2b8b31609 -r fe579dc6a713 plugin/LADSPAPluginFactory.cpp --- a/plugin/LADSPAPluginFactory.cpp Fri Jun 29 13:52:36 2018 +0100 +++ b/plugin/LADSPAPluginFactory.cpp Tue Sep 04 13:19:20 2018 +0100 @@ -422,7 +422,7 @@ if (m_libraryHandles.find(soname) == m_libraryHandles.end()) { loadLibrary(soname); if (m_libraryHandles.find(soname) == m_libraryHandles.end()) { - cerr << "WARNING: LADSPAPluginFactory::getLADSPADescriptor: loadLibrary failed for " << soname << endl; + SVCERR << "WARNING: LADSPAPluginFactory::getLADSPADescriptor: loadLibrary failed for " << soname << endl; return 0; } } @@ -433,7 +433,7 @@ DLSYM(libraryHandle, "ladspa_descriptor"); if (!fn) { - cerr << "WARNING: LADSPAPluginFactory::getLADSPADescriptor: No descriptor function in library " << soname << endl; + SVCERR << "WARNING: LADSPAPluginFactory::getLADSPADescriptor: No descriptor function in library " << soname << endl; return 0; } @@ -445,7 +445,7 @@ ++index; } - cerr << "WARNING: LADSPAPluginFactory::getLADSPADescriptor: No such plugin as " << label << " in library " << soname << endl; + SVCERR << "WARNING: LADSPAPluginFactory::getLADSPADescriptor: No such plugin as " << label << " in library " << soname << endl; return 0; } @@ -462,7 +462,7 @@ if (QFileInfo(soName).exists()) { DLERROR(); - cerr << "LADSPAPluginFactory::loadLibrary: Library \"" << soName << "\" exists, but failed to load it" << endl; + SVCERR << "LADSPAPluginFactory::loadLibrary: Library \"" << soName << "\" exists, but failed to load it" << endl; return; } @@ -484,7 +484,7 @@ if (QFileInfo(dir.filePath(fileName)).exists()) { #ifdef DEBUG_LADSPA_PLUGIN_FACTORY - cerr << "Loading: " << fileName << endl; + SVDEBUG << "Loading: " << fileName << endl; #endif libraryHandle = DLOPEN(dir.filePath(fileName), RTLD_NOW); if (libraryHandle) { @@ -497,7 +497,7 @@ QString file = dir.filePath(dir[j]); if (QFileInfo(file).baseName() == base) { #ifdef DEBUG_LADSPA_PLUGIN_FACTORY - cerr << "Loading: " << file << endl; + SVDEBUG << "Loading: " << file << endl; #endif libraryHandle = DLOPEN(file, RTLD_NOW); if (libraryHandle) { @@ -508,7 +508,7 @@ } } - cerr << "LADSPAPluginFactory::loadLibrary: Failed to locate plugin library \"" << soName << "\"" << endl; + SVCERR << "LADSPAPluginFactory::loadLibrary: Failed to locate plugin library \"" << soName << "\"" << endl; } void @@ -569,7 +569,7 @@ std::vector pathList; string path; - (void)getEnvUtf8("DSSI_PATH", path); + (void)getEnvUtf8("LADSPA_PATH", path); if (path == "") { diff -r f0c2b8b31609 -r fe579dc6a713 plugin/PluginScan.cpp --- a/plugin/PluginScan.cpp Fri Jun 29 13:52:36 2018 +0100 +++ b/plugin/PluginScan.cpp Tue Sep 04 13:19:20 2018 +0100 @@ -18,11 +18,7 @@ #include "base/Preferences.h" #include "base/HelperExecPath.h" -#ifdef HAVE_PLUGIN_CHECKER_HELPER -#include "checker/knownplugincandidates.h" -#else -class KnownPluginCandidates {}; -#endif +#include #include #include @@ -182,6 +178,95 @@ #endif } +#ifdef HAVE_PLUGIN_CHECKER_HELPER +QString +PluginScan::formatFailureReport(QString tag, + std::vector failures) const +{ + int n = int(failures.size()); + int i = 0; + + std::ostringstream os; + + os << "
    "; + for (auto f: failures) { + os << "
  • " + f.library; + + SVDEBUG << "PluginScan::formatFailureReport: tag is \"" << tag + << "\", failure code is " << int(f.code) << ", message is \"" + << f.message << "\"" << endl; + + QString userMessage = QString::fromStdString(f.message); + + switch (f.code) { + + case PluginCheckCode::FAIL_LIBRARY_NOT_FOUND: + userMessage = QObject::tr("Library file could not be opened"); + break; + + case PluginCheckCode::FAIL_WRONG_ARCHITECTURE: + if (tag == "64" || (sizeof(void *) == 8 && tag == "")) { + userMessage = QObject::tr + ("Library has wrong architecture - possibly a 32-bit plugin installed in a 64-bit plugin folder"); + } else if (tag == "32" || (sizeof(void *) == 4 && tag == "")) { + userMessage = QObject::tr + ("Library has wrong architecture - possibly a 64-bit plugin installed in a 32-bit plugin folder"); + } + break; + + case PluginCheckCode::FAIL_DEPENDENCY_MISSING: + userMessage = QObject::tr + ("Library depends on another library that cannot be found: %1") + .arg(userMessage); + break; + + case PluginCheckCode::FAIL_NOT_LOADABLE: + userMessage = QObject::tr + ("Library cannot be loaded: %1").arg(userMessage); + break; + + case PluginCheckCode::FAIL_DESCRIPTOR_MISSING: + userMessage = QObject::tr + ("Not a valid plugin library (no descriptor found)"); + break; + + case PluginCheckCode::FAIL_NO_PLUGINS: + userMessage = QObject::tr + ("Library contains no plugins"); + break; + + case PluginCheckCode::FAIL_OTHER: + if (userMessage == "") { + userMessage = QObject::tr + ("Unknown error"); + } + break; + + case PluginCheckCode::SUCCESS: + // success shouldn't happen here! + break; + } + + os << "
    " + userMessage.toStdString() + ""; + os << "
  • "; + + if (n > 10) { + if (++i == 5) { + os << "
  • "; + os << QObject::tr("... and %n further failure(s)", + "", n - i) + .toStdString(); + os << "
  • "; + break; + } + } + } + os << "
"; + + return QString::fromStdString(os.str()); +} +#endif + QString PluginScan::getStartupFailureReport() const { @@ -204,7 +289,10 @@ QString report; for (auto kp: m_kp) { - report += QString::fromStdString(kp.second->getFailureReport()); + auto failures = kp.second->getFailures(); + if (!failures.empty()) { + report += formatFailureReport(kp.first, failures); + } } if (report == "") { return report; diff -r f0c2b8b31609 -r fe579dc6a713 plugin/PluginScan.h --- a/plugin/PluginScan.h Fri Jun 29 13:52:36 2018 +0100 +++ b/plugin/PluginScan.h Tue Sep 04 13:19:20 2018 +0100 @@ -20,7 +20,11 @@ #include #include -class KnownPluginCandidates; +#ifdef HAVE_PLUGIN_CHECKER_HELPER +#include "checker/knownplugincandidates.h" +#else +class KnownPluginCandidates {}; +#endif class PluginScan { @@ -73,6 +77,12 @@ void clear(); +#ifdef HAVE_PLUGIN_CHECKER_HELPER + QString formatFailureReport(QString helperTag, + std::vector) + const; +#endif + mutable QMutex m_mutex; // while scanning; definitely can't multi-thread this std::map m_kp; // tag -> KnownPlugins client diff -r f0c2b8b31609 -r fe579dc6a713 transform/RealTimeEffectModelTransformer.cpp --- a/transform/RealTimeEffectModelTransformer.cpp Fri Jun 29 13:52:36 2018 +0100 +++ b/transform/RealTimeEffectModelTransformer.cpp Tue Sep 04 13:19:20 2018 +0100 @@ -47,14 +47,14 @@ QString pluginId = transform.getPluginIdentifier(); -// SVDEBUG << "RealTimeEffectModelTransformer::RealTimeEffectModelTransformer: plugin " << pluginId << ", output " << output << endl; + SVDEBUG << "RealTimeEffectModelTransformer::RealTimeEffectModelTransformer: plugin " << pluginId << ", output " << transform.getOutput() << endl; RealTimePluginFactory *factory = RealTimePluginFactory::instanceFor(pluginId); if (!factory) { - cerr << "RealTimeEffectModelTransformer: No factory available for plugin id \"" - << pluginId << "\"" << endl; + SVCERR << "RealTimeEffectModelTransformer: No factory available for plugin id \"" + << pluginId << "\"" << endl; return; } @@ -67,8 +67,8 @@ input->getChannelCount()); if (!m_plugin) { - cerr << "RealTimeEffectModelTransformer: Failed to instantiate plugin \"" - << pluginId << "\"" << endl; + SVCERR << "RealTimeEffectModelTransformer: Failed to instantiate plugin \"" + << pluginId << "\"" << endl; return; } @@ -129,13 +129,25 @@ SVDEBUG << "RealTimeEffectModelTransformer::run: Waiting for input model to be ready..." << endl; usleep(500000); } - if (m_abandoned) return; + if (m_abandoned) { + return; + } + if (m_outputs.empty()) { + return; + } + + SparseTimeValueModel *stvm = + dynamic_cast(m_outputs[0]); + WritableWaveFileModel *wwfm = + dynamic_cast(m_outputs[0]); - SparseTimeValueModel *stvm = dynamic_cast(m_outputs[0]); - WritableWaveFileModel *wwfm = dynamic_cast(m_outputs[0]); - if (!stvm && !wwfm) return; + if (!stvm && !wwfm) { + return; + } - if (stvm && (m_outputNo >= int(m_plugin->getControlOutputCount()))) return; + if (stvm && (m_outputNo >= int(m_plugin->getControlOutputCount()))) { + return; + } sv_samplerate_t sampleRate = input->getSampleRate(); int channelCount = input->getChannelCount();