[cl-mp3-parse-cvs] CVS update: cl-mp3-parse/ChangeLog cl-mp3-parse/mp3-parser.lisp

Denis Bueno dbueno at common-lisp.net
Sun Mar 20 02:55:29 UTC 2005


Update of /project/cl-mp3-parse/cvsroot/cl-mp3-parse
In directory common-lisp.net:/tmp/cvs-serv23120

Modified Files:
	mp3-parser.lisp 
Added Files:
	ChangeLog 
Log Message:


Date: Sun Mar 20 03:55:27 2005
Author: dbueno



Index: cl-mp3-parse/mp3-parser.lisp
diff -u cl-mp3-parse/mp3-parser.lisp:1.1.1.1 cl-mp3-parse/mp3-parser.lisp:1.2
--- cl-mp3-parse/mp3-parser.lisp:1.1.1.1	Sun Mar 20 00:19:06 2005
+++ cl-mp3-parse/mp3-parser.lisp	Sun Mar 20 03:55:27 2005
@@ -1,4 +1,57 @@
-;;;; $Id: mp3-parser.lisp,v 1.1.1.1 2005/03/19 23:19:06 dbueno Exp $
+;;;; $Id: mp3-parser.lisp,v 1.2 2005/03/20 02:55:27 dbueno Exp $
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;; This software is provided without warranty of any kind, and is
+;;;; released under the BSD license. I reserve the right to change
+;;;; that, but only in the "more permissive license" direction, if
+;;;; such is possible.
+;;;;
+;;;; Copyright (c) 2004, Denis Bueno
+;;;; All rights reserved.
+;;;;
+;;;; Redistribution and use in source and binary forms, with or
+;;;; without modification, are permitted provided that the following
+;;;; conditions are met:
+;;;;
+;;;;   Redistributions of source code must retain the above copyright
+;;;;   notice, this list of conditions and the following
+;;;;   disclaimer.
+;;;;
+;;;;   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.
+;;;;
+;;;;   The name of the Denis Bueno may not be used to endorse or
+;;;;   promote products derived from this software without specific
+;;;;   prior written permission.
+;;;;
+;;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+;;;; CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS
+;;;; 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.
+;;;;
+;;;; Notes: Originally a ported some code written by a fried of mine,
+;;;; Curtis Jones. After I understood the problem, I changed the the
+;;;; implementation of READ-MP3-FRAMES significantly.
+;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;; TODO
+;;;;
+;;;; [ ] There's something wrong with the way the average bitrate is
+;;;; calculated. Fix that.
+;;;;
+;;;; [ ] Eventually I'd like to use Peter Seibel's CLOS generic binary type
+;;;; system. Get that working.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (in-package :mpeg)
 
@@ -13,8 +66,8 @@
        (list 2 4)
        :element-type '(unsigned-byte 32)
        :initial-contents
