If you turn first to the ID3v2.2 specification, you’ll see that the basic structure of the tag is this header:
followed by frame data and padding. Since you’ve already defined binary types to read and write all the fields in the header, defining a class that can read the header of an ID3 tag is just a matter of putting them together.
((identifier (iso-8859-1-string :length 3))
(major-version u1)
(revision u1)
(flags u1)
(size id3-tag-size)))
(defun read-id3 (file)
(read-value 'id3-tag in)))
On top of this function you can build a function that takes a filename and prints the information in the tag header along with the name of the file.
It prints output that looks like this:
ID3 2.0 00000000 2165 bytes -- Kitka/Wintersongs/02 Byla Cesta.mp3
NIL
(defun mp3-p (file)
(and
(not (directory-pathname-p file))
Then you can combine show-tag-header
and with walk-directory
to print a summary of the ID3 header in each file under a given directory.
However, if you have a lot of MP3s, you may just want a count of how many ID3 tags of each version you have in your MP3 collection. To get that information, you might write a function like this:
(defun count-versions (dir)
(let ((versions (mapcar #'(lambda (x) (cons x 0)) '(2 3 4))))
(flet ((count-version (file)
(incf (cdr (assoc (major-version (read-id3 file)) versions)))))
(walk-directory dir #'count-version :test #'mp3-p))
versions))
(defun id3-p (file)