craft-audio: review fixes, round 10 (#442)

Tests only; each was confirmed to fail on a mutated encoder.

- Every sample rate code in the frame header table.
- Signals that reach the Rice parameter and LPC shift limits, where a
  value past the limit gives a file decoders refuse.
- ENCODE_EXTENSIONS lists flac.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
alehel
2026-11-04 10:35:44 +01:00
co-authored by Claude Opus 5.5
parent 5617261fdc
commit afdc045e94
3 changed files with 29 additions and 0 deletions
+8
View File
@@ -231,6 +231,14 @@ mod tests {
assert_eq!([8, 12, 16, 20, 24, 32].map(sample_size_code), [1, 2, 4, 5, 6, 0]);
}
#[test]
fn sample_rates_in_the_table_have_their_codes() {
let table = [88_200, 176_400, 192_000, 8_000, 16_000, 22_050, 24_000, 32_000, 44_100, 48_000, 96_000];
for (rate, code) in table.into_iter().zip(1..) {
assert_eq!(sample_rate_code(rate), (code, None), "{rate}");
}
}
#[test]
fn sample_rates_outside_the_table_are_named_in_the_header() {
assert_eq!(sample_rate_code(48_000), (10, None));
@@ -342,3 +342,23 @@ fn a_full_scale_click_at_32_bits_is_still_predicted() {
let Some(size) = round_trip("click-32", &planar, EncoderConfig::new(48_000, 1, 32), 4096) else { return };
assert!(size < 4_096 * 4 / 2, "{size}");
}
/// Signals that reach the format's limits, which a decoder refuses when they are passed: a Rice
/// parameter of 31 is the escape code, and an LPC shift above 15 reads as negative.
#[test]
fn rice_parameter_and_lpc_shift_stay_in_range() {
let mut r = Rng(71);
let bursts: Vec<i32> =
(0..9_000).map(|i| if i % 1024 < 128 { if i % 2 == 0 { i32::MAX } else { -i32::MAX } } else { (r.next() * 100.0) as i32 }).collect();
if round_trip("limit-rice", &[bursts], EncoderConfig::new(48_000, 1, 32), 4096).is_none() {
return;
}
let mut y = 0.0;
let correlated: Vec<i32> = (0..9_000)
.map(|_| {
y = 0.24 * y + r.next() * 8000.0;
y as i32
})
.collect();
round_trip("limit-shift", &[correlated], EncoderConfig::new(48_000, 1, 16), 4096);
}
@@ -10,6 +10,7 @@ fn only_formats_the_encoder_writes_are_named() {
assert_eq!(encode_format_for("BWF"), Some(EncodeFormat::Wav));
assert_eq!(encode_format_for(".aifc"), Some(EncodeFormat::Aiff));
assert_eq!(encode_format_for("flac"), Some(EncodeFormat::Flac));
assert!(craft_audio::ENCODE_EXTENSIONS.contains(&"flac"));
for name in craft_audio::ENCODE_EXTENSIONS {
assert!(encode_format_for(name).is_some(), "{name}");
}