#lang racket/base (require racket/file racket/path racket/place "util.rkt") (provide convert-flac-to-target-in-place) (define (temp-output-path input-path) (define-values (base name dir?) (split-path input-path)) (define name-str (path->string name)) (build-path base (format ".~a.tmp-~a.flac" name-str (current-inexact-milliseconds)))) (define (settings->alist max-sample-rate compression-level) (list (cons 'target-sample-rate max-sample-rate) (cons 'compression-level compression-level))) (define (convert-flac-to-target-in-place input-path max-sample-rate compression-level) (define tmp-path (temp-output-path input-path)) (define worker (place ch (define msg (place-channel-get ch)) (define in-file (list-ref msg 0)) (define out-file (list-ref msg 1)) (define settings (list-ref msg 2)) (with-handlers ([exn:fail? (lambda (e) (place-channel-put ch (list 'error (exn-message e))))]) (define audio-encode (dynamic-require 'racket-audio/audio-encoder 'audio-encode)) (define result (audio-encode in-file out-file (make-immutable-hash settings) #:encoder 'flac #:copy-tags? #t)) (place-channel-put ch (list 'ok result))))) (place-channel-put worker (list (path->string input-path) (path->string tmp-path) (settings->alist max-sample-rate compression-level))) (define response (place-channel-get worker)) (cond [(and (pair? response) (eq? (car response) 'ok)) (rename-file-or-directory tmp-path input-path #t) (cadr response)] [else (when (file-exists? tmp-path) (delete-file tmp-path)) (error 'convert-flac-to-target-in-place "conversion failed for ~a: ~a" input-path (if (and (pair? response) (pair? (cdr response))) (cadr response) response))]))