Add DSF and DSDIFF/DFF support

This commit is contained in:
Jonas Kvinge 2018-09-02 01:40:14 +02:00
parent 521d5cf4fa
commit ee78b6f2bb
6 changed files with 31 additions and 26 deletions

View File

@ -170,6 +170,10 @@ if (TAGLIB_FOUND AND USE_SYSTEM_TAGLIB)
set(CMAKE_REQUIRED_LIBRARIES "${TAGLIB_LIBRARIES}") set(CMAKE_REQUIRED_LIBRARIES "${TAGLIB_LIBRARIES}")
set(CMAKE_REQUIRED_INCLUDES) set(CMAKE_REQUIRED_INCLUDES)
set(CMAKE_REQUIRED_LIBRARIES) set(CMAKE_REQUIRED_LIBRARIES)
find_path(HAVE_TAGLIB_DSFFILE_H taglib/dsffile.h)
if(HAVE_TAGLIB_DSFFILE_H)
set(HAVE_TAGLIB_DSFFILE ON)
endif(HAVE_TAGLIB_DSFFILE_H)
else() else()
message(STATUS "Using builtin taglib library") message(STATUS "Using builtin taglib library")
set(TAGLIB_INCLUDE_DIRS "${CMAKE_BINARY_DIR}/3rdparty/taglib/headers/taglib/;${CMAKE_BINARY_DIR}/3rdparty/taglib/headers/") set(TAGLIB_INCLUDE_DIRS "${CMAKE_BINARY_DIR}/3rdparty/taglib/headers/taglib/;${CMAKE_BINARY_DIR}/3rdparty/taglib/headers/")
@ -177,6 +181,7 @@ else()
set(TAGLIB_LIBRARIES tag) set(TAGLIB_LIBRARIES tag)
add_subdirectory(3rdparty/utf8-cpp) add_subdirectory(3rdparty/utf8-cpp)
add_subdirectory(3rdparty/taglib) add_subdirectory(3rdparty/taglib)
set(HAVE_TAGLIB_DSFFILE ON)
endif() endif()
# LASTFM # LASTFM

View File

