#lang racket/base (require rackunit racket/file racket/path "../flac-48khz-manager.rkt" "../private/fingerprint.rkt") (define tmp (make-temporary-file "alm-test-~a" 'directory)) (define hi (build-path tmp "hires.flac")) (define cd (build-path tmp "cd.flac")) (call-with-output-file hi #:exists 'replace (lambda (out) (display "hires" out))) (call-with-output-file cd #:exists 'replace (lambda (out) (display "cd" out))) (define (u64be-bytes n) (define b (make-bytes 8 0)) (for ([i (in-range 8)]) (bytes-set! b i (bitwise-and (arithmetic-shift n (- (* 8 (- 7 i)))) #xff))) b) (define (minimal-flac-bytes sample-rate) (define streaminfo (make-bytes 34 0)) (bytes-set! streaminfo 0 #x10) (bytes-set! streaminfo 1 #x00) (bytes-set! streaminfo 2 #x10) (bytes-set! streaminfo 3 #x00) (define packed (bitwise-ior (arithmetic-shift sample-rate 44) (arithmetic-shift 1 41) (arithmetic-shift 15 36) 1000)) (bytes-copy! streaminfo 10 (u64be-bytes packed)) (bytes-append #"fLaC" (bytes #x80 #x00 #x00 #x22) streaminfo)) (define native-flac (build-path tmp "native.flac")) (define id3-flac (build-path tmp "id3-prefix.flac")) (call-with-output-file native-flac #:exists 'replace (lambda (out) (write-bytes (minimal-flac-bytes 96000) out))) (call-with-output-file id3-flac #:exists 'replace (lambda (out) (write-bytes (bytes-append #"ID3" (bytes 4 0 0 0 0 0 3) #"abc" (minimal-flac-bytes 88200)) out))) (check-equal? (flac-streaminfo-sample-rate (read-flac-streaminfo native-flac)) 96000) (check-equal? (flac-streaminfo-sample-rate (read-flac-streaminfo id3-flac)) 88200) (delete-file native-flac) (delete-file id3-flac) (define convert-count 0) (define (mock-inspect p) (define s (file->string p)) (cond [(regexp-match? #rx"converted" s) 48000] [(regexp-match? #rx"hires" s) 96000] [else 44100])) (define (mock-fingerprint p) (string-append "mock:" (file->string p))) (define (mock-convert p rate compression) (set! convert-count (add1 convert-count)) (call-with-output-file p #:exists 'replace (lambda (out) (fprintf out "converted to ~a compression ~a" rate compression))) (lambda () rate)) (define first-summary (manage-flac-tree tmp #:inspect-flac-proc mock-inspect #:fingerprint-proc mock-fingerprint #:convert-proc mock-convert)) (check-equal? (assoc 'seen first-summary) '(seen . 2)) (check-equal? (assoc 'new first-summary) '(new . 2)) (check-equal? (assoc 'converted first-summary) '(converted . 1)) (check-equal? convert-count 1) (define second-summary (manage-flac-tree tmp #:inspect-flac-proc mock-inspect #:fingerprint-proc mock-fingerprint #:convert-proc mock-convert)) (check-equal? (assoc 'seen second-summary) '(seen . 2)) (check-equal? (assoc 'unchanged second-summary) '(unchanged . 2)) (check-equal? convert-count 1) (delete-file cd) (define third-summary (manage-flac-tree tmp #:inspect-flac-proc mock-inspect #:fingerprint-proc mock-fingerprint #:convert-proc mock-convert)) (check-equal? (assoc 'removed third-summary) '(removed . 1)) (check-equal? (assoc 'unchanged third-summary) '(unchanged . 1)) (delete-directory/files tmp)