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.

    1. ((identifier (iso-8859-1-string :length 3))
    2. (major-version u1)
    3. (revision u1)
    4. (flags u1)
    5. (size id3-tag-size)))
    1. (defun read-id3 (file)
    2. (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:

    1. ID3 2.0 00000000 2165 bytes -- Kitka/Wintersongs/02 Byla Cesta.mp3
    2. NIL
    1. (defun mp3-p (file)
    2. (and
    3. (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:

    1. (defun count-versions (dir)
    2. (let ((versions (mapcar #'(lambda (x) (cons x 0)) '(2 3 4))))
    3. (flet ((count-version (file)
    4. (incf (cdr (assoc (major-version (read-id3 file)) versions)))))
    5. (walk-directory dir #'count-version :test #'mp3-p))
    6. versions))
    1. (defun id3-p (file)