| name | fax-codec |
| description | Encode images into fax audio WAV files and decode fax WAV recordings back into images, using ITU-T T.4 Modified Huffman compression and V.27ter DPSK modulation at 2400 bps. Use this skill whenever the user mentions fax, facsimile, fax audio, fax modem sounds, T.4, Group 3, V.27ter, or wants to convert images to/from the analog audio format used by fax machines. Also trigger when the user has a WAV file recorded from a fax machine and wants to extract the image, or wants to create a WAV file that sounds like (and technically is) a real fax transmission. Covers encoding (image to WAV) and decoding (WAV to image).
|
Fax Codec
This skill converts between images and Group 3 fax audio files. It produces
WAV files that are standards-compliant fax transmissions using ITU-T T.4
Modified Huffman compression and V.27ter 4-DPSK modulation at 2400 bps.
The generated WAV files sound exactly like a fax machine and are technically
interoperable: they could be played into a real fax machine's phone line to
print the image, and the decoder can process recordings of real fax machines.
Quick reference: the fax signal
A Group 3 fax transmission consists of:
- T.30 handshake — CED tone (2100 Hz, 2.6s) + V.21 HDLC preamble flags.
This is the iconic fax screech.
- V.27ter training — 256 symbols of alternating phase changes for the
receiver's equalizer and phase-lock loop to synchronize.
- Page data — The image, compressed with T.4 Modified Huffman (run-length
- Huffman coding of 1-bit black/white scan lines), scrambled with the
V.27ter polynomial (1 + x⁻⁶ + x⁻⁷), and modulated as 4-DPSK at 1200
baud / 2400 bps on an 1800 Hz carrier.
- RTC — Return to Control: 6 consecutive EOL codes signaling page end.
Standard fax resolution: 1728 pixels per scan line, 8000 Hz audio sample rate.
How to use this skill
There are two Python scripts in the scripts/ directory next to this file.
Use them rather than writing fax logic from scratch.
Encoding (image to fax WAV)
python3 <skill-path>/scripts/fax_encode.py <input_image> <output.wav> [--no-preamble]
The encoder:
- Loads any image format PIL supports (JPG, PNG, BMP, etc.)
- Converts to 1-bit black/white (threshold at 128)
- Resizes to 1728 pixels wide, preserving aspect ratio
- Compresses with T.4 Modified Huffman coding
- Scrambles with V.27ter polynomial
- DPSK-modulates onto 1800 Hz carrier at 8000 Hz sample rate
- Prepends T.30 handshake tones (optional, for authenticity)
- Writes a 16-bit mono WAV
Use --no-preamble to skip the T.30 handshake tones. The file will be
shorter and still fully decodable, but won't have the classic fax screech.
Decoding (fax WAV to image)
python3 <skill-path>/scripts/fax_decode.py <input.wav> <output.png>
The decoder:
- Reads the WAV (any sample rate — resamples to 8000 if needed)
- Detects the DPSK carrier onset (auto-skips silence and handshake tones)
- Demodulates the V.27ter 4-DPSK signal
- Locates a sync marker to find the exact data boundary
- Descrambles with V.27ter polynomial
- Decodes T.4 Modified Huffman to recover scan lines
- Saves the reconstructed 1-bit image as PNG
Typical workflow
User wants to encode an image:
- Read the input image to understand what it looks like
- Run the encoder script
- Optionally verify by decoding the WAV back and checking the roundtrip
- Deliver the WAV file to the user
User wants to decode a fax recording:
- Run the decoder script on their WAV
- Show them the decoded image
- Note: real-world recordings may have noise, which can cause some
line errors. The decoder is tolerant of moderate noise.
User asks about fax format details:
The quick reference section above has the key parameters. The main thing
people care about is that it uses T.4 compression on 1-bit images,
V.27ter DPSK modulation at 2400 bps, and the audio is standard 8000 Hz
telephone-quality audio.
Dependencies
The scripts use only numpy, Pillow, and the standard library wave module.
Install if needed:
pip install numpy Pillow --break-system-packages