]> granicus.if.org Git - taglib/commitdiff
Added reading of WAV audio length
authorLukáš Lalinský <lalinsky@gmail.com>
Sun, 11 Jul 2010 09:47:58 +0000 (09:47 +0000)
committerLukáš Lalinský <lalinsky@gmail.com>
Sun, 11 Jul 2010 09:47:58 +0000 (09:47 +0000)
BUG:116033

git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1148614 283d02a7-25f6-0310-bc7c-ecb5cbfe19da

NEWS
taglib/riff/rifffile.cpp
taglib/riff/rifffile.h
taglib/riff/wav/wavfile.cpp
taglib/riff/wav/wavproperties.cpp
taglib/riff/wav/wavproperties.h
tests/CMakeLists.txt
tests/data/empty.wav [new file with mode: 0644]
tests/test_riff.cpp

diff --git a/NEWS b/NEWS
index 919641a1a34f8d3d5f454c828d1dbc0df54e140e..102ecda354736e437b1de41d37746fb0981583cb 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,10 @@
 TagLib 1.7
 ==========
 
- * Support for reading/writing tags from Monkey's Audio files.
+ * Support for reading/writing tags from Monkey's Audio files. (BUG:210404)
  * Implemented APE::Tag::isEmpty() to check for all APE tags, not just the
    basic ones.
+ * Added reading of WAV audio length. (BUG:116033)
 
 TagLib 1.6.3 (Apr 17, 2010)
 ===========================
index 595691f5dee3317dbea3a6f45eeaef733fdba7d5..270c3672c4380e4be0560b92f1a60622a7370f5d 100644 (file)
@@ -79,6 +79,11 @@ TagLib::uint RIFF::File::chunkCount() const
   return d->chunkNames.size();
 }
 
