From f3d8100c7bf12a7e4276eb8e35b625068f59995a Mon Sep 17 00:00:00 2001 From: Tsuda Kageyu Date: Thu, 21 May 2015 14:30:37 +0900 Subject: [PATCH 1/2] Ogg Opus: AudioProperties improvements Add lengthInSeconds(), lengthInMilliseconds() properties. (#503) Remove some data members which are not needed to carry. Add some tests for audio properties. Add some supplementary comments. --- taglib/ogg/opus/opusproperties.cpp | 40 +++++++++++++++++--------- taglib/ogg/opus/opusproperties.h | 46 +++++++++++++++++++++++++++--- tests/test_opus.cpp | 12 +++++--- 3 files changed, 76 insertions(+), 22 deletions(-) diff --git a/taglib/ogg/opus/opusproperties.cpp b/taglib/ogg/opus/opusproperties.cpp index f098921b..c8aff624 100644 --- a/taglib/ogg/opus/opusproperties.cpp +++ b/taglib/ogg/opus/opusproperties.cpp @@ -41,17 +41,13 @@ using namespace TagLib::Ogg; class Opus::Properties::PropertiesPrivate { public: - PropertiesPrivate(File *f, ReadStyle s) : - file(f), - style(s), + PropertiesPrivate() : length(0), bitrate(0), inputSampleRate(0), channels(0), opusVersion(0) {} - File *file; - ReadStyle style; int length; int bitrate; int inputSampleRate; @@ -63,10 +59,11 @@ public: // public members //////////////////////////////////////////////////////////////////////////////// -Opus::Properties::Properties(File *file, ReadStyle style) : AudioProperties(style) +Opus::Properties::Properties(File *file, ReadStyle style) : + AudioProperties(style), + d(new PropertiesPrivate()) { - d = new PropertiesPrivate(file, style); - read(); + read(file); } Opus::Properties::~Properties() @@ -75,6 +72,16 @@ Opus::Properties::~Properties() } int Opus::Properties::length() const +{ + return lengthInSeconds(); +} + +int Ogg::Opus::Properties::lengthInSeconds() const +{ + return d->length / 1000; +} + +int Ogg::Opus::Properties::lengthInMilliseconds() const { return d->length; } @@ -111,13 +118,13 @@ int Opus::Properties::opusVersion() const // private members //////////////////////////////////////////////////////////////////////////////// -void Opus::Properties::read() +void Opus::Properties::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; @@ -144,16 +151,21 @@ void Opus::Properties::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) { const long long start = first->absoluteGranularPosition(); const long long end = last->absoluteGranularPosition(); if(start >= 0 && end >= 0) { - d->length = (int)((end - start - preSkip) / 48000); - d->bitrate = (int)(d->file->length() * 8.0 / (1000.0 * d->length) + 0.5); + const long long frameCount = (end - start - preSkip); + + if(frameCount > 0) { + const double length = frameCount * 1000.0 / 48000.0; + d->length = static_cast(length + 0.5); + d->bitrate = static_cast(file->length() * 8.0 / length + 0.5); + } } else { debug("Opus::Properties::read() -- The PCM values for the start or " diff --git a/taglib/ogg/opus/opusproperties.h b/taglib/ogg/opus/opusproperties.h index 946f1675..be88b146 100644 --- a/taglib/ogg/opus/opusproperties.h +++ b/taglib/ogg/opus/opusproperties.h @@ -61,11 +61,49 @@ 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. + * + * \note Always returns 48000, because Opus can decode any stream at a + * sample rate of 8, 12, 16, 24, or 48 kHz, + */ virtual int sampleRate() const; + + /*! + * Returns the number of audio channels. + */ virtual int channels() const; /*! @@ -76,7 +114,7 @@ namespace TagLib { int inputSampleRate() const; /*! - * Returns the Opus version, currently "0" (as specified by the spec). + * Returns the Opus version, in the range 0...255. */ int opusVersion() const; @@ -84,7 +122,7 @@ namespace TagLib { Properties(const Properties &); Properties &operator=(const Properties &); - void read(); + void read(File *file); class PropertiesPrivate; PropertiesPrivate *d; diff --git a/tests/test_opus.cpp b/tests/test_opus.cpp index 18556241..73863bf8 100644 --- a/tests/test_opus.cpp +++ b/tests/test_opus.cpp @@ -12,21 +12,25 @@ using namespace TagLib; class TestOpus : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(TestOpus); - CPPUNIT_TEST(testProperties); + CPPUNIT_TEST(testAudioProperties); CPPUNIT_TEST(testReadComments); CPPUNIT_TEST(testWriteComments); CPPUNIT_TEST_SUITE_END(); public: - void testProperties() + void testAudioProperties() { Ogg::Opus::File f(TEST_FILE_PATH_C("correctness_gain_silent_output.opus")); + CPPUNIT_ASSERT(f.audioProperties()); CPPUNIT_ASSERT_EQUAL(7, f.audioProperties()->length()); - CPPUNIT_ASSERT_EQUAL(41, f.audioProperties()->bitrate()); + CPPUNIT_ASSERT_EQUAL(7, f.audioProperties()->lengthInSeconds()); + CPPUNIT_ASSERT_EQUAL(7737, f.audioProperties()->lengthInMilliseconds()); + CPPUNIT_ASSERT_EQUAL(37, f.audioProperties()->bitrate()); CPPUNIT_ASSERT_EQUAL(1, f.audioProperties()->channels()); CPPUNIT_ASSERT_EQUAL(48000, f.audioProperties()->sampleRate()); - CPPUNIT_ASSERT_EQUAL(48000, ((Ogg::Opus::Properties *)f.audioProperties())->inputSampleRate()); + CPPUNIT_ASSERT_EQUAL(48000, f.audioProperties()->inputSampleRate()); + CPPUNIT_ASSERT_EQUAL(1, f.audioProperties()->opusVersion()); } void testReadComments() From f729f863cd32748fb23421b4a7e486d454fdf269 Mon Sep 17 00:00:00 2001 From: Tsuda Kageyu Date: Sat, 1 Aug 2015 00:19:20 +0900 Subject: [PATCH 2/2] Opus: Remove unused formal parameters. --- taglib/ogg/opus/opusfile.cpp | 12 ++++++------ taglib/ogg/opus/opusfile.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/taglib/ogg/opus/opusfile.cpp b/taglib/ogg/opus/opusfile.cpp index cb81a32b..ca1a3873 100644 --- a/taglib/ogg/opus/opusfile.cpp +++ b/taglib/ogg/opus/opusfile.cpp @@ -59,20 +59,20 @@ public: // public members //////////////////////////////////////////////////////////////////////////////// -Opus::File::File(FileName file, bool readProperties, Properties::ReadStyle propertiesStyle) : +Opus::File::File(FileName file, bool readProperties, Properties::ReadStyle) : Ogg::File(file), d(new FilePrivate()) { if(isOpen()) - read(readProperties, propertiesStyle); + read(readProperties); } -Opus::File::File(IOStream *stream, bool readProperties, Properties::ReadStyle propertiesStyle) : +Opus::File::File(IOStream *stream, bool readProperties, Properties::ReadStyle) : Ogg::File(stream), d(new FilePrivate()) { if(isOpen()) - read(readProperties, propertiesStyle); + read(readProperties); } Opus::File::~File() @@ -114,7 +114,7 @@ bool Opus::File::save() // private members //////////////////////////////////////////////////////////////////////////////// -void Opus::File::read(bool readProperties, Properties::ReadStyle propertiesStyle) +void Opus::File::read(bool readProperties) { ByteVector opusHeaderData = packet(0); @@ -135,5 +135,5 @@ void Opus::File::read(bool readProperties, Properties::ReadStyle propertiesStyle d->comment = new Ogg::XiphComment(commentHeaderData.mid(8)); if(readProperties) - d->properties = new Properties(this, propertiesStyle); + d->properties = new Properties(this); } diff --git a/taglib/ogg/opus/opusfile.h b/taglib/ogg/opus/opusfile.h index 275167e4..2b86f3f3 100644 --- a/taglib/ogg/opus/opusfile.h +++ b/taglib/ogg/opus/opusfile.h @@ -112,7 +112,7 @@ namespace TagLib { File(const File &); File &operator=(const File &); - void read(bool readProperties, Properties::ReadStyle propertiesStyle); + void read(bool readProperties); class FilePrivate; FilePrivate *d;