PHPackages                             phpmlkit/soundfile - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Image &amp; Media](/categories/media)
4. /
5. phpmlkit/soundfile

ActivePlatform-package[Image &amp; Media](/categories/media)

phpmlkit/soundfile
==================

Low-level libsndfile + libsamplerate bindings for PHP via FFI

1.2.0(1mo ago)015MITPHPPHP &gt;=8.2CI passing

Since May 29Pushed 1mo agoCompare

[ Source](https://github.com/phpmlkit/soundfile)[ Packagist](https://packagist.org/packages/phpmlkit/soundfile)[ RSS](/packages/phpmlkit-soundfile/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (4)Dependencies (10)Versions (5)Used By (0)

PHP SoundFile
=============

[](#php-soundfile)

Low-level audio I/O and resampling for PHP, backed by libsndfile and libsamplerate

 [![Latest Version](https://camo.githubusercontent.com/10b34e5b2d1220c742d41b99021e42d85791c761c43a12f9a7cb13607e0f9e63/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7068706d6c6b69742f736f756e6466696c653f7374796c653d666c61742d737175617265)](https://packagist.org/packages/phpmlkit/soundfile) [![GitHub Workflow Status](https://camo.githubusercontent.com/d4cb077d6c044e551c6f559dbce5a31b04aa7475b9f1dafc31095fde8100ba9f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f7068706d6c6b69742f736f756e6466696c652f74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/phpmlkit/soundfile/actions) [![Total Downloads](https://camo.githubusercontent.com/a2e79f3d80416f717afd4fd6bd2ec1d2695e0f1285db0f00f2138a19c1085d94/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7068706d6c6b69742f736f756e6466696c653f7374796c653d666c61742d737175617265)](https://packagist.org/packages/phpmlkit/soundfile) [![License](https://camo.githubusercontent.com/8bb50fd2278f18fc326bf71f6e88ca8f884f72f179d3e555e20ed30157190d0d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e2e737667)](LICENSE)

Features
--------

[](#features)

- **Read &amp; write audio files** — WAV, FLAC, Ogg Vorbis, MP3, AIFF, and 20+ other formats
- **NDArray-native** — data flows in and out as `[frames × channels]` NDArrays, no intermediate buffers
- **Streaming I/O** — instance-based `SoundFile` class with read, write, seek, tell, and block iteration
- **One-shot convenience** — `sf_read()` and `sf_write()` for simple load/save without managing a handle
- **Sample rate conversion** — `sf_resample()` with chunked progressive mode for large files, one-shot simple mode for small signals, and four quality levels
- **Metadata** — read and write title, artist, album, track number, and genre tags
- **Type-safe** — PHP 8.2+ with backed enums, readonly value objects, and strict types throughout

Installation
------------

[](#installation)

```
composer require phpmlkit/soundfile
```

**Requirements:** PHP 8.2 or higher with the FFI extension enabled.

The package ships pre-compiled shared libraries for macOS (arm64, x86\_64), Linux (x86\_64, arm64), and Windows (x64).

Quick Start
-----------

[](#quick-start)

### Read and write

[](#read-and-write)

```
use function PhpMlKit\SoundFile\{sf_read, sf_write, sf_info};

// Read a file — returns [NDArray, SfInfo]
[$audio, $info] = sf_read('input.wav');
// $audio shape: [441000] (mono, Float32)

// Write it back (format and subtype auto-detected from extension)
sf_write('output.wav', $audio, $info->sampleRate);

// Probe signal properties without loading data
$info = sf_info('input.wav');
echo "{$info->frames} frames, {$info->channels} channels, {$info->duration()}s";
```

### Resample

[](#resample)

```
use function PhpMlKit\SoundFile\sf_resample;
use PhpMlKit\SoundFile\Enums\ResampleQuality;

// Chunked progressive — safe for large files (default)
$resampled = sf_resample($audio, inputRate: 44100, outputRate: 22050);

// One-shot simple — best for small signals
$resampled = sf_resample($audio, 44100, 16000, chunkSize: null);

// Best quality, explicit chunk size
$resampled = sf_resample(
    $audio, 44100, 8000,
    quality: ResampleQuality::Best,
    chunkSize: 4096,
);
```

### Streaming with SoundFile

[](#streaming-with-soundfile)

```
use PhpMlKit\SoundFile\SoundFile;
use PhpMlKit\SoundFile\Enums\FileMode;

// Open for reading
$sf = new SoundFile('input.wav', FileMode::Read);

// Seek and read
$sf->seek(44100);
$chunk = $sf->read(512);
echo $sf->tell(); // 44612

// Iterate in blocks
foreach ($sf->blocks(1024) as $block) {
    process($block);
}
$sf->close();

// Open for writing
$out = new SoundFile('output.wav', FileMode::Write,
    sampleRate: 44100, channels: 2,
);
$out->setTitle('My Track');
$out->setArtist('My Artist');
$out->write($stereoData);
$out->close();
```

> See the [full documentation](https://phpmlkit.github.io/soundfile/) for detailed guides, tutorials, and a complete API reference.

Core Concepts
-------------

[](#core-concepts)

### Audio data layout

[](#audio-data-layout)

All NDArrays in this library use the shape `[frames × channels]` — time first, channel second. A mono file produces `[N]` or `[N, 1]` depending on the `always2d` flag. Stereo files always produce `[N, 2]`.

### DType, SampleFormat, and AudioFormat

[](#dtype-sampleformat-and-audioformat)

Three independent choices interact when writing a file:

ConceptWhat it controlsExample**NDArray DType**How the data is stored in memory`Float32`, `Int16`, `Float64`**SampleFormat**The file's encoding subtype`Pcm16`, `Float`, `Vorbis`**AudioFormat**The container`Wav`, `Flac`, `Ogg`When you call `sf_write()`, the NDArray's dtype is **automatically converted** to match the target `SampleFormat`. You never need to call `astype()` yourself. The combination of `AudioFormat` and `SampleFormat` is validated against libsndfile's compatibility table — an incompatible pair (like `Ogg + Pcm16`) throws a `SoundFileException` before any data is written.

API Reference
-------------

[](#api-reference)

### Global Functions

[](#global-functions)

These are importable with `use function PhpMlKit\SoundFile\{...}` and provide the simplest path for common operations.

#### `sf_read()`

[](#sf_read)

Read an audio file into a single NDArray.

```
function sf_read(
    string $file,
    ?int $start = null,     // First frame (0-based; null = beginning)
    ?int $stop = null,      // One past last frame (null = EOF)
    bool $always2d = false, // If true, mono returns [frames, 1] instead of [frames]
    int $blocksize = 4096,  // Chunk size for internal read loop
): array // [NDArray, SfInfo]
```

The dtype matches the file's native format. The returned `SfInfo` object contains the file's signal properties (frames, channels, sample rate, format, etc.). For partial reads, use `start` and `stop` to specify a frame range. With `$always2d = false` (default), mono files return a 1D array for convenience.

```
[$data, $info] = sf_read('song.wav');
[$part, $info] = sf_read('song.wav', start: 44100, stop: 88200);
[$data, $info] = sf_read('song.wav', always2d: true);
```

#### `sf_write()`

[](#sf_write)

Write an NDArray to an audio file.

```
function sf_write(
    string $file,
    NDArray $data,               // [frames] or [frames, channels]
    int $sampleRate,             // Sample rate in Hz
    ?AudioFormat $format = null, // Inferred from extension if null
    ?SampleFormat $subtype = null, // Format's default if null
): void
```

1D arrays are automatically expanded to `[frames, 1]` before writing. The NDArray dtype is converted to match the target subtype.

```
sf_write('out.wav', $data, sampleRate: 44100);
sf_write('out.flac', $data, 44100, subtype: SampleFormat::Pcm24);
```

#### `sf_info()`

[](#sf_info)

Read signal properties without loading audio data. Opens the file, reads the header, and closes immediately.

```
function sf_info(string $file): SfInfo
```

#### `sf_metadata()`

[](#sf_metadata)

Read string tags (title, artist, album, etc.) without loading audio data.

```
function sf_metadata(string $file): SfMetadata
```

```
$meta = sf_metadata('song.wav');
echo $meta->artist;
```

#### `sf_check_format()`

[](#sf_check_format)

Validate that a container format and encoding subtype are compatible.

```
function sf_check_format(AudioFormat $format, SampleFormat $subtype): bool
```

```
sf_check_format(AudioFormat::Wav, SampleFormat::Pcm16);  // true
sf_check_format(AudioFormat::Ogg, SampleFormat::Pcm16);  // false
```

#### `sf_resample()`

[](#sf_resample)

Convert an NDArray from one sample rate to another.

```
function sf_resample(
    NDArray $input,                     // [frames, channels]
    int $inputRate,                     // Source sample rate in Hz
    int $outputRate,                    // Target sample rate in Hz
    ResampleQuality $quality = ResampleQuality::Best,
    ?int $chunkSize = 2048,             // null = one-shot, int = chunked progressive
): NDArray                                // [newFrames, channels] Float32
```

When `$chunkSize` is non-null (default), the function uses `src_process` in a loop with a single pre-allocated output buffer — safe for large signals. When null, it uses `src_simple` for a single-pass conversion.

The output is always `Float32` regardless of input dtype. Inputs of other dtypes are automatically converted.

```
$resampled = sf_resample($data, 44100, 22050);           // chunked progressive
$resampled = sf_resample($data, 44100, 8000, chunkSize: null); // one-shot simple
```

### Classes

[](#classes)

#### `SoundFile`

[](#soundfile)

An opened audio file handle for streaming read/write.

**Constructor:**

```
new SoundFile(
    string $path,
    FileMode $mode = FileMode::Read,
    // Write-mode parameters:
    ?int $sampleRate = null,
    ?int $channels = null,
    ?AudioFormat $format = null,
    ?SampleFormat $subtype = null,
)
```

In **read mode**, only `$path` and `$mode` are needed — metadata is read from the file header. In **write mode**, `$sampleRate`, `$channels`, `$format`, and `$subtype` are required (format defaults to the file extension, subtype defaults to the format's preferred).

**Instance methods:**

MethodDescription`read(?int $numFrames): NDArray`Read up to N frames from current position. Null = all remaining.`write(NDArray $data): void`Write frames. Shape must match the file's channel count.`seek(int $offset, int $whence = SEEK_SET): void`Move the read/write position.`tell(): int`Current frame position.`eof(): bool`Whether the position has reached the end.`blocks(int $size = 4096): Generator`Yield NDArrays of up to `$size` frames.`close(): void`Close the handle (called automatically by destructor).`info(): SfInfo`Signal properties (frames, channels, sample rate, format).`frames(): int`Total frames.`channels(): int`Channel count.`sampleRate(): int`Sample rate in Hz.**Metadata getters/setters** (read/write on open handles):

GetterSetterSF\_STR constant`title()``setTitle(string)`0x01`copyright()``setCopyright(string)`0x02`software()``setSoftware(string)`0x03`artist()``setArtist(string)`0x04`comment()``setComment(string)`0x05`date()``setDate(string)`0x06`album()``setAlbum(string)`0x07`license()``setLicense(string)`0x08`trackNumber()``setTrackNumber(string)`0x09`genre()``setGenre(string)`0x10#### `SfInfo`

[](#sfinfo)

Immutable signal properties describing an audio file.

**Factory methods:**

MethodDescription`SfInfo::probe(string $path): self`Open file, read header, close.`SfInfo::fromSfInfo(FFI\CData $sfInfo): self`Create from a populated libsndfile SF\_INFO struct.`SfInfo::forWrite(int $frames, int $channels, int $sampleRate, AudioFormat $format, SampleFormat $subtype): self`Create write-ready info.**Properties:**

PropertyTypeDescription`frames``int`Total frame count`channels``int`Number of audio channels`sampleRate``int`Sample rate in Hz`format``AudioFormat`Container format`sampleFormat``SampleFormat`Encoding subtype`sections``int`Number of data sections`seekable``bool`Whether the file supports seeking**Derived values:**

MethodReturnsDescription`duration()``float`Duration in seconds`nSamples()``int`Total sample values (`frames × channels`)**Immutable builders** — return a copy with one field changed:

MethodDescription`withFrames(int $f): self`Change frame count`withChannels(int $c): self`Change channel count`withSampleRate(int $sr): self`Change sample rate### Enums

[](#enums)

#### `AudioFormat`

[](#audioformat)

Container formats (25 cases). Values are libsndfile `SF_FORMAT_*` constants.

```
AudioFormat::Wav->extension();           // 'wav'
AudioFormat::fromExtension('flac');      // AudioFormat::Flac
AudioFormat::fromPath('song.mp3');       // AudioFormat::Mpeg
AudioFormat::Wav->defaultSampleFormat(); // SampleFormat::Pcm16
AudioFormat::Wav->compatibleSampleFormats(); // [PcmS8, Pcm16, Pcm24, ...]
```

#### `SampleFormat`

[](#sampleformat)

Encoding subtypes (20 cases). Values are libsndfile `SF_FORMAT_*` subtype constants.

```
SampleFormat::Pcm16->bitDepth();    // 16
SampleFormat::Pcm16->isInteger();   // true
SampleFormat::Float->isPcm();       // false
SampleFormat::Float->toDtype();     // DType::Float32
```

#### `FileMode`

[](#filemode)

File open modes.

CaseDescription`FileMode::Read`Open for reading`FileMode::Write`Open for writing (creates/truncates)`FileMode::ReadWrite`Open for both reading and writing#### `ResampleQuality`

[](#resamplequality)

libsamplerate converter quality levels.

CaseDescription`ResampleQuality::Best`Band-limited sinc, highest quality, slowest`ResampleQuality::Medium`Band-limited sinc, medium quality`ResampleQuality::Fastest`Band-limited sinc, fastest`ResampleQuality::Linear`Linear interpolation, fastest but lowest quality### Exceptions

[](#exceptions)

`SoundFileException` — thrown for I/O errors, invalid format combinations, closed-file operations, and resampling failures. Extends `\RuntimeException`.

Documentation
-------------

[](#documentation)

- [Full Documentation](https://phpmlkit.github.io/soundfile/)
- [What is SoundFile?](https://phpmlkit.github.io/soundfile/guide/getting-started/what-is-sndfile)
- [Quick Start](https://phpmlkit.github.io/soundfile/guide/getting-started/quick-start)
- [API Reference](https://phpmlkit.github.io/soundfile/api/)

Development
-----------

[](#development)

```
# Install PHP dependencies
composer install

# Run tests
composer test

# Run static analysis (PHPStan level 8)
composer lint

# Format code
composer cs:fix
```

License
-------

[](#license)

MIT

Credits
-------

[](#credits)

- [libsndfile](https://github.com/libsndfile/libsndfile) — the C library for reading and writing audio files
- [libsamplerate](https://github.com/libsndfile/libsamplerate) — the C library for sample rate conversion
- [phpmlkit/ndarray](https://github.com/phpmlkit/ndarray) — high-performance N-dimensional arrays for PHP

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance91

Actively maintained with recent releases

Popularity6

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~4 days

Total

4

Last Release

44d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/146c2eb02350558d165083e0018f5377f15f0e71493439c93ee60e7c7ac97fc1?d=identicon)[CodeWithKyrian](/maintainers/CodeWithKyrian)

---

Top Contributors

[![CodeWithKyrian](https://avatars.githubusercontent.com/u/48791154?v=4)](https://github.com/CodeWithKyrian "CodeWithKyrian (17 commits)")

---

Tags

audioffimp3wavoggflacsoundresamplelibsndfilelibsamplerate

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/phpmlkit-soundfile/health.svg)

```
[![Health](https://phpackages.com/badges/phpmlkit-soundfile/health.svg)](https://phpackages.com/packages/phpmlkit-soundfile)
```

###  Alternatives

[wapmorgan/media-file

A unified reader of metadata from audio &amp; video files

158238.5k3](/packages/wapmorgan-media-file)[php-ffmpeg/php-ffmpeg

FFMpeg PHP, an Object Oriented library to communicate with AVconv / ffmpeg

5.0k24.0M199](/packages/php-ffmpeg-php-ffmpeg)[kiwilan/php-audio

PHP package to parse and update audio files metadata, with `JamesHeinrich/getID3`.

3115.0k1](/packages/kiwilan-php-audio)[danog/madelineproto

Async PHP client API for the telegram MTProto protocol.

3.5k902.0k24](/packages/danog-madelineproto)[wapmorgan/mp3info

The fastest php library to extract mp3 tags &amp; meta information.

1461.4M18](/packages/wapmorgan-mp3info)[buggedcom/phpvideotoolkit

PHPVideoToolkit is a set of classes aimed to provide a modular, object oriented and accessible interface for interacting with videos and audio through the FFmpeg program.

26385.2k1](/packages/buggedcom-phpvideotoolkit)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
