-
Notifications
You must be signed in to change notification settings - Fork 0
/
id3.lisp
executable file
·63 lines (50 loc) · 1.93 KB
/
id3.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
(defpackage :id3v1
(:use :cl :alexandria :flexi-streams
)
(:export #:scan-id3
#:take-bytes))
(defpackage :id3v2
(:use :cl :alexandria :flexi-streams
))
(in-package :id3v1)
(defun as-string (barray)
(map 'string (lambda (x) (code-char x))
barray))
(defun id3p (barray)
(string= "ID3"
(as-string (take-bytes barray 0 3))))
(defun strip (barray)
(remove-if (lambda (x)
(= x 0)) barray))
(defun take-bytes (seq start &optional (end (length seq)) from-end)
(if from-end
(reverse (subseq (reverse seq) start (if (not end) (1- (length seq)) end)))
(subseq seq start end)))
;;Partially generated by:
;; (mapcar (lambda (x)
;; `(,(intern (string-upcase (symbol-name x)) 'keyword)
;; (,x barray))) '(title artist album year comment track genre start-time end-time))
(defun scan-id3 (barray &optional (strict nil))
"BARRAY is a full byte array of a music file. STRICT simply tells the function whether or not it should assert that it is indeed id3 complaint with ID3P"
(let* ((tag-array (take-bytes barray 0 128 t)))
(if strict (assert (id3p tag-array)))
`((:TITLE ,(TITLE TAG-ARRAY)) (:ARTIST ,(ARTIST TAG-ARRAY)) (:ALBUM ,(ALBUM TAG-ARRAY))
(:YEAR ,(YEAR TAG-ARRAY)) (:COMMENT ,(COMMENT TAG-ARRAY))
(:GENRE ,(GENRE TAG-ARRAY)))))
(defun title (barray)
(as-string (strip (take-bytes barray 3 30))))
(defun artist (barray)
(as-string (strip (take-bytes barray 33 63))))
(defun album (barray)
(as-string (strip (take-bytes barray 63 93))))
(defun year (barray)
(as-string (strip (take-bytes barray 93 97))))
(defun comment (barray)
(as-string (strip (take-bytes barray 97 127))))
(defun genre (barray)
(aref (take-bytes barray 127 128) 0))
(defun track (barray)
(declare (ignore barray)))
(defun start-time (barray) (declare (ignore barray)))
(defun end-time (barray) (declare (ignore barray)))
(in-package :id3v2)