Overview
libsndfile is the standard C library for audio file I/O, maintained by Erik de Castro Lopo. It provides a single, consistent API across dozens of audio file formats without requiring separate codec libraries for each one. The PascalAI binding exposes the full read/write pipeline — open a file, read or write sample frames in your preferred numeric type, seek, read metadata tags, and close.
Sample data is always interleaved: for a stereo file at 44100 Hz, one frame contains two samples (left, right). Reading 1024 frames returns 2048 values. The library handles all endianness and format conversion internally.
Requires libsndfile-dev. Ubuntu/Debian: sudo apt install libsndfile-dev
Supported Formats
| Format | Constant | Read | Write | Supported Encodings |
|---|---|---|---|---|
| WAV | sfWAV ($010000) | yes | yes | PCM 8/16/24/32-bit, float, mu-law, a-law |
| AIFF | sfAIFF ($020000) | yes | yes | PCM, float, compressed |
| FLAC | sfFLAC ($170000) | yes | yes | Lossless compression, PCM 8/16/24-bit |
| OGG | sfOGG ($200000) | yes | no | Vorbis container (read only in libsndfile core) |
| AU | sfAU ($030000) | yes | yes | Sun/NeXT audio, PCM, mu-law, a-law, float |
| RAW | sfRAW ($040000) | yes | yes | Headerless PCM, any rate/depth/channels — must specify format explicitly |
Sample Formats
| Sub-format | Constant | Bits | Typical Use |
|---|---|---|---|
| Short / PCM 16 | ssfPCM_16 ($0002) | 16 | CD audio, streaming, most common interchange format |
| Int / PCM 32 | ssfPCM_32 ($0004) | 32 | Professional DAW sessions, lossless archival |
| Float | ssfFloat ($0006) | 32 | Mixing, DSP processing, intermediate computation |
| Double | ssfDouble ($0007) | 64 | Scientific audio analysis, highest precision processing |
| PCM 8 | ssfPCM_S8 ($0001) | 8 | Legacy, telephony, very low-bandwidth storage |
| PCM 24 | ssfPCM_24 ($0003) | 24 | Studio recording, Blu-ray audio, high-fidelity archival |
| mu-law | ssfULaw ($0010) | — | Telephony (North America/Japan), G.711 compatibility |
| a-law | ssfALaw ($0011) | — | Telephony (Europe), G.711 compatibility |
vs. Similar Libraries
| Library | Focus | When to use libsndfile instead |
|---|---|---|
| PortAudio | Real-time audio I/O (microphone, speakers) | You need to read/write audio files, not stream to/from hardware devices |
| FFmpeg | Video + audio, many lossy codecs (MP3, AAC, H.264) | You only need audio files and want a lightweight dependency with no video overhead |
| SoX | Command-line audio conversion tool | You need a C library with a stable ABI that you can embed directly in your program |
Quick Start
Read a WAV file
uses libsndfile;
var sf := OpenRead('recording.wav');
if sf = 0 then
begin
WriteLn('Failed to open file');
Exit;
end;
var info := GetInfo(sf);
WriteLn('Sample rate: ' + IntToStr(info.SampleRate));
WriteLn('Channels: ' + IntToStr(info.Channels));
WriteLn('Frames: ' + IntToStr(info.Frames));
WriteLn('Duration: ' + FloatToStr(Duration(sf)) + 's');
{ Read first 1024 frames as 16-bit integers }
var samples := ReadShort(sf, 1024);
WriteLn('Read ' + IntToStr(Length(samples)) + ' samples');
Close(sf);
Write a WAV file (32-bit float)
uses libsndfile;
{ Build a 1-second 440 Hz sine wave at 44100 Hz, mono }
var rate := 44100;
var frames := rate;
var buf: array of Single;
SetLength(buf, frames);
for var i := 0 to frames - 1 do
buf[i] := Sin(2.0 * 3.14159265 * 440.0 * i / rate);
{ sfWAV = $010000, ssfFloat = $0006 }
var fmt := $010000 or $0006;
var sf := OpenWrite('sine440.wav', fmt, rate, 1);
WriteFloat(sf, buf);
Close(sf);
Convert an audio file to a different format
uses libsndfile;
{ Re-encode WAV PCM 16 to FLAC at same sample rate }
{ sfFLAC = $170000, ssfPCM_16 = $0002 }
var dstFmt := $170000 or $0002;
ConvertFile('input.wav', 'output.flac', dstFmt, 44100);
WriteLn('Conversion done');
Types
TSndFile
type
TSndFile = Integer; { opaque file handle; 0 = invalid/error }
TSndInfo
type
TSndInfo = record
Frames : Int64; { total sample frames in file }
SampleRate : Integer; { samples per second (e.g. 44100, 48000) }
Channels : Integer; { 1=mono, 2=stereo, 6=5.1 surround, etc. }
Format : Integer; { bitmask: OR of TSndFormat and TSndSubFormat }
Sections : Integer; { number of sections (usually 1) }
Seekable : Boolean; { True if random-access seeking is supported }
end;
TSndFormat
type
TSndFormat = (
sfWAV = $010000, { Microsoft WAVE }
sfAIFF = $020000, { Apple AIFF/AIFC }
sfAU = $030000, { Sun/NeXT AU }
sfFLAC = $170000, { FLAC lossless }
sfOGG = $200000, { OGG container (read only) }
sfRAW = $040000 { Headerless raw PCM }
);
TSndSubFormat
type
TSndSubFormat = (
ssfPCM_S8 = $0001, { signed 8-bit PCM }
ssfPCM_16 = $0002, { signed 16-bit PCM (CD quality) }
ssfPCM_24 = $0003, { signed 24-bit PCM }
ssfPCM_32 = $0004, { signed 32-bit PCM }
ssfFloat = $0006, { 32-bit IEEE float }
ssfDouble = $0007, { 64-bit IEEE double }
ssfULaw = $0010, { mu-law (telephony, North America) }
ssfALaw = $0011 { a-law (telephony, Europe) }
);
Open / Close
All I/O operations require an open file handle. OpenRead and OpenWrite cover the common cases; OpenEx is used when you need full control over the format struct, such as for RAW files or format conversion.
| Function | Description |
|---|---|
| OpenRead(Path) | Open an existing audio file for reading. Returns TSndFile handle, or 0 on error. |
| OpenWrite(Path, Format, SampleRate, Channels) | Create a new audio file for writing. Format is the OR of a TSndFormat and TSndSubFormat constant. |
| OpenEx(Path, Mode, var Info) | Open with a full TSndInfo struct. Mode: 0x10=read, 0x20=write, 0x30=read-write. Required for RAW files. |
| Close(SF) | Flush buffers and close the file handle. Always call this when done. |
| GetInfo(SF) | Return a TSndInfo record describing the open file. |
Reading Samples
All read functions take a frame count and return a dynamic array of the corresponding numeric type. Samples are interleaved: for a stereo file, even indices are left-channel and odd indices are right-channel samples.
| Function | Returns | Description |
|---|---|---|
| ReadShort(SF, Count) | array of SmallInt | Read up to Count frames as 16-bit integers. Most efficient for WAV PCM 16. |
| ReadInt(SF, Count) | array of Integer | Read up to Count frames as 32-bit integers. |
| ReadFloat(SF, Count) | array of Single | Read up to Count frames as 32-bit floats. Values normalized to [-1.0, 1.0]. |
| ReadDouble(SF, Count) | array of Double | Read up to Count frames as 64-bit doubles. Highest precision. |
| ReadAllFloat(SF) | array of Single | Read the entire file in one call as floats. Convenience wrapper — allocates Frames * Channels elements. |
The array length returned is framesRead * channels, not framesRead. A stereo file yields twice as many array elements as frames requested.
Writing Samples
Write functions accept a dynamic array and return the number of frames actually written. The array length must be a multiple of the channel count.
| Function | Returns | Description |
|---|---|---|
| WriteShort(SF, Data) | Int64 | Write 16-bit integer frames. Data must be interleaved. |
| WriteInt(SF, Data) | Int64 | Write 32-bit integer frames. |
| WriteFloat(SF, Data) | Int64 | Write 32-bit float frames. Values should be in [-1.0, 1.0]. |
| WriteDouble(SF, Data) | Int64 | Write 64-bit double frames. |
Seeking
Seeking is supported on all formats except raw streams where TSndInfo.Seekable is False. Positions are in frames, not bytes or samples.
| Function | Description |
|---|---|
| Seek(SF, Frames, Whence) | Move the read/write position. Whence: 0=from start, 1=from current, 2=from end. Returns new frame position. |
| Tell(SF) | Return the current frame position. |
uses libsndfile;
var sf := OpenRead('long.wav');
var info := GetInfo(sf);
{ Jump to the halfway point }
Seek(sf, info.Frames div 2, 0);
WriteLn('Position after seek: ' + IntToStr(Tell(sf)));
var tail := ReadAllFloat(sf);
WriteLn('Samples in second half: ' + IntToStr(Length(tail)));
Close(sf);
Metadata
libsndfile supports string tags embedded in file formats that carry them (WAV INFO chunks, AIFF annotations, FLAC Vorbis comments). Tags are identified by well-known key names.
| Function | Description |
|---|---|
| GetString(SF, Key) | Read a metadata tag. Returns empty string if the key is absent. Valid keys: 'title', 'artist', 'album', 'comment', 'copyright', 'date'. |
| SetString(SF, Key, Value) | Write a metadata tag. Must be called before writing sample data on new files. |
uses libsndfile;
var sfIn := OpenRead('source.wav');
WriteLn('Title: ' + GetString(sfIn, 'title'));
WriteLn('Artist: ' + GetString(sfIn, 'artist'));
Close(sfIn);
{ Write tags to a new FLAC file }
var sfOut := OpenWrite('tagged.flac', $170000 or $0002, 44100, 2);
SetString(sfOut, 'title', 'My Track');
SetString(sfOut, 'artist', 'PascalAI Band');
SetString(sfOut, 'date', '2026');
{ ... write samples ... }
Close(sfOut);
Format Utilities
| Function | Description |
|---|---|
| FormatCheck(Format, SampleRate, Channels) | Return True if the combination of major format, sub-format, sample rate, and channel count is valid before opening for write. |
| FormatName(Format) | Return a human-readable description of a format integer, e.g. 'WAV (Microsoft)'. |
| Duration(SF) | Return the file duration in seconds as a Double (Frames / SampleRate). |
File Conversion
Convert an audio file from any readable format to any writable format in a single call. The library handles resampling if DstRate differs from the source rate.
| Function | Description |
|---|---|
| ConvertFile(SrcPath, DstPath, DstFormat, DstRate) | Read SrcPath and write DstPath in the specified format and sample rate. DstFormat is the OR of major and sub-format constants. |
Info
| Function | Description |
|---|---|
| LibSndFileVersion | Return the version string of the underlying libsndfile C library, e.g. 'libsndfile-1.2.2'. |
Package Info
System Requirements
libsndfile-devUbuntu/Debian:
sudo apt install libsndfile-dev
Formats Quick-Ref
sfWAV = $010000sfAIFF = $020000sfAU = $030000sfFLAC = $170000sfOGG = $200000sfRAW = $040000ssfPCM_16 = $0002ssfPCM_32 = $0004ssfFloat = $0006ssfDouble = $0007Combine with OR: e.g.
$010000 or $0002 = WAV PCM16
Functions
- OpenRead
- OpenWrite
- OpenEx
- Close / GetInfo
- ReadShort / ReadInt
- ReadFloat / ReadDouble
- ReadAllFloat
- WriteShort / WriteInt
- WriteFloat / WriteDouble
- Seek / Tell
- GetString / SetString
- FormatCheck / FormatName
- Duration
- ConvertFile
- LibSndFileVersion
See Also
- portaudio (real-time audio I/O)
- opus (low-latency codec)
- ffmpeg (video + audio)
- libsndfile