Skip to main content

sva_core/
encode.rs

1// Concern: refuses a sample past what 32-bit floats or integer PCM hold | Non-concern: the file's byte layout (sva-cli wav.rs) | IO: (node, samples) -> f32 samples or CliError
2
3use sva_engine::{Diagnostic, EngineError, Located};
4
5use crate::CliError;
6
7pub fn float32(node: &str, plane: &[f64]) -> Result<Vec<f32>, CliError> {
8    plane
9        .iter()
10        .map(|&v| match v as f32 {
11            held if held.is_finite() => Ok(held),
12            _ => Err(unrepresentable(
13                node,
14                v,
15                "a 32-bit float",
16                "scale the output down",
17            )),
18        })
19        .collect()
20}
21
22/// Integer PCM holds full scale and nothing past it.
23pub fn full_scale(node: &str, plane: &[f32]) -> Result<(), CliError> {
24    match plane.iter().find(|v| v.abs() > 1.0) {
25        Some(v) => Err(unrepresentable(
26            node,
27            f64::from(*v),
28            "integer PCM",
29            "scale the output into full scale, or write 32-bit floats with --bits 32",
30        )),
31        None => Ok(()),
32    }
33}
34
35fn unrepresentable(node: &str, value: f64, format: &str, help: &str) -> CliError {
36    CliError::Engine(EngineError::refused(Diagnostic {
37        code: "render.unrepresentable_sample".to_string(),
38        message: format!("a sample of {value:e} is past what {format} holds"),
39        location: Located::at(node, None),
40        help: help.to_string(),
41    }))
42}