Resampling
sf_resample() converts an NDArray from one sample rate to another using libsamplerate.
Full Signature
function sf_resample(
NDArray $input,
int $inputRate,
int $outputRate,
ResampleQuality $quality = ResampleQuality::Best,
?int $chunkSize = 2048,
): NDArrayTwo Modes
Chunked progressive (default)
When $chunkSize is non-null, the function processes the input signal in chunks. A single output buffer is pre-allocated and filled chunk by chunk, then wrapped in a single NDArray at the end. This is safe for large signals.
$y = sf_resample($x, 44100, 16000); // default chunkSize = 2048You can control chunk size (in frames):
$y = sf_resample($x, 44100, 16000, chunkSize: 8192);One-shot simple
When $chunkSize is null, the function process the input signal in a single pass. This is best for small signals where the convenience outweighs the memory trade-off.
$resampled = sf_resample($audio, 44100, 8000, chunkSize: null);Both modes produce identical output for the same input and ratio.
Quality Levels
Four quality levels trade CPU time for frequency response accuracy:
| Level | Description | Use Case |
|---|---|---|
ResampleQuality::Best | Band-limited sinc, highest quality | Final output, mastering |
ResampleQuality::Medium | Band-limited sinc, medium quality | General purpose |
ResampleQuality::Fastest | Band-limited sinc, fastest | Preview, real-time |
ResampleQuality::Linear | Linear interpolation | Minimum latency, low quality |
use PhpMlKit\SoundFile\Enums\ResampleQuality;
$high = sf_resample($audio, 44100, 48000, quality: ResampleQuality::Best);
$fast = sf_resample($audio, 44100, 48000, quality: ResampleQuality::Fastest);DType Handling
libsamplerate operates on 32-bit float internally. The input is automatically converted to Float32 if it has a different dtype:
// Int16 input — automatically converted to Float32
$audio = NDArray::array([[100], [200], [300]], DType::Int16);
$resampled = sf_resample($audio, 8000, 16000);
// $resampled->dtype() === DType::Float32The output is always Float32.
Multi-channel
Stereo and multi-channel inputs are resampled with all channels preserved:
$stereo = NDArray::array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]], DType::Float32);
$resampled = sf_resample($stereo, 8000, 16000);
// Shape: [6, 2] — both channels resampled independentlyFrame Count Accuracy
The output frame count is computed as ceil(inputFrames × outputRate / inputRate). For exact ratios this is precise. For non-integer ratios, the output may have one extra frame due to ceiling.