102 lines
4.0 KiB
Racket
102 lines
4.0 KiB
Racket
#lang scribble/manual
|
|
|
|
@title{PCM resampling with SoXR}
|
|
|
|
@defmodule[racket-audio/resampler]
|
|
|
|
This module provides a small Racket wrapper around @tt{libsoxr}. It is meant
|
|
for interleaved PCM buffers such as stereo @tt{L R L R ...} data. It supports
|
|
sample-rate conversion and the PCM datatypes that SoXR can process directly:
|
|
@racket['s16], @racket['s32], @racket['float32] and @racket['float64]. Packed
|
|
24-bit PCM is supported by the wrapper by expanding @racket['s24] input to
|
|
@racket['s32] before calling SoXR and packing @racket['s32] output back to
|
|
@racket['s24] afterwards.
|
|
|
|
SoXR does not perform general channel-layout conversion in this wrapper. Use it
|
|
for unchanged channel counts, for example mono-to-mono or stereo-to-stereo.
|
|
|
|
@defproc[(resampler-available?) boolean?]{
|
|
Returns @racket[#t] when @tt{libsoxr} was loaded.
|
|
}
|
|
|
|
@defproc[(resampler-version) string?]{
|
|
Returns the version string reported by @tt{libsoxr}.
|
|
}
|
|
|
|
@defproc[(make-resampler
|
|
[input-rate exact-positive-integer?]
|
|
[output-rate exact-positive-integer?]
|
|
[channels exact-positive-integer?]
|
|
[#:input-format input-format symbol? 's32]
|
|
[#:output-format output-format symbol? 's32]
|
|
[#:quality quality symbol? 'hq]
|
|
[#:phase phase symbol? 'linear]
|
|
[#:steep-filter? steep-filter? boolean? #f]
|
|
[#:scale scale real? 1.0]
|
|
[#:no-dither? no-dither? boolean? #f]
|
|
[#:num-threads num-threads exact-positive-integer? 1])
|
|
resampler?]{
|
|
Creates a streaming resampler. The supported PCM formats are @racket['s16],
|
|
@racket['s24], @racket['s32], @racket['float32] and @racket['float64].
|
|
|
|
The quality value selects a SoXR resampling recipe. Useful values are
|
|
@racket['qq], @racket['lq], @racket['mq], @racket['hq], @racket['vhq],
|
|
@racket['16-bit], @racket['20-bit], @racket['24-bit], @racket['28-bit] and
|
|
@racket['32-bit]. The @racket['24-bit] quality recipe is a filter precision
|
|
setting; it is not the same thing as 24-bit PCM output. Use
|
|
@racket[#:output-format 's24] for packed 24-bit output.
|
|
}
|
|
|
|
@defproc[(resampler-convert
|
|
[r resampler?]
|
|
[buffer bytes?]
|
|
[size exact-nonnegative-integer? (bytes-length buffer)])
|
|
(values bytes? exact-nonnegative-integer?)]{
|
|
Feeds interleaved PCM bytes to the resampler and returns converted PCM bytes and
|
|
the number of output frames. A frame contains one sample for each channel.
|
|
}
|
|
|
|
@defproc[(resampler-drain [r resampler?])
|
|
(values bytes? exact-nonnegative-integer?)]{
|
|
Flushes delayed output after the last input block and returns converted bytes and
|
|
frames.
|
|
}
|
|
|
|
@defproc[(resampler-clear! [r resampler?]) boolean?]{
|
|
Clears the resampler state so the same instance can be reused for a fresh signal
|
|
with the same configuration.
|
|
}
|
|
|
|
@defproc[(resampler-close! [r resampler?]) boolean?]{
|
|
Releases the native SoXR resampler. Calling this more than once is harmless.
|
|
}
|
|
|
|
@defproc[(resample-bytes
|
|
[buffer bytes?]
|
|
[input-rate exact-positive-integer?]
|
|
[output-rate exact-positive-integer?]
|
|
[channels exact-positive-integer?]
|
|
[#:size size exact-nonnegative-integer? (bytes-length buffer)]
|
|
[#:input-format input-format symbol? 's32]
|
|
[#:output-format output-format symbol? 's32]
|
|
[#:quality quality symbol? 'hq]
|
|
[#:phase phase symbol? 'linear]
|
|
[#:steep-filter? steep-filter? boolean? #f]
|
|
[#:scale scale real? 1.0]
|
|
[#:no-dither? no-dither? boolean? #f]
|
|
[#:num-threads num-threads exact-positive-integer? 1])
|
|
(values bytes? exact-nonnegative-integer?)]{
|
|
Convenience function for one buffer. It creates a resampler, processes the
|
|
input, drains delayed samples and closes the native state.
|
|
}
|
|
|
|
@defproc[(pcm-format? [v any/c]) boolean?]{
|
|
Returns whether @racket[v] is one of the supported PCM format symbols.
|
|
}
|
|
|
|
@defproc[(pcm-format-sample-bytes [fmt symbol?]) exact-positive-integer?]{
|
|
Returns the packed sample size in bytes for @racket[fmt]. For @racket['s24]
|
|
this is @racket[3], even though the wrapper internally expands to 32-bit samples
|
|
for SoXR.
|
|
}
|