#lang racket/base (require ffi/unsafe ffi/unsafe/define "../utils/utils.rkt" ) (provide TagLib_File_Type _TagLib_File-pointer _TagLib_Tag-pointer _TagLib_AudioProperties-pointer taglib_file_new taglib_file_new_type taglib_file_is_valid taglib_file_free taglib_file_tag taglib_file_audioproperties taglib_tag_free_strings taglib_tag_title taglib_tag_artist taglib_tag_album taglib_tag_comment taglib_tag_genre taglib_tag_year taglib_tag_track taglib_audioproperties_length taglib_audioproperties_bitrate taglib_audioproperties_samplerate taglib_audioproperties_channels taglib_property_keys taglib_property_key taglib_property_get taglib_property_val taglib_property_free taglib-get-picture ) ;(define-runtime-path lib-path ".."); ; ;(define libs (let ((os-type (system-type 'os*))) ; (if (eq? os-type 'windows) ; (list ; (build-path lib-path "lib" "dll" "tag") ; (build-path lib-path "lib" "dll" "tag_c")) ; (let* ((arch (symbol->string (system-type 'arch))) ; (subdir (string-append (symbol->string os-type) "-" arch))) ; (list ; (build-path lib-path "lib" subdir "libtag") ; (build-path lib-path "lib" subdir "libtag_c")))))) ;(define (get-lib l) ; (ffi-lib l '("2" #f) ; #:get-lib-dirs (λ () ; (cons (build-path ".") (get-lib-search-dirs))) ; #:fail (λ () ; (error (format "Cannot find library ~a" l))) ; )) (define libtag (get-lib '("tag" "libtag") '("2" #f))) (define libtag_c (get-lib '("tag_c" "libtag_c") '("#2" #f))) (define-ffi-definer define-tag-c-lib libtag_c) (define TagLib_File_Type (_enum '( mpeg ogg-vorbis flac mpc ogg-flac wavpack speex true-audio mp4 asf aiff wav ape it mod s3m xm opus dsf dsdiff shorten ))) (define _TagLib_File-pointer (_cpointer/null 'taglib-file)) (define _TagLib_Tag-pointer (_cpointer/null 'taglib-tag)) (define _TagLib_AudioProperties-pointer (_cpointer/null 'taglib-audioproperties)) ; TagLib_File *taglib_file_new(const char *filename); (define-tag-c-lib taglib_file_new (_fun _string/utf-8 -> _TagLib_File-pointer )) ; TagLib_File *taglib_file_new_type(const char *filename, TagLib_File_Type type); (define-tag-c-lib taglib_file_new_type (_fun _string/utf-8 TagLib_File_Type -> _TagLib_File-pointer)) ; void taglib_file_free(TagLib_File *file); (define-tag-c-lib taglib_file_free (_fun _TagLib_File-pointer -> _void)) ; BOOL taglib_file_is_valid(const TagLib_File *file); (define-tag-c-lib taglib_file_is_valid (_fun _TagLib_File-pointer -> _bool)) ; TagLib_Tag *taglib_file_tag(const TagLib_File *file); (define-tag-c-lib taglib_file_tag (_fun _TagLib_File-pointer -> _TagLib_Tag-pointer)) ; const TagLib_AudioProperties *taglib_file_audioproperties(const TagLib_File *file); (define-tag-c-lib taglib_file_audioproperties (_fun _TagLib_File-pointer -> _TagLib_AudioProperties-pointer)) ; void taglib_tag_free_strings(void); (define-tag-c-lib taglib_tag_free_strings (_fun -> _void)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; tags ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define-syntax tg (syntax-rules () ((_ name) (define-tag-c-lib name (_fun _TagLib_Tag-pointer -> _string/utf-8))) ((_ name ret-type) (define-tag-c-lib name (_fun _TagLib_Tag-pointer -> ret-type))) )) ; char *taglib_tag_title(const TagLib_Tag *tag); ; etc.. (tg taglib_tag_title) (tg taglib_tag_artist) (tg taglib_tag_album) (tg taglib_tag_comment) (tg taglib_tag_genre) (tg taglib_tag_year _uint) (tg taglib_tag_track _uint) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; audio properties ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define-syntax ap (syntax-rules () ((_ name) (define-tag-c-lib name (_fun _TagLib_AudioProperties-pointer -> _int))) )) ; int taglib_audioproperties_length(const TagLib_AudioProperties *audioProperties); ; etc... (ap taglib_audioproperties_length) (ap taglib_audioproperties_bitrate) (ap taglib_audioproperties_samplerate) (ap taglib_audioproperties_channels) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; keys in the propertymap ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; char** taglib_property_keys(const TagLib_File *file); (define-tag-c-lib taglib_property_keys (_fun _TagLib_File-pointer -> (_ptr i _string/utf-8))) (define (taglib_property_key keys i) (ptr-ref keys _string/utf-8 i)) ;char** taglib_property_get(const TagLib_File *file, const char *prop); (define-tag-c-lib taglib_property_get (_fun _TagLib_File-pointer _string/utf-8 -> (_ptr i _string/utf-8))) (define (taglib_property_val prop i) (ptr-ref prop _string/utf-8 i)) ; void taglib_property_free(char **props); (define-tag-c-lib taglib_property_free (_fun _pointer -> _void)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Picture data ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;typedef struct { ; char *mimeType; ; char *description; ; char *pictureType; ; char *data; ; unsigned int size; ;} TagLib_Complex_Property_Picture_Data; (define-cstruct _TagLib_Complex_Property_Picture_Data ( [mimeType _string/utf-8] [description _string/utf-8] [pictureType _string/utf-8] [data _pointer] [size _uint] )) ; TagLib_Complex_Property_Attribute*** properties = * taglib_complex_property_get(file, "PICTURE"); ; * TagLib_File *file = taglib_file_new("myfile.mp3"); ; * TagLib_Complex_Property_Attribute*** properties = ; * taglib_complex_property_get(file, "PICTURE"); ; * TagLib_Complex_Property_Picture_Data picture; ; * taglib_picture_from_complex_property(properties, &picture); ; * // Do something with picture.mimeType, picture.description, ; * // picture.pictureType, picture.data, picture.size, e.g. extract it. ; * FILE *fh = fopen("mypicture.jpg", "wb"); ; * if(fh) { ; * fwrite(picture.data, picture.size, 1, fh); ; * fclose(fh); ; * } ; * taglib_complex_property_free(properties); (define _Complex_Property_Attribute-pointer (_cpointer/null 'taglib-complex-property-attribute)) (define-tag-c-lib taglib_complex_property_get (_fun _TagLib_File-pointer _string/utf-8 -> _Complex_Property_Attribute-pointer)) (define-tag-c-lib taglib_picture_from_complex_property (_fun _Complex_Property_Attribute-pointer _TagLib_Complex_Property_Picture_Data-pointer -> _void)) (define-tag-c-lib taglib_complex_property_free (_fun _Complex_Property_Attribute-pointer -> _void)) ;TAGLIB_C_EXPORT char** taglib_complex_property_keys(const TagLib_File *file); (define-tag-c-lib taglib_complex_property_keys (_fun _TagLib_File-pointer -> (_ptr i _string/utf-8))) ; void taglib_complex_property_free_keys(char **keys); (define-tag-c-lib taglib_complex_property_free_keys (_fun _pointer -> _void)) (define (taglib-get-picture tag-file) (define (cp s) (string-append s "")) (define (to-bytestring data size) (let* ((v (make-vector size 0)) (i 0)) (while (< i size) (vector-set! v (ptr-ref data _byte i) i) (set! i (+ i 1))) v)) (let ((props (taglib_complex_property_get tag-file "PICTURE"))) (if (eq? props #f) #f (let ((pd (make-TagLib_Complex_Property_Picture_Data #f #f #f #f 0))) (taglib_picture_from_complex_property props pd) (let* ((mimetype (cp (TagLib_Complex_Property_Picture_Data-mimeType pd))) (description (cp (TagLib_Complex_Property_Picture_Data-description pd))) (type (cp (TagLib_Complex_Property_Picture_Data-pictureType pd))) (size (TagLib_Complex_Property_Picture_Data-size pd)) (data (cast (TagLib_Complex_Property_Picture_Data-data pd) _pointer (_bytes o size))) ) (let ((r (list mimetype description type size data))) (taglib_complex_property_free props) r)))) ))