ASF: AudioProperties improvements

Add lengthInSeconds(), lengthInMilliseconds() properties. (#503)
Add bitsPerSample() property. (#360)
Add some tests for audio properties.
Add some supplementary comments.
This commit is contained in:
Tsuda Kageyu 2015-05-21 11:37:45 +09:00
parent 447a4739c5
commit ff36648e92
4 changed files with 117 additions and 19 deletions

View File

@ -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()

View File

@ -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;
}

View File

@ -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

View File

@ -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()