# HG changeset patch # User Chris Cannam # Date 1456935396 0 # Node ID 6877f4200912a3ff0e6cb3f99c1ed526705e1347 # Parent ea636412f9fe27479fa8a13c64b42114554caf40# Parent 134ce7667256fb204f3bebd293c252bc57cbe07e Merge from default branch diff -r ea636412f9fe -r 6877f4200912 acinclude.m4 --- a/acinclude.m4 Thu Feb 04 11:16:05 2016 +0000 +++ b/acinclude.m4 Wed Mar 02 16:16:36 2016 +0000 @@ -69,6 +69,9 @@ AC_CHECK_PROG(QMAKE, qmake-qt5, $QTDIR/bin/qmake-qt5,,$QTDIR/bin/) fi if test x$QMAKE = x ; then + AC_CHECK_PROG(QMAKE, qt5-qmake, $QTDIR/bin/qt5-qmake,,$QTDIR/bin/) +fi +if test x$QMAKE = x ; then AC_CHECK_PROG(QMAKE, qmake, $QTDIR/bin/qmake,,$QTDIR/bin/) fi if test x$QMAKE = x ; then @@ -78,6 +81,9 @@ AC_CHECK_PROG(QMAKE, qmake-qt5, qmake-qt5,,$PATH) fi if test x$QMAKE = x ; then + AC_CHECK_PROG(QMAKE, qt5-qmake, qt5-qmake,,$PATH) +fi +if test x$QMAKE = x ; then AC_CHECK_PROG(QMAKE, qmake, qmake,,$PATH) fi if test x$QMAKE = x ; then diff -r ea636412f9fe -r 6877f4200912 configure --- a/configure Thu Feb 04 11:16:05 2016 +0000 +++ b/configure Wed Mar 02 16:16:36 2016 +0000 @@ -4129,6 +4129,45 @@ fi if test x$QMAKE = x ; then + # Extract the first word of "qt5-qmake", so it can be a program name with args. +set dummy qt5-qmake; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_QMAKE+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$QMAKE"; then + ac_cv_prog_QMAKE="$QMAKE" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $QTDIR/bin/ +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_QMAKE="$QTDIR/bin/qt5-qmake" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +QMAKE=$ac_cv_prog_QMAKE +if test -n "$QMAKE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $QMAKE" >&5 +$as_echo "$QMAKE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test x$QMAKE = x ; then # Extract the first word of "qmake", so it can be a program name with args. set dummy qmake; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -4246,6 +4285,45 @@ fi if test x$QMAKE = x ; then + # Extract the first word of "qt5-qmake", so it can be a program name with args. +set dummy qt5-qmake; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_QMAKE+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$QMAKE"; then + ac_cv_prog_QMAKE="$QMAKE" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_QMAKE="qt5-qmake" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +QMAKE=$ac_cv_prog_QMAKE +if test -n "$QMAKE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $QMAKE" >&5 +$as_echo "$QMAKE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test x$QMAKE = x ; then # Extract the first word of "qmake", so it can be a program name with args. set dummy qmake; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 diff -r ea636412f9fe -r 6877f4200912 data/fileio/AudioFileReaderFactory.cpp --- a/data/fileio/AudioFileReaderFactory.cpp Thu Feb 04 11:16:05 2016 +0000 +++ b/data/fileio/AudioFileReaderFactory.cpp Wed Mar 02 16:16:36 2016 +0000 @@ -29,6 +29,8 @@ #include #include +//#define DEBUG_AUDIO_FILE_READER_FACTORY 1 + QString AudioFileReaderFactory::getKnownExtensions() { @@ -87,7 +89,9 @@ { QString err; - SVDEBUG << "AudioFileReaderFactory::createReader(\"" << source.getLocation() << "\"): Requested rate: " << targetRate << endl; +#ifdef DEBUG_AUDIO_FILE_READER_FACTORY + cerr << "AudioFileReaderFactory::createReader(\"" << source.getLocation() << "\"): Requested rate: " << targetRate << endl; +#endif if (!source.isOK()) { cerr << "AudioFileReaderFactory::createReader(\"" << source.getLocation() << "\": Failed to retrieve source (transmission error?): " << source.getErrorString() << endl; @@ -95,7 +99,7 @@ } if (!source.isAvailable()) { - SVDEBUG << "AudioFileReaderFactory::createReader(\"" << source.getLocation() << "\": Source not found" << endl; + cerr << "AudioFileReaderFactory::createReader(\"" << source.getLocation() << "\": Source not found" << endl; return 0; } @@ -139,8 +143,10 @@ (cacheMode == CodedAudioFileReader::CacheInMemory) || (targetRate != 0 && fileRate != targetRate))) { - SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", in memory " << (cacheMode == CodedAudioFileReader::CacheInMemory) << ", creating decoding reader" << endl; - +#ifdef DEBUG_AUDIO_FILE_READER_FACTORY + cerr << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", in memory " << (cacheMode == CodedAudioFileReader::CacheInMemory) << ", creating decoding reader" << endl; +#endif + delete reader; reader = new DecodingWavFileReader (source, @@ -208,7 +214,9 @@ (cacheMode == CodedAudioFileReader::CacheInMemory) || (targetRate != 0 && fileRate != targetRate))) { - SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", in memory " << (cacheMode == CodedAudioFileReader::CacheInMemory) << ", creating decoding reader" << endl; +#ifdef DEBUG_AUDIO_FILE_READER_FACTORY + cerr << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", in memory " << (cacheMode == CodedAudioFileReader::CacheInMemory) << ", creating decoding reader" << endl; +#endif delete reader; reader = new DecodingWavFileReader diff -r ea636412f9fe -r 6877f4200912 data/fileio/CodedAudioFileReader.cpp --- a/data/fileio/CodedAudioFileReader.cpp Thu Feb 04 11:16:05 2016 +0000 +++ b/data/fileio/CodedAudioFileReader.cpp Wed Mar 02 16:16:36 2016 +0000 @@ -146,11 +146,27 @@ } fileInfo.samplerate = fileRate; fileInfo.channels = m_channelCount; - - // No point in writing 24-bit or float; generally this - // class is used for decoding files that have come from a - // 16 bit source or that decode to only 16 bits anyway. - fileInfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; + + // Previously we were writing SF_FORMAT_PCM_16 and in a + // comment I wrote: "No point in writing 24-bit or float; + // generally this class is used for decoding files that + // have come from a 16 bit source or that decode to only + // 16 bits anyway." That was naive -- we want to preserve + // the original values to the same float precision that we + // use internally. Saving PCM_16 obviously doesn't + // preserve values for sources at bit depths greater than + // 16, but it also doesn't always do so for sources at bit + // depths less than 16. + // + // (This came to light with a bug in libsndfile 1.0.26, + // which always reports every file as non-seekable, so + // that coded readers were being used even for WAV + // files. This changed the values that came from PCM_8 WAV + // sources, breaking Sonic Annotator's output comparison + // tests.) + // + // So: now we write floats. + fileInfo.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT; m_cacheFileWritePtr = sf_open(m_cacheFileName.toLocal8Bit(), SFM_WRITE, &fileInfo); diff -r ea636412f9fe -r 6877f4200912 data/fileio/MP3FileReader.cpp --- a/data/fileio/MP3FileReader.cpp Thu Feb 04 11:16:05 2016 +0000 +++ b/data/fileio/MP3FileReader.cpp Wed Mar 02 16:16:36 2016 +0000 @@ -32,6 +32,7 @@ #ifdef HAVE_ID3TAG #include #endif + //#define DEBUG_ID3TAG 1 #include @@ -178,7 +179,7 @@ id3_tag *tag = id3_file_tag(file); if (!tag) { #ifdef DEBUG_ID3TAG - SVDEBUG << "MP3FileReader::loadTags: No ID3 tag found" << endl; + cerr << "MP3FileReader::loadTags: No ID3 tag found" << endl; #endif id3_file_close(file); return; @@ -201,7 +202,7 @@ #else #ifdef DEBUG_ID3TAG - SVDEBUG << "MP3FileReader::loadTags: ID3 tag support not compiled in" + cerr << "MP3FileReader::loadTags: ID3 tag support not compiled in" << endl; #endif #endif @@ -216,20 +217,20 @@ id3_frame *frame = id3_tag_findframe(tag, name, 0); if (!frame) { #ifdef DEBUG_ID3TAG - SVDEBUG << "MP3FileReader::loadTags: No \"" << name << "\" in ID3 tag" << endl; + cerr << "MP3FileReader::loadTags: No \"" << name << "\" in ID3 tag" << endl; #endif return ""; } if (frame->nfields < 2) { - SVDEBUG << "MP3FileReader::loadTags: WARNING: Not enough fields (" << frame->nfields << ") for \"" << name << "\" in ID3 tag" << endl; + cerr << "MP3FileReader::loadTags: WARNING: Not enough fields (" << frame->nfields << ") for \"" << name << "\" in ID3 tag" << endl; return ""; } unsigned int nstrings = id3_field_getnstrings(&frame->fields[1]); if (nstrings == 0) { #ifdef DEBUG_ID3TAG - SVDEBUG << "MP3FileReader::loadTags: No strings for \"" << name << "\" in ID3 tag" << endl; + cerr << "MP3FileReader::loadTags: No strings for \"" << name << "\" in ID3 tag" << endl; #endif return ""; } @@ -237,7 +238,7 @@ id3_ucs4_t const *ustr = id3_field_getstrings(&frame->fields[1], 0); if (!ustr) { #ifdef DEBUG_ID3TAG - SVDEBUG << "MP3FileReader::loadTags: Invalid or absent data for \"" << name << "\" in ID3 tag" << endl; + cerr << "MP3FileReader::loadTags: Invalid or absent data for \"" << name << "\" in ID3 tag" << endl; #endif return ""; } @@ -252,7 +253,7 @@ free(u8str); #ifdef DEBUG_ID3TAG - SVDEBUG << "MP3FileReader::loadTags: tag \"" << name << "\" -> \"" + cerr << "MP3FileReader::loadTags: tag \"" << name << "\" -> \"" << rv << "\"" << endl; #endif diff -r ea636412f9fe -r 6877f4200912 data/fileio/WavFileReader.cpp --- a/data/fileio/WavFileReader.cpp Thu Feb 04 11:16:05 2016 +0000 +++ b/data/fileio/WavFileReader.cpp Wed Mar 02 16:16:36 2016 +0000 @@ -62,20 +62,26 @@ m_seekable = (m_fileInfo.seekable != 0); - // Our m_seekable reports whether a file is rapidly seekable, - // so things like Ogg don't qualify. We cautiously report - // every file type of "at least" the historical period of Ogg - // or FLAC as non-seekable. int type = m_fileInfo.format & SF_FORMAT_TYPEMASK; -// cerr << "WavFileReader: format type is " << type << " (flac, ogg are " << SF_FORMAT_FLAC << ", " << SF_FORMAT_OGG << ")" << endl; + int subtype = m_fileInfo.format & SF_FORMAT_SUBMASK; + if (type >= SF_FORMAT_FLAC || type >= SF_FORMAT_OGG) { -// cerr << "WavFileReader: Recording as non-seekable" << endl; + // Our m_seekable reports whether a file is rapidly + // seekable, so things like Ogg don't qualify. We + // cautiously report every file type of "at least" the + // historical period of Ogg or FLAC as non-seekable. m_seekable = false; + } else if (type == SF_FORMAT_WAV && subtype <= SF_FORMAT_DOUBLE) { + // libsndfile 1.0.26 has a bug (subsequently fixed in the + // repo) that causes all files to be reported as + // non-seekable. We know that certain common file types + // are definitely seekable so, again cautiously, identify + // and mark those (basically only non-adaptive WAVs). + m_seekable = true; } } -// cerr << "WavFileReader: Frame count " << m_frameCount << ", channel count " << m_channelCount << ", sample rate " << m_sampleRate << ", seekable " << m_seekable << endl; - +// cerr << "WavFileReader: Filename " << m_path << ", frame count " << m_frameCount << ", channel count " << m_channelCount << ", sample rate " << m_sampleRate << ", format " << m_fileInfo.format << ", seekable " << m_fileInfo.seekable << " adjusted to " << m_seekable << endl; } WavFileReader::~WavFileReader() diff -r ea636412f9fe -r 6877f4200912 plugin/FeatureExtractionPluginFactory.cpp --- a/plugin/FeatureExtractionPluginFactory.cpp Thu Feb 04 11:16:05 2016 +0000 +++ b/plugin/FeatureExtractionPluginFactory.cpp Wed Mar 02 16:16:36 2016 +0000 @@ -195,10 +195,6 @@ for (QString soname : candidates) { -#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE - cerr << "FeatureExtractionPluginFactory::getPluginIdentifiers: trying potential library " << soname << endl; -#endif - void *libraryHandle = DLOPEN(soname, RTLD_LAZY | RTLD_LOCAL); if (!libraryHandle) { @@ -206,10 +202,6 @@ continue; } -#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE - cerr << "FeatureExtractionPluginFactory::getPluginIdentifiers: It's a library all right, checking for descriptor" << endl; -#endif - VampGetPluginDescriptorFunction fn = (VampGetPluginDescriptorFunction) DLSYM(libraryHandle, "vampGetPluginDescriptor"); @@ -260,7 +252,7 @@ ("vamp", soname, descriptor->identifier); rv.push_back(id); #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE - cerr << "FeatureExtractionPluginFactory::getPluginIdentifiers: Found plugin id " << id << " at index " << index << endl; + cerr << "FeatureExtractionPluginFactory::getPluginIdentifiers: Found plugin id " << id << " at index " << index << endl; #endif ++index; } diff -r ea636412f9fe -r 6877f4200912 rdf/RDFTransformFactory.cpp --- a/rdf/RDFTransformFactory.cpp Thu Feb 04 11:16:05 2016 +0000 +++ b/rdf/RDFTransformFactory.cpp Wed Mar 02 16:16:36 2016 +0000 @@ -129,7 +129,12 @@ } m_store->import(qurl, BasicStore::ImportIgnoreDuplicates); m_isRDF = true; - } catch (...) { } + } catch (const std::exception &e) { + // The file is not RDF -- we report this by returning false + // from isRDF (because we have not reached the m_isRDF = true + // line above), but we also set the error string + m_errorString = e.what(); + } } RDFTransformFactoryImpl::~RDFTransformFactoryImpl() @@ -146,7 +151,7 @@ bool RDFTransformFactoryImpl::isOK() { - return (m_errorString == ""); + return m_isRDF && (m_errorString == ""); } QString @@ -160,6 +165,8 @@ { std::vector transforms; + if (!m_isRDF) return transforms; + std::map uriTransformMap; Nodes tnodes = m_store->match diff -r ea636412f9fe -r 6877f4200912 rdf/RDFTransformFactory.h --- a/rdf/RDFTransformFactory.h Thu Feb 04 11:16:05 2016 +0000 +++ b/rdf/RDFTransformFactory.h Wed Mar 02 16:16:36 2016 +0000 @@ -36,8 +36,28 @@ RDFTransformFactory(QString url); virtual ~RDFTransformFactory(); - bool isRDF(); // true if the file was parseable and had transforms in it - bool isOK(); // true if the transforms could be completely constructed + /** isRDF() may be queried at any point after construction. It + returns true if the file was parseable as RDF. + */ + bool isRDF(); + + /** isOK() may be queried at any point after getTransforms() has + been called. It is true if the file was parseable as RDF and + any transforms in it could be completely constructed. + + Note that even if isOK() returns true, it is still possible + that the file did not define any transforms; in this case, + getTransforms() would have returned an empty list. + + If isOK() is called before getTransforms() has been invoked to + query the file, it will return true iff isRDF() is true. + */ + bool isOK(); + + /** Return any error string resulting from loading or querying the + file. This will be non-empty if isRDF() or isOK() returns + false. + */ QString getErrorString() const; std::vector getTransforms(ProgressReporter *reporter); diff -r ea636412f9fe -r 6877f4200912 transform/CSVFeatureWriter.cpp --- a/transform/CSVFeatureWriter.cpp Thu Feb 04 11:16:05 2016 +0000 +++ b/transform/CSVFeatureWriter.cpp Wed Mar 02 16:16:36 2016 +0000 @@ -99,10 +99,10 @@ SVDEBUG << "CSVFeatureWriter::setParameters" << endl; for (map::iterator i = params.begin(); i != params.end(); ++i) { - cerr << i->first << " -> " << i->second << endl; + SVDEBUG << i->first << " -> " << i->second << endl; if (i->first == "separator") { m_separator = i->second.c_str(); - cerr << "m_separator = " << m_separator << endl; + SVDEBUG << "m_separator = " << m_separator << endl; if (m_separator == "\\t") { m_separator = QChar::Tabulation; } diff -r ea636412f9fe -r 6877f4200912 transform/Transform.cpp --- a/transform/Transform.cpp Thu Feb 04 11:16:05 2016 +0000 +++ b/transform/Transform.cpp Wed Mar 02 16:16:36 2016 +0000 @@ -54,12 +54,8 @@ int errorColumn; if (!doc.setContent(xml, false, &error, &errorLine, &errorColumn)) { - cerr << "Transform::Transform: Error in parsing XML: " - << error << " at line " << errorLine - << ", column " << errorColumn << endl; - cerr << "Input follows:" << endl; - cerr << xml << endl; - cerr << "Input ends." << endl; + m_errorString = QString("%1 at line %2, column %3") + .arg(error).arg(errorLine).arg(errorColumn); return; } diff -r ea636412f9fe -r 6877f4200912 transform/Transform.h --- a/transform/Transform.h Thu Feb 04 11:16:05 2016 +0000 +++ b/transform/Transform.h Wed Mar 02 16:16:36 2016 +0000 @@ -46,7 +46,8 @@ /** * Construct a Transform by parsing the given XML data string. - * This is the inverse of toXml. + * This is the inverse of toXml. If this fails, getErrorString() + * will return a non-empty string. */ Transform(QString xml); @@ -156,6 +157,8 @@ */ void setFromXmlAttributes(const QXmlAttributes &); + QString getErrorString() const { return m_errorString; } + static SummaryType stringToSummaryType(QString); static QString summaryTypeToString(SummaryType); @@ -195,6 +198,7 @@ RealTime m_startTime; RealTime m_duration; sv_samplerate_t m_sampleRate; + QString m_errorString; }; typedef std::vector Transforms;