audio cheatsheet

some useful commands with sox and ffmpeg

Public · content/audio_cheatsheet.md · uploaded 29 days ago

# Audio cheatsheet

Quick reference for common audio operations with `sox` and `ffmpeg`.
Both tools accept WAV, FLAC, MP3, OGG, and most other container/codec
combinations; pick whichever is already installed.

## Trimming

Time format for both tools: `HH:MM:SS[.ms]`, `MM:SS[.ms]`, or seconds
(e.g. `90`, `1:30`, `0:01:30.250`). Examples below trim from `00:10`
for `30` seconds.

### sox

`sox` takes `trim <start> <length>` after the output filename:

```bash
# Keep 30 seconds starting at 10 seconds.
sox in.wav out.wav trim 10 30

# Keep from 10 seconds through (absolute) 40 seconds — the leading
# '=' makes the second argument an end time rather than a duration.
sox in.wav out.wav trim 10 =40

# Drop a leading 2 seconds, keep the rest.
sox in.wav out.wav trim 2

# Trim silence from the start (anything below -50 dB for >0.1s).
sox in.wav out.wav silence 1 0.1 -50d
```

### ffmpeg

`-ss` is the start, `-t` is the duration; `-to` is the absolute end.

```bash
# Re-encode (safest when accuracy matters):
ffmpeg -ss 00:00:10 -t 30 -i in.wav out.wav

# Stream-copy (fast, lossless; for audio-only inputs the cut is
# sample-accurate, so this is usually the right choice):
ffmpeg -ss 00:00:10 -t 30 -i in.wav -c copy out.wav

# Absolute end time instead of duration:
ffmpeg -ss 00:00:10 -to 00:00:40 -i in.wav -c copy out.wav

# Tip: putting -ss BEFORE -i is fast (seeks in the container); putting
# it AFTER -i is slower but more accurate for some video containers.
# For pure audio they behave the same.
```

## Downsampling

"Downsampling" usually means one or more of:

- **Sample rate** (e.g. 44.1 kHz → 16 kHz)
- **Bit depth** (24-bit → 16-bit)
- **Channel count** (stereo → mono)

A common speech-friendly target is `16 kHz / 16-bit / mono` — small
files that still capture the voice band.

### sox

`sox` infers conversions from the **output** flags placed between the
input and output filenames.

```bash
# Sample-rate downsample only (sox uses a high-quality sinc filter by
# default, so there's no separate anti-aliasing step needed).
sox in.wav -r 16000 out.wav

# Bit-depth downsample only.
sox in.wav -b 16 out.wav

# Stereo to mono (average the channels).
sox in.wav -c 1 out.wav

# All three at once — the typical "downsample for ASR/transcription":
sox in.wav -r 16000 -b 16 -c 1 out.wav

# Mix only the left channel into a mono output (instead of averaging):
sox in.wav -c 1 out.wav remix 1

# Disable sox's automatic dither when reducing bit depth:
sox -D in.wav -b 16 out.wav
```

### ffmpeg

```bash
# Sample-rate downsample only.
ffmpeg -i in.wav -ar 16000 out.wav

# Bit depth: WAV uses sample_fmt, e.g. s16 (16-bit signed PCM).
ffmpeg -i in.wav -sample_fmt s16 out.wav

# Stereo to mono.
ffmpeg -i in.wav -ac 1 out.wav

# All three at once:
ffmpeg -i in.wav -ar 16000 -ac 1 -sample_fmt s16 out.wav

# Lossy compressed target (Opus, suitable for voice at low bitrates):
ffmpeg -i in.wav -ar 16000 -ac 1 -c:a libopus -b:a 24k out.opus
```

## Extracting audio from a video

Pulling the audio out of a video container is mostly an `ffmpeg` job.
The relevant flags:

- `-vn` — drop the video stream.
- `-map 0:a:0` — select the **first audio stream** (useful when the
  source has multiple language/commentary tracks).
- `-af "pan=mono|c0=c0"` — keep only the **first channel** of that
  stream (e.g. just the left channel of a stereo recording), without
  averaging it with the others.
- `-ac 1` — downmix all source channels to mono by averaging
  (different from selecting the first channel).

```bash
# Whole first audio stream → WAV, original channel layout preserved.
ffmpeg -i in.mp4 -vn -map 0:a:0 out.wav

# Just the FIRST audio channel of the first stream — copies channel 0
# only, no averaging.
ffmpeg -i in.mp4 -vn -map 0:a:0 -af "pan=mono|c0=c0" out.wav

# Same, plus speech-friendly downsample (16 kHz, 16-bit, mono).
ffmpeg -i in.mp4 -vn -map 0:a:0 -af "pan=mono|c0=c0" \
       -ar 16000 -sample_fmt s16 out.wav

# Alternative: downmix L+R to mono (averaged) instead of picking a
# single channel. Useful when both channels carry signal.
ffmpeg -i in.mp4 -vn -map 0:a:0 -ac 1 -ar 16000 -sample_fmt s16 out.wav

# Multi-stream sources: list available audio streams first.
ffmpeg -i in.mp4 2>&1 | grep "Audio:"
# Then -map 0:a:1 picks the second audio stream, etc.
```

## Combining trim and downsample

Stack the operations in one command. The output is trimmed and
downsampled in a single pass.

```bash
# sox: trim 30s starting at 0:10, then downsample to 16 kHz mono 16-bit.
sox in.wav -r 16000 -b 16 -c 1 out.wav trim 10 30

# ffmpeg: same idea.
ffmpeg -ss 10 -t 30 -i in.wav -ar 16000 -ac 1 -sample_fmt s16 out.wav
```

## Quick reference

| Operation                      | sox                                          | ffmpeg                                            |
| ------------------------------ | -------------------------------------------- | ------------------------------------------------- |
| Trim from start, length        | `sox a b trim 10 30`                          | `ffmpeg -ss 10 -t 30 -i a b`                       |
| Trim start to absolute end     | `sox a b trim 10 =40`                         | `ffmpeg -ss 10 -to 40 -i a b`                      |
| Resample to 16 kHz             | `sox a -r 16000 b`                            | `ffmpeg -i a -ar 16000 b`                          |
| Drop to 16-bit                 | `sox a -b 16 b`                               | `ffmpeg -i a -sample_fmt s16 b`                    |
| Mix to mono                    | `sox a -c 1 b`                                | `ffmpeg -i a -ac 1 b`                              |
| Speech-friendly (16k/16/mono)  | `sox a -r 16000 -b 16 -c 1 b`                 | `ffmpeg -i a -ar 16000 -ac 1 -sample_fmt s16 b`    |
| Strip video, first channel only | —                                            | `ffmpeg -i v.mp4 -vn -map 0:a:0 -af "pan=mono\|c0=c0" b.wav` |

## Batch processing

```bash
# sox: convert every WAV in a directory to 16 kHz mono.
mkdir -p downsampled
for f in *.wav; do
  sox "$f" -r 16000 -c 1 "downsampled/$f"
done

# ffmpeg: parallelize with xargs (4 jobs at a time).
mkdir -p downsampled
ls *.wav | xargs -P 4 -I{} ffmpeg -i {} -ar 16000 -ac 1 -sample_fmt s16 downsampled/{}
```