#[non_exhaustive]pub struct Metadata {Show 13 fields
pub loudness: Option<f32>,
pub input_level_dbu: Option<f32>,
pub output_level_dbu: Option<f32>,
pub gain: Option<f32>,
pub name: Option<String>,
pub modeled_by: Option<String>,
pub gear_make: Option<String>,
pub gear_model: Option<String>,
pub gear_type: Option<String>,
pub tone_type: Option<String>,
pub trainer: Option<String>,
pub date: Option<Date>,
pub training: Option<Value>,
}Expand description
The fields NAM may write into a .nam file’s metadata block.
None of this reaches the forward pass — it is descriptive only, for display and routing decisions. All fields are optional: older or minimal files omit the block entirely, and each field is parsed leniently, so one malformed entry never costs you the others. Unknown keys are ignored.
For comparison, NAM’s C++ NeuralAmpModelerCore types only the three
calibration numbers (loudness, input_level_dbu, output_level_dbu) and
leaves the rest as an untyped JSON blob for each host to re-derive.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.loudness: Option<f32>How loud the model is against NAM’s standardized input, in dBFS (NAM’s
loudness).
This is plain RMS — the trainer computes 20·log10(sqrt(mean(y²))) — not a
perceptual measure. It is not LUFS: no K-weighting, no gating. Two models
with the same loudness but different spectra will not match perceptually, so
don’t feed this number to a loudness target that expects ITU-R BS.1770.
input_level_dbu: Option<f32>Analog level (dBu) corresponding to 0 dBFS at the model input.
output_level_dbu: Option<f32>Analog level (dBu) corresponding to 0 dBFS at the model output.
gain: Option<f32>NAM’s own estimate, in 0.0..=1.0, of “how much gain / compression does the
model seem to have” — derived by the trainer from the model’s response across
a sweep of input levels, not a knob position on the modelled gear.
name: Option<String>Human-readable model name chosen by its author. Often more descriptive than the filename, which is whatever the file happens to have been saved as.
modeled_by: Option<String>Who captured the model.
gear_make: Option<String>Manufacturer of the modelled gear, e.g. "Marshall".
gear_model: Option<String>Model of the modelled gear, e.g. "JMP-50".
gear_type: Option<String>What kind of gear was captured, and — crucially — how much of the signal chain the capture covers.
This is a String rather than an enum on purpose: there is no single
vocabulary, and the vocabularies move. NAM’s trainer writes amp, pedal,
pedal_amp, amp_cab, amp_pedal_cab, preamp, studio; TONE3000 writes
amp, amp-cab, pedal, outboard, cab, space, experimental, plus
the deprecated-but-permanently-accepted full-rig and ir. Only amp and
pedal are common to both, and TONE3000 has already retired values that
exist in files on disk. An enum over either set would reject real files.
Use Metadata::includes_cab rather than matching by hand.
tone_type: Option<String>Character of the captured tone. NAM’s vocabulary is clean, overdrive,
crunch, hi_gain, fuzz; a String for the same reason as
Self::gear_type (values like "bass" and "T3K-Null" occur in the wild).
trainer: Option<String>Which trainer produced the file, when it says, e.g. "TONE3000".
date: Option<Date>When the model was exported.
training: Option<Value>The trainer’s own record of the training run — latency calibration, data checks, settings. Deliberately left untyped: the shape is trainer- and version-specific and carries no stability guarantee.
Implementations§
Source§impl Metadata
impl Metadata
Sourcepub fn includes_cab(&self) -> Option<bool>
pub fn includes_cab(&self) -> Option<bool>
Whether the capture includes a speaker cabinet, as far as
Self::gear_type says.
This is the question that matters for signal routing: stacking an impulse
response on top of a model that already has a cab in it means two cabs in
series, which sounds wrong. Some(true) says the cab is already baked in, so
don’t add an IR. Some(false) says only that this capture stops before the
speaker — whether an IR belongs directly after it still depends on the rest
of your chain, since a pedal or outboard capture wants an amp next, not a
cab.
Recognized are the values NAM’s trainer and TONE3000 actually write, plus any
value naming cab as one of its _-separated components (so a future
"pedal_amp_cab" classifies without a code change). cab is matched as a
whole token, never a substring, so "cable" and "cabless" don’t read as
cab-inclusive. Matching ignores case, surrounding whitespace, and - vs _,
so TONE3000’s "full-rig" and a hypothetical "full_rig" agree.
Anything else returns None — callers get “unknown” rather than a guess.
The token rule has a known limit: a negated spelling like "amp_no_cab"
still reads as cab-inclusive, since cab is one of its tokens. Neither
vocabulary forms values that way, and detecting negation in free text is
guesswork of the kind this function exists to avoid — so it is documented
rather than defended against.
The answer is only ever as good as the file: gear_type is author-supplied
and real captures do mislabel themselves (a file named ...-FullRig.nam
tagged gear_type: "amp"). Treat it as a default to offer, not a fact to act
on silently.
NAM’s "studio" is deliberately None: NAM documents the value nowhere, and
it reads equally well as “studio outboard gear” (no speaker — which is what
TONE3000 calls outboard) or “studio-recorded chain” (speaker included).
Guessing wrong would silently route audio through one cab too many, or none
at all, so we decline to guess.
let md = Metadata::default();
assert_eq!(md.includes_cab(), None); // no gear_type recorded