Import: AIFF files import, including EffectCraft's own AIFF renders (fixes #1428)

This commit is contained in:
Marco Arnulfo
2026-10-14 13:44:59 +02:00
parent 549e9d8251
commit 78b4fe4170
4 changed files with 31 additions and 0 deletions
Generated
+1
View File
@@ -1440,6 +1440,7 @@ dependencies = [
"log",
"rayon",
"serde_json",
"symphonia",
"thiserror 2.0.21",
]
+3
View File
@@ -91,6 +91,9 @@ filmcraft-av1 = { git = "https://github.com/storytold/filmcraft", rev = "2c5ba7a
filmcraft-interchange = { git = "https://github.com/storytold/filmcraft", rev = "2c5ba7a72619935f0481f99d59409e0d1844b234" }
filmcraft-project = { git = "https://github.com/storytold/filmcraft", rev = "2c5ba7a72619935f0481f99d59409e0d1844b234" }
filmcraft-geom = { git = "https://github.com/storytold/filmcraft", rev = "2c5ba7a72619935f0481f99d59409e0d1844b234" }
# The symphonia filmcraft-codecs already builds, named only to turn on its AIFF reader: the pinned
# rev enables wav alone (FilmCraft main enables aiff too). Drop it when the pin moves past that.
symphonia = { version = "0.5.5", default-features = false, features = ["aiff"] }
# gpu (the same wgpu eframe / egui-wgpu use)
wgpu = { version = "30.0.1", features = ["fragile-send-sync-non-atomic-wasm"] }
+25
View File
@@ -613,3 +613,28 @@ fn wav_and_aiff_audio_only() {
}
}
}
/// An AIFF EffectCraft renders imports back (#1428): plain 16-bit and AIFF-C `fl32`.
#[test]
fn rendered_aiff_imports_back() {
use effectcraft_export::render_queue::AudioFormat;
let d = out_dir("aiff-import");
let wav = d.join("tone.wav");
write_tone(&wav, 2.0);
let (p, cid) = project(Some(&wav));
let pool = MediaPool::new();
for (format, name) in [(AudioFormat::S16, "s16.aif"), (AudioFormat::F32, "f32.aif")] {
// 44.1 kHz, not the 48 kHz the samples are read back at: a wrong rate shows in the duration.
let om = OutputModule { audio_sample_rate: 44_100, audio_channels: 2, audio_format: format, ..OutputModule::for_format(OutputFormat::Aiff) };
let path = d.join(name);
assert!(run(&p, cid, &pool, &om, &path).audio);
let f = effectcraft_media::probe(&path).unwrap_or_else(|e| panic!("{name}: {e}"));
assert!(f.has_audio && !f.has_video, "{name}");
assert_eq!(f.duration, Tick::from_seconds_f64(1.2), "{name}: 52 920 frames at 44.1 kHz");
// Tone on the left, silence on the right: the two channels are read as two.
let s = MediaPool::new().audio_samples(&f, Tick::from_seconds_f64(0.3), 24_000, 48_000);
let (l, r) = (rms(s.iter().step_by(2).copied()), rms(s.iter().skip(1).step_by(2).copied()));
assert!((l - 0.3536).abs() < 0.01, "{name}: left RMS {l}");
assert!(r < 0.01, "{name}: right RMS {r}");
}
}
+2
View File
@@ -24,6 +24,8 @@ filmcraft-isobmff = { workspace = true }
filmcraft-frame = { workspace = true }
filmcraft-color = { workspace = true }
filmcraft-time = { workspace = true }
# AIFF import (#1428): enables the aiff reader of filmcraft-codecs' symphonia.
symphonia = { workspace = true }
exr = { workspace = true }
gif = { workspace = true }
image = { workspace = true, features = ["gif", "webp", "tiff", "bmp", "exr", "tga", "hdr"] }