From 6d40cbc04f25cf4181bbfbe173095f99f731b2de Mon Sep 17 00:00:00 2001 From: Tsuda Kageyu Date: Sat, 13 Jul 2013 10:38:52 +0900 Subject: [PATCH] Refactored AudioProperties classes in some ways --- taglib/ape/apeproperties.cpp | 65 +++++----- taglib/ape/apeproperties.h | 17 +-- taglib/asf/asfproperties.cpp | 16 ++- taglib/asf/asfproperties.h | 12 +- taglib/audioproperties.cpp | 26 ++-- taglib/audioproperties.h | 9 +- taglib/ebml/matroska/ebmlmatroskaaudio.cpp | 9 +- taglib/fileref.cpp | 2 +- taglib/flac/flacproperties.cpp | 30 ++--- taglib/flac/flacproperties.h | 7 +- taglib/it/itproperties.cpp | 17 ++- taglib/it/itproperties.h | 13 +- taglib/mod/modproperties.cpp | 17 ++- taglib/mod/modproperties.h | 11 +- taglib/mp4/mp4properties.cpp | 142 +++++++++++---------- taglib/mp4/mp4properties.h | 2 + taglib/mpc/mpcproperties.cpp | 32 ++--- taglib/mpc/mpcproperties.h | 19 +-- taglib/mpeg/mpegproperties.cpp | 54 +++----- taglib/mpeg/mpegproperties.h | 7 +- taglib/ogg/opus/opusproperties.cpp | 28 ++-- taglib/ogg/opus/opusproperties.h | 7 +- taglib/ogg/speex/speexproperties.cpp | 26 ++-- taglib/ogg/speex/speexproperties.h | 7 +- taglib/ogg/vorbis/vorbisproperties.cpp | 29 ++--- taglib/ogg/vorbis/vorbisproperties.h | 13 +- taglib/riff/aiff/aiffproperties.cpp | 41 +++++- taglib/riff/aiff/aiffproperties.h | 28 +++- taglib/riff/wav/wavproperties.cpp | 49 ++++--- taglib/riff/wav/wavproperties.h | 30 +++-- taglib/s3m/s3mproperties.cpp | 17 ++- taglib/s3m/s3mproperties.h | 13 +- taglib/trueaudio/trueaudiofile.cpp | 6 +- taglib/trueaudio/trueaudioproperties.cpp | 36 ++---- taglib/trueaudio/trueaudioproperties.h | 11 +- taglib/wavpack/wavpackproperties.cpp | 47 +++---- taglib/wavpack/wavpackproperties.h | 9 +- taglib/xm/xmproperties.cpp | 17 ++- taglib/xm/xmproperties.h | 13 +- tests/data/alaw.aifc | Bin 0 -> 1890 bytes tests/data/alaw.wav | Bin 0 -> 7408 bytes tests/test_aiff.cpp | 17 +++ tests/test_fileref.cpp | 12 ++ tests/test_wav.cpp | 12 ++ 44 files changed, 498 insertions(+), 477 deletions(-) create mode 100644 tests/data/alaw.aifc create mode 100644 tests/data/alaw.wav diff --git a/taglib/ape/apeproperties.cpp b/taglib/ape/apeproperties.cpp index b5edb9ef..798145d6 100644 --- a/taglib/ape/apeproperties.cpp +++ b/taglib/ape/apeproperties.cpp @@ -29,7 +29,7 @@ #include #include -#include + #include "id3v2tag.h" #include "apeproperties.h" #include "apefile.h" @@ -39,16 +39,14 @@ using namespace TagLib; class APE::AudioProperties::PropertiesPrivate { public: - PropertiesPrivate(File *file, offset_t streamLength) : + PropertiesPrivate() : length(0), bitrate(0), sampleRate(0), channels(0), version(0), bitsPerSample(0), - sampleFrames(0), - file(file), - streamLength(streamLength) {} + sampleFrames(0) {} int length; int bitrate; @@ -57,19 +55,16 @@ public: int version; int bitsPerSample; uint sampleFrames; - File *file; - offset_t streamLength; }; //////////////////////////////////////////////////////////////////////////////// // public members //////////////////////////////////////////////////////////////////////////////// -APE::AudioProperties::AudioProperties(File *file, ReadStyle style) - : TagLib::AudioProperties(style) +APE::AudioProperties::AudioProperties(File *file, ReadStyle style) : + d(new PropertiesPrivate()) { - d = new PropertiesPrivate(file, file->length()); - read(); + read(file); } APE::AudioProperties::~AudioProperties() @@ -117,35 +112,35 @@ TagLib::uint APE::AudioProperties::sampleFrames() const //////////////////////////////////////////////////////////////////////////////// -void APE::AudioProperties::read() +void APE::AudioProperties::read(File *file) { // First we are searching the descriptor - offset_t offset = findDescriptor(); + offset_t offset = findDescriptor(file); if(offset < 0) return; // Then we read the header common for all versions of APE - d->file->seek(offset); - ByteVector commonHeader = d->file->readBlock(6); + file->seek(offset); + ByteVector commonHeader = file->readBlock(6); if(!commonHeader.startsWith("MAC ")) return; d->version = commonHeader.toUInt16LE(4); if(d->version >= 3980) { - analyzeCurrent(); + analyzeCurrent(file); } else { - analyzeOld(); + analyzeOld(file); } } -offset_t APE::AudioProperties::findDescriptor() +offset_t APE::AudioProperties::findDescriptor(File *file) { - offset_t ID3v2Location = findID3v2(); + offset_t ID3v2Location = findID3v2(file); long ID3v2OriginalSize = 0; bool hasID3v2 = false; if(ID3v2Location >= 0) { - ID3v2::Tag tag(d->file, ID3v2Location); + ID3v2::Tag tag(file, ID3v2Location); ID3v2OriginalSize = tag.header()->completeTagSize(); if(tag.header()->tagSize() > 0) hasID3v2 = true; @@ -153,9 +148,9 @@ offset_t APE::AudioProperties::findDescriptor() offset_t offset = 0; if(hasID3v2) - offset = d->file->find("MAC ", ID3v2Location + ID3v2OriginalSize); + offset = file->find("MAC ", ID3v2Location + ID3v2OriginalSize); else - offset = d->file->find("MAC "); + offset = file->find("MAC "); if(offset < 0) { debug("APE::Properties::findDescriptor() -- APE descriptor not found"); @@ -165,31 +160,31 @@ offset_t APE::AudioProperties::findDescriptor() return offset; } -offset_t APE::AudioProperties::findID3v2() +offset_t APE::AudioProperties::findID3v2(File *file) { - if(!d->file->isValid()) + if(!file->isValid()) return -1; - d->file->seek(0); + file->seek(0); - if(d->file->readBlock(3) == ID3v2::Header::fileIdentifier()) + if(file->readBlock(3) == ID3v2::Header::fileIdentifier()) return 0; return -1; } -void APE::AudioProperties::analyzeCurrent() +void APE::AudioProperties::analyzeCurrent(File *file) { // Read the descriptor - d->file->seek(2, File::Current); - ByteVector descriptor = d->file->readBlock(44); + file->seek(2, File::Current); + ByteVector descriptor = file->readBlock(44); const uint descriptorBytes = descriptor.toUInt32LE(0); if ((descriptorBytes - 52) > 0) - d->file->seek(descriptorBytes - 52, File::Current); + file->seek(descriptorBytes - 52, File::Current); // Read the header - ByteVector header = d->file->readBlock(24); + ByteVector header = file->readBlock(24); // Get the APE info d->channels = header.toInt16LE(18); @@ -203,12 +198,12 @@ void APE::AudioProperties::analyzeCurrent() d->sampleFrames = totalFrames > 0 ? (totalFrames - 1) * blocksPerFrame + finalFrameBlocks : 0; d->length = d->sampleRate > 0 ? d->sampleFrames / d->sampleRate : 0; - d->bitrate = d->length > 0 ? static_cast(d->streamLength * 8L / d->length / 1000) : 0; + d->bitrate = d->length > 0 ? static_cast(file->length() * 8L / d->length / 1000) : 0; } -void APE::AudioProperties::analyzeOld() +void APE::AudioProperties::analyzeOld(File *file) { - ByteVector header = d->file->readBlock(26); + ByteVector header = file->readBlock(26); const uint totalFrames = header.toUInt32LE(18); // Fail on 0 length APE files (catches non-finalized APE files) @@ -229,6 +224,6 @@ void APE::AudioProperties::analyzeOld() const uint finalFrameBlocks = header.toUInt32LE(22); const uint totalBlocks = totalFrames > 0 ? (totalFrames - 1) * blocksPerFrame + finalFrameBlocks : 0; d->length = totalBlocks / d->sampleRate; - d->bitrate = d->length > 0 ? static_cast(d->streamLength * 8L / d->length / 1000) : 0; + d->bitrate = d->length > 0 ? static_cast(file->length() * 8L / d->length / 1000) : 0; } diff --git a/taglib/ape/apeproperties.h b/taglib/ape/apeproperties.h index 3d17e245..64bfd0ee 100644 --- a/taglib/ape/apeproperties.h +++ b/taglib/ape/apeproperties.h @@ -50,10 +50,10 @@ namespace TagLib { { public: /*! - * Create an instance of APE::AudioProperties with the data read from + * Creates an instance of APE::AudioProperties with the data read from * the ByteVector \a data. */ - AudioProperties(File *f, ReadStyle style = Average); + AudioProperties(File *file, ReadStyle style = Average); /*! * Destroys this APE::AudioProperties instance. @@ -79,16 +79,13 @@ namespace TagLib { int version() const; private: - AudioProperties(const AudioProperties &); - AudioProperties &operator=(const AudioProperties &); + void read(File *file); - void read(); + offset_t findDescriptor(File *file); + offset_t findID3v2(File *file); - offset_t findDescriptor(); - offset_t findID3v2(); - - void analyzeCurrent(); - void analyzeOld(); + void analyzeCurrent(File *file); + void analyzeOld(File *file); class PropertiesPrivate; PropertiesPrivate *d; diff --git a/taglib/asf/asfproperties.cpp b/taglib/asf/asfproperties.cpp index 18cd4c94..0174f659 100644 --- a/taglib/asf/asfproperties.cpp +++ b/taglib/asf/asfproperties.cpp @@ -32,7 +32,13 @@ using namespace TagLib; class ASF::AudioProperties::PropertiesPrivate { public: - PropertiesPrivate(): length(0), bitrate(0), sampleRate(0), channels(0), encrypted(false) {} + PropertiesPrivate() : + length(0), + bitrate(0), + sampleRate(0), + channels(0), + encrypted(false) {} + int length; int bitrate; int sampleRate; @@ -44,16 +50,14 @@ public: // public members //////////////////////////////////////////////////////////////////////////////// -ASF::AudioProperties::AudioProperties() - : TagLib::AudioProperties(AudioProperties::Average) +ASF::AudioProperties::AudioProperties() : + d(new PropertiesPrivate()) { - d = new PropertiesPrivate; } ASF::AudioProperties::~AudioProperties() { - if(d) - delete d; + delete d; } int ASF::AudioProperties::length() const diff --git a/taglib/asf/asfproperties.h b/taglib/asf/asfproperties.h index 402c5a3b..bacbc9a6 100644 --- a/taglib/asf/asfproperties.h +++ b/taglib/asf/asfproperties.h @@ -34,13 +34,16 @@ namespace TagLib { namespace ASF { + class File; + //! An implementation of ASF audio properties class TAGLIB_EXPORT AudioProperties : public TagLib::AudioProperties { - public: + friend class File; + public: /*! - * Create an instance of ASF::AudioProperties. + * Creates an instance of ASF::AudioProperties. */ AudioProperties(); @@ -50,21 +53,20 @@ namespace TagLib { virtual ~AudioProperties(); // Reimplementations. + virtual int length() const; virtual int bitrate() const; virtual int sampleRate() const; virtual int channels() const; bool isEncrypted() const; -#ifndef DO_NOT_DOCUMENT + private: void setLength(int value); void setBitrate(int value); void setSampleRate(int value); void setChannels(int value); void setEncrypted(bool value); -#endif - private: class PropertiesPrivate; PropertiesPrivate *d; }; diff --git a/taglib/audioproperties.cpp b/taglib/audioproperties.cpp index 5b25867b..231d47b9 100644 --- a/taglib/audioproperties.cpp +++ b/taglib/audioproperties.cpp @@ -28,31 +28,15 @@ using namespace TagLib; -class AudioProperties::AudioPropertiesPrivate -{ - -}; - //////////////////////////////////////////////////////////////////////////////// // public methods //////////////////////////////////////////////////////////////////////////////// AudioProperties::~AudioProperties() { - } -//////////////////////////////////////////////////////////////////////////////// -// protected methods -//////////////////////////////////////////////////////////////////////////////// - -AudioProperties::AudioProperties(ReadStyle) -{ - -} - -String -AudioProperties::toString() const +String AudioProperties::toString() const { StringList desc; desc.append("Audio"); @@ -60,3 +44,11 @@ AudioProperties::toString() const desc.append(String::number(bitrate()) + " kbps"); return desc.toString(", "); } + +//////////////////////////////////////////////////////////////////////////////// +// protected methods +//////////////////////////////////////////////////////////////////////////////// + +AudioProperties::AudioProperties() +{ +} diff --git a/taglib/audioproperties.h b/taglib/audioproperties.h index 9ae5468b..c7449dd4 100644 --- a/taglib/audioproperties.h +++ b/taglib/audioproperties.h @@ -95,21 +95,16 @@ namespace TagLib { protected: /*! - * Construct an audio properties instance. This is protected as this class + * Constructs an audio properties instance. This is protected as this class * should not be instantiated directly, but should be instantiated via its * subclasses and can be fetched from the FileRef or File APIs. - * - * \see ReadStyle */ - AudioProperties(ReadStyle style); + AudioProperties(); private: // Noncopyable. Derived classes as well. AudioProperties(const AudioProperties &); AudioProperties &operator=(const AudioProperties &); - - class AudioPropertiesPrivate; - AudioPropertiesPrivate *d; }; } diff --git a/taglib/ebml/matroska/ebmlmatroskaaudio.cpp b/taglib/ebml/matroska/ebmlmatroskaaudio.cpp index e2a8251d..8c730674 100644 --- a/taglib/ebml/matroska/ebmlmatroskaaudio.cpp +++ b/taglib/ebml/matroska/ebmlmatroskaaudio.cpp @@ -32,8 +32,7 @@ class EBML::Matroska::AudioProperties::AudioPropertiesPrivate { public: // Constructor - AudioPropertiesPrivate(File *p_document) : - document(p_document), + AudioPropertiesPrivate(File *document) : length(0), bitrate(0), channels(1), @@ -46,7 +45,7 @@ public: if(info && (value = info->getChild(Constants::Duration))) { length = static_cast(value->getAsFloat() / 1000000000.L); if((value = info->getChild(Constants::TimecodeScale))) - length *= value->getAsUnsigned(); + length *= static_cast(value->getAsUnsigned()); else length *= 1000000; } @@ -69,9 +68,6 @@ public: samplerate = static_cast(value->getAsFloat()); } - // The corresponding file - File *document; - // The length of the file int length; @@ -90,7 +86,6 @@ public: //////////////////////////////////////////////////////////////////////////////// EBML::Matroska::AudioProperties::AudioProperties(File *document) : - TagLib::AudioProperties(TagLib::AudioProperties::Fast), d(new AudioPropertiesPrivate(document)) { } diff --git a/taglib/fileref.cpp b/taglib/fileref.cpp index 306a8cd2..455321d6 100644 --- a/taglib/fileref.cpp +++ b/taglib/fileref.cpp @@ -122,7 +122,7 @@ namespace file.reset(new MP4::File(fileName, readAudioProperties, audioPropertiesStyle)); else if(ext == "WMA" || ext == "ASF") file.reset(new ASF::File(fileName, readAudioProperties, audioPropertiesStyle)); - else if(ext == "AIF" || ext == "AIFF") + else if(ext == "AIF" || ext == "AIFF" || ext == "AFC" || ext == "AIFC") file.reset(new RIFF::AIFF::File(fileName, readAudioProperties, audioPropertiesStyle)); else if(ext == "WAV") file.reset(new RIFF::WAV::File(fileName, readAudioProperties, audioPropertiesStyle)); diff --git a/taglib/flac/flacproperties.cpp b/taglib/flac/flacproperties.cpp index a5879552..6af8f11a 100644 --- a/taglib/flac/flacproperties.cpp +++ b/taglib/flac/flacproperties.cpp @@ -34,10 +34,7 @@ using namespace TagLib; class FLAC::AudioProperties::PropertiesPrivate { public: - PropertiesPrivate(const ByteVector &d, offset_t st, ReadStyle s) : - data(d), - streamLength(st), - style(s), + PropertiesPrivate() : length(0), bitrate(0), sampleRate(0), @@ -45,9 +42,6 @@ public: channels(0), sampleFrames(0) {} - ByteVector data; - offset_t streamLength; - ReadStyle style; int length; int bitrate; int sampleRate; @@ -61,11 +55,11 @@ public: // public members //////////////////////////////////////////////////////////////////////////////// -FLAC::AudioProperties::AudioProperties(const ByteVector &data, offset_t streamLength, ReadStyle style) - : TagLib::AudioProperties(style) +FLAC::AudioProperties::AudioProperties(const ByteVector &data, offset_t streamLength, + ReadStyle style) : + d(new PropertiesPrivate()) { - d = new PropertiesPrivate(data, streamLength, style); - read(); + read(data, streamLength); } FLAC::AudioProperties::~AudioProperties() @@ -112,14 +106,14 @@ ByteVector FLAC::AudioProperties::signature() const // private members //////////////////////////////////////////////////////////////////////////////// -void FLAC::AudioProperties::read() +void FLAC::AudioProperties::read(const ByteVector &data, offset_t streamLength) { - if(d->data.size() < 18) { + if(data.size() < 18) { debug("FLAC::Properties::read() - FLAC properties must contain at least 18 bytes."); return; } - uint pos = 0; + size_t pos = 0; // Minimum block size (in samples) pos += 2; @@ -133,7 +127,7 @@ void FLAC::AudioProperties::read() // Maximum frame size (in bytes) pos += 3; - const uint flags = d->data.toUInt32BE(pos); + const uint flags = data.toUInt32BE(pos); pos += 4; d->sampleRate = flags >> 12; @@ -144,7 +138,7 @@ void FLAC::AudioProperties::read() // stream length in samples. (Audio files measured in days) const ulonglong hi = flags & 0xf; - const ulonglong lo = d->data.toUInt32BE(pos); + const ulonglong lo = data.toUInt32BE(pos); pos += 4; d->sampleFrames = (hi << 32) | lo; @@ -158,7 +152,7 @@ void FLAC::AudioProperties::read() // Real bitrate: - d->bitrate = d->length > 0 ? static_cast(d->streamLength * 8L / d->length / 1000) : 0; + d->bitrate = d->length > 0 ? static_cast(streamLength * 8L / d->length / 1000) : 0; - d->signature = d->data.mid(pos, 32); + d->signature = data.mid(pos, 32); } diff --git a/taglib/flac/flacproperties.h b/taglib/flac/flacproperties.h index c29d9786..15df42e6 100644 --- a/taglib/flac/flacproperties.h +++ b/taglib/flac/flacproperties.h @@ -46,7 +46,7 @@ namespace TagLib { { public: /*! - * Create an instance of FLAC::AudioProperties with the data read from + * Creates an instance of FLAC::AudioProperties with the data read from * the ByteVector \a data. */ AudioProperties(const ByteVector &data, offset_t streamLength, ReadStyle style = Average); @@ -81,10 +81,7 @@ namespace TagLib { ByteVector signature() const; private: - AudioProperties(const AudioProperties &); - AudioProperties &operator=(const AudioProperties &); - - void read(); + void read(const ByteVector &data, offset_t streamLength); class PropertiesPrivate; PropertiesPrivate *d; diff --git a/taglib/it/itproperties.cpp b/taglib/it/itproperties.cpp index 6405fba3..912c0733 100644 --- a/taglib/it/itproperties.cpp +++ b/taglib/it/itproperties.cpp @@ -42,9 +42,7 @@ public: tempo(0), bpmSpeed(0), panningSeparation(0), - pitchWheelDepth(0) - { - } + pitchWheelDepth(0) {} int channels; ushort lengthInPatterns; @@ -63,9 +61,12 @@ public: uchar pitchWheelDepth; }; -IT::AudioProperties::AudioProperties(AudioProperties::ReadStyle propertiesStyle) - : TagLib::AudioProperties(propertiesStyle) - , d(new PropertiesPrivate) +//////////////////////////////////////////////////////////////////////////////// +// public members +//////////////////////////////////////////////////////////////////////////////// + +IT::AudioProperties::AudioProperties(AudioProperties::ReadStyle propertiesStyle) : + d(new PropertiesPrivate()) { } @@ -169,6 +170,10 @@ uchar IT::AudioProperties::pitchWheelDepth() const return d->pitchWheelDepth; } +//////////////////////////////////////////////////////////////////////////////// +// private members +//////////////////////////////////////////////////////////////////////////////// + void IT::AudioProperties::setChannels(int channels) { d->channels = channels; diff --git a/taglib/it/itproperties.h b/taglib/it/itproperties.h index ae8096a9..08fbf3a5 100644 --- a/taglib/it/itproperties.h +++ b/taglib/it/itproperties.h @@ -26,9 +26,15 @@ #include "audioproperties.h" namespace TagLib { + namespace IT { - class TAGLIB_EXPORT AudioProperties : public TagLib::AudioProperties { + + class File; + + class TAGLIB_EXPORT AudioProperties : public TagLib::AudioProperties + { friend class File; + public: /*! Flag bits. */ enum { @@ -72,6 +78,7 @@ namespace TagLib { uchar panningSeparation() const; uchar pitchWheelDepth() const; + private: void setChannels(int channels); void setLengthInPatterns(ushort lengthInPatterns); void setInstrumentCount(ushort instrumentCount); @@ -88,10 +95,6 @@ namespace TagLib { void setPanningSeparation(uchar panningSeparation); void setPitchWheelDepth (uchar pitchWheelDepth); - private: - AudioProperties(const AudioProperties&); - AudioProperties &operator=(const AudioProperties&); - class PropertiesPrivate; PropertiesPrivate *d; }; diff --git a/taglib/mod/modproperties.cpp b/taglib/mod/modproperties.cpp index 80b49b0c..20510c76 100644 --- a/taglib/mod/modproperties.cpp +++ b/taglib/mod/modproperties.cpp @@ -30,18 +30,19 @@ public: PropertiesPrivate() : channels(0), instrumentCount(0), - lengthInPatterns(0) - { - } + lengthInPatterns(0) {} int channels; uint instrumentCount; uchar lengthInPatterns; }; -Mod::AudioProperties::AudioProperties(AudioProperties::ReadStyle propertiesStyle) - : TagLib::AudioProperties(propertiesStyle) - , d(new PropertiesPrivate) +//////////////////////////////////////////////////////////////////////////////// +// public members +//////////////////////////////////////////////////////////////////////////////// + +Mod::AudioProperties::AudioProperties(AudioProperties::ReadStyle propertiesStyle) : + d(new PropertiesPrivate) { } @@ -80,6 +81,10 @@ uchar Mod::AudioProperties::lengthInPatterns() const return d->lengthInPatterns; } +//////////////////////////////////////////////////////////////////////////////// +// private members +//////////////////////////////////////////////////////////////////////////////// + void Mod::AudioProperties::setChannels(int channels) { d->channels = channels; diff --git a/taglib/mod/modproperties.h b/taglib/mod/modproperties.h index b5195710..18a47208 100644 --- a/taglib/mod/modproperties.h +++ b/taglib/mod/modproperties.h @@ -29,8 +29,12 @@ namespace TagLib { namespace Mod { + class File; + class TAGLIB_EXPORT AudioProperties : public TagLib::AudioProperties { + friend class File; + public: AudioProperties(AudioProperties::ReadStyle propertiesStyle); virtual ~AudioProperties(); @@ -43,17 +47,12 @@ namespace TagLib { uint instrumentCount() const; uchar lengthInPatterns() const; + private: void setChannels(int channels); void setInstrumentCount(uint sampleCount); void setLengthInPatterns(uchar lengthInPatterns); - private: - friend class File; - - AudioProperties(const AudioProperties&); - AudioProperties &operator=(const AudioProperties&); - class PropertiesPrivate; PropertiesPrivate *d; }; diff --git a/taglib/mp4/mp4properties.cpp b/taglib/mp4/mp4properties.cpp index ac7da3f7..5ab189d8 100644 --- a/taglib/mp4/mp4properties.cpp +++ b/taglib/mp4/mp4properties.cpp @@ -34,7 +34,14 @@ using namespace TagLib; class MP4::AudioProperties::PropertiesPrivate { public: - PropertiesPrivate() : length(0), bitrate(0), sampleRate(0), channels(0), bitsPerSample(0), encrypted(false), format(Unknown) {} + PropertiesPrivate() : + length(0), + bitrate(0), + sampleRate(0), + channels(0), + bitsPerSample(0), + encrypted(false), + format(Unknown) {} enum Format { Unknown = 0, @@ -51,11 +58,76 @@ public: Format format; }; -MP4::AudioProperties::AudioProperties(File *file, MP4::Atoms *atoms, ReadStyle style) - : TagLib::AudioProperties(style) +MP4::AudioProperties::AudioProperties(File *file, MP4::Atoms *atoms, ReadStyle style) : + d(new PropertiesPrivate()) { - d = new PropertiesPrivate; + read(file, atoms); +} +MP4::AudioProperties::~AudioProperties() +{ + delete d; +} + +int +MP4::AudioProperties::channels() const +{ + return d->channels; +} + +int +MP4::AudioProperties::sampleRate() const +{ + return d->sampleRate; +} + +int +MP4::AudioProperties::length() const +{ + return d->length; +} + +int +MP4::AudioProperties::bitrate() const +{ + return d->bitrate; +} + +int +MP4::AudioProperties::bitsPerSample() const +{ + return d->bitsPerSample; +} + +bool +MP4::AudioProperties::isEncrypted() const +{ + return d->encrypted; +} + +String +MP4::AudioProperties::toString() const +{ + String format; + if(d->format == PropertiesPrivate::AAC) { + format = "AAC"; + } + else if(d->format == PropertiesPrivate::ALAC) { + format = "ALAC"; + } + else { + format = "Unknown"; + } + StringList desc; + desc.append("MPEG-4 audio (" + format + ")"); + desc.append(String::number(length()) + " seconds"); + desc.append(String::number(bitrate()) + " kbps"); + return desc.toString(", "); +} + +void +MP4::AudioProperties::read(File *file, Atoms *atoms) +{ MP4::Atom *moov = atoms->find("moov"); if(!moov) { debug("MP4: Atom 'moov' not found"); @@ -156,65 +228,3 @@ MP4::AudioProperties::AudioProperties(File *file, MP4::Atoms *atoms, ReadStyle s d->encrypted = true; } } - -MP4::AudioProperties::~AudioProperties() -{ - delete d; -} - -int -MP4::AudioProperties::channels() const -{ - return d->channels; -} - -int -MP4::AudioProperties::sampleRate() const -{ - return d->sampleRate; -} - -int -MP4::AudioProperties::length() const -{ - return d->length; -} - -int -MP4::AudioProperties::bitrate() const -{ - return d->bitrate; -} - -int -MP4::AudioProperties::bitsPerSample() const -{ - return d->bitsPerSample; -} - -bool -MP4::AudioProperties::isEncrypted() const -{ - return d->encrypted; -} - -String -MP4::AudioProperties::toString() const -{ - String format; - if(d->format == PropertiesPrivate::AAC) { - format = "AAC"; - } - else if(d->format == PropertiesPrivate::ALAC) { - format = "ALAC"; - } - else { - format = "Unknown"; - } - StringList desc; - desc.append("MPEG-4 audio (" + format + ")"); - desc.append(String::number(length()) + " seconds"); - desc.append(String::number(bitrate()) + " kbps"); - return desc.toString(", "); -} - diff --git a/taglib/mp4/mp4properties.h b/taglib/mp4/mp4properties.h index 601ec84c..99de9dd0 100644 --- a/taglib/mp4/mp4properties.h +++ b/taglib/mp4/mp4properties.h @@ -53,6 +53,8 @@ namespace TagLib { String toString() const; private: + void read(File *file, Atoms *atoms); + class PropertiesPrivate; PropertiesPrivate *d; }; diff --git a/taglib/mpc/mpcproperties.cpp b/taglib/mpc/mpcproperties.cpp index 0dd4f969..23dc5345 100644 --- a/taglib/mpc/mpcproperties.cpp +++ b/taglib/mpc/mpcproperties.cpp @@ -36,9 +36,7 @@ using namespace TagLib; class MPC::AudioProperties::PropertiesPrivate { public: - PropertiesPrivate(offset_t length, ReadStyle s) : - streamLength(length), - style(s), + PropertiesPrivate() : version(0), length(0), bitrate(0), @@ -51,8 +49,6 @@ public: albumGain(0), albumPeak(0) {} - offset_t streamLength; - ReadStyle style; int version; int length; int bitrate; @@ -71,25 +67,17 @@ public: // public members //////////////////////////////////////////////////////////////////////////////// -MPC::AudioProperties::AudioProperties(const ByteVector &data, offset_t streamLength, ReadStyle style) - : TagLib::AudioProperties(style) +MPC::AudioProperties::AudioProperties(File *file, offset_t streamLength, ReadStyle style) : + d(new PropertiesPrivate()) { - d = new PropertiesPrivate(streamLength, style); - readSV7(data); -} - -MPC::AudioProperties::AudioProperties(File *file, offset_t streamLength, ReadStyle style) - : TagLib::AudioProperties(style) -{ - d = new PropertiesPrivate(streamLength, style); - ByteVector magic = file->readBlock(4); + const ByteVector magic = file->readBlock(4); if(magic == "MPCK") { // Musepack version 8 - readSV8(file); + readSV8(file, streamLength); } else { // Musepack version 7 or older, fixed size header - readSV7(magic + file->readBlock(MPC::HeaderSize - 4)); + readSV7(magic + file->readBlock(52), streamLength); } } @@ -190,7 +178,7 @@ namespace static const unsigned short sftable [4] = { 44100, 48000, 37800, 32000 }; } -void MPC::AudioProperties::readSV8(File *file) +void MPC::AudioProperties::readSV8(File *file, offset_t streamLength) { bool readSH = false, readRG = false; @@ -219,7 +207,7 @@ void MPC::AudioProperties::readSV8(File *file) d->channels = flags[7] * 8 + flags[6] * 4 + flags[5] * 2 + flags[4] + 1; if((d->sampleFrames - begSilence) != 0) - d->bitrate = static_cast(d->streamLength * 8.0 * d->sampleRate / (d->sampleFrames - begSilence)); + d->bitrate = static_cast(streamLength * 8.0 * d->sampleRate / (d->sampleFrames - begSilence)); d->bitrate = d->bitrate / 1000; d->length = (d->sampleFrames - begSilence) / d->sampleRate; @@ -250,7 +238,7 @@ void MPC::AudioProperties::readSV8(File *file) } } -void MPC::AudioProperties::readSV7(const ByteVector &data) +void MPC::AudioProperties::readSV7(const ByteVector &data, offset_t streamLength) { if(data.startsWith("MP+")) { d->version = data[3] & 15; @@ -316,6 +304,6 @@ void MPC::AudioProperties::readSV7(const ByteVector &data) d->length = d->sampleRate > 0 ? (d->sampleFrames + (d->sampleRate / 2)) / d->sampleRate : 0; if(!d->bitrate) - d->bitrate = d->length > 0 ? static_cast(d->streamLength * 8L / d->length / 1000) : 0; + d->bitrate = d->length > 0 ? static_cast(streamLength * 8L / d->length / 1000) : 0; } diff --git a/taglib/mpc/mpcproperties.h b/taglib/mpc/mpcproperties.h index e8cb38ec..53d82fbf 100644 --- a/taglib/mpc/mpcproperties.h +++ b/taglib/mpc/mpcproperties.h @@ -35,8 +35,6 @@ namespace TagLib { class File; - static const uint HeaderSize = 8*7; - //! An implementation of audio property reading for MPC /*! @@ -48,15 +46,7 @@ namespace TagLib { { public: /*! - * Create an instance of MPC::AudioProperties with the data read from - * the ByteVector \a data. - * - * This constructor is deprecated. It only works for MPC version up to 7. - */ - AudioProperties(const ByteVector &data, offset_t streamLength, ReadStyle style = Average); - - /*! - * Create an instance of MPC::AudioProperties with the data read directly + * Creates an instance of MPC::AudioProperties with the data read directly * from a MPC::File. */ AudioProperties(File *file, offset_t streamLength, ReadStyle style = Average); @@ -107,11 +97,8 @@ namespace TagLib { int albumPeak() const; private: - AudioProperties(const AudioProperties &); - AudioProperties &operator=(const AudioProperties &); - - void readSV7(const ByteVector &data); - void readSV8(File *file); + void readSV7(const ByteVector &data, offset_t streamLength); + void readSV8(File *file, offset_t streamLength); class PropertiesPrivate; PropertiesPrivate *d; diff --git a/taglib/mpeg/mpegproperties.cpp b/taglib/mpeg/mpegproperties.cpp index 41bfe761..d7c28db7 100644 --- a/taglib/mpeg/mpegproperties.cpp +++ b/taglib/mpeg/mpegproperties.cpp @@ -25,6 +25,7 @@ #include #include +#include #include "mpegproperties.h" #include "mpegfile.h" @@ -35,10 +36,7 @@ using namespace TagLib; class MPEG::AudioProperties::PropertiesPrivate { public: - PropertiesPrivate(File *f, ReadStyle s) : - file(f), - xingHeader(0), - style(s), + PropertiesPrivate() : length(0), bitrate(0), sampleRate(0), @@ -50,14 +48,7 @@ public: isCopyrighted(false), isOriginal(false) {} - ~PropertiesPrivate() - { - delete xingHeader; - } - - File *file; - XingHeader *xingHeader; - ReadStyle style; + SCOPED_PTR xingHeader; int length; int bitrate; int sampleRate; @@ -74,13 +65,10 @@ public: // public members //////////////////////////////////////////////////////////////////////////////// -MPEG::AudioProperties::AudioProperties(File *file, ReadStyle style) - : TagLib::AudioProperties(style) +MPEG::AudioProperties::AudioProperties(File *file, ReadStyle style) : + d(new PropertiesPrivate()) { - d = new PropertiesPrivate(file, style); - - if(file && file->isOpen()) - read(); + read(file); } MPEG::AudioProperties::~AudioProperties() @@ -110,7 +98,7 @@ int MPEG::AudioProperties::channels() const const MPEG::XingHeader *MPEG::AudioProperties::xingHeader() const { - return d->xingHeader; + return d->xingHeader.get(); } MPEG::Header::Version MPEG::AudioProperties::version() const @@ -147,22 +135,22 @@ bool MPEG::AudioProperties::isOriginal() const // private members //////////////////////////////////////////////////////////////////////////////// -void MPEG::AudioProperties::read() +void MPEG::AudioProperties::read(File *file) { // Since we've likely just looked for the ID3v1 tag, start at the end of the // file where we're least likely to have to have to move the disk head. - offset_t last = d->file->lastFrameOffset(); + offset_t last = file->lastFrameOffset(); if(last < 0) { debug("MPEG::Properties::read() -- Could not find a valid last MPEG frame in the stream."); return; } - d->file->seek(last); - Header lastHeader(d->file->readBlock(4)); + file->seek(last); + Header lastHeader(file->readBlock(4)); - offset_t first = d->file->firstFrameOffset(); + offset_t first = file->firstFrameOffset(); if(first < 0) { debug("MPEG::Properties::read() -- Could not find a valid first MPEG frame in the stream."); @@ -175,13 +163,13 @@ void MPEG::AudioProperties::read() while(pos > first) { - pos = d->file->previousFrameOffset(pos); + pos = file->previousFrameOffset(pos); if(pos < 0) break; - d->file->seek(pos); - Header header(d->file->readBlock(4)); + file->seek(pos); + Header header(file->readBlock(4)); if(header.isValid()) { lastHeader = header; @@ -193,8 +181,8 @@ void MPEG::AudioProperties::read() // Now jump back to the front of the file and read what we need from there. - d->file->seek(first); - Header firstHeader(d->file->readBlock(4)); + file->seek(first); + Header firstHeader(file->readBlock(4)); if(!firstHeader.isValid() || !lastHeader.isValid()) { debug("MPEG::Properties::read() -- Page headers were invalid."); @@ -207,8 +195,8 @@ void MPEG::AudioProperties::read() int xingHeaderOffset = MPEG::XingHeader::offset(firstHeader.version(), firstHeader.channelMode()); - d->file->seek(first + xingHeaderOffset); - d->xingHeader = new XingHeader(d->file->readBlock(16)); + file->seek(first + xingHeaderOffset); + d->xingHeader.reset(new XingHeader(file->readBlock(16))); // Read the length and the bitrate from the Xing header. @@ -228,8 +216,7 @@ void MPEG::AudioProperties::read() // Since there was no valid Xing header found, we hope that we're in a constant // bitrate file. - delete d->xingHeader; - d->xingHeader = 0; + d->xingHeader.reset(); // TODO: Make this more robust with audio property detection for VBR without a // Xing header. @@ -243,7 +230,6 @@ void MPEG::AudioProperties::read() } } - d->sampleRate = firstHeader.sampleRate(); d->channels = firstHeader.channelMode() == Header::SingleChannel ? 1 : 2; d->version = firstHeader.version(); diff --git a/taglib/mpeg/mpegproperties.h b/taglib/mpeg/mpegproperties.h index 21227f60..38e27adc 100644 --- a/taglib/mpeg/mpegproperties.h +++ b/taglib/mpeg/mpegproperties.h @@ -49,7 +49,7 @@ namespace TagLib { { public: /*! - * Create an instance of MPEG::AudioProperties with the data read from + * Creates an instance of MPEG::AudioProperties with the data read from * the MPEG::File \a file. */ AudioProperties(File *file, ReadStyle style = Average); @@ -104,10 +104,7 @@ namespace TagLib { bool isOriginal() const; private: - AudioProperties(const AudioProperties &); - AudioProperties &operator=(const AudioProperties &); - - void read(); + void read(File *file); class PropertiesPrivate; PropertiesPrivate *d; diff --git a/taglib/ogg/opus/opusproperties.cpp b/taglib/ogg/opus/opusproperties.cpp index cf68af81..00a0cc5e 100644 --- a/taglib/ogg/opus/opusproperties.cpp +++ b/taglib/ogg/opus/opusproperties.cpp @@ -29,7 +29,6 @@ #include #include - #include #include "opusproperties.h" @@ -41,16 +40,12 @@ using namespace TagLib::Ogg; class Opus::AudioProperties::PropertiesPrivate { public: - PropertiesPrivate(File *f, ReadStyle s) : - file(f), - style(s), + PropertiesPrivate() : length(0), inputSampleRate(0), channels(0), opusVersion(0) {} - File *file; - ReadStyle style; int length; int inputSampleRate; int channels; @@ -61,11 +56,10 @@ public: // public members //////////////////////////////////////////////////////////////////////////////// -Opus::AudioProperties::AudioProperties(File *file, ReadStyle style) - : TagLib::AudioProperties(style) +Opus::AudioProperties::AudioProperties(File *file, ReadStyle style) : + d(new PropertiesPrivate()) { - d = new PropertiesPrivate(file, style); - read(); + read(file); } Opus::AudioProperties::~AudioProperties() @@ -110,16 +104,16 @@ int Opus::AudioProperties::opusVersion() const // private members //////////////////////////////////////////////////////////////////////////////// -void Opus::AudioProperties::read() +void Opus::AudioProperties::read(File *file) { // Get the identification header from the Ogg implementation. // http://tools.ietf.org/html/draft-terriberry-oggopus-01#section-5.1 - ByteVector data = d->file->packet(0); + const ByteVector data = file->packet(0); // *Magic Signature* - uint pos = 8; + size_t pos = 8; // *Version* (8 bits, unsigned) d->opusVersion = uchar(data.at(pos)); @@ -143,12 +137,12 @@ void Opus::AudioProperties::read() // *Channel Mapping Family* (8 bits, unsigned) pos += 1; - const Ogg::PageHeader *first = d->file->firstPageHeader(); - const Ogg::PageHeader *last = d->file->lastPageHeader(); + const Ogg::PageHeader *first = file->firstPageHeader(); + const Ogg::PageHeader *last = file->lastPageHeader(); if(first && last) { - long long start = first->absoluteGranularPosition(); - long long end = last->absoluteGranularPosition(); + const long long start = first->absoluteGranularPosition(); + const long long end = last->absoluteGranularPosition(); if(start >= 0 && end >= 0) d->length = (int) ((end - start - preSkip) / 48000); diff --git a/taglib/ogg/opus/opusproperties.h b/taglib/ogg/opus/opusproperties.h index fea2d034..7309a58d 100644 --- a/taglib/ogg/opus/opusproperties.h +++ b/taglib/ogg/opus/opusproperties.h @@ -51,7 +51,7 @@ namespace TagLib { { public: /*! - * Create an instance of Opus::AudioProperties with the data read from + * Creates an instance of Opus::AudioProperties with the data read from * the Opus::File \a file. */ AudioProperties(File *file, ReadStyle style = Average); @@ -81,10 +81,7 @@ namespace TagLib { int opusVersion() const; private: - AudioProperties(const AudioProperties &); - AudioProperties &operator=(const AudioProperties &); - - void read(); + void read(File *file); class PropertiesPrivate; PropertiesPrivate *d; diff --git a/taglib/ogg/speex/speexproperties.cpp b/taglib/ogg/speex/speexproperties.cpp index adc7bc73..6784ca58 100644 --- a/taglib/ogg/speex/speexproperties.cpp +++ b/taglib/ogg/speex/speexproperties.cpp @@ -29,7 +29,6 @@ #include #include - #include #include "speexproperties.h" @@ -41,9 +40,7 @@ using namespace TagLib::Ogg; class Speex::AudioProperties::PropertiesPrivate { public: - PropertiesPrivate(File *f, ReadStyle s) : - file(f), - style(s), + PropertiesPrivate() : length(0), bitrate(0), sampleRate(0), @@ -52,8 +49,6 @@ public: vbr(false), mode(0) {} - File *file; - ReadStyle style; int length; int bitrate; int sampleRate; @@ -67,11 +62,10 @@ public: // public members //////////////////////////////////////////////////////////////////////////////// -Speex::AudioProperties::AudioProperties(File *file, ReadStyle style) - : TagLib::AudioProperties(style) +Speex::AudioProperties::AudioProperties(File *file, ReadStyle style) : + d(new PropertiesPrivate()) { - d = new PropertiesPrivate(file, style); - read(); + read(file); } Speex::AudioProperties::~AudioProperties() @@ -108,11 +102,11 @@ int Speex::AudioProperties::speexVersion() const // private members //////////////////////////////////////////////////////////////////////////////// -void Speex::AudioProperties::read() +void Speex::AudioProperties::read(File *file) { // Get the identification header from the Ogg implementation. - ByteVector data = d->file->packet(0); + const ByteVector data = file->packet(0); size_t pos = 28; @@ -153,12 +147,12 @@ void Speex::AudioProperties::read() // frames_per_packet; /**< Number of frames stored per Ogg packet */ // unsigned int framesPerPacket = data.mid(pos, 4).toUInt(false); - const Ogg::PageHeader *first = d->file->firstPageHeader(); - const Ogg::PageHeader *last = d->file->lastPageHeader(); + const Ogg::PageHeader *first = file->firstPageHeader(); + const Ogg::PageHeader *last = file->lastPageHeader(); if(first && last) { - long long start = first->absoluteGranularPosition(); - long long end = last->absoluteGranularPosition(); + const long long start = first->absoluteGranularPosition(); + const long long end = last->absoluteGranularPosition(); if(start >= 0 && end >= 0 && d->sampleRate > 0) d->length = (int) ((end - start) / (long long) d->sampleRate); diff --git a/taglib/ogg/speex/speexproperties.h b/taglib/ogg/speex/speexproperties.h index 0c54d2b5..91fad343 100644 --- a/taglib/ogg/speex/speexproperties.h +++ b/taglib/ogg/speex/speexproperties.h @@ -51,7 +51,7 @@ namespace TagLib { { public: /*! - * Create an instance of Speex::AudioProperties with the data read from + * Creates an instance of Speex::AudioProperties with the data read from * the Speex::File \a file. */ AudioProperties(File *file, ReadStyle style = Average); @@ -74,10 +74,7 @@ namespace TagLib { int speexVersion() const; private: - AudioProperties(const AudioProperties &); - AudioProperties &operator=(const AudioProperties &); - - void read(); + void read(File *file); class PropertiesPrivate; PropertiesPrivate *d; diff --git a/taglib/ogg/vorbis/vorbisproperties.cpp b/taglib/ogg/vorbis/vorbisproperties.cpp index 0ab7106e..41cb87d5 100644 --- a/taglib/ogg/vorbis/vorbisproperties.cpp +++ b/taglib/ogg/vorbis/vorbisproperties.cpp @@ -36,9 +36,7 @@ using namespace TagLib; class Ogg::Vorbis::AudioProperties::PropertiesPrivate { public: - PropertiesPrivate(File *f, ReadStyle s) : - file(f), - style(s), + PropertiesPrivate() : length(0), bitrate(0), sampleRate(0), @@ -48,8 +46,6 @@ public: bitrateNominal(0), bitrateMinimum(0) {} - File *file; - ReadStyle style; int length; int bitrate; int sampleRate; @@ -65,18 +61,17 @@ namespace TagLib { * Vorbis headers can be found with one type ID byte and the string "vorbis" in * an Ogg stream. 0x01 indicates the setup header. */ - static const char vorbisSetupHeaderID[] = { 0x01, 'v', 'o', 'r', 'b', 'i', 's', 0 }; + const char vorbisSetupHeaderID[] = { 0x01, 'v', 'o', 'r', 'b', 'i', 's', 0 }; } //////////////////////////////////////////////////////////////////////////////// // public members //////////////////////////////////////////////////////////////////////////////// -Ogg::Vorbis::AudioProperties::AudioProperties(File *file, ReadStyle style) - : TagLib::AudioProperties(style) +Ogg::Vorbis::AudioProperties::AudioProperties(File *file, ReadStyle style) : + d(new PropertiesPrivate()) { - d = new PropertiesPrivate(file, style); - read(); + read(file); } Ogg::Vorbis::AudioProperties::~AudioProperties() @@ -137,13 +132,13 @@ String Ogg::Vorbis::AudioProperties::toString() const // private members //////////////////////////////////////////////////////////////////////////////// -void Ogg::Vorbis::AudioProperties::read() +void Ogg::Vorbis::AudioProperties::read(File *file) { // Get the identification header from the Ogg implementation. - ByteVector data = d->file->packet(0); + const ByteVector data = file->packet(0); - uint pos = 0; + size_t pos = 0; if(data.mid(pos, 7) != vorbisSetupHeaderID) { debug("Ogg::Vorbis::Properties::read() -- invalid Ogg::Vorbis identification header"); @@ -175,12 +170,12 @@ void Ogg::Vorbis::AudioProperties::read() // Find the length of the file. See http://wiki.xiph.org/Ogg::VorbisStreamLength/ // for my notes on the topic. - const Ogg::PageHeader *first = d->file->firstPageHeader(); - const Ogg::PageHeader *last = d->file->lastPageHeader(); + const Ogg::PageHeader *first = file->firstPageHeader(); + const Ogg::PageHeader *last = file->lastPageHeader(); if(first && last) { - long long start = first->absoluteGranularPosition(); - long long end = last->absoluteGranularPosition(); + const long long start = first->absoluteGranularPosition(); + const long long end = last->absoluteGranularPosition(); if(start >= 0 && end >= 0 && d->sampleRate > 0) d->length = (int)((end - start) / (long long) d->sampleRate); diff --git a/taglib/ogg/vorbis/vorbisproperties.h b/taglib/ogg/vorbis/vorbisproperties.h index 531afeb8..3f56d3b9 100644 --- a/taglib/ogg/vorbis/vorbisproperties.h +++ b/taglib/ogg/vorbis/vorbisproperties.h @@ -48,7 +48,7 @@ namespace TagLib { { public: /*! - * Create an instance of Vorbis::Properties with the data read from the + * Creates an instance of Vorbis::Properties with the data read from the * Vorbis::File \a file. */ AudioProperties(File *file, ReadStyle style = Average); @@ -74,26 +74,29 @@ namespace TagLib { /*! * Returns the maximum bitrate as read from the Vorbis identification * header. + * + * \note The value is in bits per second unlike bitrate(). */ int bitrateMaximum() const; /*! * Returns the nominal bitrate as read from the Vorbis identification * header. + * + * \note The value is in bits per second unlike bitrate(). */ int bitrateNominal() const; /*! * Returns the minimum bitrate as read from the Vorbis identification * header. + * + * \note The value is in bits per second unlike bitrate(). */ int bitrateMinimum() const; private: - AudioProperties(const AudioProperties &); - AudioProperties &operator=(const AudioProperties &); - - void read(); + void read(File *file); class PropertiesPrivate; PropertiesPrivate *d; diff --git a/taglib/riff/aiff/aiffproperties.cpp b/taglib/riff/aiff/aiffproperties.cpp index 57dd65de..6d103e83 100644 --- a/taglib/riff/aiff/aiffproperties.cpp +++ b/taglib/riff/aiff/aiffproperties.cpp @@ -38,15 +38,17 @@ public: sampleRate(0), channels(0), sampleWidth(0), - sampleFrames(0) - { - } + sampleFrames(0) {} int length; int bitrate; int sampleRate; int channels; int sampleWidth; + + ByteVector compressionType; + String compressionName; + uint sampleFrames; }; @@ -54,9 +56,8 @@ public: // public members //////////////////////////////////////////////////////////////////////////////// -RIFF::AIFF::AudioProperties::AudioProperties(const ByteVector &data, ReadStyle style) - : TagLib::AudioProperties(style) - , d(new PropertiesPrivate()) +RIFF::AIFF::AudioProperties::AudioProperties(const ByteVector &data, ReadStyle style) : + d(new PropertiesPrivate()) { read(data); } @@ -101,12 +102,32 @@ TagLib::uint RIFF::AIFF::AudioProperties::sampleFrames() const return d->sampleFrames; } +bool RIFF::AIFF::AudioProperties::isAiffC() const +{ + return (!d->compressionType.isEmpty()); +} + +ByteVector RIFF::AIFF::AudioProperties::compressionType() const +{ + return d->compressionType; +} + +String RIFF::AIFF::AudioProperties::compressionName() const +{ + return d->compressionName; +} + //////////////////////////////////////////////////////////////////////////////// // private members //////////////////////////////////////////////////////////////////////////////// void RIFF::AIFF::AudioProperties::read(const ByteVector &data) { + if(data.size() < 18) { + debug("RIFF::AIFF::AudioProperties::read() - \"COMM\" chunk is too short for AIFF."); + return; + } + d->channels = data.toInt16BE(0); d->sampleFrames = data.toUInt32BE(2); d->sampleWidth = data.toInt16BE(6); @@ -114,4 +135,12 @@ void RIFF::AIFF::AudioProperties::read(const ByteVector &data) d->sampleRate = static_cast(sampleRate); d->bitrate = static_cast((sampleRate * d->sampleWidth * d->channels) / 1000.0); d->length = d->sampleRate > 0 ? d->sampleFrames / d->sampleRate : 0; + + if(data.size() < 23) { + debug("RIFF::AIFF::AudioProperties::read() - \"COMM\" chunk is too short for AIFF-C."); + return; + } + + d->compressionType = data.mid(18, 4); + d->compressionName = String(data.mid(23, static_cast(data[22]))); } diff --git a/taglib/riff/aiff/aiffproperties.h b/taglib/riff/aiff/aiffproperties.h index cc05bd45..1cc89a3d 100644 --- a/taglib/riff/aiff/aiffproperties.h +++ b/taglib/riff/aiff/aiffproperties.h @@ -36,7 +36,7 @@ namespace TagLib { class File; - //! An implementation of audio property reading for AIFF + //! An implementation of audio property reading for AIFF or AIFF-C /*! * This reads the data from an AIFF stream found in the AudioProperties @@ -47,7 +47,7 @@ namespace TagLib { { public: /*! - * Create an instance of AIFF::AudioProperties with the data read from + * Creates an instance of AIFF::AudioProperties with the data read from * the ByteVector \a data. */ AudioProperties(const ByteVector &data, ReadStyle style); @@ -69,6 +69,30 @@ namespace TagLib { int sampleWidth() const; uint sampleFrames() const; + /*! + * Returns true if the file is in AIFF-C format, false if AIFF format. + */ + bool isAiffC() const; + + /*! + * Returns the compression type of the AIFF-C file. For example, "NONE" for + * not compressed, "ACE2" for ACE 2-to-1. + * + * If the file is in AIFF format, always returns an empty vector. + * + * \see isAiffC() + */ + ByteVector compressionType() const; + + /*! + * Returns the concrete compression name of the AIFF-C file. + * + * If the file is in AIFF format, always returns an empty string. + * + * \see isAiffC() + */ + String compressionName() const; + private: void read(const ByteVector &data); diff --git a/taglib/riff/wav/wavproperties.cpp b/taglib/riff/wav/wavproperties.cpp index b454e621..18a8a4d6 100644 --- a/taglib/riff/wav/wavproperties.cpp +++ b/taglib/riff/wav/wavproperties.cpp @@ -23,30 +23,23 @@ * http://www.mozilla.org/MPL/ * ***************************************************************************/ -#include "wavproperties.h" - #include #include -#include -#include +#include "wavproperties.h" using namespace TagLib; class RIFF::WAV::AudioProperties::PropertiesPrivate { public: - PropertiesPrivate(uint streamLength = 0) : + PropertiesPrivate() : format(0), length(0), bitrate(0), sampleRate(0), channels(0), sampleWidth(0), - sampleFrames(0), - streamLength(streamLength) - { - - } + sampleFrames(0) {} short format; int length; @@ -55,25 +48,17 @@ public: int channels; int sampleWidth; uint sampleFrames; - uint streamLength; }; //////////////////////////////////////////////////////////////////////////////// // public members //////////////////////////////////////////////////////////////////////////////// -RIFF::WAV::AudioProperties::AudioProperties(const ByteVector &data, ReadStyle style) - : TagLib::AudioProperties(style) +RIFF::WAV::AudioProperties::AudioProperties(const ByteVector &data, uint streamLength, + ReadStyle style) : + d(new PropertiesPrivate()) { - d = new PropertiesPrivate(); - read(data); -} - -RIFF::WAV::AudioProperties::AudioProperties(const ByteVector &data, uint streamLength, ReadStyle style) - : TagLib::AudioProperties(style) -{ - d = new PropertiesPrivate(streamLength); - read(data); + read(data, streamLength); } RIFF::WAV::AudioProperties::~AudioProperties() @@ -111,12 +96,22 @@ TagLib::uint RIFF::WAV::AudioProperties::sampleFrames() const return d->sampleFrames; } +TagLib::uint RIFF::WAV::AudioProperties::format() const +{ + return d->format; +} + //////////////////////////////////////////////////////////////////////////////// // private members //////////////////////////////////////////////////////////////////////////////// -void RIFF::WAV::AudioProperties::read(const ByteVector &data) +void RIFF::WAV::AudioProperties::read(const ByteVector &data, uint streamLength) { + if(data.size() < 16) { + debug("RIFF::WAV::AudioProperties::read() - \"fmt \" chunk is too short."); + return; + } + d->format = data.toInt16LE(0); d->channels = data.toInt16LE(2); d->sampleRate = data.toUInt32LE(4); @@ -125,7 +120,9 @@ void RIFF::WAV::AudioProperties::read(const ByteVector &data) const uint byteRate = data.toUInt32LE(8); d->bitrate = byteRate * 8 / 1000; - d->length = byteRate > 0 ? d->streamLength / byteRate : 0; - if(d->channels > 0 && d->sampleWidth > 0) - d->sampleFrames = d->streamLength / (d->channels * ((d->sampleWidth + 7) / 8)); + d->length = byteRate > 0 ? streamLength / byteRate : 0; + + // format ID 1 means uncompressed PCM. + if(d->format == 1 && d->channels > 0 && d->sampleWidth > 0) + d->sampleFrames = streamLength / (d->channels * ((d->sampleWidth + 7) / 8)); } diff --git a/taglib/riff/wav/wavproperties.h b/taglib/riff/wav/wavproperties.h index 7452398b..9a6dd4ba 100644 --- a/taglib/riff/wav/wavproperties.h +++ b/taglib/riff/wav/wavproperties.h @@ -50,13 +50,7 @@ namespace TagLib { { public: /*! - * Create an instance of WAV::AudioProperties with the data read from - * the ByteVector \a data. - */ - AudioProperties(const ByteVector &data, ReadStyle style); - - /*! - * Create an instance of WAV::Properties with the data read from the + * Creates an instance of WAV::Properties with the data read from the * ByteVector \a data and the length calculated using \a streamLength. */ AudioProperties(const ByteVector &data, uint streamLength, ReadStyle style); @@ -73,14 +67,28 @@ namespace TagLib { virtual int sampleRate() const; virtual int channels() const; + /*! + * Returns the count of bits per sample. + */ int sampleWidth() const; + + /*! + * Returns the total number of the samples. + * + * If the format ID is not 1, always returns 0. + * + * \see format() + */ uint sampleFrames() const; - private: - AudioProperties(const AudioProperties &); - AudioProperties &operator=(const AudioProperties &); + /*! + * Returns the format ID of the WAVE file. For example, 0 for Unknown, + * 1 for PCM and so forth. + */ + uint format() const; - void read(const ByteVector &data); + private: + void read(const ByteVector &data, uint streamLength); class PropertiesPrivate; PropertiesPrivate *d; diff --git a/taglib/s3m/s3mproperties.cpp b/taglib/s3m/s3mproperties.cpp index 84fa6a21..065863c4 100644 --- a/taglib/s3m/s3mproperties.cpp +++ b/taglib/s3m/s3mproperties.cpp @@ -39,9 +39,7 @@ public: globalVolume(0), masterVolume(0), tempo(0), - bpmSpeed(0) - { - } + bpmSpeed(0) {} ushort lengthInPatterns; int channels; @@ -57,9 +55,12 @@ public: uchar bpmSpeed; }; -S3M::AudioProperties::AudioProperties(AudioProperties::ReadStyle propertiesStyle) - : TagLib::AudioProperties(propertiesStyle) - , d(new PropertiesPrivate) +//////////////////////////////////////////////////////////////////////////////// +// public members +//////////////////////////////////////////////////////////////////////////////// + +S3M::AudioProperties::AudioProperties(AudioProperties::ReadStyle propertiesStyle) : + d(new PropertiesPrivate()) { } @@ -143,6 +144,10 @@ uchar S3M::AudioProperties::bpmSpeed() const return d->bpmSpeed; } +//////////////////////////////////////////////////////////////////////////////// +// private members +//////////////////////////////////////////////////////////////////////////////// + void S3M::AudioProperties::setLengthInPatterns(ushort lengthInPatterns) { d->lengthInPatterns = lengthInPatterns; diff --git a/taglib/s3m/s3mproperties.h b/taglib/s3m/s3mproperties.h index b087b011..efdb4ba7 100644 --- a/taglib/s3m/s3mproperties.h +++ b/taglib/s3m/s3mproperties.h @@ -26,9 +26,15 @@ #include "audioproperties.h" namespace TagLib { + namespace S3M { - class TAGLIB_EXPORT AudioProperties : public TagLib::AudioProperties { + + class File; + + class TAGLIB_EXPORT AudioProperties : public TagLib::AudioProperties + { friend class File; + public: /*! Flag bits. */ enum { @@ -61,6 +67,7 @@ namespace TagLib { uchar tempo() const; uchar bpmSpeed() const; + private: void setChannels(int channels); void setLengthInPatterns (ushort lengthInPatterns); @@ -75,10 +82,6 @@ namespace TagLib { void setTempo (uchar tempo); void setBpmSpeed (uchar bpmSpeed); - private: - AudioProperties(const AudioProperties&); - AudioProperties &operator=(const AudioProperties&); - class PropertiesPrivate; PropertiesPrivate *d; }; diff --git a/taglib/trueaudio/trueaudiofile.cpp b/taglib/trueaudio/trueaudiofile.cpp index dad08006..5c2aca1b 100644 --- a/taglib/trueaudio/trueaudiofile.cpp +++ b/taglib/trueaudio/trueaudiofile.cpp @@ -269,13 +269,11 @@ void TrueAudio::File::read(bool readProperties, AudioProperties::ReadStyle /* pr if(readProperties) { if(d->ID3v2Location >= 0) { seek(d->ID3v2Location + d->ID3v2OriginalSize); - d->properties = new AudioProperties(readBlock(TrueAudio::HeaderSize), - length() - d->ID3v2OriginalSize); + d->properties = new AudioProperties(this, length() - d->ID3v2OriginalSize); } else { seek(0); - d->properties = new AudioProperties(readBlock(TrueAudio::HeaderSize), - length()); + d->properties = new AudioProperties(this, length()); } } } diff --git a/taglib/trueaudio/trueaudioproperties.cpp b/taglib/trueaudio/trueaudioproperties.cpp index 5f73a821..0d5eab0c 100644 --- a/taglib/trueaudio/trueaudioproperties.cpp +++ b/taglib/trueaudio/trueaudioproperties.cpp @@ -29,7 +29,6 @@ #include #include -#include #include "trueaudioproperties.h" #include "trueaudiofile.h" @@ -39,10 +38,7 @@ using namespace TagLib; class TrueAudio::AudioProperties::PropertiesPrivate { public: - PropertiesPrivate(const ByteVector &d, offset_t length, ReadStyle s) : - data(d), - streamLength(length), - style(s), + PropertiesPrivate() : version(0), length(0), bitrate(0), @@ -51,9 +47,6 @@ public: bitsPerSample(0), sampleFrames(0) {} - ByteVector data; - offset_t streamLength; - ReadStyle style; int version; int length; int bitrate; @@ -67,12 +60,10 @@ public: // public members //////////////////////////////////////////////////////////////////////////////// -TrueAudio::AudioProperties::AudioProperties( - const ByteVector &data, offset_t streamLength, ReadStyle style) - : TagLib::AudioProperties(style) +TrueAudio::AudioProperties::AudioProperties(File *file, offset_t streamLength, ReadStyle style) : + d(new PropertiesPrivate()) { - d = new PropertiesPrivate(data, streamLength, style); - read(); + read(file, streamLength); } TrueAudio::AudioProperties::~AudioProperties() @@ -119,14 +110,15 @@ int TrueAudio::AudioProperties::ttaVersion() const // private members //////////////////////////////////////////////////////////////////////////////// -void TrueAudio::AudioProperties::read() +void TrueAudio::AudioProperties::read(File *file, offset_t streamLength) { - if(!d->data.startsWith("TTA")) + const ByteVector data = file->readBlock(18); + if(!data.startsWith("TTA")) return; - int pos = 3; + size_t pos = 3; - d->version = d->data[pos] - '0'; + d->version = data[pos] - '0'; pos += 1; // According to http://en.true-audio.com/TTA_Lossless_Audio_Codec_-_Format_Description @@ -135,18 +127,18 @@ void TrueAudio::AudioProperties::read() // Skip the audio format pos += 2; - d->channels = d->data.toInt16LE(pos); + d->channels = data.toInt16LE(pos); pos += 2; - d->bitsPerSample = d->data.toInt16LE(pos); + d->bitsPerSample = data.toInt16LE(pos); pos += 2; - d->sampleRate = d->data.toUInt32LE(pos); + d->sampleRate = data.toUInt32LE(pos); pos += 4; - d->sampleFrames = d->data.toUInt32LE(pos); + d->sampleFrames = data.toUInt32LE(pos); d->length = d->sampleRate > 0 ? d->sampleFrames / d->sampleRate : 0; - d->bitrate = d->length > 0 ? static_cast(d->streamLength * 8L / d->length / 1000) : 0; + d->bitrate = d->length > 0 ? static_cast(streamLength * 8L / d->length / 1000) : 0; } } diff --git a/taglib/trueaudio/trueaudioproperties.h b/taglib/trueaudio/trueaudioproperties.h index 3623d844..7f2c74cf 100644 --- a/taglib/trueaudio/trueaudioproperties.h +++ b/taglib/trueaudio/trueaudioproperties.h @@ -38,8 +38,6 @@ namespace TagLib { class File; - static const uint HeaderSize = 18; - //! An implementation of audio property reading for TrueAudio /*! @@ -51,10 +49,10 @@ namespace TagLib { { public: /*! - * Create an instance of TrueAudio::AudioProperties with the data read from + * Creates an instance of TrueAudio::AudioProperties with the data read from * the ByteVector \a data. */ - AudioProperties(const ByteVector &data, offset_t streamLength, ReadStyle style = Average); + AudioProperties(File *file, offset_t streamLength, ReadStyle style = Average); /*! * Destroys this TrueAudio::AudioProperties instance. @@ -84,10 +82,7 @@ namespace TagLib { int ttaVersion() const; private: - AudioProperties(const AudioProperties &); - AudioProperties &operator=(const AudioProperties &); - - void read(); + void read(File *file, offset_t streamLength); class PropertiesPrivate; PropertiesPrivate *d; diff --git a/taglib/wavpack/wavpackproperties.cpp b/taglib/wavpack/wavpackproperties.cpp index a66f8574..9dc023cc 100644 --- a/taglib/wavpack/wavpackproperties.cpp +++ b/taglib/wavpack/wavpackproperties.cpp @@ -38,22 +38,15 @@ using namespace TagLib; class WavPack::AudioProperties::PropertiesPrivate { public: - PropertiesPrivate(const ByteVector &d, offset_t length, ReadStyle s, File *f) : - data(d), - streamLength(length), - style(s), + PropertiesPrivate() : length(0), bitrate(0), sampleRate(0), channels(0), version(0), bitsPerSample(0), - sampleFrames(0), - file(f) {} + sampleFrames(0) {} - ByteVector data; - offset_t streamLength; - ReadStyle style; int length; int bitrate; int sampleRate; @@ -61,19 +54,16 @@ public: int version; int bitsPerSample; uint sampleFrames; - File *file; }; //////////////////////////////////////////////////////////////////////////////// // public members //////////////////////////////////////////////////////////////////////////////// -WavPack::AudioProperties::AudioProperties(File *file, offset_t streamLength, ReadStyle style) - : TagLib::AudioProperties(style) +WavPack::AudioProperties::AudioProperties(File *file, offset_t streamLength, ReadStyle style) : + d(new PropertiesPrivate()) { - ByteVector data = file->readBlock(32); - d = new PropertiesPrivate(data, streamLength, style, file); - read(); + read(file, streamLength, style); } WavPack::AudioProperties::~AudioProperties() @@ -140,25 +130,26 @@ namespace #define FINAL_BLOCK 0x1000 -void WavPack::AudioProperties::read() +void WavPack::AudioProperties::read(File *file, offset_t streamLength, ReadStyle style) { - if(!d->data.startsWith("wvpk")) + const ByteVector data = file->readBlock(32); + if(!data.startsWith("wvpk")) return; - d->version = d->data.toInt16LE(8); + d->version = data.toInt16LE(8); if(d->version < MIN_STREAM_VERS || d->version > MAX_STREAM_VERS) return; - const uint flags = d->data.toUInt32LE(24); + const uint flags = data.toUInt32LE(24); d->bitsPerSample = ((flags & BYTES_STORED) + 1) * 8 - ((flags & SHIFT_MASK) >> SHIFT_LSB); d->sampleRate = sample_rates[(flags & SRATE_MASK) >> SRATE_LSB]; d->channels = (flags & MONO_FLAG) ? 1 : 2; - uint samples = d->data.toUInt32LE(12); + uint samples = data.toUInt32LE(12); if(samples == ~0u) { - if(d->style != Fast) { - samples = seekFinalIndex(); + if(style != Fast) { + samples = seekFinalIndex(file, streamLength); } else { samples = 0; @@ -167,20 +158,20 @@ void WavPack::AudioProperties::read() d->length = d->sampleRate > 0 ? (samples + (d->sampleRate / 2)) / d->sampleRate : 0; d->sampleFrames = samples; - d->bitrate = d->length > 0 ? static_cast(d->streamLength * 8L / d->length / 1000) : 0; + d->bitrate = d->length > 0 ? static_cast(streamLength * 8L / d->length / 1000) : 0; } -unsigned int WavPack::AudioProperties::seekFinalIndex() +unsigned int WavPack::AudioProperties::seekFinalIndex(File *file, offset_t streamLength) { ByteVector blockID("wvpk", 4); - offset_t offset = d->streamLength; + offset_t offset = streamLength; while(offset > 0) { - offset = d->file->rfind(blockID, offset); + offset = file->rfind(blockID, offset); if(offset == -1) return 0; - d->file->seek(offset); - ByteVector data = d->file->readBlock(32); + file->seek(offset); + ByteVector data = file->readBlock(32); if(data.size() != 32) return 0; const int version = data.toInt16LE(8); diff --git a/taglib/wavpack/wavpackproperties.h b/taglib/wavpack/wavpackproperties.h index 2392d5db..06553a05 100644 --- a/taglib/wavpack/wavpackproperties.h +++ b/taglib/wavpack/wavpackproperties.h @@ -52,7 +52,7 @@ namespace TagLib { { public: /*! - * Create an instance of WavPack::AudioProperties. + * Creates an instance of WavPack::AudioProperties. */ AudioProperties(File *file, offset_t streamLength, ReadStyle style = Average); @@ -80,11 +80,8 @@ namespace TagLib { int version() const; private: - AudioProperties(const AudioProperties &); - AudioProperties &operator=(const AudioProperties &); - - void read(); - unsigned int seekFinalIndex(); + void read(File *file, offset_t streamLength, ReadStyle style); + unsigned int seekFinalIndex(File *file, offset_t streamLength); class PropertiesPrivate; PropertiesPrivate *d; diff --git a/taglib/xm/xmproperties.cpp b/taglib/xm/xmproperties.cpp index 55e0daa9..60fd12ff 100644 --- a/taglib/xm/xmproperties.cpp +++ b/taglib/xm/xmproperties.cpp @@ -37,9 +37,7 @@ public: sampleCount(0), flags(0), tempo(0), - bpmSpeed(0) - { - } + bpmSpeed(0) {} ushort lengthInPatterns; int channels; @@ -53,9 +51,12 @@ public: ushort bpmSpeed; }; -XM::AudioProperties::AudioProperties(AudioProperties::ReadStyle propertiesStyle) - : TagLib::AudioProperties(propertiesStyle) - , d(new PropertiesPrivate) +//////////////////////////////////////////////////////////////////////////////// +// public members +//////////////////////////////////////////////////////////////////////////////// + +XM::AudioProperties::AudioProperties(AudioProperties::ReadStyle propertiesStyle) : + d(new PropertiesPrivate()) { } @@ -129,6 +130,10 @@ TagLib::ushort XM::AudioProperties::bpmSpeed() const return d->bpmSpeed; } +//////////////////////////////////////////////////////////////////////////////// +// private members +//////////////////////////////////////////////////////////////////////////////// + void XM::AudioProperties::setLengthInPatterns(ushort lengthInPatterns) { d->lengthInPatterns = lengthInPatterns; diff --git a/taglib/xm/xmproperties.h b/taglib/xm/xmproperties.h index 549fe9e6..d956f307 100644 --- a/taglib/xm/xmproperties.h +++ b/taglib/xm/xmproperties.h @@ -27,9 +27,15 @@ #include "audioproperties.h" namespace TagLib { + namespace XM { - class AudioProperties : public TagLib::AudioProperties { + + class File; + + class AudioProperties : public TagLib::AudioProperties + { friend class File; + public: /*! Flag bits. */ enum { @@ -54,6 +60,7 @@ namespace TagLib { ushort tempo() const; ushort bpmSpeed() const; + private: void setChannels(int channels); void setLengthInPatterns(ushort lengthInPatterns); @@ -66,10 +73,6 @@ namespace TagLib { void setTempo(ushort tempo); void setBpmSpeed(ushort bpmSpeed); - private: - AudioProperties(const AudioProperties&); - AudioProperties &operator=(const AudioProperties&); - class PropertiesPrivate; PropertiesPrivate *d; }; diff --git a/tests/data/alaw.aifc b/tests/data/alaw.aifc new file mode 100644 index 0000000000000000000000000000000000000000..33b4ea2a5734c10af92aa556de6c50aa102efac6 GIT binary patch literal 1890 zcmX|B2~d+~8vb*iBm@uwf(e)eaX^Vl{)7;~EUlJSP=Q*Zvn~oOpa_aq?d(j=eIJC| zaD+e(?1G$0AV6@{+3u+9+6ubuw2Kr$%28cfS9i3#`_plKXTF*5d*0`J-s_uh-@)8$ z0KgQAv-V}~JMwNW0077?$>F`32eTm@NCaR2fIb2Q?a zKcBvT7oW|hi<2skU(6QgegF~P2aub$004iYw2Xd^URhmz1_0o{BBfO&ZxO^>PR$z* z@-62Ll9iK}4`E><0Jsdhyy=CMH5b`&Sjp))nJ`pl;_ z6=mh;>Fksgb|U@%{v2`kyO1AuvAVkCL}hjHDIhN|2dW8u3_^dk**7*b^Kd3_U)FCI zlq!laDQPJ+ISExx0J&9OfuK9vuW`Fj?E_q7&M|5v|8N zJnHJ}bE=3Lse+U=He0}ArH6X_F1vetK;xV8PpAO_9m*w{NCx+S(ZuB%tOC#+?mkw^qLB{nfJR)qOMEjMZg$Gflf^f^6$hJ&1B zPDvZ_1hJB`bRC?0RoxA8l4!k_y;&JwV{y7vvcaO*gMe&I{5)xS=Oq1R_ zG-~hfx!ULUm4PWjA(IuCm_$z{{NnSwT%BG0*ZMmr8o=1Z-El0YkjWHsqD<~hy4^Y9 zH8n?Z81%R}db}`=Po&fhxcYl~dR>#ohTKqWI(>J-t~e&|c)iLnGUe{NcCE{)seu}l zA&iIautaE!XDBf4bh|n`9m7|m*eOf~BR)Q!kxqK$3AkM@$9Q03K+}K%1@W;gW{N18 zhrDhaa@srXj=+FUeFMeKV8qg6nIb+=S+ALNLSuD}jVKFHygeyQ7Cn}cMmpK98xHs# z(4fY23rN050M*A}q;i0l+DWIw;SWqr`XoOi`58i{P>`OH1_l*dy`yfs9SS~Vc!37f z8LU_qL%_iWHyQ@V98glDLmtIl8W|J`p!l$m7(9qbCL)kw&pM=1wW8J5-rjDRKO3VI&>_K`WYjw7k65Xj93h*4p(O7fUan zF9}8yNko8JIlZvUGHHS2tvZEbm779NQvbCdUQ_;AY2<_@LG zsNeLM>o3#LP`BA>86ptH|QPF7>sgN`^HH$ zmb;1bNSLYxg~mHD;Psegs+QG*F+?y;#Np#$FL7(Qqu6izmaV z71vkmuc)*>?}%2?v3NWt3JH+0SR6DyYRQ^art^7ydYPj3<@u@*43q&I-Ld-M6cr%hxjX_1i2jX5W!7p*(Nfo;JzG+I{15Ma_0Ly}|GD$s%vaZ+zxes~7y0{h z4v60oAIv(ixA4&1%^Tm`fAHmZU*Ebpee3?=V;_HfwBT4l!S8ZEdU)^Nmk(!VXa5J= CPx9XY literal 0 HcmV?d00001 diff --git a/tests/data/alaw.wav b/tests/data/alaw.wav new file mode 100644 index 0000000000000000000000000000000000000000..754ed8566fe08ba9b2dd7edabf2aee89aeeca57f GIT binary patch literal 7408 zcmeIuu?c`M6olamh*()z3p$Dx25eJkVf9eb*=062aR{hE89cs@z1|Q<48xONS-9^5W(YKmY**5I_I{1Q0*~0R#|0009ILKmY** P5I_I{1Q0*~fnNn)lU45I literal 0 HcmV?d00001 diff --git a/tests/test_aiff.cpp b/tests/test_aiff.cpp index df1c5ac1..bfd0cd57 100644 --- a/tests/test_aiff.cpp +++ b/tests/test_aiff.cpp @@ -13,6 +13,7 @@ class TestAIFF : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(TestAIFF); CPPUNIT_TEST(testReading); + CPPUNIT_TEST(testAiffCProperties); CPPUNIT_TEST_SUITE_END(); public: @@ -24,6 +25,22 @@ public: RIFF::AIFF::File *f = new RIFF::AIFF::File(filename.c_str()); CPPUNIT_ASSERT_EQUAL(705, f->audioProperties()->bitrate()); + CPPUNIT_ASSERT(!f->audioProperties()->isAiffC()); + + delete f; + } + + void testAiffCProperties() + { + ScopedFileCopy copy("alaw", ".aifc"); + string filename = copy.fileName(); + + RIFF::AIFF::File *f = new RIFF::AIFF::File(filename.c_str()); + CPPUNIT_ASSERT(f->audioProperties()->isAiffC()); + CPPUNIT_ASSERT_EQUAL(ByteVector("ALAW"), f->audioProperties()->compressionType()); + CPPUNIT_ASSERT_EQUAL(String("SGI CCITT G.711 A-law"), f->audioProperties()->compressionName()); + + delete f; } }; diff --git a/tests/test_fileref.cpp b/tests/test_fileref.cpp index 692013e6..f77a434c 100644 --- a/tests/test_fileref.cpp +++ b/tests/test_fileref.cpp @@ -27,6 +27,8 @@ class TestFileRef : public CppUnit::TestFixture CPPUNIT_TEST(testTrueAudio); CPPUNIT_TEST(testAPE); CPPUNIT_TEST(testWav); + CPPUNIT_TEST(testAIFF); + CPPUNIT_TEST(testAIFC); CPPUNIT_TEST(testUnsupported); CPPUNIT_TEST_SUITE_END(); @@ -155,6 +157,16 @@ public: fileRefSave("empty", ".wav"); } + void testAIFF() + { + fileRefSave("empty", ".aiff"); + } + + void testAIFC() + { + fileRefSave("alaw", ".aifc"); + } + void testOGA_FLAC() { FileRef *f = new FileRef(TEST_FILE_PATH_C("empty_flac.oga")); diff --git a/tests/test_wav.cpp b/tests/test_wav.cpp index d17ce2cc..e42bc916 100644 --- a/tests/test_wav.cpp +++ b/tests/test_wav.cpp @@ -14,6 +14,7 @@ class TestWAV : public CppUnit::TestFixture CPPUNIT_TEST_SUITE(TestWAV); CPPUNIT_TEST(testLength); CPPUNIT_TEST(testZeroSizeDataChunk); + CPPUNIT_TEST(testFormat); CPPUNIT_TEST_SUITE_END(); public: @@ -30,6 +31,17 @@ public: RIFF::WAV::File f(TEST_FILE_PATH_C("zero-size-chunk.wav")); CPPUNIT_ASSERT_EQUAL(false, f.isValid()); } + + void testFormat() + { + RIFF::WAV::File f1(TEST_FILE_PATH_C("empty.wav")); + CPPUNIT_ASSERT_EQUAL(true, f1.isValid()); + CPPUNIT_ASSERT_EQUAL((uint)1, f1.audioProperties()->format()); + + RIFF::WAV::File f2(TEST_FILE_PATH_C("alaw.wav")); + CPPUNIT_ASSERT_EQUAL(true, f2.isValid()); + CPPUNIT_ASSERT_EQUAL((uint)6, f2.audioProperties()->format()); + } };