]> granicus.if.org Git - taglib/commitdiff
Get all of the basic AIFF properties working.
authorScott Wheeler <wheeler@kde.org>
Fri, 16 May 2008 08:50:17 +0000 (08:50 +0000)
committerScott Wheeler <wheeler@kde.org>
Fri, 16 May 2008 08:50:17 +0000 (08:50 +0000)
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@808275 283d02a7-25f6-0310-bc7c-ecb5cbfe19da

taglib/riff/aiff/aifffile.cpp
taglib/riff/aiff/aiffproperties.cpp

index 2f2498b4102eb4ac91714461a2d41a0ebe445a5e..2afdd159545cd8f9805ed22b6ec25baba4af48f9 100644 (file)
@@ -39,6 +39,7 @@ class RIFF::AIFF::File::FilePrivate
 {
 public:
   FilePrivate() :
+    properties(0),
     tag(0)
   {
 
@@ -46,9 +47,11 @@ public:
 
   ~FilePrivate()
   {
+    delete properties;
     delete tag;
   }
 
+  Properties *properties;
   ID3v2::Tag *tag;
 };
 
@@ -76,7 +79,7 @@ ID3v2::Tag *RIFF::AIFF::File::tag() const
 
 RIFF::AIFF::Properties *RIFF::AIFF::File::audioProperties() const
 {
-  return 0;
+  return d->properties;
 }
 
 bool RIFF::AIFF::File::save()
@@ -95,11 +98,13 @@ bool RIFF::AIFF::File::save()
 // private members
 ////////////////////////////////////////////////////////////////////////////////
 
-void RIFF::AIFF::File::read(bool readProperties, Properties::ReadStyle /* propertiesStyle */)
+void RIFF::AIFF::File::read(bool readProperties, Properties::ReadStyle propertiesStyle)
 {
   for(uint i = 0; i < chunkCount(); i++) {
     if(chunkName(i) == "ID3 ")
       d->tag = new ID3v2::Tag(this, chunkOffset(i));
+    else if(chunkName(i) == "COMM" && readProperties)
+      d->properties = new Properties(chunkData(i), propertiesStyle);
   }
 
   if(!d->tag)
index dd4a52443327991d1cf2aad876686eec8639cb0a..df867fcc5f448e0eab5ecf80920b60a7cd4453a1 100644 (file)
 
 #include <tstring.h>
 #include <tdebug.h>
-#include <bitset>
+#include <cmath>
 
 #include "aiffproperties.h"
 
+////////////////////////////////////////////////////////////////////////////////
+// nasty 80-bit float helpers
+////////////////////////////////////////////////////////////////////////////////
+
+#define UnsignedToFloat(u) (((double)((long)(u - 2147483647L - 1))) + 2147483648.0)
+
+static double ConvertFromIeeeExtended(unsigned char *bytes)
+{
+  double f;
+  int expon;
+  unsigned long hiMant, loMant;
+    
+  expon  = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
+
+  hiMant = ((unsigned long)(bytes[2] & 0xFF) << 24) |
+           ((unsigned long)(bytes[3] & 0xFF) << 16) |
+           ((unsigned long)(bytes[4] & 0xFF) << 8)  |
+           ((unsigned long)(bytes[5] & 0xFF));
+
+  loMant = ((unsigned long)(bytes[6] & 0xFF) << 24) |
+           ((unsigned long)(bytes[7] & 0xFF) << 16) |
+           ((unsigned long)(bytes[8] & 0xFF) << 8)  |
+           ((unsigned long)(bytes[9] & 0xFF));
+
+  if (expon == 0 && hiMant == 0 && loMant == 0)
+    f = 0;
+  else {
+    if(expon == 0x7FFF) /* Infinity or NaN */
+      f = HUGE_VAL;
+    else {
+      expon -= 16383;
+      f  = ldexp(UnsignedToFloat(hiMant), expon -= 31);
+      f += ldexp(UnsignedToFloat(loMant), expon -= 32);
+    }
+  }
+
+  if(bytes[0] & 0x80)
+    return -f;
+  else
+    return f;
+}
+
 using namespace TagLib;
 
 class RIFF::AIFF::Properties::PropertiesPrivate
@@ -84,12 +126,17 @@ int RIFF::AIFF::Properties::channels() const
   return d->channels;
 }
 
-
 ////////////////////////////////////////////////////////////////////////////////
 // private members
 ////////////////////////////////////////////////////////////////////////////////
 
 void RIFF::AIFF::Properties::read(const ByteVector &data)
 {
-
+  d->channels       = data.mid(0, 2).toShort();
+  uint sampleFrames = data.mid(2, 4).toUInt();
+  short sampleSize  = data.mid(6, 2).toShort();
+  double sampleRate = ConvertFromIeeeExtended(reinterpret_cast<unsigned char *>(data.mid(8, 10).data()));
+  d->sampleRate     = sampleRate;
+  d->bitrate        = (sampleRate * sampleSize * d->channels) / 1024.0;
+  d->length         = sampleFrames / d->sampleRate;
 }