mp3-tag.lisp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. ;;; -*- Mode: Lisp; show-trailing-whitespace: t; Base: 10; indent-tabs: nil; Syntax: ANSI-Common-Lisp; Package: MP3-TAG; -*-
  2. ;;; Copyright (c) 2013, Mark VandenBrink. All rights reserved.
  3. (in-package #:mp3-tag)
  4. (defparameter *id3v1-genres*
  5. #("Blues"
  6. "Classic Rock"
  7. "Country"
  8. "Dance"
  9. "Disco"
  10. "Funk"
  11. "Grunge"
  12. "Hip-Hop"
  13. "Jazz"
  14. "Metal"
  15. "New Age"
  16. "Oldies"
  17. "Other"
  18. "Pop"
  19. "R&B"
  20. "Rap"
  21. "Reggae"
  22. "Rock"
  23. "Techno"
  24. "Industrial"
  25. "Alternative"
  26. "Ska"
  27. "Death Metal"
  28. "Pranks"
  29. "Soundtrack"
  30. "Euro-Techno"
  31. "Ambient"
  32. "Trip-Hop"
  33. "Vocal"
  34. "Jazz+Funk"
  35. "Fusion"
  36. "Trance"
  37. "Classical"
  38. "Instrumental"
  39. "Acid"
  40. "House"
  41. "Game"
  42. "Sound Clip"
  43. "Gospel"
  44. "Noise"
  45. "Alternative Rock"
  46. "Bass"
  47. "Soul"
  48. "Punk"
  49. "Space"
  50. "Meditative"
  51. "Instrumental Pop"
  52. "Instrumental Rock"
  53. "Ethnic"
  54. "Gothic"
  55. "Darkwave"
  56. "Techno-Industrial"
  57. "Electronic"
  58. "Pop-Folk"
  59. "Eurodance"
  60. "Dream"
  61. "Southern Rock"
  62. "Comedy"
  63. "Cult"
  64. "Gangsta"
  65. "Top 40"
  66. "Christian Rap"
  67. "Pop/Funk"
  68. "Jungle"
  69. "Native American"
  70. "Cabaret"
  71. "New Wave"
  72. "Psychedelic"
  73. "Rave"
  74. "Showtunes"
  75. "Trailer"
  76. "Lo-Fi"
  77. "Tribal"
  78. "Acid Punk"
  79. "Acid Jazz"
  80. "Polka"
  81. "Retro"
  82. "Musical"
  83. "Rock & Roll"
  84. "Hard Rock"
  85. "Folk"
  86. "Folk/Rock"
  87. "National Folk"
  88. "Swing"
  89. "Fusion"
  90. "Bebob"
  91. "Latin"
  92. "Revival"
  93. "Celtic"
  94. "Bluegrass"
  95. "Avantgarde"
  96. "Gothic Rock"
  97. "Progressive Rock"
  98. "Psychedelic Rock"
  99. "Symphonic Rock"
  100. "Slow Rock"
  101. "Big Band"
  102. "Chorus"
  103. "Easy Listening"
  104. "Acoustic"
  105. "Humour"
  106. "Speech"
  107. "Chanson"
  108. "Opera"
  109. "Chamber Music"
  110. "Sonata"
  111. "Symphony"
  112. "Booty Bass"
  113. "Primus"
  114. "Porn Groove"
  115. "Satire"
  116. "Slow Jam"
  117. "Club"
  118. "Tango"
  119. "Samba"
  120. "Folklore"
  121. "Ballad"
  122. "Power Ballad"
  123. "Rhythmic Soul"
  124. "Freestyle"
  125. "Duet"
  126. "Punk Rock"
  127. "Drum Solo"
  128. "A Cappella"
  129. "Euro-House"
  130. "Dance Hall"
  131. "Goa"
  132. "Drum & Bass"
  133. "Club-House"
  134. "Hardcore"
  135. "Terror"
  136. "Indie"
  137. "BritPop"
  138. "Negerpunk"
  139. "Polsk Punk"
  140. "Beat"
  141. "Christian Gangsta Rap"
  142. "Heavy Metal"
  143. "Black Metal"
  144. "Crossover"
  145. "Contemporary Christian"
  146. "Christian Rock"
  147. "Merengue"
  148. "Salsa"
  149. "Thrash Metal"
  150. "Anime"
  151. "Jpop"
  152. "Synthpop"))
  153. (defun get-id3v1-genre (n)
  154. (let ((idx (- n 1))) ; arrays are zero-based
  155. (if (> idx (length *id3v1-genres*))
  156. "BAD GENRE!?!?!?"
  157. (aref *id3v1-genres* idx))))
  158. (defun get-frames (stream names)
  159. (let (found-frames)
  160. (mp3-map-frames stream
  161. :func (lambda (f)
  162. (when (member (id f) names :test #'string=)
  163. (push f found-frames))))
  164. found-frames))
  165. (defmethod album ((me mp3-file-stream))
  166. (let ((ret (get-frames me '("TAL" "TALB"))))
  167. (when ret
  168. (assert (= 1 (length ret)) () "There can be only one album tag")
  169. (return-from album (info (first ret)))))
  170. (if (v21-tag-header (mp3-header me))
  171. (album (v21-tag-header (mp3-header me)))
  172. nil))
  173. (defmethod artist ((me mp3-file-stream))
  174. (let ((ret (get-frames me '("TP1" "TPE1"))))
  175. (when ret
  176. (assert (= 1 (length ret)) () "There can be only one artist tag")
  177. (return-from artist (info (first ret)))))
  178. (if (v21-tag-header (mp3-header me))
  179. (artist (v21-tag-header (mp3-header me)))
  180. nil))
  181. (defmethod comment ((me mp3-file-stream))
  182. (let ((ret (get-frames me '("COM" "COMM"))))
  183. (when ret
  184. (let ((new-ret))
  185. (dolist (f ret)
  186. (push (list (encoding f) (lang f) (desc f) (val f)) new-ret))
  187. (return-from comment new-ret))))
  188. (if (v21-tag-header (mp3-header me))
  189. (comment (v21-tag-header (mp3-header me)))
  190. nil))
  191. (defmethod year ((me mp3-file-stream))
  192. (let ((ret (get-frames me '("TRD" "TDRC"))))
  193. (when ret
  194. (assert (= 1 (length ret)) () "There can be only one year tag")
  195. (return-from year (info (first ret)))))
  196. (if (v21-tag-header (mp3-header me))
  197. (year (v21-tag-header (mp3-header me)))
  198. nil))
  199. (defmethod title ((me mp3-file-stream))
  200. (let ((ret (get-frames me '("TT2" "TIT2"))))
  201. (when ret
  202. (assert (= 1 (length ret)) () "There can be only one title tag")
  203. (return-from title (info (first ret)))))
  204. (if (v21-tag-header (mp3-header me))
  205. (title (v21-tag-header (mp3-header me)))
  206. nil))
  207. (defmethod genre ((me mp3-file-stream))
  208. (let ((ret (get-frames me '("TCO" "TCON"))))
  209. (when ret
  210. (assert (= 1 (length ret)) () "There can be only one genre tag")
  211. (return-from genre (info (first ret)))))
  212. (if (v21-tag-header (mp3-header me))
  213. (get-id3v1-genre (genre (v21-tag-header (mp3-header me))))
  214. nil))
  215. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; no V2.1 tags for any of these ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  216. (defmethod album-artist ((me mp3-file-stream))
  217. (let ((ret (get-frames me '("TP2" "TPE2"))))
  218. (when ret
  219. (assert (= 1 (length ret)) () "There can be only one album-artist tag")
  220. (return-from album-artist (info (first ret)))))
  221. nil)
  222. (defmethod composer ((me mp3-file-stream))
  223. (let ((ret (get-frames me '("TCM" "TCOM"))))
  224. (when ret
  225. (assert (= 1 (length ret)) () "There can be only one composer tag")
  226. (return-from composer (info (first ret)))))
  227. nil)
  228. (defmethod copyright ((me mp3-file-stream))
  229. (let ((ret (get-frames me '("TCR" "TCOP"))))
  230. (when ret
  231. (assert (= 1 (length ret)) () "There can be only one copyright tag")
  232. (return-from copyright (info (first ret)))))
  233. nil)
  234. (defmethod encoder ((me mp3-file-stream))
  235. (let ((ret (get-frames me '("TEN" "TENC"))))
  236. (when ret
  237. (assert (= 1 (length ret)) () "There can be only one encoder tag")
  238. (return-from encoder (info (first ret)))))
  239. nil)
  240. (defmethod groups ((me mp3-file-stream))
  241. (let ((ret (get-frames me '("TT1" "TTE1"))))
  242. (when ret
  243. (assert (= 1 (length ret)) () "There can be only one group tag")
  244. (return-from groups (info (first ret)))))
  245. nil)
  246. (defmethod lyrics ((me mp3-file-stream))
  247. (let ((ret (get-frames me '("ULT" "USLT"))))
  248. (when ret
  249. (assert (= 1 (length ret)) () "There can be only one lyrics tag")
  250. (return-from lyrics (val (first ret)))))
  251. nil)
  252. (defmethod purchased-date ((me mp3-file-stream)) "NIY")
  253. (defmethod tool ((me mp3-file-stream)) "NIY")
  254. (defmethod writer ((me mp3-file-stream))
  255. (let ((ret (get-frames me '("TCM" "TCOM"))))
  256. (when ret
  257. (assert (= 1 (length ret)) () "There can be only one composer tag")
  258. (return-from writer (info (first ret)))))
  259. nil)
  260. (defmethod compilation ((me mp3-file-stream)) "NIY")
  261. (defmethod disk ((me mp3-file-stream))
  262. (let ((ret (get-frames me '("TPA" "TPOS"))))
  263. (when ret
  264. (assert (= 1 (length ret)) () "There can be only one disk number tag")
  265. (return-from disk (info (first ret)))))
  266. nil)
  267. (defmethod tempo ((me mp3-file-stream))
  268. (let ((ret (get-frames me '("TBP" "TBPM"))))
  269. (when ret
  270. (assert (= 1 (length ret)) () "There can be only one tempo tag")
  271. (return-from tempo (info (first ret)))))
  272. nil)
  273. (defmethod track ((me mp3-file-stream))
  274. (let ((ret (get-frames me '("TRK" "TRCK"))))
  275. (when ret
  276. (assert (= 1 (length ret)) () "There can be only one track number tag")
  277. (return-from track (info (first ret)))))
  278. nil)
  279. (defmethod show-tags ((me mp3-file-stream) &key (raw nil))
  280. "Show the tags for an mp3-file"
  281. (if raw
  282. (format t "~a:~a~%" (stream-filename me) (mp3-frame:vpprint (audio-streams:mp3-header me) nil))
  283. (let ((album (album me))
  284. (album-artist (album-artist me))
  285. (artist (artist me))
  286. (comment (comment me))
  287. (compilation (compilation me))
  288. (composer (composer me))
  289. (copyright (copyright me))
  290. (disk (disk me))
  291. (encoder (encoder me))
  292. (genre (genre me))
  293. (groups (groups me))
  294. (lyrics (lyrics me))
  295. (purchased-date (purchased-date me))
  296. (tempo (tempo me))
  297. (title (title me))
  298. (tool (tool me))
  299. (track (track me))
  300. (writer (writer me))
  301. (year (year me)))
  302. (format t "~a~%" (stream-filename me))
  303. (when album (format t "~4talbum: ~a~%" album))
  304. (when album-artist (format t "~4talbum-artist: ~a~%" album-artist))
  305. (when artist (format t "~4tartist: ~a~%" artist))
  306. (when comment (format t "~4tcomment: ~a~%" comment))
  307. (format t "~4tcompilation: ~a~%" compilation)
  308. (when composer (format t "~4tcomposer: ~a~%" composer))
  309. (when copyright (format t "~4tcopyright: ~a~%" copyright))
  310. (when disk (format t "~4tdisk: ~a~%" disk))
  311. (when encoder (format t "~4tencoder: ~a~%" encoder))
  312. (when genre (format t "~4tgenre: ~a~%" genre))
  313. (when groups (format t "~4tgroups: ~a~%" groups))
  314. (when lyrics (format t "~4tlyrics: ~a~%" lyrics))
  315. (when purchased-date (format t "~4tpurchased date: ~a~%" purchased-date))
  316. (when tempo (format t "~4ttempo: ~a~%" tempo))
  317. (when title (format t "~4ttitle: ~a~%" title))
  318. (when tool (format t "~4ttool: ~a~%" tool))
  319. (when track (format t "~4ttrack: ~a~%" track))
  320. (when writer (format t "~4twriter: ~a~%" writer))
  321. (when year (format t "~4tyear: ~a~%" year)))))