AudioResampler

Converts interleaved float audio from one sample rate to another.

The engine converts the decoder's rate to the rate that the audio device accepted. By default it uses its own windowed-sinc filter, written in Kotlin. An AudioResamplerFactory in AudioConfig.resampler replaces that filter.

Where it runs

One instance for each audio stream. It runs after the channel mix, so every buffer has the device's channel count, and before the tempo stage. Samples are interleaved: frame after frame, with one value for each channel in a frame.

Threading

The engine never calls two members at the same time, so an implementation needs no lock. A filter may hold input between calls, because it needs samples on both sides of each output.

Limits

The engine allocates the output array before each call, and never more than 4 Mi float values for one buffer. An outputCapacity below zero or past that size, or a process or flush answer outside zero to that capacity, stops playback with PlaybackError.DecoderFailed.

Functions

Link copied to clipboard
abstract override fun close()

Releases what the resampler holds. The engine calls nothing after it.

Link copied to clipboard
abstract fun flush(output: FloatArray): Int

Writes what this resampler still holds, at the end of the stream. output holds at least outputCapacity(0) frames.

Link copied to clipboard
abstract fun outputCapacity(inputFrames: Int): Int

The most frames that the next process call can write for inputFrames frames of input, counting what this resampler holds from earlier calls. The engine sizes the output array from this answer. With zero input, it is the most frames that flush can write.

Link copied to clipboard
abstract fun process(input: FloatArray, frames: Int, output: FloatArray): Int

Converts frames frames of interleaved input and writes the result to output, which holds at least outputCapacity(frames) frames. The engine never keeps input after the call returns.

Link copied to clipboard
abstract fun reset()

Drops everything held, for a seek. The next process call starts a new signal.