FFmpeg and Raw PCM: Format Names, Copy-Ready Commands and the New Whisper Filter
Raw PCM has no header, so FFmpeg cannot work out the sample rate, channel count or sample format on its own. You have to tell it, and the way you do that is the same for every conversion. This guide collects the options and format names that matter, based on FFmpeg's own manual and source code, and then covers what FFmpeg 8.0 and 8.1 changed for audio, including a speech-to-text filter.
If you are not sure which settings your file needs, work that out first with our raw audio troubleshooting guide, then come back here to script the conversion.
The Three Options That Describe Raw Input
The FFmpeg manual says that -ar (sample rate) and -ac (channel count), when applied to an input, only make sense for audio grabbing devices and raw demuxers, where they are mapped to the corresponding demuxer options. -f forces the input format. So for headerless PCM you give all three before -i:
ffmpeg -f s16le -ar 44100 -ac 2 -i input.pcm output.wavThis reads input.pcm as signed 16-bit little-endian, 44,100 Hz, stereo, and writes a WAV file.
Position matters. The manual states that options are applied to the next file specified on the command line. Before -i, -ar and -ac describe the input. After the input and before the output name, they apply to the output instead and cause resampling or channel conversion. An easy mistake is to put them after -i and expect them to describe the raw file, which leaves the input read with the wrong settings.
The Raw PCM Format Names
The names come from FFmpeg's raw PCM format list. Most names follow a pattern: a letter for the sample type (u unsigned, s signed, f floating-point), the bit depth, and le or be for little-endian or big-endian byte order. mulaw and alaw are the exceptions:
| Name | FFmpeg's description |
|---|---|
u8 | PCM unsigned 8-bit |
s8 | PCM signed 8-bit |
s16le | PCM signed 16-bit little-endian |
s16be | PCM signed 16-bit big-endian |
s24le | PCM signed 24-bit little-endian |
s32le | PCM signed 32-bit little-endian |
f32le | PCM 32-bit floating-point little-endian |
f64le | PCM 64-bit floating-point little-endian |
mulaw | PCM mu-law |
alaw | PCM A-law |
The same names exist for reading and for writing, and the list also includes big-endian variants such as s24be and f32be, unsigned variants such as u16le, and a few more.
PCM Drop's 8-bit, 16-bit and 32-bit float settings correspond to u8, s16le and f32le on a little-endian device (our player reads 16-bit and float samples in the device's native byte order). Our player treats 8-bit samples as unsigned with silence at 128, which is what u8 means. For telephone formats, see our guide to µ-law and A-law audio.
Copy-Ready Commands
Raw PCM to WAV, which adds a header and leaves the samples alone for 16-bit input:
ffmpeg -f s16le -ar 16000 -ac 1 -i input.pcm output.wavThis works unchanged because the WAV muxer's default audio codec in FFmpeg's source is pcm_s16le, so the audio is encoded as 16-bit unless you choose another codec. To keep 8-bit unsigned samples as 8-bit, add -c:a pcm_u8:
ffmpeg -f u8 -ar 8000 -ac 1 -i input.pcm -c:a pcm_u8 output.wavAny audio file to headerless 16-bit PCM. Without -ar and -ac, the output keeps the input's sample rate and channel count, which is the manual's stated default:
ffmpeg -i input.wav -f s16le output.pcmConvert to 16 kHz, mono, 16-bit PCM (16 kHz is the sample rate whisper.cpp works at, as covered below). Here -ar and -ac come after the input, so they apply to the output:
ffmpeg -i input.wav -ar 16000 -ac 1 -f s16le output.pcmDecode a raw µ-law recording to a WAV file:
ffmpeg -f mulaw -ar 8000 -ac 1 -i call.raw output.wavRaw PCM to FLAC. The output extension selects FLAC, which is lossless, so decoding the file back to s16le returns the original samples (see our article on RFC 9639):
ffmpeg -f s16le -ar 44100 -ac 2 -i input.pcm output.flacFor MP3 output and bitrate choices, our PCM to MP3 guide covers the encoder options. To see which filters your build of FFmpeg includes, run ffmpeg -filters, an option the manual describes as listing all filters.
What FFmpeg 8.0 and 8.1 Added for Audio
These are the main audio-related items we found in the official release notes. The notes list many more video and platform features, which we have left out.
| Release | Date | Audio additions |
|---|---|---|
| FFmpeg 8.0 "Huffman" | 22 August 2025 | Whisper filter, G.728 decoder, Sanyo LD-ADPCM decoder, ADPCM IMA Xbox decoder |
| FFmpeg 8.1 "Hoare" | 16 March 2026 | MPEG-H 3D Audio decoding via the mpeghdec library, experimental xHE-AAC Mps212 decoding, IAMF projection-mode Ambisonic audio element muxing and demuxing |
The first of these, the Whisper filter, is the one most people will want to try.
The Whisper Filter: Speech-to-Text Inside FFmpeg
The whisper filter runs automatic speech recognition with OpenAI's Whisper model. It needs the whisper.cpp library as a prerequisite, and FFmpeg has to be configured with --enable-whisper, so a particular build may not include it. Check the output of ffmpeg -filters before relying on it. You also need a whisper.cpp model file, and the whisper.cpp README shows how to fetch one with sh ./models/download-ggml-model.sh base.en, run from its own folder.
These are the options in the FFmpeg 8.0 documentation:
| Option | What it does | Default |
|---|---|---|
model | Path to the downloaded whisper.cpp model file (mandatory) | none |
language | Language to transcribe, or auto to detect it | auto |
queue | Audio to queue before processing. Small values process more often with lower quality and more CPU use. Large values such as 10–20 seconds are more accurate and cheaper but add delay, so they are not suited to real-time streams | 3 seconds |
use_gpu | Enable GPU support | true |
gpu_device | GPU device index | 0 |
destination | File or URL for the output. If unset, output is logged as info messages. An existing file is overwritten | unset |
format | text, srt or json | text |
vad_model | Path to a Silero voice-activity-detection model used to split the audio queue. Use it with a larger queue | unset |
vad_threshold | Voice-activity threshold | 0.5 |
vad_min_speech_duration | Minimum speech duration | 0.1 |
vad_min_silence_duration | Minimum silence duration | 0.5 |
The FFmpeg 8.1 documentation adds one more option, max_len, which splits transcription segments to a maximum length in characters (default 0, meaning no limit). That is useful for shorter subtitle lines.
This example, adapted from the FFmpeg documentation, writes subtitles for a video file to an SRT file:
ffmpeg -i input.mp4 -vn -af "whisper=model=../whisper.cpp/models/ggml-base.en.bin\
:language=en\
:queue=3\
:destination=output.srt\
:format=srt" -f null --vn ignores the video, and -f null - discards the normal media output, because the filter writes its transcript to destination.
One detail connects this to the rest of this guide. In FFmpeg's source, the filter accepts only mono, 32-bit floating-point audio at whisper.cpp's sample rate, which is 16,000 Hz. The documented example feeds the filter an ordinary MP4 file. As with any automatic transcription, read the output before you publish it.
Summary
For raw PCM, FFmpeg needs three things before -i: the format name, the sample rate and the channel count. Options placed after the input apply to the output instead, which is an easy way to end up with a conversion that sounds wrong. FFmpeg 8.0 added a Whisper speech-to-text filter, and FFmpeg 8.1 added MPEG-H 3D Audio decoding and more, but the filter needs a build with whisper.cpp support, so check ffmpeg -filters first. For one-off files, you can also check the settings by ear in the online PCM player before scripting anything.
Sources and verification
The facts in this article were checked against the primary sources below on . Figures described as our own calculation are derived from those sources. If you spot a mistake, please tell us through the contact page.
- FFmpeg manual: ffmpeg — behaviour of -f, -ar and -ac on raw input, the rule that options apply to the next file, defaults for output rate and channels, and -filters
- libavformat/pcmdec.c at tag n8.0 (GitHub) — raw PCM format names and their descriptions
- libavformat/pcmenc.c at tag n8.0 (GitHub) — the same format names as muxers, used for writing raw PCM
- libavformat/wavenc.c at tag n8.0 (GitHub) — the WAV muxer’s default audio codec, pcm_s16le
- libavcodec/codec_desc.c at tag n8.0 (GitHub) — PCM codec names such as pcm_u8
- FFmpeg news and release highlights (ffmpeg.org) — release dates for FFmpeg 8.0 (22 August 2025) and 8.1 (16 March 2026)
- FFmpeg 8.0 Changelog (release/8.0 branch) — the 8.0 feature list, including the Whisper filter and new audio decoders
- FFmpeg 8.1 Changelog (release/8.1 branch) — the 8.1 feature list, including MPEG-H, xHE-AAC Mps212 and IAMF additions
- FFmpeg filter documentation at tag n8.0 (doc/filters.texi) — whisper filter options, defaults and the documented example
- FFmpeg filter documentation at tag n8.1 (doc/filters.texi) — the max_len option added to the whisper filter documentation
- libavfilter/af_whisper.c at tag n8.0 (GitHub) — option defaults and the mono, 32-bit float input the filter accepts
- whisper.cpp header whisper.h (GitHub) — WHISPER_SAMPLE_RATE is defined as 16000
- whisper.cpp README (GitHub) — the model download script