Added capability information

This commit is contained in:
2026-08-08 14:20:46 +02:00
parent 070f6bd12a
commit 8e6bf4e0f7
7 changed files with 119 additions and 19 deletions
+26 -1
View File
@@ -10,6 +10,7 @@
racket/contract
racket/string
racket/path
racket-mimetypes
)
(provide audio-open
@@ -24,6 +25,8 @@
make-audio-reader
audio-handle?
audio-supported-extensions
audio-supported-formats
audio-decoder-for-extension
current-opusfile-output-format
opusfile-output-format?
)
@@ -107,6 +110,20 @@
(define (audio-supported-extensions)
known-extensions)
(define/contract (audio-supported-formats)
(-> (listof
(cons/c string?
string?)))
(for/list ((extension
(in-list known-extensions)))
(cons
extension
(mimetype-for-ext
(string-append "audio."
extension)
#:default
"application/octet-stream"))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Register audio reader
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -268,6 +285,14 @@
(cons 'wma 'ffmpeg)
(cons 'matroska 'ffmpeg))))
(define/contract (audio-decoder-for-extension extension)
(-> (or/c string? symbol?)
(or/c #f symbol?))
(hash-ref
reader-for-kind
(audio-format-for-extension extension)
#f))
(define (find-reader audio-file)
@@ -286,4 +311,4 @@
) ; end of module
+2 -1
View File
@@ -414,7 +414,8 @@
(audio-seek ao-dec percentage)))
(define (volume percentage)
(set! req-volume percentage))
(set! req-volume percentage)
(check-volume))
(define (ao-buf-ms)
(ao-playback-buf-ms))
+32 -16
View File
@@ -10,6 +10,7 @@
audio-sniff-format
audio-sniff-format/extension
audio-sniff-extension
audio-format-for-extension
audio-format-matches?
audio-format-known?)
@@ -46,6 +47,30 @@
(substring s 1)
s))])))
(define (audio-format-for-extension* extension)
(let* ((text (string-downcase
(format "~a" extension)))
(normalized
(if (string-prefix? text ".")
(substring text 1)
text)))
(case (string->symbol normalized)
[(mp3 mp2 mp1) 'mp3]
[(flac) 'flac]
[(ogg oga) 'ogg]
[(opus) 'opus]
[(wav wave) 'wav]
[(aif aiff aifc) 'aiff]
[(m4a mp4 m4b m4p) 'mp4]
[(aac) 'aac]
[(alac) 'alac]
[(ac3) 'ac3]
[(ape) 'ape]
[(wv wvp wvpk wavpack) 'wavpack]
[(wma asf) 'wma]
[(webm mka mkv) 'matroska]
[else 'unknown])))
(define (file-readable-status file)
(cond
[(not (file-exists? file)) 'file-not-found]
@@ -294,22 +319,9 @@
fmt]
[(not (eq? fmt 'unknown)) fmt]
[else
(case (string->symbol (or (audio-sniff-extension* file) ""))
[(mp3 mp2 mp1) 'mp3]
[(flac) 'flac]
[(ogg oga) 'ogg]
[(opus) 'opus]
[(wav wave) 'wav]
[(aif aiff aifc) 'aiff]
[(m4a mp4 m4b m4p) 'mp4]
[(aac) 'aac]
[(alac) 'alac]
[(ac3) 'ac3]
[(ape) 'ape]
[(wv wvp wvpk wavpack) 'wavpack]
[(wma asf) 'wma]
[(webm mka mkv) 'matroska]
[else 'unknown])])))
(audio-format-for-extension*
(or (audio-sniff-extension* file)
""))])))
(define (audio-format-known?* fmt)
(not (eq? (memq fmt audio-formats) #f)))
@@ -321,6 +333,10 @@
(-> path-string? (or/c string? #f))
(audio-sniff-extension* file))
(define/contract (audio-format-for-extension extension)
(-> (or/c string? symbol?) audio-format?)
(audio-format-for-extension* extension))
(define/contract (audio-sniff-format file)
(-> path-string? audio-format?)
(audio-sniff-format* file))
+1
View File
@@ -15,6 +15,7 @@
'("racket/gui" "racket/base" "racket"
"finalizer" "draw-lib" "net-lib"
"simple-log" "simple-ini" "racket-sprintf"
"racket-mimetypes"
"early-return" "let-assert"
"uni-channel" "port-channel"
"rackunit-lib"
+7
View File
@@ -3,12 +3,19 @@
(require "taglib.rkt"
"audio-sniffer.rkt"
"audio-player.rkt"
(only-in "audio-decoder.rkt"
audio-supported-extensions
audio-supported-formats
audio-decoder-for-extension)
"opusfile-decoder.rkt"
)
(provide (all-from-out "taglib.rkt")
(all-from-out "audio-sniffer.rkt")
(all-from-out "audio-player.rkt")
audio-supported-extensions
audio-supported-formats
audio-decoder-for-extension
current-opusfile-output-format
opusfile-output-format?
)
+19 -1
View File
@@ -105,6 +105,24 @@ Returns the current list of supported filename extensions. This is the
same list returned by @racket[audio-known-exts?].
}
@defproc[(audio-supported-formats)
(listof (cons/c string? string?))]{
Returns the supported filename extensions together with the MIME type
reported by @racketmodname[racket-mimetypes]. Unknown MIME types use
@racket["application/octet-stream"].
}
@defproc[(audio-decoder-for-extension
[extension (or/c string? symbol?)])
(or/c #f symbol?)]{
Returns the decoder selected for audio with @racket[extension], such as
@racket['flac], @racket['opusfile], or @racket['ffmpeg]. The result is
@racket[#f] when the extension is not recognized. Actual playback still
sniffs the file contents before selecting its decoder.
}
@section{Built-in decoder selection}
The built-in decoder table contains:
@@ -306,4 +324,4 @@ A backend integrated through this interface should provide:
Once registered, files with matching extensions can be opened through
@racket[audio-open] in the same way as the built-in FLAC, MP3,
Opusfile, and FFmpeg backends.
Opusfile, and FFmpeg backends.
+32
View File
@@ -0,0 +1,32 @@
#lang racket/base
(require rackunit
racket-audio)
(define formats
(audio-supported-formats))
(check-not-false
(member "flac"
(audio-supported-extensions)))
(check-equal?
(cdr (assoc "flac" formats))
"audio/x-flac")
(check-eq?
(audio-decoder-for-extension "flac")
'flac)
(check-eq?
(audio-decoder-for-extension ".mp3")
'ffmpeg)
(check-not-false
(member (audio-decoder-for-extension 'opus)
'(opusfile ffmpeg)))
(check-false
(audio-decoder-for-extension "not-audio"))
(for ((extension
(in-list
(audio-supported-extensions))))
(check-true
(symbol?
(audio-decoder-for-extension extension))))