{"id":51441726,"url":"https://github.com/elementmerc/flac-io","last_synced_at":"2026-07-05T12:30:29.495Z","repository":{"id":364228021,"uuid":"1262260416","full_name":"elementmerc/flac-io","owner":"elementmerc","description":"Pure-Rust FLAC decoder and encoder, no unsafe code and no C dependency","archived":false,"fork":false,"pushed_at":"2026-06-12T06:05:51.000Z","size":440,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-12T08:07:42.733Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/elementmerc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-07T19:20:11.000Z","updated_at":"2026-06-12T06:05:53.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/elementmerc/flac-io","commit_stats":null,"previous_names":["elementmerc/flac-io"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/elementmerc/flac-io","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elementmerc%2Fflac-io","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elementmerc%2Fflac-io/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elementmerc%2Fflac-io/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elementmerc%2Fflac-io/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/elementmerc","download_url":"https://codeload.github.com/elementmerc/flac-io/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elementmerc%2Fflac-io/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35154748,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-05T02:00:06.290Z","response_time":100,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-05T12:30:27.312Z","updated_at":"2026-07-05T12:30:29.363Z","avatar_url":"https://github.com/elementmerc.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# flac-io\n\nA pure-Rust FLAC decoder and encoder.\n\nFLAC, the Free Lossless Audio Codec, is a way to shrink audio files without\nlosing a single detail. A codec is just a \"coder and decoder\", the thing that\npacks sound into a file and unpacks it again. \"Lossless\" is the important word:\nunlike MP3, which throws away parts of the sound you probably will not notice,\nFLAC gives you back the exact audio you started with, down to the last number.\n\nThink of it like a ZIP file, but for sound. When you unzip a document you get\nthe original file back, character for character. FLAC does the same for audio.\n\n```\n   original audio              FLAC file                back again\n   (a list of numbers)         (smaller)                (same numbers)\n  +-------------------+ encode +-----------+  decode  +-------------------+\n  |  -3  5  5  12 ... | -----\u003e |  fLaC.... | -------\u003e |  -3  5  5  12 ... |\n  +-------------------+        +-----------+          +-------------------+\n                  what comes out is identical to what went in\n```\n\nThis crate reads a FLAC file into those raw numbers (called samples), and writes\nsamples back into a valid FLAC file. It never passes through a lossy format in\nbetween, so the numbers always survive the trip exactly.\n\nIt is built for work that needs the raw samples directly: hiding data inside\naudio (steganography), adding inaudible markers (watermarking), forensic\nanalysis, and anything else where you need the exact numbers and a promise that\ndecoding then re-encoding changes nothing.\n\n## What a \"sample\" is\n\nSound is a wave. To store it, a computer measures the height of that wave many\nthousands of times a second (44,100 times a second for a CD). Each measurement\nis one sample: a single whole number. Play the numbers back fast enough and you\nhear the sound again. It is the same trick a flipbook uses to turn still\ndrawings into motion.\n\nThis crate hands you those numbers, one list per channel (left and right for\nstereo):\n\n```\n  samples[0] = left   -\u003e  [ s0  s1  s2  s3  s4  ... ]\n  samples[1] = right  -\u003e  [ s0  s1  s2  s3  s4  ... ]\n                             |\n                             one column = one instant in time\n```\n\nEvery channel list has the same length, and the numbers are plain signed\nintegers (they can be negative, because a wave goes up and down).\n\n## What this crate does\n\nYou get three things, two doors into a FLAC file and one back out:\n\n```\n        bytes of a .flac file               raw samples\n       +----------------------+  decode()   +---------------------+\n       |  66 4C 61 43 00 ...   | ----------\u003e |  [ -3, 5, 5, 12 ]   |\n       |                       |             |  one list / channel |\n       |                       |  encode()   |                     |\n       |                       | \u003c---------- |                     |\n       +----------------------+              +---------------------+\n                 ^\n                 | info()  -\u003e  just the facts: 44100 Hz, 2 channels, 16-bit\n```\n\n- **`decode`** turns FLAC bytes into the raw samples plus the basic facts about\n  the audio.\n- **`info`** reads just those facts (sample rate, channels, bit depth, total\n  length) without decoding the audio, so it stays fast on a huge file.\n- **`encode`** turns raw samples back into a valid FLAC file.\n\nThe promise that ties them together: decode a file, encode the same samples, and\nthe result decodes to the identical numbers. Nothing drifts.\n\n### Two containers, read automatically\n\nFLAC comes in two wrappers: the plain `.flac` file, and an `.oga` file where the\nsame FLAC data rides inside an Ogg container (the box that Vorbis and Opus use\ntoo). You do not have to say which one you have: `decode` and `info` look at the\nfirst few bytes and pick the right path themselves.\n\n```\n   .flac  (starts with \"fLaC\")  --.\n                                   \u003e--  decode() / info()  --\u003e  same result\n   .oga   (starts with \"OggS\")  --'\n```\n\nWriting is the one case where you choose, because raw samples do not say which\nwrapper you want: `encode` writes a `.flac`, `encode_ogg` writes an `.oga`.\n\n## What this crate does not do\n\n- It does not change the audio: no resampling, no volume changes, no dithering,\n  no switching the bit depth.\n- It does not give you floating-point samples; they stay as whole numbers in the\n  file's own bit depth.\n\nSo it is a precise in-and-out tool, not an audio editor.\n\n## Which FLAC features it understands\n\nFLAC has a few ways of packing each chunk of audio. This crate handles all of\nthem, so it reads files from any standard FLAC encoder:\n\n- All four block types: constant, verbatim, fixed (orders 0 to 4), and LPC\n  (orders 1 to 32). These are the maths tricks FLAC uses to describe a run of\n  samples compactly.\n- Both ways of coding the leftover error values (4-bit and 5-bit Rice\n  parameters).\n- All the stereo tricks where one channel is stored as a difference from\n  another (independent, left/side, right/side, mid/side), including at the full\n  32-bit depth.\n- Files with a fixed block size and files that vary it.\n- Bit depths from 4 to 32 bits per sample.\n- Both containers: plain native FLAC (`.flac`) and Ogg-wrapped FLAC (`.oga`),\n  read and written.\n\n## Example\n\n```rust,no_run\nuse flac_io::{decode, encode};\n\nlet bytes = std::fs::read(\"song.flac\").unwrap();\n\n// Decode to samples plus the stream parameters.\nlet audio = decode(\u0026bytes).unwrap();\nprintln!(\"{} Hz, {} channels, {} bits\", audio.sample_rate, audio.channels, audio.bits_per_sample);\n\n// Re-encode the same samples into a fresh FLAC file.\nlet out = encode(\u0026audio).unwrap();\nstd::fs::write(\"song_reencoded.flac\", out).unwrap();\n```\n\nThe same `decode` call also reads an Ogg-wrapped `.oga` file with no extra\nsteps. To write one, swap `encode` for `flac_io::encode_ogg`.\n\n## Safety on untrusted input\n\nA FLAC file might come from anywhere, so the decoder treats every byte as if an\nattacker wrote it. Here is what protects you:\n\n```\n  bad bytes in  ----\u003e [ check every field ] ----\u003e a clear error, never a crash\n                      [ cap the memory     ]\n                      [ no unsafe code     ]\n```\n\n- **No `unsafe` code.** The crate sets `#![forbid(unsafe_code)]`, so the compiler\n  guarantees there are no memory tricks that could read or write out of bounds.\n- **No crashes on bad input.** Every length and code is checked the moment it is\n  read. A broken, cut-off, or deliberately nasty file returns an error; it never\n  takes down your program. Tests throw millions of random and bit-flipped bytes\n  at the decoder to keep this honest.\n- **Bounded memory.** Decoding cannot ask for unlimited memory. The number of\n  samples it will produce is capped (near one billion, about four gibibytes), so\n  a few kilobytes of crafted input cannot trick it into trying to allocate\n  hundreds of gigabytes. A file that wants more gets a `LimitExceeded` error.\n- **Built-in correctness check.** A FLAC file usually stores a fingerprint (an\n  MD5 hash) of its samples. The decoder recomputes that fingerprint from what it\n  decoded and rejects the file if they disagree, so a successful decode really\n  is bit-for-bit correct. A file that stores no fingerprint (all zeros) skips\n  this check, so treat its samples as unverified.\n\nSee [`SECURITY.md`](SECURITY.md) for the full threat model and how to report a\nproblem, and [`docs/architecture.md`](docs/architecture.md) for how the code is\nbuilt.\n\n## Licence\n\nLicensed under either of Apache License, Version 2.0 or MIT licence at your\noption.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felementmerc%2Fflac-io","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felementmerc%2Fflac-io","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felementmerc%2Fflac-io/lists"}