]> granicus.if.org Git - taglib/commitdiff
Add a tool to inspect audio files, only MP4 is implemented for now
authorLukáš Lalinský <lalinsky@gmail.com>
Sun, 11 Nov 2012 15:43:36 +0000 (16:43 +0100)
committerLukáš Lalinský <lalinsky@gmail.com>
Sun, 11 Nov 2012 15:43:36 +0000 (16:43 +0100)
16 files changed:
examples/CMakeLists.txt
examples/inspect.cpp [new file with mode: 0644]
taglib/audioproperties.cpp
taglib/audioproperties.h
taglib/mp4/mp4file.cpp
taglib/mp4/mp4file.h
taglib/mp4/mp4item.cpp
taglib/mp4/mp4item.h
taglib/mp4/mp4properties.cpp
taglib/mp4/mp4properties.h
taglib/mp4/mp4tag.cpp
taglib/mp4/mp4tag.h
taglib/tag.cpp
taglib/tag.h
taglib/toolkit/tfile.cpp
taglib/toolkit/tfile.h

index 17d4bd6bc8a693ab2da147a18b8cd3270b3cd9a6..7812d2e9639d7a1db926713f1b689871e4690a90 100644 (file)
@@ -5,6 +5,7 @@ INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/../taglib
                     ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpeg
                     ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpeg/id3v1
                     ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpeg/id3v2
+                    ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mp4
                     ${CMAKE_CURRENT_SOURCE_DIR}/../bindings/c/  )
 
 if(ENABLE_STATIC)
@@ -46,5 +47,12 @@ ADD_EXECUTABLE(strip-id3v1 strip-id3v1.cpp)
 TARGET_LINK_LIBRARIES(strip-id3v1  tag )
 
 
+########### next target ###############
+
+ADD_EXECUTABLE(inspect inspect.cpp)
+
+TARGET_LINK_LIBRARIES(inspect  tag )
+
+
 endif(BUILD_EXAMPLES)
 
diff --git a/examples/inspect.cpp b/examples/inspect.cpp
new file mode 100644 (file)
index 0000000..90a94db
--- /dev/null
@@ -0,0 +1,61 @@
+/* Copyright (C) 2012 Lukas Lalinsky <lalinsky@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <iostream>
+#include <stdlib.h>
+
+#include <fileref.h>
+#include <mp4file.h>
+
+using namespace std;
+using namespace TagLib;
+
+#define MAYBE_PRINT_DESC(_Type) \
+    if(dynamic_cast<_Type *>(f.file())) { \
+      cout << dynamic_cast<_Type *>(f.file())->toString().to8Bit(true) << endl; \
+      found = 1; \
+    }
+
+int main(int argc, char *argv[])
+{
+  // process the command line args
+
+  for(int i = 1; i < argc; i++) {
+
+    cout << "******************** \"" << argv[i] << "\"********************" << endl;
+
+    FileRef f(argv[i]);
+
+    bool found = 0;
+    if(!f.isNull() && f.file()) {
+      MAYBE_PRINT_DESC(MP4::File);
+      MAYBE_PRINT_DESC(File);
+    }
+
+    if(!found) {
+      cout << "could not find any information about the file" << endl;
+    }
+
+  }
+}
index 298b97da12973e2693435eee042ddf2656052e56..5b25867b09684d2c0d89778d91441698dfbde146 100644 (file)
@@ -24,6 +24,7 @@
  ***************************************************************************/
 
 #include "audioproperties.h"
+#include "tstringlist.h"
 
 using namespace TagLib;
 
@@ -49,3 +50,13 @@ AudioProperties::AudioProperties(ReadStyle)
 {
 
 }
+
+String
+AudioProperties::toString() const
+{
+  StringList desc;
+  desc.append("Audio");
+  desc.append(String::number(length()) + " seconds");
+  desc.append(String::number(bitrate()) + " kbps");
+  return desc.toString(", ");
+}
index e9844fa0c77b5bbd03b12a299050a5ef77762cdf..12400b9fb2e3e6ed5b3fb0e7baa69a0ca25ce901 100644 (file)
@@ -27,6 +27,7 @@
 #define TAGLIB_AUDIOPROPERTIES_H
 
 #include "taglib_export.h"
