mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-28 20:16:52 -06:00
Merge pull request #357 from HEOJUNFO/fix-317-aiff-float
Export: AIFF 32-bit float writes AIFF-C fl32 instead of 24-bit (#317)
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
//! | WebM | WebM (Matroska) | VP9 profile 0 (`effectcraft-vp9enc`: key + inter frames, a key frame every 2 s, loop filter), 8-bit 4:2:0; or AV1 (`effectcraft-av1enc`) | VP9 alpha (BlockAdditional) | Opus (`effectcraft-opusenc`: SILK / hybrid / CELT by bitrate and application), 48 kHz |
|
||||
//! | HEVC | MP4 (`hvc1`) | `effectcraft-hevcenc` Main / Main 10 4:2:0, I + P slices, bitrate or constant quality, level, key-frame interval | no | AAC-LC (FilmCraft) |
|
||||
//! | AV1 | MP4 (`av01`) | `effectcraft-av1enc` Main 8/10-bit 4:2:0, key + inter frames | no | AAC-LC (FilmCraft) |
|
||||
//! | WAV / AIFF | RIFF WAVE / AIFF | — | — | PCM 16/24-bit (WAV also 32-bit float), mono/stereo (audio only) |
|
||||
//! | WAV / AIFF | RIFF WAVE / AIFF (AIFF-C for float) | — | — | PCM 16/24-bit or 32-bit float, mono/stereo (audio only) |
|
||||
//!
|
||||
//! Every frame goes through [`pipeline`]: the Render Settings overrides (Effects, Solo Switches,
|
||||
//! Guide Layers, Frame Blending, Motion Blur, Color Depth), field rendering (two fields half a
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
//! frames every two seconds, inter frames between them: SimpleBlocks carry the key flag, inter
|
||||
//! BlockGroups a ReferenceBlock; the alpha stream's key frames line up with the colour stream's),
|
||||
//! Opus from `effectcraft-opusenc` (CELT, 48 kHz stereo, 20 ms packets,
|
||||
//! `CodecDelay` = pre-skip). WAV (RIFF, 16-bit PCM) and AIFF (big-endian 16-bit, 80-bit
|
||||
//! extended sample rate) follow their published file layouts.
|
||||
//! `CodecDelay` = pre-skip). WAV (RIFF, PCM or IEEE float) and AIFF (big-endian PCM, 80-bit
|
||||
//! extended sample rate; AIFF-C `fl32` for float) follow their published file layouts.
|
||||
|
||||
use std::io::{Seek, SeekFrom, Write};
|
||||
|
||||
@@ -322,14 +322,11 @@ fn ieee_extended(v: f64) -> [u8; 10] {
|
||||
}
|
||||
|
||||
/// WAV or AIFF: the comp's audio over the render span (Audio Output: sample rate, mono/stereo,
|
||||
/// 16/24-bit integer or 32-bit float; AIFF has no float in plain AIFF, so it writes 24-bit).
|
||||
/// 16/24-bit integer or 32-bit float; plain AIFF has no float, so 32-bit float is AIFF-C `fl32`).
|
||||
pub(crate) fn audio_file(job: &Cx, comp: &Comp, aiff: bool, st: &mut State) -> Result<Report> {
|
||||
let sr = job.output.audio_sample_rate.clamp(8_000, 192_000);
|
||||
let channels = if job.output.audio_channels == 1 { 1u16 } else { 2 };
|
||||
let fmt = match job.output.audio_format {
|
||||
AudioFormat::F32 if aiff => AudioFormat::S24,
|
||||
f => f,
|
||||
};
|
||||
let fmt = job.output.audio_format;
|
||||
let bytes_per_sample: u16 = match fmt {
|
||||
AudioFormat::S16 => 2,
|
||||
AudioFormat::S24 => 3,
|
||||
@@ -363,15 +360,33 @@ pub(crate) fn audio_file(job: &Cx, comp: &Comp, aiff: bool, st: &mut State) -> R
|
||||
let frames = (pcm.len() / block_align as usize) as u32;
|
||||
let mut out = vec![];
|
||||
if aiff {
|
||||
// AIFF-C (Apple, 1991) for float: a format version chunk, and the COMM chunk names the
|
||||
// compression type and its Pascal-string name, padded to an even length.
|
||||
let float = fmt == AudioFormat::F32;
|
||||
let mut comm = vec![];
|
||||
comm.extend_from_slice(&channels.to_be_bytes());
|
||||
comm.extend_from_slice(&frames.to_be_bytes());
|
||||
comm.extend_from_slice(&(bytes_per_sample * 8).to_be_bytes());
|
||||
comm.extend_from_slice(&ieee_extended(sr as f64));
|
||||
let mut fver = vec![];
|
||||
if float {
|
||||
const NAME: &[u8] = b"32-bit floating point";
|
||||
comm.extend_from_slice(b"fl32");
|
||||
comm.push(NAME.len() as u8);
|
||||
comm.extend_from_slice(NAME);
|
||||
if (1 + NAME.len()) % 2 == 1 {
|
||||
comm.push(0);
|
||||
}
|
||||
fver.extend_from_slice(b"FVER");
|
||||
fver.extend_from_slice(&4u32.to_be_bytes());
|
||||
// AIFC Version 1 (May 23, 1990, 2:40 pm).
|
||||
fver.extend_from_slice(&0xA280_5140u32.to_be_bytes());
|
||||
}
|
||||
let ssnd_len = 8 + pcm.len();
|
||||
out.extend_from_slice(b"FORM");
|
||||
out.extend_from_slice(&((4 + 8 + comm.len() + 8 + ssnd_len + ssnd_len % 2) as u32).to_be_bytes());
|
||||
out.extend_from_slice(b"AIFF");
|
||||
out.extend_from_slice(&((4 + fver.len() + 8 + comm.len() + 8 + ssnd_len + ssnd_len % 2) as u32).to_be_bytes());
|
||||
out.extend_from_slice(if float { b"AIFC" } else { b"AIFF" });
|
||||
out.extend_from_slice(&fver);
|
||||
out.extend_from_slice(b"COMM");
|
||||
out.extend_from_slice(&(comm.len() as u32).to_be_bytes());
|
||||
out.extend_from_slice(&comm);
|
||||
|
||||
Reference in New Issue
Block a user