Skip to main content

resample/
resample_type.rs

1use std::ffi::CStr;
2
3use libsamplerate_rs::src_get_description;
4use libsamplerate_rs::src_get_name;
5use libsamplerate_rs::SRC_LINEAR;
6use libsamplerate_rs::SRC_SINC_BEST_QUALITY;
7use libsamplerate_rs::SRC_SINC_FASTEST;
8use libsamplerate_rs::SRC_SINC_MEDIUM_QUALITY;
9use libsamplerate_rs::SRC_ZERO_ORDER_HOLD;
10
11
12/// The resampler type used to distinguish the interpolation function
13/// used by `libsamplerate`.
14///
15/// Has a great impact on quality and performance.
16#[non_exhaustive]
17#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
18pub enum ResampleType {
19    SincBestQuality = SRC_SINC_BEST_QUALITY as isize,
20    SincMediumQuality = SRC_SINC_MEDIUM_QUALITY as isize,
21    SincFastest = SRC_SINC_FASTEST as isize,
22    ZeroOrderHold = SRC_ZERO_ORDER_HOLD as isize,
23    Linear = SRC_LINEAR as isize,
24}
25
26impl ResampleType {
27    /// Return a human-readable name for this type of resampler.
28    pub fn name(&self) -> &'static str {
29        // SAFETY: `src_get_name` is always safe to call.
30        let ptr = unsafe { src_get_name(*self as i32) };
31        // SANITY: `src_get_name` always returns a valid pointer for a
32        //         valid convert and we only have known convert types.
33        assert!(!ptr.is_null());
34
35        // SAFETY: `ptr` is not NULL and guaranteed to be valid.
36        unsafe { CStr::from_ptr(ptr) }.to_str().unwrap()
37    }
38
39    /// Return the human-readable description for this type of resampler.
40    pub fn description(&self) -> &'static str {
41        // SAFETY: `src_get_description` is always safe to call.
42        let ptr = unsafe { src_get_description(*self as i32) };
43        // SANITY: `src_get_description` always returns a valid pointer
44        //         for a valid convert and we only have known convert
45        //         types.
46        assert!(!ptr.is_null());
47
48        // SAFETY: `ptr` is not NULL and guaranteed to be valid.
49        unsafe { CStr::from_ptr(ptr) }.to_str().unwrap()
50    }
51}
52
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58
59    #[test]
60    fn name() {
61        assert_eq!(
62            ResampleType::SincBestQuality.name(),
63            "Best Sinc Interpolator"
64        );
65        assert_eq!(
66            ResampleType::SincMediumQuality.name(),
67            "Medium Sinc Interpolator"
68        );
69        assert_eq!(
70            ResampleType::SincFastest.name(),
71            "Fastest Sinc Interpolator"
72        );
73        assert_eq!(ResampleType::ZeroOrderHold.name(), "ZOH Interpolator");
74        assert_eq!(ResampleType::Linear.name(), "Linear Interpolator");
75    }
76
77    #[test]
78    fn description() {
79        assert_eq!(
80            ResampleType::SincBestQuality.description(),
81            "Band limited sinc interpolation, best quality, 144dB SNR, 96% BW."
82        );
83        assert_eq!(
84            ResampleType::SincMediumQuality.description(),
85            "Band limited sinc interpolation, medium quality, 121dB SNR, 90% BW."
86        );
87        assert_eq!(
88            ResampleType::SincFastest.description(),
89            "Band limited sinc interpolation, fastest, 97dB SNR, 80% BW."
90        );
91        assert_eq!(
92            ResampleType::ZeroOrderHold.description(),
93            "Zero order hold interpolator, very fast, poor quality."
94        );
95        assert_eq!(
96            ResampleType::Linear.description(),
97            "Linear interpolator, very fast, poor quality."
98        );
99    }
100}