# HG changeset patch # User Chris Cannam # Date 1548076577 0 # Node ID f8e3dcbafb4d0fcd7f496b43ac6cefdec8c74e9f # Parent 6e68bd92ee21f34de4ea73176522844cf2fa7829 Implement title/maker in wav readers; extra handling of supported-ness for file types diff -r 6e68bd92ee21 -r f8e3dcbafb4d data/fileio/AudioFileReader.h --- a/data/fileio/AudioFileReader.h Mon Jan 21 11:45:51 2019 +0000 +++ b/data/fileio/AudioFileReader.h Mon Jan 21 13:16:17 2019 +0000 @@ -79,14 +79,14 @@ * may be implemented by subclasses that support file tagging. * This is not the same thing as the file name. */ - virtual QString getTitle() const { return ""; } + virtual QString getTitle() const = 0; /** * Return the "maker" of the work in the audio file, if known. * This could represent almost anything (band, composer, * conductor, artist etc). */ - virtual QString getMaker() const { return ""; } + virtual QString getMaker() const = 0; /** * Return the local file path of the audio data. This is the diff -r 6e68bd92ee21 -r f8e3dcbafb4d data/fileio/AudioFileReaderFactory.cpp --- a/data/fileio/AudioFileReaderFactory.cpp Mon Jan 21 11:45:51 2019 +0000 +++ b/data/fileio/AudioFileReaderFactory.cpp Mon Jan 21 13:16:17 2019 +0000 @@ -50,6 +50,23 @@ return rv; } +bool +AudioFileReaderFactory::isSupported(FileSource source) +{ +#ifdef HAVE_MAD + if (MP3FileReader::supports(source)) { + return true; + } +#endif + if (WavFileReader::supports(source)) { + return true; + } + if (BQAFileReader::supports(source)) { + return true; + } + return false; +} + AudioFileReader * AudioFileReaderFactory::createReader(FileSource source, Parameters params, @@ -122,40 +139,34 @@ } #ifdef HAVE_MAD - if (anyReader || MP3FileReader::supports(source)) { + // Having said we'll try any reader on the second pass, we + // actually don't want to try the mp3 reader for anything not + // identified as an mp3 - it can't identify files by header, + // it'll try to read any data and then fail with + // synchronisation errors - causing misleading and potentially + // alarming warning messages at the least + if (!anyReader) { + if (MP3FileReader::supports(source)) { - MP3FileReader::GaplessMode gapless = - params.gaplessMode == GaplessMode::Gapless ? - MP3FileReader::GaplessMode::Gapless : - MP3FileReader::GaplessMode::Gappy; + MP3FileReader::GaplessMode gapless = + params.gaplessMode == GaplessMode::Gapless ? + MP3FileReader::GaplessMode::Gapless : + MP3FileReader::GaplessMode::Gappy; - reader = new MP3FileReader - (source, decodeMode, cacheMode, gapless, - targetRate, normalised, reporter); + reader = new MP3FileReader + (source, decodeMode, cacheMode, gapless, + targetRate, normalised, reporter); - if (reader->isOK()) { - SVDEBUG << "AudioFileReaderFactory: MP3 file reader is OK, returning it" << endl; - return reader; - } else { - delete reader; + if (reader->isOK()) { + SVDEBUG << "AudioFileReaderFactory: MP3 file reader is OK, returning it" << endl; + return reader; + } else { + delete reader; + } } } #endif - if (anyReader || BQAFileReader::supports(source)) { - - reader = new BQAFileReader - (source, decodeMode, cacheMode, - targetRate, normalised, reporter); - - if (reader->isOK()) { - SVDEBUG << "AudioFileReaderFactory: BQA reader is OK, returning it" << endl; - return reader; - } else { - delete reader; - } - } - if (anyReader || WavFileReader::supports(source)) { reader = new WavFileReader(source); @@ -186,6 +197,20 @@ delete reader; } } + + if (anyReader || BQAFileReader::supports(source)) { + + reader = new BQAFileReader + (source, decodeMode, cacheMode, + targetRate, normalised, reporter); + + if (reader->isOK()) { + SVDEBUG << "AudioFileReaderFactory: BQA reader is OK, returning it" << endl; + return reader; + } else { + delete reader; + } + } } SVCERR << "AudioFileReaderFactory::Failed to create a reader for " diff -r 6e68bd92ee21 -r f8e3dcbafb4d data/fileio/AudioFileReaderFactory.h --- a/data/fileio/AudioFileReaderFactory.h Mon Jan 21 11:45:51 2019 +0000 +++ b/data/fileio/AudioFileReaderFactory.h Mon Jan 21 13:16:17 2019 +0000 @@ -141,6 +141,15 @@ static AudioFileReader *createReader(FileSource source, Parameters parameters, ProgressReporter *reporter = 0); + + /** + * Return true if the given source has a file extension that + * indicates a supported file type. This does not necessarily mean + * that it can be opened; conversely it may theoretically be + * possible to open some files without supported extensions, + * depending on the readers available. + */ + static bool isSupported(FileSource source); }; #endif diff -r 6e68bd92ee21 -r f8e3dcbafb4d data/fileio/AudioFileSizeEstimator.cpp --- a/data/fileio/AudioFileSizeEstimator.cpp Mon Jan 21 11:45:51 2019 +0000 +++ b/data/fileio/AudioFileSizeEstimator.cpp Mon Jan 21 13:16:17 2019 +0000 @@ -83,7 +83,7 @@ if (extension == "ogg" || extension == "oga" || extension == "m4a" || extension == "mp3" || - extension == "wma") { + extension == "wma" || extension == "opus") { // Usually a lossy file. Compression ratios can vary // dramatically, but don't usually exceed about 20x compared diff -r 6e68bd92ee21 -r f8e3dcbafb4d data/fileio/DecodingWavFileReader.cpp --- a/data/fileio/DecodingWavFileReader.cpp Mon Jan 21 11:45:51 2019 +0000 +++ b/data/fileio/DecodingWavFileReader.cpp Mon Jan 21 13:16:17 2019 +0000 @@ -58,6 +58,9 @@ m_channelCount = m_original->getChannelCount(); m_fileRate = m_original->getSampleRate(); + m_title = m_original->getTitle(); + m_maker = m_original->getMaker(); + initialiseDecodeCache(); if (decodeMode == DecodeAtOnce) { diff -r 6e68bd92ee21 -r f8e3dcbafb4d data/fileio/DecodingWavFileReader.h --- a/data/fileio/DecodingWavFileReader.h Mon Jan 21 11:45:51 2019 +0000 +++ b/data/fileio/DecodingWavFileReader.h Mon Jan 21 13:16:17 2019 +0000 @@ -37,6 +37,9 @@ ProgressReporter *reporter = 0); virtual ~DecodingWavFileReader(); + QString getTitle() const override { return m_title; } + QString getMaker() const override { return m_maker; } + virtual QString getError() const { return m_error; } virtual QString getLocation() const { return m_source.getLocation(); } static void getSupportedExtensions(std::set &extensions); @@ -55,6 +58,8 @@ protected: FileSource m_source; + QString m_title; + QString m_maker; QString m_path; QString m_error; bool m_cancelled; diff -r 6e68bd92ee21 -r f8e3dcbafb4d data/fileio/WavFileReader.cpp --- a/data/fileio/WavFileReader.cpp Mon Jan 21 11:45:51 2019 +0000 +++ b/data/fileio/WavFileReader.cpp Mon Jan 21 13:16:17 2019 +0000 @@ -95,6 +95,15 @@ if (m_normalisation != Normalisation::None && !m_updating) { m_max = getMax(); } + + const char *str = sf_get_string(m_file, SF_STR_TITLE); + if (str) { + m_title = str; + } + str = sf_get_string(m_file, SF_STR_ARTIST); + if (str) { + m_maker = str; + } } SVDEBUG << "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 << ", normalisation " << int(m_normalisation) << endl; diff -r 6e68bd92ee21 -r f8e3dcbafb4d data/fileio/WavFileReader.h --- a/data/fileio/WavFileReader.h Mon Jan 21 11:45:51 2019 +0000 +++ b/data/fileio/WavFileReader.h Mon Jan 21 13:16:17 2019 +0000 @@ -51,6 +51,9 @@ virtual QString getLocation() const { return m_source.getLocation(); } virtual QString getError() const { return m_error; } + QString getTitle() const override { return m_title; } + QString getMaker() const override { return m_maker; } + virtual QString getLocalFilename() const { return m_path; } virtual bool isQuicklySeekable() const { return m_seekable; } @@ -81,6 +84,8 @@ FileSource m_source; QString m_path; QString m_error; + QString m_title; + QString m_maker; bool m_seekable; diff -r 6e68bd92ee21 -r f8e3dcbafb4d data/fileio/test/EncodingTest.h --- a/data/fileio/test/EncodingTest.h Mon Jan 21 11:45:51 2019 +0000 +++ b/data/fileio/test/EncodingTest.h Mon Jan 21 13:16:17 2019 +0000 @@ -101,6 +101,15 @@ QFETCH(QString, audiofile); + if (!AudioFileReaderFactory::isSupported(encodingDir + "/" + + audiofile)) { +#if ( QT_VERSION >= 0x050000 ) + QSKIP("Known unsupported file, skipping"); +#else + QSKIP("Known unsupported file, skipping", SkipSingle); +#endif + } + AudioFileReaderFactory::Parameters params; AudioFileReader *reader = AudioFileReaderFactory::createReader @@ -128,7 +137,13 @@ AudioFileReaderFactory::createReader (encodingDir + "/" + audiofile, params); - QVERIFY(reader != nullptr); + if (!reader) { +#if ( QT_VERSION >= 0x050000 ) + QSKIP("Unsupported file, skipping"); +#else + QSKIP("Unsupported file, skipping", SkipSingle); +#endif + } QStringList fileAndExt = audiofile.split("."); QString file = fileAndExt[0]; @@ -225,7 +240,14 @@ AudioFileReader *reader = AudioFileReaderFactory::createReader (encodingDir + "/" + audiofile, params); - QVERIFY(reader != nullptr); + + if (!reader) { +#if ( QT_VERSION >= 0x050000 ) + QSKIP("Unsupported file, skipping"); +#else + QSKIP("Unsupported file, skipping", SkipSingle); +#endif + } QString title = reader->getTitle(); QVERIFY(title != QString());