PCM Drop logoPCM Drop

FFmpeg and Raw PCM: Format Names, Copy-Ready Commands and the New Whisper Filter

·7 min read

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.wav

This 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:

NameFFmpeg's description
u8PCM unsigned 8-bit
s8PCM signed 8-bit
s16lePCM signed 16-bit little-endian
s16bePCM signed 16-bit big-endian
s24lePCM signed 24-bit little-endian
s32lePCM signed 32-bit little-endian
f32lePCM 32-bit floating-point little-endian
f64lePCM 64-bit floating-point little-endian
mulawPCM mu-law
alawPCM 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.wav

This 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.wav

Any 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.pcm

Convert 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.pcm

Decode a raw µ-law recording to a WAV file:

ffmpeg -f mulaw -ar 8000 -ac 1 -i call.raw output.wav

Raw 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.flac

For 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.

ReleaseDateAudio additions
FFmpeg 8.0 "Huffman"22 August 2025Whisper filter, G.728 decoder, Sanyo LD-ADPCM decoder, ADPCM IMA Xbox decoder
FFmpeg 8.1 "Hoare"16 March 2026MPEG-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:

OptionWhat it doesDefault
modelPath to the downloaded whisper.cpp model file (mandatory)none
languageLanguage to transcribe, or auto to detect itauto
queueAudio 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 streams3 seconds
use_gpuEnable GPU supporttrue
gpu_deviceGPU device index0
destinationFile or URL for the output. If unset, output is logged as info messages. An existing file is overwrittenunset
formattext, srt or jsontext
vad_modelPath to a Silero voice-activity-detection model used to split the audio queue. Use it with a larger queueunset
vad_thresholdVoice-activity threshold0.5
vad_min_speech_durationMinimum speech duration0.1
vad_min_silence_durationMinimum silence duration0.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.