+TagLib::uint RIFF::File::chunkDataSize(uint i) const
+{
+  return d->chunkSizes[i];
+}
+
 TagLib::uint RIFF::File::chunkOffset(uint i) const
 {
   return d->chunkOffsets[i];
index 3b375e29e8f6e4adfedce5c153b1f96e9f1f7e19..2f8881d95435dfd55a2eb4771b4c9451e112c564 100644 (file)
@@ -67,6 +67,11 @@ namespace TagLib {
        */
       uint chunkOffset(uint i) const;
 
+      /*!
+       * \return The size of the chunk data.
+       */
+      uint chunkDataSize(uint i) const;
+
       /*!
        * \return The name of the specified chunk, for instance, "COMM" or "ID3 "
        */
index b2123ad5eb35ef5474408526c13cb9721f5ae12d..f323a27d31b7e293ec36f42d669e94cc1a3aace3 100644 (file)
@@ -96,13 +96,20 @@ bool RIFF::WAV::File::save()
 
 void RIFF::WAV::File::read(bool readProperties, Properties::ReadStyle propertiesStyle)
 {
+  ByteVector formatData;
+  uint streamLength = 0;
   for(uint i = 0; i < chunkCount(); i++) {
     if(chunkName(i) == "ID3 ")
       d->tag = new ID3v2::Tag(this, chunkOffset(i));
     else if(chunkName(i) == "fmt " && readProperties)
-      d->properties = new Properties(chunkData(i), propertiesStyle);
+      formatData = chunkData(i);
+    else if(chunkName(i) == "data" && readProperties)
+      streamLength = chunkDataSize(i);
   }
 
+  if(!formatData.isEmpty())
+    d->properties = new Properties(formatData, streamLength, propertiesStyle);
+
   if(!d->tag)
     d->tag = new ID3v2::Tag;
 }
index 18920dd22eedaac5f08cc7fbc8b16747d011f601..b0e4e034a0313e94f5dc94e878d0408819e51904 100644 (file)
@@ -35,12 +35,13 @@ using namespace TagLib;
 class RIFF::WAV::Properties::PropertiesPrivate
 {
 public:
-  PropertiesPrivate() :
+  PropertiesPrivate(uint streamLength = 0) :
     format(0),
     length(0),
     bitrate(0),
     sampleRate(0),
-    channels(0)
+    channels(0),
+       streamLength(streamLength)
   {
 
   }
@@ -50,6 +51,7 @@ public:
   int bitrate;
   int sampleRate;
   int channels;
+  uint streamLength;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -58,7 +60,13 @@ public:
 
 RIFF::WAV::Properties::Properties(const ByteVector &data, ReadStyle style) : AudioProperties(style)
 {
-  d = new PropertiesPrivate;
+  d = new PropertiesPrivate();
+  read(data);
+}
+
+RIFF::WAV::Properties::Properties(const ByteVector &data, uint streamLength, ReadStyle style) : AudioProperties(style)
+{
+  d = new PropertiesPrivate(streamLength);
   read(data);
 }
 
@@ -93,12 +101,12 @@ int RIFF::WAV::Properties::channels() const
 
 void RIFF::WAV::Properties::read(const ByteVector &data)
 {
-  d->format     = data.mid(0, 2).toShort(false);
-  d->channels   = data.mid(2, 2).toShort(false);
+  d->format = data.mid(0, 2).toShort(false);
+  d->channels = data.mid(2, 2).toShort(false);
   d->sampleRate = data.mid(4, 4).toUInt(false);
-  d->bitrate    = data.mid(8, 4).toUInt(false) * 8 / 1024;
 
-  // short bitsPerSample = data.mid(10, 2).toShort();
-  // d->bitrate    = (sampleRate * sampleSize * d->channels) / 1024.0;
-  // d->length     = sampleFrames / d->sampleRate;
+  uint byteRate = data.mid(8, 4).toUInt(false);
+  d->bitrate = byteRate * 8 / 1024;
+
+  d->length = byteRate > 0 ? d->streamLength / byteRate : 0;
 }
index 531f877f7ef990fd9ca9d8e2c6e2ebf04ff32362..10fbba1cf2729165eae3bf4fad4c78126e6361f5 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef TAGLIB_WAVPROPERTIES_H
 #define TAGLIB_WAVPROPERTIES_H
 
+#include "taglib.h"
 #include "audioproperties.h"
 
 namespace TagLib {
@@ -54,6 +55,12 @@ namespace TagLib {
         */
        Properties(const ByteVector &data, ReadStyle style);
 
+       /*!
+        * Create an instance of WAV::Properties with the data read from the
+        * ByteVector \a data and the length calculated using \a streamLength.
+        */
+       Properties(const ByteVector &data, uint streamLength, ReadStyle style);
+
        /*!
         * Destroys this WAV::Properties instance.
         */
index 136f9b63ec12a4ad4a5b319b3f0d8a2613f5c968..f5b80c6912a93e08d846751ec1db0ee638f5e276 100644 (file)
@@ -12,6 +12,7 @@ INCLUDE_DIRECTORIES(
   ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mp4
   ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/riff
   ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/riff/aiff
+  ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/riff/wav
   ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/trueaudio
   ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg
   ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg/vorbis
@@ -40,6 +41,7 @@ SET(test_runner_SRCS
   test_flac.cpp
   test_ape.cpp
   test_apetag.cpp
+  test_wav.cpp
 )
 IF(WITH_MP4)
    SET(test_runner_SRCS ${test_runner_SRCS}
diff --git a/tests/data/empty.wav b/tests/data/empty.wav
new file mode 100644 (file)
index 0000000..74b5a6d
Binary files /dev/null and b/tests/data/empty.wav differ
index ac7f40d71c095ae9f383d36d31772e7dcc2c23bd..20539ae1c97f7f7d4703eb1843c585ba4b77ef66 100644 (file)
@@ -15,6 +15,7 @@ public:
   PublicRIFF(FileName file) : RIFF::File(file, BigEndian) {};
   TagLib::uint chunkCount() { return RIFF::File::chunkCount(); };
   TagLib::uint chunkOffset(TagLib::uint i) { return RIFF::File::chunkOffset(i); };
+  TagLib::uint chunkDataSize(TagLib::uint i) { return RIFF::File::chunkDataSize(i); };
   ByteVector chunkName(TagLib::uint i) { return RIFF::File::chunkName(i); };
   ByteVector chunkData(TagLib::uint i) { return RIFF::File::chunkData(i); };
   void setChunkData(const ByteVector &name, const ByteVector &data) {
@@ -48,6 +49,7 @@ public:
     f = new PublicRIFF(filename.c_str());
     CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f->chunkName(2));
     CPPUNIT_ASSERT_EQUAL(ByteVector("foo"), f->chunkData(2));
+    CPPUNIT_ASSERT_EQUAL(TagLib::uint(3), f->chunkDataSize(2));
     CPPUNIT_ASSERT_EQUAL(TagLib::uint(0x1728 + 8), f->chunkOffset(2));
 
     f->setChunkData("SSND", "abcd");