Skip to main content

use_acoustics/
intensity.rs

1use crate::decibel::REFERENCE_SOUND_INTENSITY_W_PER_M2;
2
3/// A validated sound intensity in watts per square meter.
4#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
5pub struct SoundIntensityWPerM2(f64);
6
7impl SoundIntensityWPerM2 {
8    /// Creates a validated sound intensity value.
9    #[must_use]
10    pub fn new(value: f64) -> Option<Self> {
11        if is_valid_positive_scalar(value) {
12            Some(Self(value))
13        } else {
14            None
15        }
16    }
17
18    /// Returns the stored intensity value.
19    #[must_use]
20    pub fn value(self) -> f64 {
21        self.0
22    }
23
24    /// Returns the sound intensity level for this intensity.
25    #[must_use]
26    pub fn level_db_sil(self) -> f64 {
27        10.0 * (self.0.log10() - REFERENCE_SOUND_INTENSITY_W_PER_M2.log10())
28    }
29}
30
31/// Computes sound intensity in watts per square meter from sound intensity level in decibels.
32#[must_use]
33pub fn intensity_from_sil_db(db_sil: f64) -> Option<f64> {
34    if !db_sil.is_finite() {
35        return None;
36    }
37
38    let intensity = REFERENCE_SOUND_INTENSITY_W_PER_M2 * 10.0_f64.powf(db_sil / 10.0);
39
40    if intensity.is_finite() && intensity > 0.0 {
41        Some(intensity)
42    } else {
43        None
44    }
45}
46
47fn is_valid_positive_scalar(value: f64) -> bool {
48    value.is_finite() && value > 0.0
49}