m5unified 0.2.0

Safe Rust wrapper for M5Unified.
Documentation
use core::ffi::c_int;

use crate::Error;

#[derive(Debug)]
pub struct Mic;

impl Mic {
    pub fn begin(&mut self) -> bool {
        unsafe { m5unified_sys::m5u_mic_begin() }
    }

    pub fn record_i16(&mut self, buffer: &mut [i16]) -> bool {
        unsafe { m5unified_sys::m5u_mic_record_i16(buffer.as_mut_ptr(), buffer.len()) }
    }

    pub fn rms(&mut self, buffer: &mut [i16]) -> Option<f32> {
        if !self.record_i16(buffer) || buffer.is_empty() {
            return None;
        }
        let sum_sq: f32 = buffer.iter().map(|&s| (s as f32) * (s as f32)).sum();
        Some((sum_sq / buffer.len() as f32).sqrt())
    }

    pub fn is_enabled(&self) -> bool {
        unsafe { m5unified_sys::m5u_mic_is_enabled() }
    }

    pub fn is_recording(&self) -> bool {
        unsafe { m5unified_sys::m5u_mic_is_recording() }
    }

    pub fn end(&mut self) {
        unsafe { m5unified_sys::m5u_mic_end() }
    }

    pub fn record_i16_at(&mut self, buffer: &mut [i16], sample_rate_hz: u32) -> bool {
        unsafe {
            m5unified_sys::m5u_mic_record_i16_at(buffer.as_mut_ptr(), buffer.len(), sample_rate_hz)
        }
    }

    pub fn config(&self) -> MicConfig {
        MicConfig {
            noise_filter_level: unsafe { m5unified_sys::m5u_mic_get_noise_filter_level() as i32 },
        }
    }

    pub fn set_config(&mut self, config: MicConfig) -> Result<(), Error> {
        unsafe { m5unified_sys::m5u_mic_set_noise_filter_level(config.noise_filter_level as c_int) }
            .then_some(())
            .ok_or(Error::Unavailable("microphone config"))
    }
}

#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
pub struct MicConfig {
    pub noise_filter_level: i32,
}

#[derive(Debug)]
pub struct Speaker;

impl Speaker {
    pub fn begin(&mut self) -> bool {
        unsafe { m5unified_sys::m5u_speaker_begin() }
    }

    pub fn set_volume(&mut self, volume: u8) {
        unsafe { m5unified_sys::m5u_speaker_set_volume(volume) }
    }

    pub fn tone(&mut self, frequency_hz: u32, duration_ms: u32) -> bool {
        unsafe { m5unified_sys::m5u_speaker_tone(frequency_hz, duration_ms) }
    }

    pub fn play_i16(&mut self, samples: &[i16], sample_rate_hz: u32) -> bool {
        unsafe {
            m5unified_sys::m5u_speaker_play_i16(samples.as_ptr(), samples.len(), sample_rate_hz)
        }
    }

    pub fn is_enabled(&self) -> bool {
        unsafe { m5unified_sys::m5u_speaker_is_enabled() }
    }

    pub fn end(&mut self) {
        unsafe { m5unified_sys::m5u_speaker_end() }
    }

    pub fn volume(&self) -> u8 {
        unsafe { m5unified_sys::m5u_speaker_get_volume() }
    }

    pub fn tone_ex(&mut self, frequency_hz: f32, duration_ms: u32, channel: Option<u8>) -> bool {
        unsafe {
            m5unified_sys::m5u_speaker_tone_ex(
                frequency_hz,
                duration_ms,
                channel.map(i32::from).unwrap_or(-1),
            )
        }
    }

    pub fn play_u8(&mut self, samples: &[u8], sample_rate_hz: u32) -> bool {
        unsafe {
            m5unified_sys::m5u_speaker_play_u8(samples.as_ptr(), samples.len(), sample_rate_hz)
        }
    }

    pub fn play_wav(&mut self, data: &[u8]) -> bool {
        unsafe { m5unified_sys::m5u_speaker_play_wav(data.as_ptr(), data.len()) }
    }

    pub fn is_playing(&self, channel: Option<u8>) -> bool {
        unsafe { m5unified_sys::m5u_speaker_is_playing(channel.map(i32::from).unwrap_or(-1)) }
    }

    pub fn stop(&mut self, channel: Option<u8>) {
        unsafe { m5unified_sys::m5u_speaker_stop(channel.map(i32::from).unwrap_or(-1)) }
    }

    pub fn channel_volume(&self, channel: u8) -> u8 {
        unsafe { m5unified_sys::m5u_speaker_get_channel_volume(i32::from(channel)) }
    }

    pub fn set_channel_volume(&mut self, channel: u8, volume: u8) {
        unsafe { m5unified_sys::m5u_speaker_set_channel_volume(i32::from(channel), volume) }
    }

    pub fn set_all_channel_volume(&mut self, volume: u8) {
        unsafe { m5unified_sys::m5u_speaker_set_all_channel_volume(volume) }
    }
}