From: Tsuda Kageyu <tsuda.kageyu@gmail.com> Date: Thu, 21 May 2015 02:37:45 +0000 (+0900) Subject: ASF: AudioProperties improvements X-Git-Tag: v1.10beta~47^2~6 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ff36648e92d1ce12a6be1f46f783d94014b80d6b;p=taglib ASF: AudioProperties improvements Add lengthInSeconds(), lengthInMilliseconds() properties. (#503) Add bitsPerSample() property. (#360) Add some tests for audio properties. Add some supplementary comments. --- diff --git a/taglib/asf/asffile.cpp b/taglib/asf/asffile.cpp index 452b28fe..e8414ff4 100644 --- a/taglib/asf/asffile.cpp +++ b/taglib/asf/asffile.cpp @@ -186,8 +186,14 @@ ByteVector ASF::File::FilePropertiesObject::guid() void ASF::File::FilePropertiesObject::parse(ASF::File *file, uint size) { BaseObject::parse(file, size); - file->d->properties->setLength( - (int)(data.toLongLong(40, false) / 10000000L - data.toLongLong(56, false) / 1000L)); + if(data.size() < 64) { + debug("ASF::File::FilePropertiesObject::parse() -- data is too short."); + return; + } + + const long long duration = data.toLongLong(40, false); + const long long preroll = data.toLongLong(56, false); + file->d->properties->setLengthInMilliseconds(static_cast<int>(duration / 10000.0 - preroll + 0.5)); } ByteVector ASF::File::StreamPropertiesObject::guid() @@ -198,9 +204,15 @@ ByteVector ASF::File::StreamPropertiesObject::guid() void ASF::File::StreamPropertiesObject::parse(ASF::File *file, uint size) { BaseObject::parse(file, size); - file->d->properties->setChannels(data.toShort(56, false)); + if(data.size() < 70) { + debug("ASF::File::StreamPropertiesObject::parse() -- data is too short."); + return; + } + + file->d->properties->setChannels(data.toUShort(56, false)); file->d->properties->setSampleRate(data.toUInt(58, false)); - file->d->properties->setBitrate(data.toUInt(62, false) * 8 / 1000); + file->d->properties->setBitrate(static_cast<int>(data.toUInt(62, false) * 8.0 / 1000.0 + 0.5)); + file->d->properties->setBitsPerSample(data.toUShort(68, false)); } ByteVector ASF::File::ContentDescriptionObject::guid() diff --git a/taglib/asf/asfproperties.cpp b/taglib/asf/asfproperties.cpp index acec09d2..1b7c6ec1 100644 --- a/taglib/asf/asfproperties.cpp +++ b/taglib/asf/asfproperties.cpp @@ -32,11 +32,19 @@ using namespace TagLib; class ASF::Properties::PropertiesPrivate { public: - PropertiesPrivate(): length(0), bitrate(0), sampleRate(0), channels(0), encrypted(false) {} + PropertiesPrivate() : + length(0), + bitrate(0), + sampleRate(0), + channels(0), + bitsPerSample(0), + encrypted(false) {} + int length; int bitrate; int sampleRate; int channels; + int bitsPerSample; bool encrypted; }; @@ -44,9 +52,10 @@ public: // public members //////////////////////////////////////////////////////////////////////////////// -ASF::Properties::Properties() : AudioProperties(AudioProperties::Average) +ASF::Properties::Properties() : + AudioProperties(AudioProperties::Average), + d(new PropertiesPrivate()) { - d = new PropertiesPrivate; } ASF::Properties::~Properties() @@ -55,6 +64,16 @@ ASF::Properties::~Properties() } int ASF::Properties::length() const +{ + return lengthInSeconds(); +} + +int ASF::Properties::lengthInSeconds() const +{ + return d->length / 1000; +} + +int ASF::Properties::lengthInMilliseconds() const { return d->length; } @@ -74,6 +93,11 @@ int ASF::Properties::channels() const return d->channels; } +int ASF::Properties::bitsPerSample() const +{ + return d->bitsPerSample; +} + bool ASF::Properties::isEncrypted() const { return d->encrypted; @@ -83,28 +107,37 @@ bool ASF::Properties::isEncrypted() const // private members //////////////////////////////////////////////////////////////////////////////// -void ASF::Properties::setLength(int length) +void ASF::Properties::setLength(int /*length*/) { - d->length = length; + debug("ASF::Properties::setLength() -- This method is deprecated. Do not use."); } -void ASF::Properties::setBitrate(int length) +void ASF::Properties::setLengthInMilliseconds(int value) { - d->bitrate = length; + d->length = value; } -void ASF::Properties::setSampleRate(int length) +void ASF::Properties::setBitrate(int value) { - d->sampleRate = length; + d->bitrate = value; } -void ASF::Properties::setChannels(int length) +void ASF::Properties::setSampleRate(int value) { - d->channels = length; + d->sampleRate = value; } -void ASF::Properties::setEncrypted(bool encrypted) +void ASF::Properties::setChannels(int value) { - d->encrypted = encrypted; + d->channels = value; } +void ASF::Properties::setBitsPerSample(int value) +{ + d->bitsPerSample = value; +} + +void ASF::Properties::setEncrypted(bool value) +{ + d->encrypted = value; +} diff --git a/taglib/asf/asfproperties.h b/taglib/asf/asfproperties.h index 95730d8e..5275aa1a 100644 --- a/taglib/asf/asfproperties.h +++ b/taglib/asf/asfproperties.h @@ -49,18 +49,66 @@ namespace TagLib { */ virtual ~Properties(); - // Reimplementations. + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \note This method is just an alias of lengthInSeconds(). + * + * \deprecated + */ virtual int length() const; + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \see lengthInMilliseconds() + */ + // BIC: make virtual + int lengthInSeconds() const; + + /*! + * Returns the length of the file in milliseconds. + * + * \see lengthInSeconds() + */ + // BIC: make virtual + int lengthInMilliseconds() const; + + /*! + * Returns the average bit rate of the file in kb/s. + */ virtual int bitrate() const; + + /*! + * Returns the sample rate in Hz. + */ virtual int sampleRate() const; + /*! + * Returns the number of audio channels. + */ virtual int channels() const; + + /*! + * Returns the number of bits per audio sample. + */ + int bitsPerSample() const; + + /*! + * Returns whether or not the file is encrypted. + */ bool isEncrypted() const; #ifndef DO_NOT_DOCUMENT + // deprecated void setLength(int value); + + void setLengthInMilliseconds(int value); void setBitrate(int value); void setSampleRate(int value); void setChannels(int value); + void setBitsPerSample(int value); void setEncrypted(bool value); #endif diff --git a/tests/test_asf.cpp b/tests/test_asf.cpp index 21c35324..82df4d1d 100644 --- a/tests/test_asf.cpp +++ b/tests/test_asf.cpp @@ -31,10 +31,15 @@ public: void testAudioProperties() { ASF::File f(TEST_FILE_PATH_C("silence-1.wma")); - CPPUNIT_ASSERT_EQUAL(4, f.audioProperties()->length()); + CPPUNIT_ASSERT(f.audioProperties()); + CPPUNIT_ASSERT_EQUAL(3, f.audioProperties()->length()); + CPPUNIT_ASSERT_EQUAL(3, f.audioProperties()->lengthInSeconds()); + CPPUNIT_ASSERT_EQUAL(3712, f.audioProperties()->lengthInMilliseconds()); CPPUNIT_ASSERT_EQUAL(64, f.audioProperties()->bitrate()); CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->channels()); CPPUNIT_ASSERT_EQUAL(48000, f.audioProperties()->sampleRate()); + CPPUNIT_ASSERT_EQUAL(16, f.audioProperties()->bitsPerSample()); + CPPUNIT_ASSERT_EQUAL(false, f.audioProperties()->isEncrypted()); } void testRead()