Source

cl-taglib / cl-taglib.lisp

;;;; cl-taglib.lisp

(in-package #:cl-taglib)

;;; "cl-taglib" goes here. Hacks and glory await!
(define-foreign-library taglib
  (t (:default "libtag_c")))

(use-foreign-library taglib)

(defcfun (set-strings-unicode "taglib_set_strings_unicode") :void
  (unicode :boolean))

(defcfun (set-string-management "taglib_set_string_management_enabled") :void
  (mangement :boolean))

(defcfun (free "taglib_free") :void
  (str :pointer))

(defcfun (file-new "taglib_file_new") :pointer
  (filename :string))

(defcfun (file-free "taglib_file_free") :void
  (file :pointer))

(defcfun (file-is-valid "taglib_file_is_valid") :boolean
  (file :pointer))

(defcfun (file-tag "taglib_file_tag") :pointer
  (file :pointer))

;;; taglib_file_audioproperties
(defcfun (file-save "taglib_file_save") :boolean
  (file :pointer))

(defmacro with-tag-file ((var path) &body body)
  `(let ((,var (file-new ,path)))
     ,@body
     (file-free ,var)))

(defmacro taglib-accessor-for (slot type)
  (let ((function-name (intern (concatenate 'string "TAG-" (string slot))))
	(foreign-name (string-downcase (concatenate 'string "taglib_tag_" (string slot))))
	(foreign-set-name (string-downcase (concatenate 'string "taglib_tag_set_" (string slot)))))
    (list 'progn
	  (if (eq type :string)
	      `(defun ,function-name (tag)
		(let ((str-ptr (foreign-funcall ,foreign-name :pointer tag :string+ptr)))
		  (foreign-funcall "taglib_free" :pointer (cadr str-ptr) :void)
		  (car str-ptr)))
	      `(defun ,function-name (tag)
		(foreign-funcall ,foreign-name :pointer tag ,type)))
	  `(defun (setf ,function-name) (value tag)
	    (foreign-funcall ,foreign-set-name :pointer tag ,type value :void)))))

(taglib-accessor-for :title :string)
(taglib-accessor-for :artist :string)
(taglib-accessor-for :album :string)
(taglib-accessor-for :comment :string)
(taglib-accessor-for :genre :string)
(taglib-accessor-for :year :uint)
(taglib-accessor-for :track :uint)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.