This commit is contained in:
2026-08-09 19:55:28 +02:00
parent 8e6bf4e0f7
commit 1d9899c0d2
8 changed files with 29 additions and 20 deletions
+1 -1
View File
@@ -166,7 +166,7 @@ The first backend version supports mono and stereo input.
The FLAC backend uses the @tt{libFLAC} stream encoder. It writes interleaved The FLAC backend uses the @tt{libFLAC} stream encoder. It writes interleaved
integer PCM samples through the FLAC encoder API. When the requested output integer PCM samples through the FLAC encoder API. When the requested output
sample rate differs from the decoded input format, @racketmodname[racket-audio/private/pcm-converter] sample rate differs from the decoded input format, @tt{racket-audio/private/pcm-converter}
uses @racketmodname[racket-audio/resampler], backed by @tt{libsoxr}, to perform uses @racketmodname[racket-audio/resampler], backed by @tt{libsoxr}, to perform
PCM sample-rate conversion. Channel-count conversion is not handled by this PCM sample-rate conversion. Channel-count conversion is not handled by this
SoXR path; keep the source channel count for encoder-side conversion. SoXR path; keep the source channel count for encoder-side conversion.
+1 -1
View File
@@ -12,7 +12,7 @@
@defmodule[racket-audio/ffmpeg-decoder] @defmodule[racket-audio/ffmpeg-decoder]
This module provides an audio decoder based on the FFmpeg audio shim. It This module provides an audio decoder based on the FFmpeg audio shim. It
uses the lower-level @racketmodname[racket-sound/ffmpeg-ffi] module and presents a uses the lower-level @racketmodname[racket-audio/ffmpeg-ffi] module and presents a
callback-based decoder interface comparable to the other audio decoders. callback-based decoder interface comparable to the other audio decoders.
The native FFmpeg layer decodes audio to signed 32-bit interleaved PCM. The native FFmpeg layer decodes audio to signed 32-bit interleaved PCM.
+1 -1
View File
@@ -90,7 +90,7 @@ Small and stable structures, such as @tt{AVRational} and
then calculates the correct field offsets for the current platform ABI and then calculates the correct field offsets for the current platform ABI and
creates the corresponding pointer type, constructor, accessors and mutators. creates the corresponding pointer type, constructor, accessors and mutators.
The larger FFmpeg structures are handled by @racket[def-cstruct] from The larger FFmpeg structures are handled by @tt{def-cstruct} from
@filepath{private/cstruct-helper.rkt}. Structures such as @filepath{private/cstruct-helper.rkt}. Structures such as
@tt{AVCodecParameters}, @tt{AVStream}, @tt{AVFormatContext}, @tt{AVFrame} and @tt{AVCodecParameters}, @tt{AVStream}, @tt{AVFormatContext}, @tt{AVFrame} and
@tt{AVPacket} are large and may differ between FFmpeg major versions. The @tt{AVPacket} are large and may differ between FFmpeg major versions. The
+12 -5
View File
@@ -9,7 +9,7 @@
@title{flac-decoder} @title{flac-decoder}
@author[@author+email["Hans Dijkema" "hans@dijkewijk.nl"]] @author[@author+email["Hans Dijkema" "hans@dijkewijk.nl"]]
@defmodule[racket-audio/flac-decoder] @defmodule[racket-audio/flac-decoder #:use-sources (racket-audio/flac-definitions)]
This module provides a small decoder interface on top of the FLAC This module provides a small decoder interface on top of the FLAC
FFI layer. It opens a decoder for a file, reads stream metadata, FFI layer. It opens a decoder for a file, reads stream metadata,
@@ -33,12 +33,12 @@ exist, the result is @racket[#f].
Otherwise a native decoder handler is created with Otherwise a native decoder handler is created with
@racket[flac-ffi-decoder-handler], initialized with the file, and @racket[flac-ffi-decoder-handler], initialized with the file, and
wrapped in a @racket[flac-handle]. The given callbacks are stored wrapped in a @racket[flac-handle?]. The given callbacks are stored
in the handle. in the handle.
When metadata of type @racket['streaminfo] is processed and When metadata of type @racket['streaminfo] is processed and
@racket[cb-stream-info] is a procedure, it is called with a @racket[cb-stream-info] is a procedure, it is called with a
@racket[flac-stream-info] value. @racket[flac-stream-info?] value.
When decoded audio data is processed and @racket[cb-audio] is a When decoded audio data is processed and @racket[cb-audio] is a
procedure, it is called as procedure, it is called as
@@ -80,7 +80,7 @@ with @racket['stopped-reading] and @racket[reading] is reset to
Whenever pending metadata is available, it is processed with Whenever pending metadata is available, it is processed with
@racket[process-meta]. For metadata of type @racket[process-meta]. For metadata of type
@racket['streaminfo], a @racket[flac-stream-info] value is @racket['streaminfo], a @racket[flac-stream-info?] value is
constructed, stored in the handle, and passed to the constructed, stored in the handle, and passed to the
stream-info callback. stream-info callback.
@@ -110,7 +110,7 @@ metadata is processed and the stored stream info is returned.
Otherwise the result is @racket[#f]. Otherwise the result is @racket[#f].
Only metadata of type @racket['streaminfo] is converted into a Only metadata of type @racket['streaminfo] is converted into a
@racket[flac-stream-info] value by this module. @racket[flac-stream-info?] value by this module.
} }
@defproc[(flac-stop [handle flac-handle?]) void?]{ @defproc[(flac-stop [handle flac-handle?]) void?]{
@@ -125,6 +125,13 @@ The procedure prints timing information before and after the
wait. wait.
} }
@defproc[(flac-duration [handle flac-handle?])
(or/c #f exact-nonnegative-integer?)]{
Returns the rounded duration in seconds, or @racket[#f] while no stream
information is available.
}
@section{Diagnostic bindings} @section{Diagnostic bindings}
@defthing[kinds hash?]{ @defthing[kinds hash?]{
+2
View File
@@ -27,6 +27,8 @@
@title{@elem{Introduction racket-audio}} @title{@elem{Introduction racket-audio}}
@defmodule[racket-audio]
@;;title{racket-audio} @;;title{racket-audio}
@author[@author+email["Hans Dijkema" "hans@dijkewijk.nl"]] @author[@author+email["Hans Dijkema" "hans@dijkewijk.nl"]]
+6 -6
View File
@@ -16,10 +16,10 @@ reports stream information through a callback, streams decoded PCM
buffers, and supports stopping and seeking. buffers, and supports stopping and seeking.
The module is intended to be used through The module is intended to be used through
@racketmodname[racket-sound/audio-decoder], but its procedures can also @racketmodname[racket-audio/audio-decoder], but its procedures can also
be used directly. be used directly.
@section{Validation} @section[#:tag "mp3-decoder-validation"]{Validation}
@defproc[(mp3-valid? [mp3-file any/c]) boolean?]{ @defproc[(mp3-valid? [mp3-file any/c]) boolean?]{
@@ -27,14 +27,14 @@ Returns #t.
The current implementation does not inspect mp3-file. This procedure The current implementation does not inspect mp3-file. This procedure
exists to satisfy the reader interface used by exists to satisfy the reader interface used by
@racketmodname[racket-sound/audio-decoder]. @racketmodname[racket-audio/audio-decoder].
Basic validation such as file existence and extension matching is Basic validation such as file existence and extension matching is
performed in the higher-level module. This procedure therefore acts as performed in the higher-level module. This procedure therefore acts as
an additional hook and currently accepts all inputs. an additional hook and currently accepts all inputs.
} }
@section{Opening} @section[#:tag "mp3-decoder-opening"]{Opening}
@defproc[(mp3-open [mp3-file* (or/c path? string?)] @defproc[(mp3-open [mp3-file* (or/c path? string?)]
[cb-stream-info procedure?] [cb-stream-info procedure?]
@@ -68,7 +68,7 @@ where info is a mutable hash containing at least:
@item{'total-samples}] @item{'total-samples}]
} }
@section{Reading} @section[#:tag "mp3-decoder-reading"]{Reading}
@defproc[(mp3-read [handle struct?]) any/c]{ @defproc[(mp3-read [handle struct?]) any/c]{
@@ -127,7 +127,7 @@ If the total number of samples is unavailable or equal to -1, this
procedure has no effect. procedure has no effect.
} }
@section{Stopping} @section[#:tag "mp3-decoder-stopping"]{Stopping}
@defproc[(mp3-stop [handle struct?]) void?]{ @defproc[(mp3-stop [handle struct?]) void?]{
+5 -5
View File
@@ -71,10 +71,10 @@ Example:
This binding is also re-exported by This binding is also re-exported by
@racketmodname[racket-audio/audio-decoder] and by @racketmodname[racket-audio/audio-decoder] and by
@racketmodname[racket-audio/main]. @racketmodname[racket-audio].
} }
@section{Validation} @section[#:tag "opusfile-decoder-validation"]{Validation}
@defproc[(opusfile-valid? [audio-file any/c]) boolean?]{ @defproc[(opusfile-valid? [audio-file any/c]) boolean?]{
@@ -86,7 +86,7 @@ when the file is opened by @racket[opusfile-open]. The generic decoder
layer also performs extension and existence checks before opening a file. layer also performs extension and existence checks before opening a file.
} }
@section{Opening} @section[#:tag "opusfile-decoder-opening"]{Opening}
@defproc[(opusfile-open [audio-file (or/c path? string?)] @defproc[(opusfile-open [audio-file (or/c path? string?)]
[cb-stream-info procedure?] [cb-stream-info procedure?]
@@ -125,7 +125,7 @@ where @racket[info] is a mutable hash containing at least:
or the value reported by @tt{libopusfile}.}] or the value reported by @tt{libopusfile}.}]
} }
@section{Reading} @section[#:tag "opusfile-decoder-reading"]{Reading}
@defproc[(opusfile-read [handle struct?]) any/c]{ @defproc[(opusfile-read [handle struct?]) any/c]{
@@ -176,7 +176,7 @@ a target decoded sample and stores it as a pending seek request. The
actual native seek is performed later by @racket[opusfile-read]. actual native seek is performed later by @racket[opusfile-read].
} }
@section{Stopping} @section[#:tag "opusfile-decoder-stopping"]{Stopping}
@defproc[(opusfile-stop [handle struct?]) void?]{ @defproc[(opusfile-stop [handle struct?]) void?]{
+1 -1
View File
@@ -12,7 +12,7 @@
@defmodule[racket-audio/play-test] @defmodule[racket-audio/play-test]
The @racketmodname[racket-audio/play-test.rkt] module is a small integration test and The @racketmodname[racket-audio/play-test] module is a small integration test and
usage example for @racketmodname[racket-audio/audio-player]. It is not the public usage example for @racketmodname[racket-audio/audio-player]. It is not the public
playback API itself; normal applications should use @racketmodname[racket-audio/audio-player] playback API itself; normal applications should use @racketmodname[racket-audio/audio-player]
directly. This module shows how a program can create an audio player, observe directly. This module shows how a program can create an audio player, observe