+#include "tstring.h"
 
 namespace TagLib {
 
@@ -86,6 +87,8 @@ namespace TagLib {
      */
     virtual int channels() const = 0;
 
+    String toString() const;
+
   protected:
 
     /*!
index a95432117dd84280186a33c5ec42ed1bcbd6b94b..8d6a99a311ad82f92c014f410373d4377526982d 100644 (file)
@@ -149,3 +149,16 @@ MP4::File::save()
   return d->tag->save();
 }
 
+String
+MP4::File::toString() const
+{
+  StringList desc;
+  if(d->properties) {
+    desc.append(d->properties->toString());
+  }
+  if(d->tag) {
+    desc.append(d->tag->toString());
+  }
+  return desc.toString("\n");
+}
+
index 2ed3bea581e087b0bb089a930aaf37ca793201d2..d8468490ff6c4992cfdf14590f3ab2b7473553c4 100644 (file)
@@ -100,6 +100,11 @@ namespace TagLib {
        */
       bool save();
 
+      /*!
+       * Description of the file.
+       */
+      String toString() const;
+
     private:
 
       void read(bool readProperties, Properties::ReadStyle audioPropertiesStyle);
index af2cc65c80de9f06e3da1fcf27b50679c2004ba3..4ed11a270b37e307cce88e06fa6de3fdc4904a0e 100644 (file)
@@ -26,6 +26,7 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
+#include <stdio.h>
 
 #include <taglib.h>
 #include <tdebug.h>
@@ -36,10 +37,11 @@ using namespace TagLib;
 class MP4::Item::ItemPrivate : public RefCounter
 {
 public:
-  ItemPrivate() : RefCounter(), valid(true), atomDataType(TypeUndefined) {}
+  ItemPrivate() : RefCounter(), valid(true), atomDataType(MP4::TypeUndefined), type(MP4::Item::TypeUndefined) {}
 
   bool valid;
   AtomDataType atomDataType;
+  ItemType type;
   union {
     bool m_bool;
     int m_int;
@@ -86,30 +88,35 @@ MP4::Item::Item(bool value)
 {
   d = new ItemPrivate;
   d->m_bool = value;
+  d->type = TypeBool;
 }
 
 MP4::Item::Item(int value)
 {
   d = new ItemPrivate;
   d->m_int = value;
+  d->type = TypeInt;
 }
 
 MP4::Item::Item(uchar value)
 {
   d = new ItemPrivate;
   d->m_byte = value;
+  d->type = TypeByte;
 }
 
 MP4::Item::Item(uint value)
 {
   d = new ItemPrivate;
   d->m_uint = value;
+  d->type = TypeUInt;
 }
 
 MP4::Item::Item(long long value)
 {
   d = new ItemPrivate;
   d->m_longlong = value;
+  d->type = TypeLongLong;
 }
 
 MP4::Item::Item(int value1, int value2)
@@ -117,24 +124,28 @@ MP4::Item::Item(int value1, int value2)
   d = new ItemPrivate;
   d->m_intPair.first = value1;
   d->m_intPair.second = value2;
+  d->type = TypeIntPair;
 }
 
 MP4::Item::Item(const ByteVectorList &value)
 {
   d = new ItemPrivate;
   d->m_byteVectorList = value;
+  d->type = TypeByteVectorList;
 }
 
 MP4::Item::Item(const StringList &value)
 {
   d = new ItemPrivate;
   d->m_stringList = value;
+  d->type = TypeStringList;
 }
 
 MP4::Item::Item(const MP4::CoverArtList &value)
 {
   d = new ItemPrivate;
   d->m_coverArtList = value;
+  d->type = TypeCoverArtList;
 }
 
 void MP4::Item::setAtomDataType(MP4::AtomDataType type)
@@ -207,3 +218,46 @@ MP4::Item::isValid() const
   return d->valid;
 }
 
+String
+MP4::Item::toString() const
+{
+  StringList desc;
+  char tmp[256];
+  switch (d->type) {
+    case TypeBool:
+      return d->m_bool ? "true" : "false";
+    case TypeInt:
+      sprintf(tmp, "%d", d->m_int);
+      return tmp;
+    case TypeIntPair:
+      sprintf(tmp, "%d/%d", d->m_intPair.first, d->m_intPair.second);
+      return tmp;
+    case TypeByte:
+      sprintf(tmp, "%d", d->m_byte);
+      return tmp;
+    case TypeUInt:
+      sprintf(tmp, "%u", d->m_uint);
+      return tmp;
+    case TypeLongLong:
+      sprintf(tmp, "%lld", d->m_longlong);
+      return tmp;
+    case TypeStringList:
+      return d->m_stringList.toString(" / ");
+    case TypeByteVectorList:
+      for(int i = 0; i < d->m_byteVectorList.size(); i++) {
+        sprintf(tmp, "[%d bytes of data]", d->m_byteVectorList[i].size());
+        desc.append(tmp);
+      }
+      return desc.toString(", ");
+    case TypeCoverArtList:
+      for(int i = 0; i < d->m_coverArtList.size(); i++) {
+        sprintf(tmp, "[%d bytes of data]", d->m_coverArtList[i].data().size());
+        desc.append(tmp);
+      }
+      return desc.toString(", ");
+    case TypeUndefined:
+      return "[unknown]";
+  }
+  return String();
+}
+
index be7aa1a17fc11760f424d8f2fc8bdf9922b367d4..d97c983403605142443ca2b10eb268115645ee1c 100644 (file)
@@ -41,6 +41,19 @@ namespace TagLib {
         int first, second;
       };
 
+      enum ItemType {
+        TypeUndefined = 0,
+        TypeBool,
+        TypeInt,
+        TypeIntPair,
+        TypeByte,
+        TypeUInt,
+        TypeLongLong,
+        TypeStringList,
+        TypeByteVectorList,
+        TypeCoverArtList,
+      };
+
       Item();
       Item(const Item &item);
       Item &operator=(const Item &item);
@@ -69,8 +82,12 @@ namespace TagLib {
       ByteVectorList toByteVectorList() const;
       CoverArtList toCoverArtList() const;
 
+      ItemType type() const;
+
       bool isValid() const;
 
+      String toString() const;
+
     private:
       class ItemPrivate;
       ItemPrivate *d;
index d2d04167c472b24c144cc752ad5b131826ca9cf7..35830bb9f1e04ab209864b26be5465958a1d43d4 100644 (file)
@@ -38,7 +38,13 @@ using namespace TagLib;
 class MP4::Properties::PropertiesPrivate
 {
 public:
-  PropertiesPrivate() : length(0), bitrate(0), sampleRate(0), channels(0), bitsPerSample(0), encrypted(false) {}
+  PropertiesPrivate() : length(0), bitrate(0), sampleRate(0), channels(0), bitsPerSample(0), encrypted(false), format(Unknown) {}
+
+  enum Format {
+    Unknown = 0,
+    AAC = 1,
+    ALAC = 2,
+  };
 
   int length;
   int bitrate;
@@ -46,6 +52,7 @@ public:
   int channels;
   int bitsPerSample;
   bool encrypted;
+  Format format;
 };
 
 MP4::Properties::Properties(File *file, MP4::Atoms *atoms, ReadStyle style)
@@ -118,6 +125,7 @@ MP4::Properties::Properties(File *file, MP4::Atoms *atoms, ReadStyle style)
   file->seek(atom->offset);
   data = file->readBlock(atom->length);
   if(data.mid(20, 4) == "mp4a") {
+    d->format = PropertiesPrivate::AAC;
     d->channels = data.mid(40, 2).toShort();
     d->bitsPerSample = data.mid(42, 2).toShort();
     d->sampleRate = data.mid(46, 4).toUInt();
@@ -138,6 +146,7 @@ MP4::Properties::Properties(File *file, MP4::Atoms *atoms, ReadStyle style)
     }
   }
   else if (data.mid(20, 4) == "alac") {
+    d->format = PropertiesPrivate::ALAC;
     if (atom->length == 88 && data.mid(56, 4) == "alac") {
       d->bitsPerSample = data.at(69);
       d->channels = data.at(73);
@@ -193,3 +202,23 @@ MP4::Properties::isEncrypted() const
   return d->encrypted;
 }
 
+String
+MP4::Properties::toString() const
+{
+  String format;
+  if(d->format == PropertiesPrivate::AAC) {
+    format = "AAC";
+  }
+  else if(d->format == PropertiesPrivate::ALAC) {
+    format = "ALAC";
+  }
+  else {
+    format = "Unknown";
+  }
+  StringList desc;
+  desc.append("MPEG-4 audio (" + format + ")");
+  desc.append(String::number(length()) + " seconds");
+  desc.append(String::number(bitrate()) + " kbps");
+  return desc.toString(", ");
+}
+
index 7906824d8f450a04b00d2e8ccde3ff0bfaf7808f..0f12f934134beb00670eceb4affa14cc92a6cb61 100644 (file)
@@ -50,6 +50,8 @@ namespace TagLib {
       virtual int bitsPerSample() const;
       bool isEncrypted() const;
 
+      String toString() const;
+
     private:
       class PropertiesPrivate;
       PropertiesPrivate *d;
index afecf98ad5f99c793cea813392f36ca4816d6666..24693fe091e7b90a20d2571e8147432c1cc3074b 100644 (file)
@@ -759,3 +759,13 @@ MP4::Tag::itemListMap()
   return d->items;
 }
 
+String
+MP4::Tag::toString() const
+{
+  StringList desc;
+  for(MP4::ItemListMap::Iterator i = d->items.begin(); i != d->items.end(); i++) {
+    desc.append(i->first + "=" + i->second.toString());
+  }
+  return desc.toString("\n");
+}
+
index b5ea6ebbc5ef9e7f824fd2fea8474ca6745ce08e..2270432cca598edae38e68a3a96c22c245e3c60c 100644 (file)
@@ -67,6 +67,8 @@ namespace TagLib {
 
         ItemListMap &itemListMap();
 
+        String toString() const;
+
     private:
         AtomDataList parseData2(Atom *atom, TagLib::File *file, int expectedFlags = -1, bool freeForm = false);
         TagLib::ByteVectorList parseData(Atom *atom, TagLib::File *file, int expectedFlags = -1, bool freeForm = false);
index 676340817b4bf792453beb5f9a29c177cef0c0de..17dcca5c15146cf8b56d380caa7004d98f63ee43 100644 (file)
@@ -178,3 +178,17 @@ void Tag::duplicate(const Tag *source, Tag *target, bool overwrite) // static
       target->setTrack(source->track());
   }
 }
+
+String Tag::toString() const
+{
+  StringList desc;
+  desc.append("title=" + title());
+  desc.append("artist=" + artist());
+  desc.append("album=" + album());
+  desc.append("comment=" + comment());
+  desc.append("genre=" + genre());
+  desc.append("year=" + String::number(year()));
+  desc.append("track=" + String::number(track()));
+  return desc.toString("\n");
+}
+
index 76c9a82af1c9ea841d97a1aac8615df0698f2cfe..43337a74c759f8837747a0c3982d03feef448979 100644 (file)
@@ -182,6 +182,8 @@ namespace TagLib {
      */
     static void duplicate(const Tag *source, Tag *target, bool overwrite = true);
 
+    String toString() const;
+
   protected:
     /*!
      * Construct a Tag.  This is protected since tags should only be instantiated
index 8d7ccdc95279e17ce775f05bb11e6c22fa681f39..3d7c188548aa8f6bd1500426a36707890d38895d 100644 (file)
@@ -489,6 +489,20 @@ bool File::isWritable(const char *file)
 
 }
 
+String File::toString() const
+{
+  StringList desc;
+  AudioProperties *properties = audioProperties();
+  if(properties) {
+    desc.append(properties->toString());
+  }
+  Tag *t = tag();
+  if(t) {
+    desc.append(t->toString());
+  }
+  return desc.toString("\n");
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // protected members
 ////////////////////////////////////////////////////////////////////////////////
index 7e6f2b9369cea060745a52de6f88f6e43ba821b1..a7cd2d09bf51ef9f719ea75791fbb19b90afdd91 100644 (file)
@@ -247,6 +247,11 @@ namespace TagLib {
      */
     static bool isWritable(const char *name);
 
+    /*!
+     * Description of the file.
+     */
+    String toString() const;
+
   protected:
     /*!
      * Construct a File object and opens the \a file.  \a file should be a