1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//! A pure-Rust General MIDI synthesizer. Its DSP code has no third-party Rust
//! dependencies. Default builds embed separately licensed recorded material
//! from first-party asset crates, so no external SoundFont or runtime sound-bank
//! lookup is required. Input is a Standard MIDI File; output is interleaved
//! stereo `f32`.
//!
//! Two surfaces:
//!
//! - [`offline`] — load or parse an SMF, then render, normalize, and atomically
//! write a WAV with bounded audio memory. The path shown below.
//! - [`live`] — [`live::RealtimeSynth`]: raw MIDI bytes in via
//! [`write_byte`](live::RealtimeSynth::write_byte), stereo blocks summed
//! into your output buffer via
//! [`render_add`](live::RealtimeSynth::render_add).
//!
//! ```no_run
//! use ferrosintesis::offline::{self, Normalization, Options};
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! // A one-note Standard MIDI File, assembled in memory: format 0, one
//! // track, 480 ticks per quarter; a harp plays middle C for one beat.
//! let mut smf: Vec<u8> = Vec::new();
//! smf.extend(b"MThd");
//! smf.extend(6u32.to_be_bytes()); // header length
//! smf.extend(0u16.to_be_bytes()); // format 0
//! smf.extend(1u16.to_be_bytes()); // one track
//! smf.extend(480u16.to_be_bytes()); // ticks per quarter note
//! let track = [
//! 0x00, 0xC0, 46, // program change: harp
//! 0x00, 0x90, 60, 100, // note on: middle C, velocity 100
//! 0x83, 0x60, 0x80, 60, 0, // 480 ticks later: note off
//! 0x00, 0xFF, 0x2F, 0x00, // end of track
//! ];
//! smf.extend(b"MTrk");
//! smf.extend((track.len() as u32).to_be_bytes());
//! smf.extend(track);
//!
//! let song = offline::parse(&smf)?;
//! let opt = Options::default().with_tail(1.0); // short reverb tail
//! let stats = offline::render_to_wav(
//! &song,
//! &opt,
//! std::path::Path::new("output.wav"),
//! Normalization::loudness(-18.0, -1.0),
//! )?;
//! assert!(stats.voices_spawned >= 1 && stats.peak > 0.0);
//! # Ok(())
//! # }
//! ```
//!
//! Rendering is deterministic for a fixed executable, MIDI file, and options.
//! The default `embedded-samples` feature compiles
//! roughly 111 MiB of recorded audio — 1156 WAVs across twenty-five
//! first-party asset crates — into the binary; `default-features = false`
//! builds the fully modeled synth instead, a far smaller artifact with
//! synthetic note onsets in place of the recorded ones.
//! [`embedded_samples_available`] reports which build this is. No unsafe
//! code, no build scripts.
//!
//! Most of that audio is CC0; ten of the twenty-five crates carry an
//! attribution obligation that travels with a distributed binary. The
//! `NOTICE` file at the repository root is the index of what you must
//! reproduce, and each asset crate packages the exact required text.
//!
//! All 128 GM melodic program numbers route to a synthesized voice family, but
//! programs within a family may share an engine and support varies by program.
//! The GM sound-effects block 120–127 also has explicit voice paths. This is not
//! a claim of GM conformance or reference-module timbre. The README carries the
//! program-by-program table; DESIGN.md in the repository carries the full design
//! essay.
// The public surface ships to docs.rs. An undocumented public item is a bug, and the
// gate (`clippy -D warnings`) makes this one fail the build rather than rot quietly.
pub use MidiError;
/// Whether this build contains the optional compile-time attack-sample bank.
///
/// Disable the crate's default features to build the fully modeled synth without
/// embedding any of the sample-asset packages. See the README's "Sample provenance
/// and licensing" section for what a default build embeds and what it obliges a
/// binary distributor to reproduce.
pub const
pub
pub
pub
pub
// These oracles inspect sibling packages and repository policy. `.cargo/config.toml`
// enables them in a checkout; the published archive omits both the inputs and the cfg.
pub
pub
pub
pub
pub
pub
pub
pub