Skip to main content

hidpp/feature/
sidetone.rs

1//! Implements `Sidetone` (feature `0x8300`) for audio devices.
2
3use openlogi_hidpp_derive::Feature;
4
5use crate::{feature::FeatureEndpoint, protocol::v20::Hidpp20Error};
6
7/// Per-channel sidetone mute statuses.
8#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize))]
10#[non_exhaustive]
11pub struct SidetoneMuteStatus {
12    /// Raw mute-status bitmask. A set bit means the channel is muted.
13    pub statuses: u8,
14}
15
16/// Change mask and statuses for sidetone mute settings.
17#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
18#[cfg_attr(feature = "serde", derive(serde::Serialize))]
19pub struct SidetoneMuteChange {
20    /// Channels to update. A set bit means the corresponding status bit applies.
21    pub change_mask: u8,
22    /// Desired mute statuses. A set bit means the channel should be muted.
23    pub statuses: u8,
24}
25
26/// Implements the `Sidetone` / `0x8300` feature.
27#[derive(Clone, Feature)]
28#[creatable(id = 0x8300, version = 1)]
29pub struct SidetoneFeature {
30    /// The endpoint this feature talks to.
31    endpoint: FeatureEndpoint,
32}
33
34impl SidetoneFeature {
35    /// Retrieves the sidetone level, in the documented `0..=100` range.
36    pub async fn get_sidetone_level(&self) -> Result<u8, Hidpp20Error> {
37        Ok(self.endpoint.call(0, [0; 3]).await?.extend_payload()[0])
38    }
39
40    /// Sets the sidetone level. Devices reject values outside `0..=100`.
41    pub async fn set_sidetone_level(&self, level: u8) -> Result<(), Hidpp20Error> {
42        self.endpoint.call(1, [level, 0, 0]).await?;
43        Ok(())
44    }
45
46    /// Retrieves sidetone mute statuses.
47    pub async fn get_sidetone_mute(&self) -> Result<SidetoneMuteStatus, Hidpp20Error> {
48        Ok(SidetoneMuteStatus {
49            statuses: self.endpoint.call(2, [0; 3]).await?.extend_payload()[0],
50        })
51    }
52
53    /// Updates selected sidetone mute statuses.
54    pub async fn set_sidetone_mute(&self, change: SidetoneMuteChange) -> Result<(), Hidpp20Error> {
55        self.endpoint
56            .call(3, [change.change_mask, change.statuses, 0])
57            .await?;
58        Ok(())
59    }
60}