Bladeren bron

changed package names to id3/flac/m4a

Mark VandenBrink 12 jaren geleden
bovenliggende
commit
bc1524ade3
10 gewijzigde bestanden met toevoegingen van 272 en 193 verwijderingen
  1. 4 4
      README.md
  2. 128 128
      abstract-tag.lisp
  3. 6 6
      audio-streams.lisp
  4. 2 2
      flac.lisp
  5. 16 5
      id3.lisp
  6. 16 5
      m4a.lisp
  7. 3 3
      mpeg.lisp
  8. 10 9
      packages.lisp
  9. 83 27
      taglib-tests.lisp
  10. 4 4
      taglib.asd

+ 4 - 4
README.md

@@ -114,8 +114,8 @@ Header: version/revision: 3/0, flags: 0x00: 0/0/0/0, size = 11,899 bytes; No ext
   simple array-references.  Under CCL, uses MAP-FILE-TO-OCTET-VECTOR function to mmap the file. Other Lisps just
   slurp in the whole file (probably should revisit this, but since we use displaced arrays for dissecting the file,
   this would require a rewrite.
-* __flac-frame.lisp:__ Parses FLAC files.
-* __id3-frame.lisp:__ Parses the ID3 frames in an MP3 file.
+* __flac.lisp:__ Parses FLAC files.
+* __id3.lisp:__ Parses the ID3 frames in an MP3 file.
    For each frame type we are interested in, DEFCLASS a class with
    specfic naming convention: frame-xxx/frame-xxxx, where xxx is valid ID3V2.2 frame name
    and xxxx is a valid ID3V2.[34] frame name.  Upon finding a frame name in an MP3 file,
@@ -149,7 +149,7 @@ Header: version/revision: 3/0, flags: 0x00: 0/0/0/0, size = 11,899 bytes; No ext
 	* __writer:__ Returns name of who wrote this song.
 	* __year:__ Returns the year when the song was recorded.
 
-* __mp4-atom.lisp:__ Parses MP4 audio files.  Similar logic to __id-frame.lisp__, but has two main differnces: first,
+* __m4a:__ Parses MP4 audio files.  Similar logic to __id-frame.lisp__, but has two main differnces: first,
   it returns a tree structure (needed, since, that's how M4A atoms/boxes work), and secondly, has an *atom-skip* class
   that records the name and position of an atom, but seeks to the next atom rather than reading in contents.
 
@@ -157,7 +157,7 @@ Header: version/revision: 3/0, flags: 0x00: 0/0/0/0, size = 11,899 bytes; No ext
     * Pure container atoms: have no data and are only used to contain other atoms.  This is akin to a UNIX filesystem's directory notion.
     * Pure "data" atoms: has no nested atoms.  Only has a payload.
     * A mixture of both.
-* __tree.lisp:__ The tree library (used by mp4-atom).  Adapted from code from [Jorge Gajon](http://gajon.org/trees-linked-lists-common-lisp/)
+* __tree.lisp:__ The tree library (used by m4a).  Adapted from code from [Jorge Gajon](http://gajon.org/trees-linked-lists-common-lisp/)
 * __mpeg.lisp:__ Parses the audio information (ie the non-ID3 info) in an MP3 file.
 * __packages.lisp:__ Holds all the package definitions.
 * __taglib-tests.asd:__ Contains build instructions for taglib-tests.lisp.  An ASDF file.

+ 128 - 128
abstract-tag.lisp

@@ -71,80 +71,80 @@ is > 0 and < (sizeof *ID3V1-GENRES*)"
 (defgeneric genre (stream))
 
 ;;;; MP3
-(defmethod cover ((me id3-frame:mp3-file))
+(defmethod cover ((me id3:mp3-file))
   (declare #.utils:*standard-optimize-settings*)
   (let ((pictures)
-        (frames (id3-frame:get-frames me '("PIC" "APIC"))))
+        (frames (id3:get-frames me '("PIC" "APIC"))))
     (when frames
       (dolist (f frames)
-        (push (id3-frame:picture-info f) pictures)))
+        (push (id3:picture-info f) pictures)))
     pictures))
 
-(defmethod album ((me id3-frame:mp3-file))
+(defmethod album ((me id3:mp3-file))
   (declare #.utils:*standard-optimize-settings*)
-  (let ((frames (id3-frame:get-frames me '("TAL" "TALB"))))
+  (let ((frames (id3:get-frames me '("TAL" "TALB"))))
     (when frames
       (assert (= 1 (length frames)) () "There can be only one album tag")
-      (return-from album (id3-frame:info (first frames)))))
-  (if (id3-frame:v21-tag-header (id3-frame:id3-header me))
-      (id3-frame:album (id3-frame:v21-tag-header (id3-frame:id3-header me)))
+      (return-from album (id3:info (first frames)))))
+  (if (id3:v21-tag-header (id3:id3-header me))
+      (id3:album (id3:v21-tag-header (id3:id3-header me)))
       nil))
 
-(defmethod artist ((me id3-frame:mp3-file))
+(defmethod artist ((me id3:mp3-file))
   (declare #.utils:*standard-optimize-settings*)
-  (let ((frames (id3-frame:get-frames me '("TP1" "TPE1"))))
+  (let ((frames (id3:get-frames me '("TP1" "TPE1"))))
     (when frames
       (assert (= 1 (length frames)) () "There can be only one artist tag")
-      (return-from artist (id3-frame:info (first frames)))))
-  (if (id3-frame:v21-tag-header (id3-frame:id3-header me))
-      (id3-frame:artist (id3-frame:v21-tag-header (id3-frame:id3-header me)))
+      (return-from artist (id3:info (first frames)))))
+  (if (id3:v21-tag-header (id3:id3-header me))
+      (id3:artist (id3:v21-tag-header (id3:id3-header me)))
       nil))
 
-(defmethod comment ((me id3-frame:mp3-file))
+(defmethod comment ((me id3:mp3-file))
   (declare #.utils:*standard-optimize-settings*)
-  (let ((frames (id3-frame:get-frames me '("COM" "COMM"))))
+  (let ((frames (id3:get-frames me '("COM" "COMM"))))
     (when frames
       (let ((new-frames))
         (dolist (f frames)
-          (push (list (id3-frame:encoding f)
-                      (id3-frame:lang f)
-                      (id3-frame:desc f)
-                      (id3-frame:val f)) new-frames))
+          (push (list (id3:encoding f)
+                      (id3:lang f)
+                      (id3:desc f)
+                      (id3:val f)) new-frames))
         (return-from comment new-frames))))
-  (if (id3-frame:v21-tag-header (id3-frame:id3-header me))
-      (id3-frame:comment (id3-frame:v21-tag-header (id3-frame:id3-header me)))
+  (if (id3:v21-tag-header (id3:id3-header me))
+      (id3:comment (id3:v21-tag-header (id3:id3-header me)))
       nil))
 
-(defmethod year ((me id3-frame:mp3-file))
+(defmethod year ((me id3:mp3-file))
   (declare #.utils:*standard-optimize-settings*)
-  (let ((frames (id3-frame:get-frames me '("TRD" "TDRC"))))
+  (let ((frames (id3:get-frames me '("TRD" "TDRC"))))
     (when frames
       (assert (= 1 (length frames)) () "There can be only one year tag")
-      (return-from year (id3-frame:info (first frames)))))
-  (if (id3-frame:v21-tag-header (id3-frame:id3-header me))
-      (id3-frame:year (id3-frame:v21-tag-header (id3-frame:id3-header me)))
+      (return-from year (id3:info (first frames)))))
+  (if (id3:v21-tag-header (id3:id3-header me))
+      (id3:year (id3:v21-tag-header (id3:id3-header me)))
       nil))
 
-(defmethod title ((me id3-frame:mp3-file))
+(defmethod title ((me id3:mp3-file))
   (declare #.utils:*standard-optimize-settings*)
-  (let ((frames (id3-frame:get-frames me '("TT2" "TIT2"))))
+  (let ((frames (id3:get-frames me '("TT2" "TIT2"))))
     (when frames
       (assert (= 1 (length frames)) () "There can be only one title tag")
-      (return-from title (id3-frame:info (first frames)))))
-  (if (id3-frame:v21-tag-header (id3-frame:id3-header me))
-      (id3-frame:title (id3-frame:v21-tag-header (id3-frame:id3-header me)))
+      (return-from title (id3:info (first frames)))))
+  (if (id3:v21-tag-header (id3:id3-header me))
+      (id3:title (id3:v21-tag-header (id3:id3-header me)))
       nil))
 
-(defmethod genre ((me id3-frame:mp3-file))
+(defmethod genre ((me id3:mp3-file))
   (declare #.utils:*standard-optimize-settings*)
-  (let ((frames (id3-frame:get-frames me '("TCO" "TCON"))))
+  (let ((frames (id3:get-frames me '("TCO" "TCON"))))
     (when frames
       (when (> (length frames) 1)
         (warn-user "file ~a has more than one genre frame, will only use the first"
-                   (id3-frame:filename me)))
+                   (id3:filename me)))
       (let ((count)
             (end)
-            (str (id3-frame:info (first frames))))
+            (str (id3:info (first frames))))
 
         ;; For V23/V24 TCON frames, a genre can be pretty gnarly.
         ;; if the first byte of the TCON INFO field is a '(', what is between this '('
@@ -163,88 +163,88 @@ is > 0 and < (sizeof *ID3V1-GENRES*)"
           (setf str (get-id3v1-genre (parse-integer (subseq str 1 end)))))
         (return-from genre str))))
 
-  (if (id3-frame:v21-tag-header (id3-frame:id3-header me))
-      (get-id3v1-genre (id3-frame:genre (id3-frame:v21-tag-header (id3-frame:id3-header me))))
+  (if (id3:v21-tag-header (id3:id3-header me))
+      (get-id3v1-genre (id3:genre (id3:v21-tag-header (id3:id3-header me))))
       nil))
 
 ;;;; No V2.1 tags for any of these
-(defmethod album-artist ((me id3-frame:mp3-file))
+(defmethod album-artist ((me id3:mp3-file))
   (declare #.utils:*standard-optimize-settings*)
-  (let ((frames (id3-frame:get-frames me '("TP2" "TPE2"))))
+  (let ((frames (id3:get-frames me '("TP2" "TPE2"))))
     (when frames
       (assert (= 1 (length frames)) () "There can be only one album-artist tag")
-      (return-from album-artist (id3-frame:info (first frames)))))
+      (return-from album-artist (id3:info (first frames)))))
   nil)
 
-(defmethod composer ((me id3-frame:mp3-file))
+(defmethod composer ((me id3:mp3-file))
   (declare #.utils:*standard-optimize-settings*)
-  (let ((frames (id3-frame:get-frames me '("TCM" "TCOM"))))
+  (let ((frames (id3:get-frames me '("TCM" "TCOM"))))
     (when frames
       (assert (= 1 (length frames)) () "There can be only one composer tag")
-      (return-from composer (id3-frame:info (first frames)))))
+      (return-from composer (id3:info (first frames)))))
   nil)
 
-(defmethod copyright ((me id3-frame:mp3-file))
+(defmethod copyright ((me id3:mp3-file))
   (declare #.utils:*standard-optimize-settings*)
-  (let ((frames (id3-frame:get-frames me '("TCR" "TCOP"))))
+  (let ((frames (id3:get-frames me '("TCR" "TCOP"))))
     (when frames
       (assert (= 1 (length frames)) () "There can be only one copyright tag")
-      (return-from copyright (id3-frame:info (first frames)))))
+      (return-from copyright (id3:info (first frames)))))
   nil)
 
-(defmethod encoder ((me id3-frame:mp3-file))
+(defmethod encoder ((me id3:mp3-file))
   (declare #.utils:*standard-optimize-settings*)
-  (let ((frames (id3-frame:get-frames me '("TEN" "TENC"))))
+  (let ((frames (id3:get-frames me '("TEN" "TENC"))))
     (when frames
       (assert (= 1 (length frames)) () "There can be only one encoder tag")
-      (return-from encoder (id3-frame:info (first frames)))))
+      (return-from encoder (id3:info (first frames)))))
   nil)
 
-(defmethod groups ((me id3-frame:mp3-file))
+(defmethod groups ((me id3:mp3-file))
   (declare #.utils:*standard-optimize-settings*)
-  (let ((frames (id3-frame:get-frames me '("TT1" "TTE1"))))
+  (let ((frames (id3:get-frames me '("TT1" "TTE1"))))
     (when frames
       (assert (= 1 (length frames)) () "There can be only one group tag")
-      (return-from groups (id3-frame:info (first frames)))))
+      (return-from groups (id3:info (first frames)))))
   nil)
 
-(defmethod lyrics ((me id3-frame:mp3-file))
+(defmethod lyrics ((me id3:mp3-file))
   (declare #.utils:*standard-optimize-settings*)
-  (let ((frames (id3-frame:get-frames me '("ULT" "USLT"))))
+  (let ((frames (id3:get-frames me '("ULT" "USLT"))))
     (when frames
       (assert (= 1 (length frames)) () "There can be only one lyrics tag")
-      (return-from lyrics (id3-frame:val (first frames)))))
+      (return-from lyrics (id3:val (first frames)))))
   nil)
 
-(defmethod writer ((me id3-frame:mp3-file))
+(defmethod writer ((me id3:mp3-file))
   (declare #.utils:*standard-optimize-settings*)
-  (let ((frames (id3-frame:get-frames me '("TCM" "TCOM"))))
+  (let ((frames (id3:get-frames me '("TCM" "TCOM"))))
     (when frames
       (assert (= 1 (length frames)) () "There can be only one composer tag")
-      (return-from writer (id3-frame:info (first frames)))))
+      (return-from writer (id3:info (first frames)))))
   nil)
 
-(defmethod compilation ((me id3-frame:mp3-file))
+(defmethod compilation ((me id3:mp3-file))
   (declare #.utils:*standard-optimize-settings*)
-  (let ((frames (id3-frame:get-frames me '("TCMP" "TCP"))))
+  (let ((frames (id3:get-frames me '("TCMP" "TCP"))))
     (if frames
-        (id3-frame:info (first frames))
+        (id3:info (first frames))
       "no")))
 
-(defmethod disk ((me id3-frame:mp3-file))
+(defmethod disk ((me id3:mp3-file))
   (declare #.utils:*standard-optimize-settings*)
-  (let ((frames (id3-frame:get-frames me '("TPA" "TPOS"))))
+  (let ((frames (id3:get-frames me '("TPA" "TPOS"))))
     (when frames
       (assert (= 1 (length frames)) () "There can be only one disk number tag")
-      (return-from disk (mk-lst (id3-frame:info (first frames))))))
+      (return-from disk (mk-lst (id3:info (first frames))))))
   nil)
 
-(defmethod tempo ((me id3-frame:mp3-file))
+(defmethod tempo ((me id3:mp3-file))
   (declare #.utils:*standard-optimize-settings*)
-  (let ((frames (id3-frame:get-frames me '("TBP" "TBPM"))))
+  (let ((frames (id3:get-frames me '("TBP" "TBPM"))))
     (when frames
       (assert (= 1 (length frames)) () "There can be only one tempo tag")
-      (return-from tempo (id3-frame:info (first frames)))))
+      (return-from tempo (id3:info (first frames)))))
   nil)
 
 (defun mk-lst (str)
@@ -255,25 +255,25 @@ is > 0 and < (sizeof *ID3V1-GENRES*)"
         (list str)
         (list (subseq str 0 pos) (subseq str (+ 1 pos))))))
 
-(defmethod track ((me id3-frame:mp3-file))
+(defmethod track ((me id3:mp3-file))
   (declare #.utils:*standard-optimize-settings*)
-  (let ((frames (id3-frame:get-frames me '("TRK" "TRCK"))))
+  (let ((frames (id3:get-frames me '("TRK" "TRCK"))))
     (when frames
       (assert (= 1 (length frames)) () "There can be only one track number tag")
-      (return-from track (mk-lst (id3-frame:info (first frames))))))
+      (return-from track (mk-lst (id3:info (first frames))))))
   nil)
 
-(defmethod show-tags ((me id3-frame:mp3-file) &key (raw *raw-tags*))
+(defmethod show-tags ((me id3:mp3-file) &key (raw *raw-tags*))
   "Show the tags for an MP3.  If RAW is non-nil, dump all the frames;
 else, print out a subset."
   (declare #.utils:*standard-optimize-settings*)
   (if raw
-      (format t "~a~%~a~%" (id3-frame:filename me)
+      (format t "~a~%~a~%" (id3:filename me)
               (with-output-to-string (s)
-                (when (id3-frame:audio-info me)
-                  (mpeg::vpprint (id3-frame:audio-info me) s)
+                (when (id3:audio-info me)
+                  (mpeg::vpprint (id3:audio-info me) s)
                   (format s "~%"))
-                (id3-frame:vpprint (id3-frame:id3-header me) s)))
+                (id3:vpprint (id3:id3-header me) s)))
       (let ((album (album me))
             (album-artist (album-artist me))
             (artist (artist me))
@@ -293,9 +293,9 @@ else, print out a subset."
             (writer (writer me))
             (year (year me)))
 
-        (format t "~a~%~a~%" (id3-frame:filename me)
-                (if (id3-frame:audio-info me)
-                    (mpeg::vpprint (id3-frame:audio-info me) nil) ""))
+        (format t "~a~%~a~%" (id3:filename me)
+                (if (id3:audio-info me)
+                    (mpeg::vpprint (id3:audio-info me) nil) ""))
 
         (when album (format t "~4talbum: ~a~%" album))
         (when album-artist (format t "~4talbum-artist: ~a~%" album-artist))
@@ -317,53 +317,53 @@ else, print out a subset."
         (when year (format t "~4tyear: ~a~%" year)))))
 
 ;;;;;;;;;;;;;;;;;;;; MP4 ;;;;;;;;;;;;;;;;;;;;
-(defmethod album        ((me mp4-atom:mp4-file)) (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-album+))
-(defmethod album-artist ((me mp4-atom:mp4-file)) (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-album-artist+))
-(defmethod artist       ((me mp4-atom:mp4-file)) (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-artist+))
-(defmethod comment      ((me mp4-atom:mp4-file)) (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-comment+))
-(defmethod composer     ((me mp4-atom:mp4-file)) (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-composer+))
-(defmethod copyright    ((me mp4-atom:mp4-file)) (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-copyright+))
-;;;(defmethod cover        ((me mp4-atom:mp4-file)) (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-cover-art+))
-(defmethod year         ((me mp4-atom:mp4-file)) (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-year+))
-(defmethod encoder      ((me mp4-atom:mp4-file)) (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-encoder+))
-(defmethod groups       ((me mp4-atom:mp4-file)) (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-groups+))
-(defmethod lyrics       ((me mp4-atom:mp4-file)) (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-lyrics+))
-(defmethod title        ((me mp4-atom:mp4-file)) (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-title+))
-(defmethod writer       ((me mp4-atom:mp4-file)) (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-writer+))
-(defmethod compilation  ((me mp4-atom:mp4-file)) (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-compilation+))
-(defmethod disk         ((me mp4-atom:mp4-file)) (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-disk+))
-(defmethod tempo        ((me mp4-atom:mp4-file)) (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-tempo+))
-
-(defmethod genre        ((me mp4-atom:mp4-file))
+(defmethod album        ((me m4a:mp4-file)) (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-album+))
+(defmethod album-artist ((me m4a:mp4-file)) (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-album-artist+))
+(defmethod artist       ((me m4a:mp4-file)) (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-artist+))
+(defmethod comment      ((me m4a:mp4-file)) (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-comment+))
+(defmethod composer     ((me m4a:mp4-file)) (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-composer+))
+(defmethod copyright    ((me m4a:mp4-file)) (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-copyright+))
+;;;(defmethod cover        ((me m4a:mp4-file)) (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-cover-art+))
+(defmethod year         ((me m4a:mp4-file)) (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-year+))
+(defmethod encoder      ((me m4a:mp4-file)) (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-encoder+))
+(defmethod groups       ((me m4a:mp4-file)) (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-groups+))
+(defmethod lyrics       ((me m4a:mp4-file)) (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-lyrics+))
+(defmethod title        ((me m4a:mp4-file)) (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-title+))
+(defmethod writer       ((me m4a:mp4-file)) (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-writer+))
+(defmethod compilation  ((me m4a:mp4-file)) (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-compilation+))
+(defmethod disk         ((me m4a:mp4-file)) (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-disk+))
+(defmethod tempo        ((me m4a:mp4-file)) (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-tempo+))
+
+(defmethod genre        ((me m4a:mp4-file))
   (declare #.utils:*standard-optimize-settings*)
-  (let ((genre   (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-genre+))
-        (genre-x (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-genre-x+)))
+  (let ((genre   (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-genre+))
+        (genre-x (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-genre-x+)))
     (assert (not (and genre genre-x)))
     (cond
       (genre   (format nil "~d (~a)" genre (get-id3v1-genre (1- genre))))
       (genre-x genre-x)
       (t       "not present"))))
 
-(defmethod track ((me mp4-atom:mp4-file))
+(defmethod track ((me m4a:mp4-file))
   (declare #.utils:*standard-optimize-settings*)
-  (let ((track   (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-track+))
-        (track-n (mp4-atom:tag-get-value (mp4-atom:mp4-atoms me) mp4-atom:+itunes-track-n+)))
+  (let ((track   (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-track+))
+        (track-n (m4a:tag-get-value (m4a:mp4-atoms me) m4a:+itunes-track-n+)))
     (assert (not (and track track-n)))
     (if track
         track
         track-n)))
 
-(defmethod show-tags ((me mp4-atom:mp4-file) &key (raw *raw-tags*))
+(defmethod show-tags ((me m4a:mp4-file) &key (raw *raw-tags*))
   "Show the tags for an MP4-FILE. If RAW is non-nil, dump the DATA atoms;
 else show subset of DATA atoms"
   (declare #.utils:*standard-optimize-settings*)
 
-  (format t "~a~%" (mp4-atom:filename me))
+  (format t "~a~%" (m4a:filename me))
   (if raw
       (progn
-        (if (mp4-atom:audio-info me)
-            (mp4-atom:vpprint (mp4-atom:audio-info me) t))
-        (mp4-atom:mp4-show-raw-tag-atoms me t))
+        (if (m4a:audio-info me)
+            (m4a:vpprint (m4a:audio-info me) t))
+        (m4a:mp4-show-raw-tag-atoms me t))
       (let ((album (album me))
             (album-artist (album-artist me))
             (artist (artist me))
@@ -383,8 +383,8 @@ else show subset of DATA atoms"
             (writer (writer me))
             (year (year me)))
 
-        (if (mp4-atom:audio-info me)
-            (mp4-atom:vpprint (mp4-atom:audio-info me) t))
+        (if (m4a:audio-info me)
+            (m4a:vpprint (m4a:audio-info me) t))
 
         (when album (format t "~&~4talbum: ~a~%" album))
         (when album-artist (format t "~4talbum-artist: ~a~%" album-artist))
@@ -407,32 +407,32 @@ else show subset of DATA atoms"
 
 ;;;;;;;;;;;;;;;;;;;; FLAC ;;;;;;;;;;;;;;;;;;;;
 (defmacro get-flac-tag-info (stream name)
-  `(flac-frame:flac-get-tag (flac-frame:flac-tags ,stream) ,name))
-
-(defmethod album        ((me flac-frame:flac-file)) (get-flac-tag-info me "album"))
-(defmethod artist       ((me flac-frame:flac-file)) (get-flac-tag-info me "artist"))
-(defmethod album-artist ((me flac-frame:flac-file)) (get-flac-tag-info me "album artist"))
-(defmethod comment      ((me flac-frame:flac-file)) (get-flac-tag-info me "comment"))
-(defmethod composer     ((me flac-frame:flac-file)) (get-flac-tag-info me "composer"))
-(defmethod copyright    ((me flac-frame:flac-file)) (get-flac-tag-info me "copyright"))
-(defmethod disk         ((me flac-frame:flac-file)) (get-flac-tag-info me "disk"))
-(defmethod encoder      ((me flac-frame:flac-file)) (get-flac-tag-info me "encoder"))
-(defmethod year         ((me flac-frame:flac-file)) (get-flac-tag-info me "date"))
-(defmethod title        ((me flac-frame:flac-file)) (get-flac-tag-info me "title"))
-(defmethod genre        ((me flac-frame:flac-file)) (get-flac-tag-info me "genre"))
-
-(defmethod track        ((me flac-frame:flac-file))
+  `(flac:flac-get-tag (flac:flac-tags ,stream) ,name))
+
+(defmethod album        ((me flac:flac-file)) (get-flac-tag-info me "album"))
+(defmethod artist       ((me flac:flac-file)) (get-flac-tag-info me "artist"))
+(defmethod album-artist ((me flac:flac-file)) (get-flac-tag-info me "album artist"))
+(defmethod comment      ((me flac:flac-file)) (get-flac-tag-info me "comment"))
+(defmethod composer     ((me flac:flac-file)) (get-flac-tag-info me "composer"))
+(defmethod copyright    ((me flac:flac-file)) (get-flac-tag-info me "copyright"))
+(defmethod disk         ((me flac:flac-file)) (get-flac-tag-info me "disk"))
+(defmethod encoder      ((me flac:flac-file)) (get-flac-tag-info me "encoder"))
+(defmethod year         ((me flac:flac-file)) (get-flac-tag-info me "date"))
+(defmethod title        ((me flac:flac-file)) (get-flac-tag-info me "title"))
+(defmethod genre        ((me flac:flac-file)) (get-flac-tag-info me "genre"))
+
+(defmethod track        ((me flac:flac-file))
   (let ((tr (get-flac-tag-info me "tracknumber"))
         (tn (get-flac-tag-info me "tracktotal")))
     (if tn (list tr tn) tr)))
 
-(defmethod show-tags ((me flac-frame:flac-file) &key (raw *raw-tags*))
+(defmethod show-tags ((me flac:flac-file) &key (raw *raw-tags*))
   "Show the tags for a FLAC-FILE."
   (declare #.utils:*standard-optimize-settings*)
 
-  (format t "~a~%" (flac-frame:filename me))
+  (format t "~a~%" (flac:filename me))
   (if raw
-      (flac-frame:flac-show-raw-tag me t)
+      (flac:flac-show-raw-tag me t)
       (let ((album (album me))
             (album-artist (album-artist me))
             (artist (artist me))
@@ -445,8 +445,8 @@ else show subset of DATA atoms"
             (track (track me))
             (year (year me)))
 
-        (if (flac-frame:audio-info me)
-            (flac-frame:vpprint (flac-frame:audio-info me) t))
+        (if (flac:audio-info me)
+            (flac:vpprint (flac:audio-info me) t))
 
         (when album (format t "~&~4talbum: ~a~%" album))
         (when album-artist (format t "~4talbum-artist: ~a~%" album-artist))

+ 6 - 6
audio-streams.lisp

@@ -219,12 +219,12 @@ byte-order marks, so we have to do that here before calling."
            (setf stream (make-audio-stream filename))
            (when stream
              (setf info
-                   (cond ((id3-frame:is-valid-mp3-file stream)
-                          (id3-frame:parse-audio-file stream get-audio-info))
-                         ((mp4-atom:is-valid-m4-file stream)
-                          (mp4-atom:parse-audio-file stream get-audio-info))
-                         ((flac-frame:is-valid-flac-file stream)
-                          (flac-frame:parse-audio-file stream get-audio-info))
+                   (cond ((id3:is-valid-mp3-file stream)
+                          (id3:parse-audio-file stream get-audio-info))
+                         ((m4a:is-valid-m4-file stream)
+                          (m4a:parse-audio-file stream get-audio-info))
+                         ((flac:is-valid-flac-file stream)
+                          (flac:parse-audio-file stream get-audio-info))
                          (t nil)))))
       (when stream
         (close stream)))

+ 2 - 2
flac-frame.lisp → flac.lisp

@@ -1,6 +1,6 @@
-;;; -*- Mode: Lisp;  show-trailing-whitespace: t; Base: 10; indent-tabs: nil; Syntax: ANSI-Common-Lisp; Package: FLAC-FRAME; -*-
+;;; -*- Mode: Lisp;  show-trailing-whitespace: t; Base: 10; indent-tabs: nil; Syntax: ANSI-Common-Lisp; Package: FLAC; -*-
 ;;; Copyright (c) 2013, Mark VandenBrink. All rights reserved.
-(in-package #:flac-frame)
+(in-package #:flac)
 
 ;;; FLAC header types
 (defconstant* +metadata-streaminfo+  0)

+ 16 - 5
id3-frame.lisp → id3.lisp

@@ -1,7 +1,7 @@
-;;; -*- Mode: Lisp;  show-trailing-whitespace: t; Base: 10; indent-tabs: nil; Syntax: ANSI-Common-Lisp; Package: ID3-FRAME; -*-
+;;; -*- Mode: Lisp;  show-trailing-whitespace: t; Base: 10; indent-tabs: nil; Syntax: ANSI-Common-Lisp; Package: ID3; -*-
 ;;; Copyright (c) 2013, Mark VandenBrink. All rights reserved.
 
-(in-package #:id3-frame)
+(in-package #:id3)
 
 ;;;; ID3 string encoding support
 (defun id3-read-string (instream &key (len nil) (encoding 0))
@@ -887,12 +887,23 @@ NB: 2.3 and 2.4 extended flags are different..."
   (string-upcase (concatenate 'string "frame-" id)))
 (utils:memoize 'mk-frame-class-name)
 
-(defparameter *skipped-id3-frames* nil)
+(defparameter *skipped-id3-frames* (make-hash-table :test #'equalp))
+
+(defun clear-skipped ()
+  (setf *skipped-id3-frames* (make-hash-table :test #'equalp)))
+
+(defun add-skipped (id)
+  (multiple-value-bind (value foundp)
+      (gethash id *skipped-id3-frames*)
+    (setf (gethash id *skipped-id3-frames*)
+          (if foundp
+              (1+ value)
+              1))))
 
 (defun find-frame-class (id)
   "Search by concatenating 'frame-' with ID and look for that symbol in this package"
   (declare #.utils:*standard-optimize-settings*)
-  (let ((found-class-symbol (find-symbol (mk-frame-class-name id) :ID3-FRAME))
+  (let ((found-class-symbol (find-symbol (mk-frame-class-name id) :ID3))
         found-class)
 
     ;; if we found the class name, return the class (to be used for MAKE-INSTANCE)
@@ -910,7 +921,7 @@ NB: 2.3 and 2.4 extended flags are different..."
                          ;; then just read it raw
                          (when (possibly-valid-frame-id? id)
                            (find-class (find-symbol "FRAME-RAW" :ID3-FRAME))))))
-    (pushnew id *skipped-id3-frames*)
+    (add-skipped id)
     found-class))
 
 (utils:memoize 'find-frame-class)

+ 16 - 5
mp4-atom.lisp → m4a.lisp

@@ -1,6 +1,6 @@
-;;; -*- Mode: Lisp;  show-trailing-whitespace: t; Base: 10; indent-tabs: nil; Syntax: ANSI-Common-Lisp; Package: MP4-ATOM; -*-
+;;; -*- Mode: Lisp;  show-trailing-whitespace: t; Base: 10; indent-tabs: nil; Syntax: ANSI-Common-Lisp; Package: M4A; -*-
 ;;; Copyright (c) 2013, Mark VandenBrink. All rights reserved.
-(in-package #:mp4-atom)
+(in-package #:m4a)
 
 ;;;; ATOMS
 ;;;
@@ -412,7 +412,18 @@ reading the container atoms"
       (warn-user "Bad atom type name: c = ~a, str = <~a>" c str)))
   t)
 
-(defparameter *skipped-atoms* nil)
+(defparameter *skipped-m4a-atoms* (make-hash-table :test #'equalp))
+
+(defun clear-skipped ()
+  (setf *skipped-m4a-atoms* (make-hash-table :test #'equalp)))
+
+(defun add-skipped (id)
+  (multiple-value-bind (value foundp)
+      (gethash id *skipped-m4a-atoms*)
+    (setf (gethash id *skipped-m4a-atoms*)
+          (if foundp
+              (1+ value)
+              1))))
 
 (defun find-atom-class (id)
   "Search by concatenating 'atom-' with ID and look for that symbol in this package"
@@ -420,14 +431,14 @@ reading the container atoms"
 
   (is-valid id)
 
-  (let ((found-class-symbol (find-symbol (mk-atom-class-name id) :MP4-ATOM)))
+  (let ((found-class-symbol (find-symbol (mk-atom-class-name id) :M4A)))
 
     ;; if we found the class name, return the class (to be used for MAKE-INSTANCE)
     (when found-class-symbol
       (return-from find-atom-class (find-class found-class-symbol)))
 
     ;; didn't find a class, so return ATOM-SKIP class
-    (pushnew id *skipped-atoms*)
+    (add-skipped id)
     'atom-skip))
 
 (utils:memoize 'find-atom-class)

+ 3 - 3
mpeg.lisp

@@ -476,8 +476,8 @@ Bits   1-0 (2  bits): the emphasis"
           ;; No Xing header found. Assume CBR and calculate based on first frame
           (let* ((first (pos first-frame))
                  (last (- (stream-size instream)
-                          (if (id3-frame:v21-tag-header
-                               (id3-frame:id3-header mp3-file)) 128 0)))
+                          (if (id3:v21-tag-header
+                               (id3:id3-header mp3-file)) 128 0)))
                  (n-fr (round (/ (float (- last first))
                                  (float (size first-frame)))))
                  (n-sec (round (/ (float (* (size first-frame) n-fr))
@@ -487,4 +487,4 @@ Bits   1-0 (2  bits): the emphasis"
                   n-frames 1
                   len      n-sec
                   bit-rate (float (bit-rate first-frame))))))
-    (setf (id3-frame:audio-info mp3-file) info)))
+    (setf (id3:audio-info mp3-file) info)))

+ 10 - 9
packages.lisp

@@ -35,19 +35,19 @@
            #:stream-seek #:open-audio-file)
   (:use #:common-lisp #:utils))
 
-(defpackage #:flac-frame
-  (:export #:flac-frame-condition #:flac-header #:vpprint
+(defpackage #:flac
+  (:export #:flac-header #:vpprint
            #:is-valid-flac-file #:find-flac-frames #:get-flac-audio-info
            #:flac-get-tag #:get-flac-audio-info #:flac-show-raw-tag
            #:parse-audio-file #:flac-file #:flac-headers #:audio-info
            #:flac-tags #:filename)
   (:use #:common-lisp #:utils #:audio-streams))
 
-(defpackage #:mp4-atom
+(defpackage #:m4a
   (:export #:mp4-atom #:map-mp4-atom #:find-mp4-atoms #:traverse
-           #:mp4-atom-condition #:atom-file-pos #:atom-children #:atom-size
+           #:atom-file-pos #:atom-children #:atom-size
            #:atom-of-interest #:atom-decoded #:atom-type #:vpprint #:*tag-path*
-           #:tag-get-value #:mp4-atom-condition #:mp4-show-raw-tag-atoms
+           #:tag-get-value #:mp4-show-raw-tag-atoms
            #:get-mp4-audio-info #:is-valid-m4-file #:+itunes-album+
            #:+itunes-album-artist+ #:+itunes-artist+ #:+itunes-comment+
            #:+itunes-composer+ #:+itunes-copyright+ #:+itunes-year+
@@ -56,17 +56,18 @@
            #:+itunes-writer+ #:+itunes-compilation+ #:+itunes-cover-art+
            #:+itunes-disk+ #:+itunes-genre+ #:+itunes-genre-x+ #:+itunes-tempo+
            #:+itunes-track+ #:+itunes-track-n+ #:parse-audio-file #:mp4-file
-           #:mp4-atoms #:audio-info #:filename)
+           #:mp4-atoms #:audio-info #:filename #:*skipped-m4a-atoms*
+           #:clear-skipped)
   (:use #:common-lisp #:audio-streams #:utils))
 
-(defpackage #:id3-frame
-  (:export #:id3-frame #:find-id3-frames #:id3-frame-condition #:vpprint
+(defpackage #:id3
+  (:export #:id3-frame #:find-id3-frames #:vpprint
            #:header #:get-frame-info #:is-valid-mp3-file #:encoding #:lang
            #:desc #:val #:comment #:artist #:album #:year #:comment #:year
            #:map-id3-frames #:frames #:year #:title #:genre #:id
            #:mp3-file #:id3-header #:audio-info #:parse-audio-file
            #:v21-tag-header #:info #:version #:picture-info #:get-frames
-           #:filename)
+           #:filename #:skipped-id3-frames* #:clear-skipped)
   (:use #:common-lisp #:audio-streams #:utils #:iso-639-2))
 
 (defpackage #:abstract-tag

+ 83 - 27
taglib-tests.lisp

@@ -35,41 +35,97 @@
   (awhen (open-audio-file file)
     (funcall func it)))
 
+(defstruct file-counts
+  (mp3-count   0 :type fixnum)
+  (flac-count  0 :type fixnum)
+  (mp4-count   0 :type fixnum)
+  (other-count 0 :type fixnum))
+
+(defmethod print-object ((me file-counts) stream)
+  (with-slots (mp3-count flac-count mp4-count other-count) me
+    (format stream
+            "~&~:d MP3s, ~:d MP4s, ~:d FLACs, ~:d Others, for a total of ~:d files~%"
+            mp3-count mp4-count flac-count other-count
+            (+ mp3-count mp4-count flac-count other-count))))
+
 (defun do-audio-dir (&key (dir "/home/markv/Music/Queen")
                           (file-system-encoding :utf-8)
                           (func #'abstract-tag:show-tags))
   "Walk :DIR and FUNCALL specified function for each file audio found."
   (set-pathname-encoding file-system-encoding)
-  (let ((mp3-count 0)
-        (flac-count 0)
-        (mp4-count 0)
-        (other-count 0))
-    (cl-fad:walk-directory dir
-                           (lambda (f)
-                             (do-audio-file :file f
-                               :func (lambda (s)
-                                       (cond ((typep s 'id3-frame:mp3-file)
-                                              (incf mp3-count))
-                                             ((typep s 'flac-frame:flac-file)
-                                              (incf flac-count))
-                                             ((typep s 'mp4-atom:mp4-file)
-                                              (incf mp4-count))
-                                             ((null s)
-                                              (incf other-count)))
-                                       (when (and (not (null s)) func)
-                                         (funcall func s))))))
-
-    (format t "~&~:d MP3s, ~:d MP4s, ~:d FLACs, ~:d Others, for a total of ~:d~%"
-            mp3-count mp4-count flac-count other-count
-            (+ mp3-count mp4-count flac-count other-count))))
+  (let ((file-counts (make-file-counts)))
+    (with-slots (mp3-count flac-count mp4-count other-count) file-counts
+      (cl-fad:walk-directory dir
+                             (lambda (f)
+                               (do-audio-file :file f
+                                 :func (lambda (s)
+                                         (cond ((typep s 'id3:mp3-file)
+                                                (incf mp3-count))
+                                               ((typep s 'flac:flac-file)
+                                                (incf flac-count))
+                                               ((typep s 'm4a:mp4-file)
+                                                (incf mp4-count))
+                                               ((null s)
+                                                (incf other-count)))
+                                         (when (and (not (null s)) func)
+                                           (funcall func s)))))))
+    file-counts))
 
 (defun time-test (&key (dir "/home/markv/Music/Queen")
                        (file-system-encoding :utf-8) (do-audio-processing t))
   "Time parsing of DIR."
   (set-pathname-encoding file-system-encoding)
   (let ((audio-streams:*get-audio-info* do-audio-processing))
-    (time (do-audio-dir :dir dir
-            :file-system-encoding file-system-encoding :func nil))))
+    (time (format t "~a~%"
+                  (do-audio-dir :dir dir
+                    :file-system-encoding file-system-encoding :func nil)))))
+
+;; (defun get-stats (&key (dir "/home/markv/Music/Queen")
+;;                        (file-system-encoding :utf-8)
+;;                        (do-audio-processing t))
+;;   "Gen up some interesting statistics on DIR"
+;;   (let ((m4-ht (make-hash-table :test #'equalp))
+;;         (m3-ht (make-hash-table :test #'equalp))
+;;         (fl-ht (make-hash-table :test #'equalp)))
+;;     (do-audio-dir
+;;       :dir dir
+;;       :file-system-encoding file-system-encoding
+;;       :func (lambda (s)
+;;               (cond ((typep s 'id3:mp3-file)
+;;                      (id3:map-id3-frames
+;;                       s
+;;                       :func (lambda (f)
+;;                               (multiple-value-bind (value foundp)
+;;                                   (gethash (id3:id f) m3-ht)
+;;                                 (setf (gethash (id3:id f) m3-ht)
+;;                                       (if foundp
+;;                                           (1+ value)
+;;                                           1))))))
+;;                       ((typep s 'flac:flac-file)
+;;                        t)
+;;                       ((typep s 'm4a:mp4-file)
+;;                        (tree:traverse
+;;                         (m4a:mp4-atoms s)
+;;                         (lambda (node depth)
+;;                           (declare (ignore depth))
+;;                           (setf node (tree:data node))
+;;                           (multiple-value-bind (value foundp)
+;;                               (gethash (m4a:atom-type node) m3-ht)
+;;                             (setf (gethash (m4a:atom-type node) m3-ht)
+;;                                   (if foundp
+;;                                       (1+ value)
+;;                                       1))))))
+;;                     ((null s)
+;;                      (incf other-count)))))
+;;     (format t "MP3 Stats:~%")
+;;     (loop for key being the hash-keys of m3-ht
+;;           using (hash-value value)
+;;           do (format t "~a:~:d~%" key value))
+;;     (format t "M4A Stats:~%")
+;;     (loop for key being the hash-keys of m4-ht
+;;           using (hash-value value)
+;;           do (format t "~a:~:d~%" key value))
+;;   (values m3-ht m4-ht fl-ht)))
 
 ;;;; multi-thread code below
 #+(or :ccl :sbcl :abcl)
@@ -118,11 +174,11 @@
 
                        (do-audio-file :file f
                          :func (lambda (s)
-                                 (cond ((typep s 'id3-frame:mp3-file)
+                                 (cond ((typep s 'id3:mp3-file)
                                         (incf mp3-count))
-                                       ((typep s 'flac-frame:flac-file)
+                                       ((typep s 'flac:flac-file)
                                         (incf flac-count))
-                                       ((typep s 'mp4-atom:mp4-file)
+                                       ((typep s 'm4a:mp4-file)
                                         (incf mp4-count))
                                        ((null s)
                                         (incf other-count)))

+ 4 - 4
taglib.asd

@@ -16,7 +16,7 @@
                (:file "audio-streams" :depends-on ("packages" "utils"))
                (:file "mpeg"          :depends-on ("packages" "audio-streams" "utils"))
                (:file "iso-639-2"     :depends-on ("packages" "utils"))
-               (:file "id3-frame"     :depends-on ("packages" "utils"))
-               (:file "flac-frame"    :depends-on ("packages" "utils"))
-               (:file "abstract-tag"  :depends-on ("packages" "id3-frame" "audio-streams" "mp4-atom" "utils"))
-               (:file "mp4-atom"      :depends-on ("packages" "utils"))))
+               (:file "id3"           :depends-on ("packages" "utils"))
+               (:file "flac"          :depends-on ("packages" "utils"))
+               (:file "abstract-tag"  :depends-on ("packages" "id3" "audio-streams" "m4a" "utils"))
+               (:file "m4a"           :depends-on ("packages" "utils"))))