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 PATHalso saves the decoded frames into a.fjffile. This lets you merge frames recovered from several recordings of the same transmission.--threads Nsets 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)
| File | Size | Uploaded | |
|---|---|---|---|
| filejack-1.0.0.tar.gz | 15.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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 logRelease 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