-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathlame.cljc
48 lines (45 loc) · 1.78 KB
/
lame.cljc
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
#?(:clj (set! *warn-on-reflection* true))
(ns mp3-parser.lame
(:require
[biscuit.core :as b]
[mp3-parser.mpeg :as mpeg]
[mp3-parser.xing :as xing]
[octet.core :as o]))
; the lame tag spec
(def spec (o/spec :encoder (o/string 9)
:rev-method o/byte
:lowpass o/byte
:replay-gain (o/bytes 8)
:athtype-flags o/byte
:abr-bitrate o/byte
:delays (o/bytes 3)
:misc o/byte
:mp3-gain o/byte
:preset (o/bytes 2)
:music-length (o/bytes 4)
:music-crc (o/bytes 2)
:tag-crc o/uint16))
(defn revision
[rev-method]
(bit-shift-right rev-method 4))
(defn parse
[buf {{::mpeg/keys [frame-length]} :mpeg {::xing/keys [offset]} :xing :as xing-parsed}]
(if (not (:xing-tag? xing-parsed))
xing-parsed
(do
(assert (>= (o/get-capacity buf) frame-length)
(str "Buffer size " (o/get-capacity buf) " insufficient for frame length " frame-length))
(let [parsed (o/read buf spec {:offset (+ offset 120)})
revision (revision (:rev-method parsed))
tag? (if (and (re-matches #"LAME.*" (:encoder parsed))
(or (= revision 0) (= revision 1) (= revision 15))) true false)
lame-parsed (assoc xing-parsed :lame-tag? tag?)]
(if (not tag?)
lame-parsed
(let [tag-crc (:tag-crc parsed)
calc-crc (b/crc16 (o/read buf (o/bytes 190)))]
(assoc lame-parsed :lame
(assoc (:lame lame-parsed)
::encoder (:encoder parsed)
::revision revision
::crc-valid? (= tag-crc calc-crc)))))))))