From dabcb4840a07b01cfb5c2302f4829f7fa2a35ca4 Mon Sep 17 00:00:00 2001 From: MarekSpodBiedry <73122968+MarekSpodBiedry@users.noreply.github.com> Date: Mon, 12 Oct 2026 16:27:57 +0200 Subject: [PATCH] Open .m4b audiobook files like .m4a M4B is the same MP4/AAC container as M4A, and the decoder already reads it, but the Open dialog, the web file picker and the file browser hid .m4b files. Add m4b to those lists and to the extension fallback. --- apps/soundcraft-web/src/web.rs | 4 +++- apps/soundcraft/src/main.rs | 2 +- crates/audio-io/src/lib.rs | 2 +- crates/audio-io/tests/malformed.rs | 1 + crates/ui-egui/src/windows.rs | 2 +- 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/soundcraft-web/src/web.rs b/apps/soundcraft-web/src/web.rs index 02f1e13..452e807 100644 --- a/apps/soundcraft-web/src/web.rs +++ b/apps/soundcraft-web/src/web.rs @@ -67,7 +67,9 @@ enum Purpose { } const SESSION_EXTS: &[&str] = &[io::BUNDLE_EXTENSION, soundcraft_model::SESSION_EXTENSION]; -const AUDIO_EXTS: &[&str] = &["wav", "wave", "bwf", "aif", "aiff", "aifc", "flac", "mp3", "ogg", "oga", "m4a", "aac", "mp4", "caf", "mkv", "webm"]; +const AUDIO_EXTS: &[&str] = &[ + "wav", "wave", "bwf", "aif", "aiff", "aifc", "flac", "mp3", "ogg", "oga", "m4a", "m4b", "aac", "mp4", "caf", "mkv", "webm", +]; const MIDI_EXTS: &[&str] = &["mid", "midi", "smf"]; impl Purpose { diff --git a/apps/soundcraft/src/main.rs b/apps/soundcraft/src/main.rs index 28723b7..1931d2c 100644 --- a/apps/soundcraft/src/main.rs +++ b/apps/soundcraft/src/main.rs @@ -162,7 +162,7 @@ fn services() -> Services { "file.import_midi" => d.add_filter("MIDI", &["mid", "midi", "smf"]), _ => d.add_filter( "Audio", - &["wav", "wave", "bwf", "aif", "aiff", "aifc", "flac", "mp3", "ogg", "oga", "m4a", "aac", "mp4", "caf", "mkv", "webm"], + &["wav", "wave", "bwf", "aif", "aiff", "aifc", "flac", "mp3", "ogg", "oga", "m4a", "m4b", "aac", "mp4", "caf", "mkv", "webm"], ), }; d.pick_file().map(|p| p.to_string_lossy().into_owned()) diff --git a/crates/audio-io/src/lib.rs b/crates/audio-io/src/lib.rs index 87241c6..0e3fdd9 100644 --- a/crates/audio-io/src/lib.rs +++ b/crates/audio-io/src/lib.rs @@ -187,7 +187,7 @@ fn detect_by_ext(ext: &str) -> FileFormat { "flac" => FileFormat::Flac, "mp3" | "mp2" | "mp1" => FileFormat::Mp3, "ogg" | "oga" => FileFormat::Ogg, - "aac" | "m4a" | "mp4" | "adts" => FileFormat::Aac, + "aac" | "m4a" | "m4b" | "mp4" | "adts" => FileFormat::Aac, "caf" => FileFormat::Caf, _ => FileFormat::Other, } diff --git a/crates/audio-io/tests/malformed.rs b/crates/audio-io/tests/malformed.rs index 1cec656..384e4bf 100644 --- a/crates/audio-io/tests/malformed.rs +++ b/crates/audio-io/tests/malformed.rs @@ -240,6 +240,7 @@ fn detect_format_by_magic_and_hint() { assert_eq!(detect_format(b"", Some(".WAV")), FileFormat::Wav); assert_eq!(detect_format(b"zz", Some("aif")), FileFormat::Aiff); assert_eq!(detect_format(b"zz", Some("m4a")), FileFormat::Aac); + assert_eq!(detect_format(b"zz", Some("M4B")), FileFormat::Aac); assert_eq!(detect_format(b"zz", Some("flac")), FileFormat::Flac); assert_eq!(detect_format(b"zz", Some("xyz")), FileFormat::Other); assert_eq!(detect_format(b"zz", None), FileFormat::Other); diff --git a/crates/ui-egui/src/windows.rs b/crates/ui-egui/src/windows.rs index 12b3540..2b280cf 100644 --- a/crates/ui-egui/src/windows.rs +++ b/crates/ui-egui/src/windows.rs @@ -334,7 +334,7 @@ fn workspace(app: &mut SoundApp, ctx: &egui::Context) { } let is_dir = e.file_type().is_ok_and(|t| t.is_dir()); let ext = std::path::Path::new(&name).extension().and_then(|x| x.to_str()).unwrap_or("").to_ascii_lowercase(); - (is_dir || ["wav", "aif", "aiff", "flac", "mp3", "ogg", "m4a", "caf", "mid", "midi", "scraft"].contains(&ext.as_str())) + (is_dir || ["wav", "aif", "aiff", "flac", "mp3", "ogg", "m4a", "m4b", "caf", "mid", "midi", "scraft"].contains(&ext.as_str())) .then_some((name, is_dir)) }) .collect()