xmrs/mix_plugin.rs
1//! IT-style mix-plugin table (OpenMPT extension).
2//!
3//! ScreamTracker / Impulse Tracker file formats can carry an
4//! optional plugin section, originally introduced by OpenMPT, that
5//! describes a chain of DSP / VST plugins applied to channels and
6//! buses at mix time. The plugin payloads themselves are opaque
7//! binary blobs (typically VST chunk dumps) — xmrs does not host
8//! the plugins, but it preserves them verbatim so a round-trip
9//! through the editor doesn't lose the author's mix settings.
10//!
11//! Non-IT formats leave the containing `Module::mix_plugins` field
12//! at `None`.
13
14use serde::{Deserialize, Serialize};
15
16use alloc::vec::Vec;
17
18/// Identification + routing fields for a single plugin slot,
19/// mirroring OpenMPT's `SNDMIXPLUGININFO`. Identifiers are kept as
20/// raw `u32`s because the four-character codes used by the format
21/// are not always valid UTF-8 (and aren't always meaningful as
22/// FOURCCs — some are numeric IDs).
23#[derive(Serialize, Deserialize, Debug, Clone, Default)]
24pub struct MixPluginInfo {
25 /// Primary plugin ID (typically a packed four-character code
26 /// such as `'VstP'` for a generic VST host slot, or a built-in
27 /// identifier for OpenMPT's bundled effects).
28 pub id1: u32,
29 /// Secondary plugin ID, used by the host to disambiguate
30 /// between plugins that share the same `id1`.
31 pub id2: u32,
32 /// Source bus for plugin input. Routing semantics follow
33 /// OpenMPT — see its docs for the exact field encoding.
34 pub input_routing: u32,
35 /// Destination bus for plugin output.
36 pub output_routing: u32,
37}
38
39/// One plugin slot. The `data` blob is the plugin's serialised
40/// state (typically a VST chunk produced by `effGetChunk`); xmrs
41/// treats it as opaque bytes.
42#[derive(Serialize, Deserialize, Debug, Clone, Default)]
43pub struct MixPlugin {
44 pub info: MixPluginInfo,
45 /// Plugin-specific binary state. `None` when the slot exists
46 /// in the file but carries no chunk (i.e., a default-state
47 /// plugin or an empty slot kept for indexing).
48 pub data: Option<Vec<u8>>,
49}
50
51/// Mix-plugin table for one module. Two parallel pieces of data:
52/// per-channel routing assignments, and a flat list of plugin
53/// slots referenced by those assignments.
54#[derive(Serialize, Deserialize, Debug, Clone, Default)]
55pub struct MixPlugins {
56 /// Per-channel plugin assignment. Index = channel number.
57 /// Value `0` = no plugin on that channel; value `N` (1-based)
58 /// means the channel is routed through `plugins[N - 1]`. The
59 /// IT format reserves up to 64 entries.
60 pub channel_assignments: Vec<u32>,
61 /// Flat list of plugin slots, addressed 1-based by
62 /// `channel_assignments`. Up to 64 entries.
63 pub plugins: Vec<MixPlugin>,
64}