ruuda / claxon

A FLAC decoder in Rust
Apache License 2.0
285 stars 28 forks source link

Some FLAC files don't decode because LPC order > 12 is not supported #18

Closed cubetastic33 closed 5 years ago

cubetastic33 commented 5 years ago

I want to play some audio files in rust, so I used the rodio crate. Rodio uses claxon for decoding FLAC files, and some files didn't work with rodio.

When I tried the decode_simple.rs example's code from this repo, I got this error: thread 'main' panicked at 'failed to decode FLAC stream: Unsupported("LPC order > 12 is not supported")', src/libcore/result.rs:999:5. Here's a file that doesn't work. (Edit by @ruuda: link to private file removed.)

There is a fairly complicated workaround I came up with, here's the code. This method is, however, pretty slow. Can this feature be implemented in claxon?

ruuda commented 5 years ago

Thank you for taking the time to open an issue and for providing a sample file.

There is no fundamental reason that LPC order > 12 is not supported, other than that I never observed it in any real-world file, and subsequently optimized based on that. It should be easy enough to add support for it, I will take a look.

The Flac format defines a "subset" format that places additional restrictions on some parameters, to allow for streaming and to simplify hardware decoders. A maximum LPC order of 12 is one of the requirements of the subset format. All encoders I know of will generate subset files by default. Until now, I had never observed a non-subset file in the wild, but yours is one.

There is a fairly complicated workaround I came up with

As a different workaround, if re-encoding the file is an option for you, you can encode it with flac -8 input.flac -o output.flac. flac will generate subset-compliant files by default.

ruuda commented 5 years ago

@cubetastic33 I removed the link to the file from your report. I will include the problematic subframe as a test sample in the repository. This will be such a small sample that the original audio will not be recognizable.

ruuda commented 5 years ago

The non-subset-lpc branch contains a version that can decode your file. I will still add a regression test and run the fuzzers before merging it to master.

cubetastic33 commented 5 years ago

@ruuda thanks very much for a quick response!

Until now, I had never observed a non-subset file in the wild, but yours is one.

I see. I have more than one of these, too

The non-subset-lpc branch contains a version that can decode your file. I will still add a regression test and run the fuzzers before merging it to master.

Brilliant! Can't wait :grin:

ruuda commented 5 years ago

Version 0.3.3 and 0.4.2 which include a fix are now on crates.io. Thanks again for reporting!

Shnatsel commented 5 years ago

It would be interesting to scrape the internet for real-world FLAC samples and try running them through both libflac and claxon, then comparing the outputs. Archive.org has a ton of freely-licensed FLACs, but I'm not sure if they provide a reasonable API to scrape them.