mirror of
https://github.com/storytold/craft-libs.git
synced 2026-11-14 06:22:24 +00:00
* craft-audio: native MP3 (Layer III) decoder (feature `mp3-decode`) A clean-room Layer III decoder written from ISO/IEC 11172-3 and 13818-3: MPEG-1, MPEG-2 and MPEG-2.5 (8-48 kHz), CBR and VBR, mono, stereo, dual channel and joint stereo (mid/side and intensity), long, short and mixed blocks, and the bit reservoir. It shares the encoder's Huffman and scalefactor band tables and the MP1/MP2 synthesis filter. `decode`, `Decoder` and `TrackDecoder` now read raw .mp3 files and MP3 in MP4 and Matroska natively instead of through symphonia. A Xing / Info / VBRI frame is not a packet, and the LAME tag's encoder delay and padding are applied, so a file decodes to its exact presented length. The seek pre-roll covers how far back the bit reservoir can reach, so a seek is bit-exact. symphonia stays the fallback for free-format MP3. The encoder moves to mp3/encoder.rs so that each half builds without the other. * craft-audio: MP3 review and CI fixes - Huffman: big values stop at the granule's part2_3_length. A damaged granule no longer reads the next granule's bits, as ffmpeg does. - Joint stereo runs on the lines in coded order, before short blocks are reordered, as ffmpeg and libmad do. Where the two channels' block layouts differ, against the specification, each channel is then reordered by its own layout. - Seek pre-roll: sized from the smallest frame the stream can hold (the lowest bit rate for its version, rate, mode and CRC), not the last frame, so a seek into a VBR stream's small frames still has the reservoir. The decoder learns the stream's format from its first frame. - Mixed-block oracle test: edit only granules whose scalefactors take no bits, so the edited streams stay valid, and not before a pure short block. ffmpeg's short-block IMDCT drops overlap that a mixed block's long subbands carry, where the specification adds it. Use 16 kHz instead of 12 kHz. - Routing oracle: ffmpeg before 9 decodes the 1105 samples of the MP3 Matroska CodecDelay. * craft-audio: MPEG audio packets of several frames keep their length An MP4 or Matroska packet may hold several MP1/MP2/MP3 frames. TrackDecoder now counts the frames each packet holds from their headers: - frames_per_packet is None once a packet in the lookahead or a decoded packet has held several frames, so an MP4 track's length is no longer capped at one frame per sample and the container's timing decides. - Concealment is the length of the frames a damaged packet holds. For MP3 a packet lost whole is as long as the last packet, and one frame before any is decoded. Also corrects the Huffman doc comment: a big-value pair that starts before the granule's end is kept whole, as ffmpeg does. * craft-audio: MPEG audio concealment after partial packets and before the first - A packet whose later frame fails decodes only in part: like AC-3, it no longer replaces the length of the last whole packet that concealment uses. - MP1/MP2: a packet lost before any has decoded, or right after a seek, is one frame (384 or 1152 samples) of silence rather than none, as MP3's already is. --------- Co-authored-by: alehel <git@ornumhelgaker.no>
92 lines
3.3 KiB
TOML
92 lines
3.3 KiB
TOML
[package]
|
|
name = "craft-audio"
|
|
description = "Audio file I/O and codecs: WAV/AIFF read and write, FLAC encoder, AAC and ALAC decoders and encoders, AC-3/E-AC-3 decoder and encoder, MP3 decoder and encoder, Opus and MP1/MP2 decoders."
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
license.workspace = true
|
|
rust-version.workspace = true
|
|
repository.workspace = true
|
|
|
|
[package.metadata.docs.rs]
|
|
all-features = true
|
|
|
|
[lints]
|
|
workspace = true
|
|
|
|
[features]
|
|
# Probe and decode files: WAV and AIFF natively; AAC, ALAC, Opus, AC-3/E-AC-3, MP1/MP2/MP3 and
|
|
# PCM through craft-media's demuxers and this crate's decoders; FLAC, Vorbis, CAF, ADPCM, A-law,
|
|
# µ-law and free-format MP3 through symphonia.
|
|
decode = ["decode-native", "symphonia"]
|
|
# `decode` without symphonia: only the formats with a native decoder (others are Unsupported).
|
|
decode-native = ["aac-decode", "alac-decode", "opus-decode", "ac3-decode", "mpa-decode", "mp3-decode", "craft-media/isobmff", "craft-media/matroska", "craft-media/ogg", "dep:log"]
|
|
# The symphonia fallback for the formats with no native decoder yet.
|
|
symphonia = ["decode-native", "dep:symphonia"]
|
|
# Every encoder: the lossless file writers and the AAC, ALAC, AC-3/E-AC-3 and MP3 encoders.
|
|
encode = ["lossless-encode", "aac-encode", "alac-encode", "ac3-encode", "eac3-encode", "mp3-encode"]
|
|
# Encode WAV/BWF/RF64, AIFF/AIFF-C and FLAC files.
|
|
lossless-encode = ["pcm-encode", "flac-encode"]
|
|
# Encode WAV/BWF/RF64 and AIFF/AIFF-C files.
|
|
pcm-encode = []
|
|
# Encode FLAC files.
|
|
flac-encode = ["craft-media/bitstream"]
|
|
# Codec modules on their own, for packet-level use.
|
|
aac-decode = ["craft-media/bitstream"]
|
|
aac-encode = ["craft-media/bitstream"]
|
|
opus-decode = []
|
|
ac3-decode = ["craft-media/bitstream"]
|
|
mpa-decode = ["craft-media/bitstream"]
|
|
# MPEG-1/2 Layer III (MP3) decoder (`mp3::Decoder`).
|
|
mp3-decode = ["mpa-decode"]
|
|
# ALAC packet decoder and encoder (`alac`), ported from Apple's reference implementation.
|
|
alac-decode = []
|
|
alac-encode = []
|
|
ac3-encode = ["craft-media/bitstream"]
|
|
eac3-encode = ["craft-media/bitstream"]
|
|
# MPEG-1/2 Layer III (MP3) encoder (`mp3`).
|
|
mp3-encode = ["craft-media/bitstream"]
|
|
# Multi-resolution waveform overviews (`peaks`).
|
|
peaks = []
|
|
# Encode AAC channels in parallel (with `aac-encode`).
|
|
rayon = ["dep:rayon"]
|
|
# Serialize and Deserialize for the shared types.
|
|
serde = ["dep:serde", "craft-media/serde"]
|
|
|
|
[dependencies]
|
|
craft-media = { workspace = true }
|
|
thiserror = { workspace = true }
|
|
serde = { workspace = true, optional = true }
|
|
log = { version = "0.4", optional = true }
|
|
rayon = { workspace = true, optional = true }
|
|
# symphonia keeps its AAC decoder for AAC in CAF, a container craft-media does not read.
|
|
symphonia = { version = "0.6.1", optional = true, default-features = false, features = ["mp3", "flac", "vorbis", "ogg", "wav", "pcm", "aiff", "isomp4", "aac", "alac", "adpcm", "caf", "mkv"] }
|
|
|
|
[dev-dependencies]
|
|
craft-media-testkit = { workspace = true }
|
|
proptest = { workspace = true }
|
|
serde_json = { workspace = true }
|
|
|
|
[[test]]
|
|
name = "audio"
|
|
required-features = ["decode", "lossless-encode", "peaks"]
|
|
|
|
[[test]]
|
|
name = "codecs"
|
|
required-features = ["decode", "encode"]
|
|
|
|
[[example]]
|
|
name = "info"
|
|
required-features = ["decode"]
|
|
|
|
[[example]]
|
|
name = "stream"
|
|
required-features = ["decode"]
|
|
|
|
[[example]]
|
|
name = "packets"
|
|
required-features = ["decode"]
|
|
|
|
[[example]]
|
|
name = "encode"
|
|
required-features = ["lossless-encode", "aac-encode"]
|