mirror of
https://github.com/storytold/craft-libs.git
synced 2026-11-14 06:22:24 +00:00
* craft-audio: integer PCM of WAV and AIFF files bit for bit, and minimal files around it wav_pcm and aiff_pcm (feature decode-native) return a file's integer PCM as stored (RawPcm: little-endian interleaved bytes, 8-bit unsigned, with channels, rate and bits), built on the existing WAV and AIFF chunk parsers. pcm_wav_file, pcm_wav_header, pcm_aiff_file and pcm_aiff_header (feature pcm-encode) write the 44-byte canonical WAVE header and the plain AIFF header around such bytes. For essence embedded in AAF and OMF files, which is moved bit for bit and whose descriptors hold a bare header as a summary. The writers are FilmCraft's (filmcraft-interchange wav.rs); the readers replace its second WAV/AIFF parser with this crate's. * craft-timeline: exact media time, reports, media paths, ALE and CMX 3600 EDL New crate for editorial timeline interchange (#782), moved from FilmCraft at 4bec22bd: - time: filmcraft-time whole (Tick, FrameRate, TimeRange, SMPTE timecode, feet+frames, typed-timecode parsing) with its tests. - report: Report / Level / ReportEntry. - path: file URL and path conversion, relative references joined to a folder. - rate: timebase+ntsc and floating rates to exact rates, MAX_RATE. - ale: AleDoc, parse, write, standard heading and columns. - edl: the parser (events, lines, timecode fields, M2, AUD, comment extensions), the frame-rate guess, and the line layout of the writer, on frame counts. - Format, detect_text, decode_text. Each format module gives the document as the format writes it. Mapping onto an application's timeline stays in the application. * craft-timeline: strip a UTF-8 byte order mark when parsing ALE files An ALE saved with a BOM was refused as "not an ALE file": the mark made the first line something other than "Heading". Ported from storytold/filmcraft#4531. * craft-aaf: AAF (Edit Protocol) and OMF 2.0 readers and writers over one composition model New crate (#782), moved from FilmCraft's filmcraft-interchange at 4bec22bd: the mob-style model types of comp.rs, aaf/{ids,store,read,write}.rs and omf/{bento,read,write}.rs, with their structural and hostile-input tests rebuilt on model documents instead of FilmCraft projects. The container is craft-cfb, time and reports are craft-timeline's, and the WAVE/AIFF wrappers of embedded PCM are craft-audio's. The writer's identity (company, product, version, AAF product id) is passed in instead of being FilmCraft's. The private tags and properties FilmCraft wrote keep their names so existing files read back. The mapping between the model and an application's project stays in the application. --------- Co-authored-by: NetterSilver <133535268+Silvertree2010@users.noreply.github.com>
48 lines
2.2 KiB
Rust
48 lines
2.2 KiB
Rust
//! OMF Interchange 2.0 for audio post: written, and the same structures read.
|
||
//!
|
||
//! Written from the public *OMF Interchange Specification Version 2.0* (Avid Technology, 1995/97)
|
||
//! and Apple's *Bento Specification* revision 1.0d5 for the container ([`bento`]).
|
||
//!
|
||
//! The file holds a composition mob (`CMOB`) with a timecode slot and one sound slot per audio
|
||
//! track (one per channel when broken out to mono): sequences (`SEQU`) of fillers (`FILL`), source
|
||
//! clips (`SCLP`) and transitions (`TRAN` with a `SimpleMonoAudioDissolve` effect); clip volume is a
|
||
//! `MonoAudioGain` effect (`EFFE`) whose slot −1 is the clip and slot 1 the amplitude
|
||
//! (`CVAL` constant or `VVAL` keyframes). Every media item has a master mob (`MMOB`), a file source
|
||
//! mob (`SMOB` with a `WAVD` / `AIFD` descriptor: embedded essence in a `WAVE` media data object,
|
||
//! or a locator to a separate file) and a tape source mob carrying its timecode. Times are in
|
||
//! samples (sound slots use the sample rate as edit rate) so edits are sample-exact.
|
||
//!
|
||
//! Only sound is written: picture tracks and markers of the model are left out, and a nested
|
||
//! composition is not written as one (readers of OMF do not follow compositions). A caller with
|
||
//! nested sequences mixes their sound and passes it as media like any other; Premiere Pro's OMF
|
||
//! export does the same.
|
||
//!
|
||
//! Private properties. `FilmCraft:SCLP:ClipName` (a clip's name) and `FilmCraft:EFFE:EffectID` (a
|
||
//! transition's name) are not in the specification; they were first written by FilmCraft and keep
|
||
//! their names so that existing files read back.
|
||
|
||
pub(crate) mod bento;
|
||
mod read;
|
||
mod write;
|
||
|
||
use crate::model::Document;
|
||
use crate::{Identity, Report, Result};
|
||
|
||
/// Write the sound of `doc`'s first composition as an OMF 2.0 file.
|
||
pub fn write(doc: &Document, identity: &Identity<'_>, report: &mut Report) -> Result<Vec<u8>> {
|
||
write::write(doc, identity, report)
|
||
}
|
||
|
||
/// Read an OMF 2.0 file (as written by [`write`] and by applications using the same structures).
|
||
pub fn read(bytes: &[u8], report: &mut Report) -> Result<Document> {
|
||
read::read(bytes, report)
|
||
}
|
||
|
||
/// Whether `bytes` end with a Bento container label (OMF files do).
|
||
pub fn sniff(bytes: &[u8]) -> bool {
|
||
bento::sniff(bytes)
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests;
|