From 930903fb427bb231c4cfa0d80a2e979edb1dfa61 Mon Sep 17 00:00:00 2001 From: Hans Dijkema Date: Wed, 10 Jun 2026 08:31:47 +0200 Subject: [PATCH] No places. --- README.md | 3 +- flac2opus-manager.rkt | 4 +- private/convert-place.rkt | 63 ++++++++++++------------- private/opus-convert-place.rkt | 53 +++++++++++---------- private/scan.rkt | 3 +- private/util.rkt | 11 +++++ scribblings/audio-library-manager.scrbl | 3 +- 7 files changed, 77 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 449196d..e5b7918 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,7 @@ absolute mount points are not stored, and path separators are always `/`. ## FLAC 48 kHz manager The command keeps a FLAC directory tree at a maximum sample rate of 48 kHz. -Files above the configured threshold are converted in place through a Racket -place. The conversion path uses `racket-audio/audio-encoder` dynamically, so the +Files above the configured threshold are converted synchronously by the batch process. The conversion path uses `racket-audio/audio-encoder` dynamically, so the package can still compile on systems where the native audio libraries are not installed yet. diff --git a/flac2opus-manager.rkt b/flac2opus-manager.rkt index 6897f3b..a68b980 100644 --- a/flac2opus-manager.rkt +++ b/flac2opus-manager.rkt @@ -168,7 +168,9 @@ (summary-inc s 'removed))))) (define (find-source-files source-dir) - (filter (lambda (p) (not (manager-admin-relpath? (source-relpath-string source-dir p)))) + (filter (lambda (p) + (and (not (manager-temp-path? p)) + (not (manager-admin-relpath? (source-relpath-string source-dir p))))) (directory-file-paths source-dir))) (define (manage-flac2opus-tree source-directory target-directory diff --git a/private/convert-place.rkt b/private/convert-place.rkt index 94c6103..bb784df 100644 --- a/private/convert-place.rkt +++ b/private/convert-place.rkt @@ -1,9 +1,7 @@ #lang racket/base (require racket/file - racket/path - racket/place - "util.rkt") + racket/path) (provide convert-flac-to-target-in-place) @@ -12,35 +10,34 @@ (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 (settings->hash max-sample-rate compression-level) + (make-immutable-hash + (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 (delete-file/quiet path) + (with-handlers ([exn:fail? (lambda (_) #f)]) + (when (file-exists? path) (delete-file path)))) + +(define (convert-flac-to-target-in-place input-path max-sample-rate compression-level + #:progress-callback [progress-callback #f]) (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))])) + (define audio-encode (dynamic-require 'racket-audio/audio-encoder 'audio-encode)) + (with-handlers ([exn:break? + (lambda (e) + (delete-file/quiet tmp-path) + (raise e))] + [exn:fail? + (lambda (e) + (delete-file/quiet tmp-path) + (error 'convert-flac-to-target-in-place + "conversion failed for ~a: ~a" input-path (exn-message e)))]) + (define result + (audio-encode (path->string input-path) + (path->string tmp-path) + (settings->hash max-sample-rate compression-level) + #:encoder 'flac + #:copy-tags? #t + #:progress-callback progress-callback)) + (rename-file-or-directory tmp-path input-path #t) + result)) diff --git a/private/opus-convert-place.rkt b/private/opus-convert-place.rkt index c8b9349..5acd432 100644 --- a/private/opus-convert-place.rkt +++ b/private/opus-convert-place.rkt @@ -3,7 +3,6 @@ (require racket/file racket/list racket/path - racket/place racket/string "util.rkt") @@ -84,28 +83,34 @@ (tags-save! tags))) #:mode 'read-write)) -(define (convert-flac-to-opus input-path output-path kbps) +(define (delete-file/quiet path) + (with-handlers ([exn:fail? (lambda (_) #f)]) + (when (file-exists? path) (delete-file path)))) + +(define (convert-flac-to-opus input-path output-path kbps + #:progress-callback [progress-callback #f]) (define tmp-path (temp-output-path output-path)) (ensure-parent-directory! tmp-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 kbps (list-ref msg 2)) - (with-handlers ([exn:fail? (lambda (e) (place-channel-put ch (list 'error (exn-message e))))]) - (define-values (settings properties picture) (source-tags->settings in-file kbps)) - (define audio-encode (dynamic-require 'racket-audio/audio-encoder 'audio-encode)) - (define result (audio-encode in-file out-file settings #:encoder 'opus #:copy-tags? #f)) - (copy-all-tag-properties! out-file properties picture) - (place-channel-put ch (list 'ok result))))) - (place-channel-put worker (list (path->string input-path) (path->string tmp-path) kbps)) - (define response (place-channel-get worker)) - (cond [(and (pair? response) (eq? (car response) 'ok)) - (ensure-parent-directory! output-path) - (rename-file-or-directory tmp-path output-path #t) - (cadr response)] - [else - (when (file-exists? tmp-path) (delete-file tmp-path)) - (error 'convert-flac-to-opus "conversion failed for ~a: ~a" input-path - (if (and (pair? response) (pair? (cdr response))) (cadr response) response))])) + (with-handlers ([exn:break? + (lambda (e) + (delete-file/quiet tmp-path) + (raise e))] + [exn:fail? + (lambda (e) + (delete-file/quiet tmp-path) + (error 'convert-flac-to-opus + "conversion failed for ~a: ~a" input-path (exn-message e)))]) + (define-values (settings properties picture) + (source-tags->settings (path->string input-path) kbps)) + (define audio-encode (dynamic-require 'racket-audio/audio-encoder 'audio-encode)) + (define result + (audio-encode (path->string input-path) + (path->string tmp-path) + settings + #:encoder 'opus + #:copy-tags? #f + #:progress-callback progress-callback)) + (copy-all-tag-properties! (path->string tmp-path) properties picture) + (ensure-parent-directory! output-path) + (rename-file-or-directory tmp-path output-path #t) + result)) diff --git a/private/scan.rkt b/private/scan.rkt index 3f46e86..8a3c998 100644 --- a/private/scan.rkt +++ b/private/scan.rkt @@ -36,4 +36,5 @@ [else acc])))) (define (find-flac-files base-dir) - (sort-paths (filter flac-path? (find-regular-files base-dir)))) + (sort-paths (filter (lambda (p) (and (flac-path? p) (not (manager-temp-path? p)))) + (find-regular-files base-dir)))) diff --git a/private/util.rkt b/private/util.rkt index b3a367e..ea5f2f9 100644 --- a/private/util.rkt +++ b/private/util.rkt @@ -17,6 +17,7 @@ filesystem-path flac-path? opus-path? + manager-temp-path? directory-file-paths replace-path-extension ensure-parent-directory! @@ -112,6 +113,16 @@ (define (file-exists?/quiet p) (with-handlers ([exn:fail? (lambda (_) #f)]) (file-exists? p))) +(define (path-file-name-string p) + (let-values ([(base name dir?) (split-path p)]) + (and (path? name) (path->string name)))) + +(define (manager-temp-path? p) + (define name (path-file-name-string p)) + (and name + (string-prefix? name ".") + (regexp-match? #rx"\\.tmp-[0-9.]+\\.(flac|opus)$" name))) + (define (flac-path? p) (and (file-exists?/quiet p) (extension-ci=? p ".flac"))) diff --git a/scribblings/audio-library-manager.scrbl b/scribblings/audio-library-manager.scrbl index f730cb1..e4ea9ca 100644 --- a/scribblings/audio-library-manager.scrbl +++ b/scribblings/audio-library-manager.scrbl @@ -24,8 +24,7 @@ so it can share the same database with the 48 kHz manager. @section{FLAC 48 kHz manager} The tool @filepath{flac-48khz-manager.rkt} keeps a FLAC tree at a maximum sample -rate of 48 kHz. Files with a higher sample rate are converted in place through a -worker place. The conversion path uses +rate of 48 kHz. Files with a higher sample rate are converted synchronously by the batch process. The conversion path uses @racketmodname[racket-audio/audio-encoder] dynamically, so the manager module can still be compiled on systems where the native audio libraries are not available.