# Copilot instructions (audio_samples)

## Big picture
- This crate is a trait-based audio DSP toolbox built around `AudioSamples<'a, T>` in `src/repr.rs` (wraps `ndarray` mono `Array1` / multi `Array2` + metadata: `sample_rate`, `ChannelLayout`). Multi-channel is shaped `(channels, samples_per_channel)` (channels are rows).
- Operations are organized as focused traits in `src/operations/traits.rs` with implementations split by domain in `src/operations/` (e.g. `statistics.rs`, `processing.rs`, `editing.rs`, `channels.rs`, `transforms.rs`). Many modules are feature-gated; keep new code behind the same feature flags.

## Type system & conversions (project-specific)
- Use `ConvertTo<T>` for audio-aware scaling between sample formats (PCM ↔ normalized float). Use `CastFrom/CastInto` only for raw numeric casts (no audio scaling). See `src/traits.rs` and `ARCHITECTURE.md`.
- Always use the crate re-exported `I24` type (not `i24::I24` directly) as noted in `ARCHITECTURE.md`.

## Error handling conventions
- Prefer returning `AudioSampleResult<T>` / `AudioSampleError` from `src/error.rs` for fallible ops; keep errors in the correct subtree (`Conversion`, `Parameter`, `Layout`, `Processing`, `Feature`, plus feature-gated variants).
- Avoid `unwrap()`/`expect()` in library code (crate has `#![warn(clippy::unwrap_used)]`). Use `?`.

## Performance & data access
- Preserve the “views first / zero-allocation where possible” approach: prefer `ndarray` views and in-place mutation, and avoid needless cloning/collecting (crate enables performance-focused clippy lints in `src/lib.rs`).
- When an op requires contiguous data, use/return `LayoutError::NonContiguous` patterns from `src/error.rs` rather than silently copying.

## Feature flags (don’t accidentally add heavy deps)
- `Cargo.toml` currently has `default = ["full"]` (convenient for dev/testing). When iterating on core code, prefer narrower feature sets like `core-ops` or `minimal` to keep builds fast.
- New modules/APIs that depend on heavy crates must be gated (see `[features]` in `Cargo.toml` and existing `#[cfg(feature = ...)]` in `src/operations/mod.rs`).
- Common feature groups:
  - `core-ops` (statistics/processing/editing/channels)
  - `fft`, `spectral-analysis`, `beat-detection`
  - `plotting` and `static-plots`
  - `resampling`, `serialization`, `parallel-processing`, `simd`, `mkl`, `progress-tracking`

## Extending the crate (where to put things)
- New operation: add the trait method signature in `src/operations/traits.rs` (under the right `#[cfg(feature = ...)]`), implement it in the matching domain module in `src/operations/` (e.g. `processing.rs`, `statistics.rs`), and re-export the trait from `src/operations/mod.rs` under the same cfg.
- New supporting enums/configs: put them in `src/operations/types.rs` and re-export from `src/operations/mod.rs`.
- New fallible behavior: return `AudioSampleResult<T>` and use the specific error subtree from `src/error.rs` (`ParameterError` for validation, `LayoutError` for shape/contiguity, etc.).
- Data access: preserve the mono `Array1` / multi `Array2` (channels-as-rows) convention from `src/repr.rs`; prefer views/in-place mutation and don’t silently copy to “fix” layout.
- Tests: follow the existing pattern of module-local `#[cfg(test)] mod tests` in the module you changed; run `cargo test --lib` (and feature-specific tests via `cargo test --features <feature>`).

## Public API / docs expectations
- `src/lib.rs` has `#![deny(missing_docs)]`: any new public items must be documented.
- Prefer adding functionality as trait methods in the appropriate `src/operations/*` module and re-export through `src/operations/mod.rs` under the same cfg gates.

## Dev workflows (confirmed)
- Build/check/lint/format: `cargo build`, `cargo check`, `cargo clippy`, `cargo fmt` (see `CLAUDE.md`).
- Tests: `cargo test` (core), `cargo test --features full` (all features).
- Example runs: `cargo run --example processing_builder_demo --features full` (see `CLAUDE.md`).
