anchor.diff:              (make-mp4-atom mp4-file me))))
   
   ;;;; ILST ATOMS (ie atoms related to tagging)
  -(defclass |atom-ilst| (mp4-container-atom) ())
  +;(defclass |atom-ilst| (atom-container) ())
   
   (eval-when (:compile-toplevel :load-toplevel :execute)
  -  (defparameter *ilst-atoms*
  -    '(("account-type"      "akID")
  -      ("album"             "©alb")
  -      ("album-artist"      "aART")
  -      ("artist"            "©ART")
  -      ("at-id"             "atID")
  -      ("cn-id"             "cnID")
  -      ("comment"           "©cmt")
  -      ("compilation"       "cpil")
  -      ("composer"          "©com")
  -      ("content-rating"    "rtng")
  -      ("copyright"         "cprt")
  -      ("cover-art"         "covr")
  -      ("disk"              "disk")
  -      ("encoder"           "©enc")
  -      ("gapless-playback"  "pgap")
  -      ("ge-id"             "geID")
  -      ("genre"             "gnre")
  -      ("genre-x"           "©gen")
  -      ("groups"            "©grp")
  -      ("lyrics"            "©lyr")
  -      ("media-type"        "stik")
  -      ("purchase-account"  "apID")
  -      ("purchased-date"    "purd")
  -      ("sort-album"        "soal")
  -      ("sort-album-artist" "soaa")
  -      ("sort-artist"       "soar")
  -      ("sort-composer"     "soco")
  -      ("sort-name"         "sonm")
  -      ("store"             "sfID")
  -      ("tempo"             "tmpo")
  -      ("title"             "©nam")
  -      ("tool"              "©too")
  -      ("track"             "©trk")
  -      ("track-n"           "trkn")
  -      ("writer"            "©wrt")
  -      ("year"              "©day"))
  -    "This is the list of ILST atoms we handle. Each entry is constant-name/class-name")
  -
  -  (defmacro mk-ilst-atoms-constants ()
  +  (defun generate-it (name type super-class)
  +    (let ((class-name (if super-class
  +                          `(defclass ,(mksym nil "atom-" type) (,super-class) ())))
  +          (constant `(defconstant* ,(mksym t "+itunes-" name "+") ,type))
  +          (exported `(export ',(mksym t "+itunes-" name "+"))))
  +      `(progn ,constant ,exported ,class-name)))
  +
  +  (defmacro ncls-atom-entry (a b) `(list ,a ,b nil))             ; no superclass
  +  (defmacro ilst-atom-entry (a b) `(list ,a ,b '|atom-ilst|))    ; itunes tagging
  +  (defmacro skip-atom-entry (a b) `(list ,a ,b 'atom-skip))      ; read and skip
  +  (defmacro cont-atom-entry (a b) `(list ,a ,b 'atom-container)) ; contains other atoms, but no data
  +
  +  (defparameter *handled-atoms*
  +    (list (ncls-atom-entry "root"                         "ROOT") ; pseudo-atom
  +          (ncls-atom-entry "ilst-data"                    "data")
  +          (ncls-atom-entry "atom-handler"                 "hdlr")
  +          (ncls-atom-entry "media-header"                 "mdhd")
  +          (ncls-atom-entry "sample-table-desc"            "stsd")
  +          (ncls-atom-entry "mp4a-codec"                   "mp4a")
  +          (ncls-atom-entry "elementary-stream-descriptor" "esds")
  +          (ncls-atom-entry "item-list"                    "ilst")
  +          (ncls-atom-entry "metadata"                     "meta")
  +
  +          (ilst-atom-entry "account-type"                 "akID")
  +          (ilst-atom-entry "album"                        "©alb")
  +          (ilst-atom-entry "album-artist"                 "aART")
  +          (ilst-atom-entry "artist"                       "©ART")
  +          (ilst-atom-entry "at-id"                        "atID")
  +          (ilst-atom-entry "cn-id"                        "cnID")
  +          (ilst-atom-entry "comment"                      "©cmt")
  +          (ilst-atom-entry "compilation"                  "cpil")
  +          (ilst-atom-entry "composer"                     "©com")
  +          (ilst-atom-entry "content-rating"               "rtng")
  +          (ilst-atom-entry "copyright"                    "cprt")
  +          (ilst-atom-entry "cover-art"                    "covr")
  +          (ilst-atom-entry "disk"                         "disk")
  +          (ilst-atom-entry "encoder"                      "©enc")
  +          (ilst-atom-entry "flavor"                       "flvr")
  +          (ilst-atom-entry "gapless-playback"             "pgap")
  +          (ilst-atom-entry "ge-id"                        "geID")
  +          (ilst-atom-entry "genre"                        "gnre")
  +          (ilst-atom-entry "genre-x"                      "©gen")
  +          (ilst-atom-entry "groups"                       "©grp")
  +          (ilst-atom-entry "lyrics"                       "©lyr")
  +          (ilst-atom-entry "media-type"                   "stik")
  +          (ilst-atom-entry "purchase-account"             "apID")
  +          (ilst-atom-entry "purchased-date"               "purd")
  +          (ilst-atom-entry "sort-album"                   "soal")
  +          (ilst-atom-entry "sort-album-artist"            "soaa")
  +          (ilst-atom-entry "sort-artist"                  "soar")
  +          (ilst-atom-entry "sort-composer"                "soco")
  +          (ilst-atom-entry "sort-name"                    "sonm")
  +          (ilst-atom-entry "store"                        "sfID")
  +          (ilst-atom-entry "tempo"                        "tmpo")
  +          (ilst-atom-entry "title"                        "©nam")
  +          (ilst-atom-entry "tool"                         "©too")
  +          (ilst-atom-entry "track"                        "©trk")
  +          (ilst-atom-entry "track-n"                      "trkn")
  +          (ilst-atom-entry "writer"                       "©wrt")
  +          (ilst-atom-entry "unique-id"                    "xid ") ; Note: space at the end
  +          (ilst-atom-entry "year"                         "©day")
  +
  +          (skip-atom-entry "composer-id"                  "cmID")
  +          (skip-atom-entry "mean"                         "mean")
  +          (skip-atom-entry "data-ref-url"                 "url ")
  +          (skip-atom-entry "data-ref-alis"                "alis")
  +          (skip-atom-entry "data-ref-rsrc"                "rsrc")
  +          (skip-atom-entry "unk-drm"                      "drms")
  +          (skip-atom-entry "edit-atom"                    "edts")
  +          (skip-atom-entry "free"                         "free")
  +          (skip-atom-entry "file-type"                    "ftyp")
  +          (skip-atom-entry "unk-iods"                     "iods")
  +          (skip-atom-entry "media-data-atom"              "mdat")
  +          (skip-atom-entry "movie-header"                 "mvhd")
  +          (skip-atom-entry "name-atom"                    "name")
  +          (skip-atom-entry "unk-pinf"                     "pinf")
  +          (skip-atom-entry "play-list-id"                 "plID")
  +          (skip-atom-entry "unk-sbtd"                     "sbtd")
  +          (skip-atom-entry "sound-media-header"           "smhd")
  +          (skip-atom-entry "sample-table-chunk-offset"    "stco")
  +          (skip-atom-entry "sample-table-sample"          "stsc")
  +          (skip-atom-entry "sample-table-size"            "stsz")
  +          (skip-atom-entry "sample-table-time"            "stts")
  +          (skip-atom-entry "track-header"                 "tkhd")
  +
  +          (cont-atom-entry "free-form"                    "----")
  +          (cont-atom-entry "data-info"                    "dinf")
  +          (cont-atom-entry "item-list"                    "ilst")
  +          (cont-atom-entry "media"                        "mdia")
  +          (cont-atom-entry "media-info"                   "minf")
  +          (cont-atom-entry "movie"                        "moov")
  +          (cont-atom-entry "sample-table"                 "stbl")
  +          (cont-atom-entry "trak-header"                  "trak")
  +          (cont-atom-entry "user-data"                    "udta"))
  + "This is the list of atoms we 'handle', where 'handle' may well indeed mean to
  +skip or just define a constant. Each entry is constant-name/class-name.
  +From this data structure we auto-generate (optionally) class-names
  +and (always) defconstants.")
  +
  +  (defmacro mk-handled-atoms-constants-and-classes ()
       `(progn
  -       ,@(loop for e in *ilst-atoms*
  +       ,@(loop for e in *handled-atoms*
                  collect
  -               `(progn
  -                  (defclass ,(mksym nil "atom-" (second e)) (|atom-ilst|) ())
  -                  (defconstant* ,(mksym t "+itunes-" (first e) "+") ,(second e))
  -                  (export ',(mksym t "+itunes-" (first e) "+")))))))
  -
  -;;; generate the ilst atoms/constants/exports
  -(mk-ilst-atoms-constants)
  -
  +               (generate-it (first e) (second e) (third e))))))
  +
  +;;; generate the handled atoms/constants/exports
  +(mk-handled-atoms-constants-and-classes)
   
   (defclass |atom-data| (mp4-atom)
     ((atom-version :accessor atom-version :initarg :atom-version :initform nil)
  
positive.code:                               :atom-file-pos pos
                                :parent parent
                                :mp4-file mp4-file))
      atom))
  
  (defmethod vpprint ((me mp4-atom) stream)
    (declare #.utils:*standard-optimize-settings*)
  
    (format stream "~a"
            (with-output-to-string (s)
              (with-mp4-atom-slots (me)
                (format s "atom:: type: <~a> @ ~:d of size ~:d"
                        atom-type atom-file-pos atom-size))
              (if (typep me '|atom-data|)
                  (with-slots (atom-version atom-flags atom-value atom-type) me
                    (format s ", ilst fields: verison = ~d, flags = ~x, data = ~a"
                            atom-version atom-flags
                            (if (typep atom-value 'octets)
                                (printable-array atom-value)
                                atom-value)))))))
  
  (defun is-valid-m4-file (mp4-file)
    "Make sure this is an MP4 file.  Quick check: is first atom (at file-offset 4) == FSTYP?
  Written in this fashion so as to be 'crash-proof' when passed an arbitrary file."
    (declare #.utils:*standard-optimize-settings*)
  
    (let ((valid)
          (size)
          (header))
      (when (> (stream-size mp4-file) 8)
        (stream-seek mp4-file 0 :start)
        (setf size   (stream-read-u32 mp4-file)
              header (as-string (stream-read-u32 mp4-file))
              valid  (and (<= size (stream-size mp4-file))
                          (string= header +m4-ftyp+))))
      (stream-seek mp4-file 0 :start)
      valid))
  
  
negative.code:                :documentation "holds tree of parsed MP4 atoms/boxes")
     (audio-info :accessor audio-info :initform nil
                 :documentation "holds the bit-rate, etc info"))
    (:documentation "For parsing MP4 audio files"))
  
  (defun parse-audio-file (instream &optional (get-audio-info nil))
    "Given a valid MP4 file, look for the 'right' atoms and return them."
  