-       '((0 5 4 3)                          ;mpeg-2
-         (0 2 1 0))                         ;mpeg-1
+       '((0 5 4 3)                          ; mpeg-2
+         (0 2 1 0))                         ; mpeg-1
        )))
 
   (unless (boundp 'mpeg-frequency)
@@ -70,25 +123,28 @@
 (defmacro df (num)
   `(coerce ,num 'double-float))
 
-;; (setq lu-debug:*dprint-print-base* 16)
-;; (lu-debug:ondebug "mpeg-load.info" "mpeg-load.debug")
-
 (defun frame-header-p (arr &optional (pos 0))
-  "see if there is a frame header starting at POS in ARR. checks
+  "See if there is a frame header starting at POS in ARR. checks
   that all the frame sync bytes are set."
   (and (= #xff (aref arr pos))
        (= #xf (ldb (byte 4 4) (aref arr (1+ pos))))))
 
-;;; written by me
-
 (define-condition invalid-frame-header ()
-  ((text :initarg :text :reader text)
-   (data :initarg :data :reader data)))
+  ((text :initarg :text :reader text)))
 
 (define-condition invalid-layer-code ()
   ((code :initarg :code :reader code)))
 
 (defun read-mp3-frames (filename &optional (spos 0))
+  "Read from FILENAME, an MP3 file, and return a list
+  of (simple-array (unsigned-byte 8))'s, which contain the frame
+  data for each frame in the MP3. The arrays returned include the
+  header data for each frame. If SPOS is specified, SPOS bytes
+  starting from the beginning of the file stream will be skipped
+  before attempting to parse the frames of the MP3. This is
+  primarily useful because this parser doesn't (yet) assume the
+  presence of ID3 tags. SPOS can hence be used to skip over the
+  ID3 tag(s) before attempting to parse."
   (with-open-file (stream filename :element-type '(unsigned-byte 8))
     (file-position stream spos)
     (read-mp3-frames-rec stream)))
@@ -185,12 +241,14 @@
                           (make-array 4
                                       :element-type '(unsigned-byte 8)
                                       :initial-element 0)))
+  "Read the MP3 header from the given data buffer. The buffer
+  should contain at least 4 bytes of data (that's how long
+  headers are)."
   (unless (frame-header-p data bufpos)
     (error 'invalid-frame-header :data data))
 
   ;; read the 4 bytes that make up the header
   (replace head data :start2 bufpos :end2 (+ bufpos 4))
-  (lu-debug:dprint "read-mp3-header.debug" "raw header: ~a" head)
 
   ;; grab the coded values from the header...
   (let ((bitrate (ldb (byte 4 4) (aref head 2)))
@@ -204,6 +262,7 @@
     (values head bitrate layer mpegid frequ padding protect chan)))
 
 (defun calculate-framebytes (bitrate frequ pad-code layer-code)
+  "Calculate the number of bytes in a given frame."
   (case layer-code
     ((or #.mpeg-layer-2 #.mpeg-layer-3)
      (floor
@@ -214,11 +273,12 @@
       (* (+ (/ (* bitrate 1000 12) frequ)
             (if (zerop pad-code) 0 4))
          4)))
-    (t (error 'invalid-layer-code))))
-
-;;; print the header of a frame
+    (t (error 'invalid-layer-code :code layer-code))))
 
 (defun print-frame-header (head &optional (framenum nil))
+  "Print the values in the frame header so that they make sense
+  to a human. FRAMENUM is used if you want to label the frame
+  you're printing."
   (assert (= 4 (length head)))
   (multiple-value-bind (h bitrate layer mpegid frequ padding protect chan)
       (read-mp3-header head)
@@ -238,18 +298,22 @@
     (format t "~&  channel: ~d~%" (channel-code->value chan))))
 
 (defun bitrate-code->value (bitrate-code mpegid-code layer-code)
+  "Map a bitrate code to its value."
   (aref mpeg-bitrate bitrate-code
         (aref mpeg-style mpegid-code layer-code)))
 
 (defun layer-code->value (layer-code)
+  "Map a layer code to its value."
   (case layer-code
-    ;; I found a use for #. notation: to evaluate a constant at read-time!
+    ;; I found a necessary use for #. notation: to evaluate a constant at
+    ;; read-time!
     (#.mpeg-layer-1 'mpeg-layer-1)
     (#.mpeg-layer-2 'mpeg-layer-2)
     (#.mpeg-layer-3 'mpeg-layer-3)
     (t 'unknown)))
 
 (defun id-code->value (id-code)
+  "Map the mpeg id code to its value."
   (case id-code
     (0 'mpeg-2.5-unofficial)
     (1 'reserved)
@@ -257,9 +321,11 @@
     (3 'mpeg-1-iso/iec-11172-3)))
 
 (defun frequ-code->value (frequ-code id-code)
+  "Map the frequency code to its value."
   (aref mpeg-frequency frequ-code id-code))
 
 (defun channel-code->value (channel-code)
+  "Map the channel code to its value."
   (case channel-code
     (0 'stereo)
     (1 'joint-stereo)




More information about the Cl-mp3-parse-cvs mailing list