@ -63,6 +63,10 @@
#include <taglib/mpcfile.h> #include <taglib/mpcfile.h>
#include <taglib/mpegfile.h> #include <taglib/mpegfile.h>
#include <taglib/opusfile.h> #include <taglib/opusfile.h>
#ifdef HAVE_TAGLIB_DSFFILE
# include <taglib/dsffile.h>
# include <taglib/dsdifffile.h>
#endif
#include <QtGlobal> #include <QtGlobal>
#include <QFile> #include <QFile>
@ -135,7 +139,7 @@ TagReader::TagReader()
kEmbeddedCover("(embedded)") {} kEmbeddedCover("(embedded)") {}
void TagReader::ReadFile(const QString &filename, pb::tagreader::SongMetadata *song) const { void TagReader::ReadFile(const QString &filename, pb::tagreader::SongMetadata *song) const {
const QByteArray url(QUrl::fromLocalFile(filename).toEncoded()); const QByteArray url(QUrl::fromLocalFile(filename).toEncoded());
const QFileInfo info(filename); const QFileInfo info(filename);
@ -149,10 +153,10 @@ void TagReader::ReadFile(const QString &filename, pb::tagreader::SongMetadata *s
std::unique_ptr<TagLib::FileRef> fileref(factory_->GetFileRef(filename)); std::unique_ptr<TagLib::FileRef> fileref(factory_->GetFileRef(filename));
if (fileref->isNull()) { if (fileref->isNull()) {
qLog(Info) << "TagLib hasn't been able to read " << filename << " file"; qLog(Info) << "TagLib hasn't been able to read" << filename << "file";
return; return;
} }
if (fileref->audioProperties()) { if (fileref->audioProperties()) {
song->set_bitrate(fileref->audioProperties()->bitrate()); song->set_bitrate(fileref->audioProperties()->bitrate());
song->set_samplerate(fileref->audioProperties()->sampleRate()); song->set_samplerate(fileref->audioProperties()->sampleRate());
@ -177,8 +181,7 @@ void TagReader::ReadFile(const QString &filename, pb::tagreader::SongMetadata *s
QString compilation; QString compilation;
// Handle all the files which have VorbisComments (Ogg, OPUS, ...) in the same way; // Handle all the files which have VorbisComments (Ogg, OPUS, ...) in the same way;
// apart, so we keep specific behavior for some formats by adding another // apart, so we keep specific behavior for some formats by adding another "else if" block below.
// "else if" block below.
if (TagLib::Ogg::XiphComment *tag = dynamic_cast<TagLib::Ogg::XiphComment*>(fileref->file()->tag())) { if (TagLib::Ogg::XiphComment *tag = dynamic_cast<TagLib::Ogg::XiphComment*>(fileref->file()->tag())) {
ParseOggTag(tag->fieldListMap(), nullptr, &disc, &compilation, song); ParseOggTag(tag->fieldListMap(), nullptr, &disc, &compilation, song);
@ -292,16 +295,12 @@ void TagReader::ReadFile(const QString &filename, pb::tagreader::SongMetadata *s
if (items.contains(kMP4_OriginalYear_ID)) { if (items.contains(kMP4_OriginalYear_ID)) {
song->set_originalyear( song->set_originalyear(
TStringToQString( TStringToQString(items[kMP4_OriginalYear_ID].toStringList().toString('\n')).left(4).toInt());
items[kMP4_OriginalYear_ID].toStringList().toString('\n'))
.left(4)
.toInt());
} }
Decode(mp4_tag->comment(), nullptr, song->mutable_comment()); Decode(mp4_tag->comment(), nullptr, song->mutable_comment());
} }
} }
#ifdef TAGLIB_WITH_ASF
else if (TagLib::ASF::File *file = dynamic_cast<TagLib::ASF::File*>(fileref->file())) { else if (TagLib::ASF::File *file = dynamic_cast<TagLib::ASF::File*>(fileref->file())) {
@ -310,23 +309,19 @@ void TagReader::ReadFile(const QString &filename, pb::tagreader::SongMetadata *s
const TagLib::ASF::AttributeListMap &attributes_map = file->tag()->attributeListMap(); const TagLib::ASF::AttributeListMap &attributes_map = file->tag()->attributeListMap();
if (attributes_map.contains(kASF_OriginalDate_ID)) { if (attributes_map.contains(kASF_OriginalDate_ID)) {
const TagLib::ASF::AttributeList &attributes = const TagLib::ASF::AttributeList &attributes = attributes_map[kASF_OriginalDate_ID];
attributes_map[kASF_OriginalDate_ID];
if (!attributes.isEmpty()) { if (!attributes.isEmpty()) {
song->set_originalyear( song->set_originalyear(TStringToQString(attributes.front().toString()).left(4).toInt());
TStringToQString(attributes.front().toString()).left(4).toInt());
} }
} }
else if (attributes_map.contains(kASF_OriginalYear_ID)) { else if (attributes_map.contains(kASF_OriginalYear_ID)) {
const TagLib::ASF::AttributeList &attributes = const TagLib::ASF::AttributeList &attributes = attributes_map[kASF_OriginalYear_ID];
attributes_map[kASF_OriginalYear_ID];
if (!attributes.isEmpty()) { if (!attributes.isEmpty()) {
song->set_originalyear( song->set_originalyear(TStringToQString(attributes.front().toString()).left(4).toInt());
TStringToQString(attributes.front().toString()).left(4).toInt());
} }
} }
} }
#endif
else if (tag) { else if (tag) {
Decode(tag->comment(), nullptr, song->mutable_comment()); Decode(tag->comment(), nullptr, song->mutable_comment());
} }
@ -352,8 +347,6 @@ void TagReader::ReadFile(const QString &filename, pb::tagreader::SongMetadata *s
song->set_compilation(compilation.toInt() == 1); song->set_compilation(compilation.toInt() == 1);
} }
// Set integer fields to -1 if they're not valid // Set integer fields to -1 if they're not valid
#define SetDefault(field) if (song->field() <= 0) { song->set_##field(-1); } #define SetDefault(field) if (song->field() <= 0) { song->set_##field(-1); }
SetDefault(track); SetDefault(track);
@ -473,15 +466,15 @@ pb::tagreader::SongMetadata_Type TagReader::GuessFileType(TagLib::FileRef *filer
if (dynamic_cast<TagLib::Ogg::Opus::File*>(fileref->file())) return pb::tagreader::SongMetadata_Type_OGGOPUS; if (dynamic_cast<TagLib::Ogg::Opus::File*>(fileref->file())) return pb::tagreader::SongMetadata_Type_OGGOPUS;
if (dynamic_cast<TagLib::Ogg::Speex::File*>(fileref->file())) return pb::tagreader::SongMetadata_Type_OGGSPEEX; if (dynamic_cast<TagLib::Ogg::Speex::File*>(fileref->file())) return pb::tagreader::SongMetadata_Type_OGGSPEEX;
if (dynamic_cast<TagLib::MPEG::File*>(fileref->file())) return pb::tagreader::SongMetadata_Type_MPEG; if (dynamic_cast<TagLib::MPEG::File*>(fileref->file())) return pb::tagreader::SongMetadata_Type_MPEG;
#ifdef TAGLIB_WITH_MP4
if (dynamic_cast<TagLib::MP4::File*>(fileref->file())) return pb::tagreader::SongMetadata_Type_MP4; if (dynamic_cast<TagLib::MP4::File*>(fileref->file())) return pb::tagreader::SongMetadata_Type_MP4;
#endif
#ifdef TAGLIB_WITH_ASF
if (dynamic_cast<TagLib::ASF::File*>(fileref->file())) return pb::tagreader::SongMetadata_Type_ASF; if (dynamic_cast<TagLib::ASF::File*>(fileref->file())) return pb::tagreader::SongMetadata_Type_ASF;
#endif
if (dynamic_cast<TagLib::RIFF::AIFF::File*>(fileref->file())) return pb::tagreader::SongMetadata_Type_AIFF; if (dynamic_cast<TagLib::RIFF::AIFF::File*>(fileref->file())) return pb::tagreader::SongMetadata_Type_AIFF;
if (dynamic_cast<TagLib::MPC::File*>(fileref->file())) return pb::tagreader::SongMetadata_Type_MPC; if (dynamic_cast<TagLib::MPC::File*>(fileref->file())) return pb::tagreader::SongMetadata_Type_MPC;
if (dynamic_cast<TagLib::TrueAudio::File*>(fileref->file())) return pb::tagreader::SongMetadata_Type_TRUEAUDIO; if (dynamic_cast<TagLib::TrueAudio::File*>(fileref->file())) return pb::tagreader::SongMetadata_Type_TRUEAUDIO;
#ifdef HAVE_TAGLIB_DSFFILE
if (dynamic_cast<TagLib::DSF::File*>(fileref->file())) return pb::tagreader::SongMetadata_Type_DSF;
if (dynamic_cast<TagLib::DSDIFF::File*>(fileref->file())) return pb::tagreader::SongMetadata_Type_DSDIFF;
#endif
return pb::tagreader::SongMetadata_Type_UNKNOWN; return pb::tagreader::SongMetadata_Type_UNKNOWN;

View File

@ -19,6 +19,8 @@ message SongMetadata {
AIFF = 11; AIFF = 11;
MPC = 12; MPC = 12;
TRUEAUDIO = 13; TRUEAUDIO = 13;
DSF = 14;
DSDIFF = 15;
CDDA = 90; CDDA = 90;
STREAM = 91; STREAM = 91;
} }

View File

@ -37,6 +37,7 @@
#cmakedefine HAVE_QCA #cmakedefine HAVE_QCA
#cmakedefine HAVE_SPARKLE #cmakedefine HAVE_SPARKLE
#cmakedefine HAVE_CHROMAPRINT #cmakedefine HAVE_CHROMAPRINT
#cmakedefine HAVE_TAGLIB_DSFFILE
#cmakedefine IMOBILEDEVICE_USES_UDIDS #cmakedefine IMOBILEDEVICE_USES_UDIDS
#cmakedefine USE_INSTALL_PREFIX #cmakedefine USE_INSTALL_PREFIX
#cmakedefine USE_SYSTEM_SHA2 #cmakedefine USE_SYSTEM_SHA2

View File

@ -379,6 +379,8 @@ QString Song::TextForFiletype(FileType type) {
case Song::Type_MPC: return QObject::tr("MPC"); case Song::Type_MPC: return QObject::tr("MPC");
case Song::Type_TrueAudio: return QObject::tr("TrueAudio"); case Song::Type_TrueAudio: return QObject::tr("TrueAudio");
case Song::Type_CDDA: return QObject::tr("CDDA"); case Song::Type_CDDA: return QObject::tr("CDDA");
case Song::Type_DSF: return QObject::tr("DSF"); // .dsf
case Song::Type_DSDIFF: return QObject::tr("DSDIFF"); // .dff
case Song::Type_Unknown: case Song::Type_Unknown:
default: default:
return QObject::tr("Unknown"); return QObject::tr("Unknown");
@ -693,7 +695,7 @@ void Song::InitFromFilePartial(const QString &filename) {
TagLib::FileRef fileref(filename.toUtf8().constData()); TagLib::FileRef fileref(filename.toUtf8().constData());
//if (TagLib::FileRef::defaultFileExtensions().contains(suffix.toUtf8().constData())) { //if (TagLib::FileRef::defaultFileExtensions().contains(suffix.toUtf8().constData())) {
if (fileref.file() || (suffix == "dsf")) d->valid_ = true; if (fileref.file()) d->valid_ = true;
else { else {
d->valid_ = false; d->valid_ = false;
qLog(Error) << "File" << filename << "is not recognized by TagLib as a valid audio file."; qLog(Error) << "File" << filename << "is not recognized by TagLib as a valid audio file.";

View File

@ -102,6 +102,8 @@ class Song {
Type_AIFF = 11, Type_AIFF = 11,
Type_MPC = 12, Type_MPC = 12,
Type_TrueAudio = 13, Type_TrueAudio = 13,
Type_DSF = 14,
Type_DSDIFF = 15,
Type_CDDA = 90, Type_CDDA = 90,
Type_Stream = 91, Type_Stream = 91,
}; };