#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. }