/// Environmental parameters supplied to modules once when a plan is activated.
///
/// Modules that depend on these parameters (e.g. oscillators that use `sample_rate`)
/// should store them in [`Module::initialise`] and use the stored copies during
/// [`Module::process`] rather than receiving them per sample.
///
/// `poly_voices` is the number of active polyphony voices. Poly cable buffers always
/// hold 16 channels (`[f32; 16]`) regardless of this value; modules should use
/// `poly_voices` to know how many of those channels carry live data.
///
/// `hosted` indicates whether the engine is running inside a plugin host (e.g. a
/// DAW via CLAP). When `true`, host transport state is available on the
/// `GLOBAL_TRANSPORT` backplane slot. Modules like `MasterSequencer` use this to
/// decide whether to synchronise with the host or run their own clock.
///
/// `periodic_update_interval` is the number of inner ticks between successive
/// [`Module::periodic_update`] calls. At 1× oversampling this equals
/// [`BASE_PERIODIC_UPDATE_INTERVAL`] (32); at N× oversampling it equals
/// `BASE_PERIODIC_UPDATE_INTERVAL * N`, preserving the same wall-clock update rate.
/// Modules with `wants_periodic() == true` should use this value (not the
/// compile-time constant) to compute per-sample interpolation deltas.
///
/// [`BASE_PERIODIC_UPDATE_INTERVAL`]: crate::BASE_PERIODIC_UPDATE_INTERVAL
/// [`Module::periodic_update`]: crate::Module::periodic_update
#[derive(Debug, Clone, Copy)]
pub struct AudioEnvironment {
    pub sample_rate: f32,
    pub poly_voices: usize,
    pub periodic_update_interval: u32,
    pub hosted: bool,
}