Skip to main content

FileJack

File encoding/decoding to audio signals.

FileJack turns an arbitrary file into a WAV audio signal and back. The data is carried on a 12 kHz carrier using differential 8-PSK modulation, protected with Reed-Solomon error correction and a per-frame CRC. It is meant for sending files over an audio link (for example a 3.5 mm jack cable or an acoustic channel).

How it works

The encoder splits the input into frames. Each frame carries a header (sequence number, total frame count, payload length), the payload and a CRC32, then gets Reed-Solomon encoded into a 255-byte codeword (223 data bytes + 32 parity bytes, so up to 209 payload bytes per frame). Each codeword is mapped to symbols and modulated onto the carrier, preceded by a preamble and a syncword so the decoder can find frame boundaries.

The decoder demodulates the recording, locks onto the preamble/syncword, recovers the symbols, runs Reed-Solomon correction and checks each frame's CRC. Valid frames are collected by sequence number and reassembled into the original file. Decoding runs across multiple threads over overlapping blocks, so partial or noisy recordings still recover whatever frames are intact.

Signal parameters live in filejack/values.py: 48 kHz sample rate, 4000 baud, 12 kHz carrier, 8-PSK.

Installation

pip install filejack

Or from source:

pip install .

Dependencies: numpy, scipy, reedsolo.

Command line usage

Encoding writes a WAV file. By default it produces an anti-phase stereo signal (the right channel is the inverted left channel), which lets the decoder cancel common-mode noise by subtracting the channels.

filejack encode input.bin
filejack encode input.bin output.wav
filejack encode input.bin output.wav --mono

Decoding reads a WAV file and writes the reconstructed file. Stereo input is folded down automatically.

filejack decode output.wav
filejack decode output.wav recovered.bin

Decode options:

  • --fjf PATH also saves the decoded frames into a .fjf file. This lets you merge frames recovered from several recordings of the same transmission.
  • --threads N sets the number of decoding threads (default 12).

The command is also available as python -m filejack.

Library usage

import zlib
from scipy.io import wavfile
import numpy as np

from filejack.encode_frames import encode_data
from filejack.decode_data import decode_data
from filejack.reconstruct_data import reconstruct_data
from filejack.values import SAMPLE_RATE

data = open("input.bin", "rb").read()

# Encode to samples and write a WAV
waveform = encode_data(data)
wavfile.write("output.wav", SAMPLE_RATE, waveform)

# Read a WAV and decode
fs, rx = wavfile.read("output.wav")
rx = rx.astype(np.float32)
if rx.ndim == 2:
	rx = (rx[:, 0] - rx[:, 1]) / 2

frames_payload, total_expected, stats = decode_data(rx)
recovered = reconstruct_data(frames_payload, total_expected)

assert zlib.crc32(recovered) == zlib.crc32(data)

More runnable scripts are in filejack/examples, including stereo_to_mono.py for folding an anti-phase stereo recording down to mono.

.fjf files

A .fjf (FileJack Frames) file stores decoded frames with their sequence numbers. Because each frame is independent, you can decode the same transmission several times, save each attempt to a .fjf, and merge them to fill in frames that were missed in individual passes. See filejack/merge_frames.py and the merge example.

Development

pip install .[test]
pytest

License

MIT. See LICENSE.

Metadata

Release files for filejack 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for filejack 1.0.0
File Size Uploaded
filejack-1.0.0.tar.gz 15.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for filejack 1.0.0
File Interpreter ABI Platform
filejack-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 34.5 kB

Release files / filejack-1.0.0.tar.gz

Download URL filejack-1.0.0.tar.gz
Size 15.9 kB
Tags Source
SHA-256 checksum
How to use checksums
a633317865428d99241cadf257ad32c34d935ee142b43b63b9d946cc629d16cd
BLAKE2b-256 checksum
How to use checksums
2dd6ed7b0dd69ab32142e4de87476d10f3e523899d13cf6298e815122220cffc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 5, 2026.

Transparency log

Release files / filejack-1.0.0-py3-none-any.whl

Download URL filejack-1.0.0-py3-none-any.whl
Size 18.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f3d12331e14ac02aeafc8be1396e1478f70855a31f47c8f03f8c28039a798ce6
BLAKE2b-256 checksum
How to use checksums
08b4f55c6f38ea350865ee885c59ec2bbc0a9b5743aa6be006a664935e7783bb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 5, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page