0x8300 · sidetone
Headset sidetone control — read or write the microphone-to-ear playback level (0–100) and per-channel mute state so wearers can hear their own voice while speaking.
Headset sidetone control: routes the microphone signal back into the ear cups so the wearer can hear their own voice while speaking. Two independent axes are exposed: get_sidetone_level / set_sidetone_level manage the playback level as a value in 0..=100 (the device rejects out-of-range writes), and get_sidetone_mute / set_sidetone_mute manage per-channel mute state via a bitmask.
SidetoneMuteStatus—statuses: u8bitmask; a set bit means the corresponding channel is muted.SidetoneMuteChange—change_mask: u8selects which channels to update;statuses: u8carries the desired mute state for those channels. Bits absent fromchange_maskare left unchanged on the device.
Spec: Logitech HID++ 2.0 — Sidetone. Used by: Typed wrapper in
openlogi-hidpp.
Function reference
The SidetoneFeature wrapper (0x8300) exposes:
Methods
| Function | HID++ fn | Signature | Returns |
|---|---|---|---|
get_sidetone_level | 0 | () | u8 |
set_sidetone_level | 1 | (level: u8) | () |
get_sidetone_mute | 2 | () | SidetoneMuteStatus |
set_sidetone_mute | 3 | (change: SidetoneMuteChange) | () |
All methods are async and return Result<…, Hidpp20Error>.
Types
SidetoneMuteStatus
Per-channel sidetone mute statuses.
| Field | Type | Description |
|---|---|---|
statuses | u8 | Raw mute-status bitmask. A set bit means the channel is muted. |
SidetoneMuteChange
Change mask and statuses for sidetone mute settings.
| Field | Type | Description |
|---|---|---|
change_mask | u8 | Channels to update. A set bit means the corresponding status bit applies. |
statuses | u8 | Desired mute statuses. A set bit means the channel should be muted. |
Wire format
All four functions use a short 3-byte request payload and a 16-byte long response payload (the crate reads results from extend_payload()). The feature index byte is managed by FeatureEndpoint; only the function-specific payload bytes are shown below.
get_sidetone_level (fn 0)
Request: [0x00, 0x00, 0x00] — no parameters; all bytes are padding.
Response (byte → field):
| Byte | Field | Notes |
|---|---|---|
| 0 | level (u8) | Sidetone level in the range 0..=100. |
set_sidetone_level (fn 1)
Request: [level, 0x00, 0x00]
| Byte | Value | Notes |
|---|---|---|
| 0 | level | Sidetone level to write. Device rejects values outside 0..=100. |
| 1–2 | 0x00 | Padding. |
Response: acknowledged only; no payload fields are read.
get_sidetone_mute (fn 2)
Request: [0x00, 0x00, 0x00] — no parameters; all bytes are padding.
Response (byte → field):
| Byte | Field | Notes |
|---|---|---|
| 0 | SidetoneMuteStatus::statuses (u8) | Bitmask; a set bit means that channel is muted. |
set_sidetone_mute (fn 3)
Request: [change_mask, statuses, 0x00]
| Byte | Value | Notes |
|---|---|---|
| 0 | SidetoneMuteChange::change_mask | Selects which channel bits to overwrite on the device. |
| 1 | SidetoneMuteChange::statuses | Desired mute state for the selected channels. |
| 2 | 0x00 | Padding. |
Response: acknowledged only; no payload fields are read.
Usage (Rust)
use hidpp::{device::Device, feature::sidetone::{SidetoneMuteChange, SidetoneFeature}};
// device: &mut Device, already created via Device::new(channel, index).await?
device.enumerate_features().await?;
if let Some(feat) = device.get_feature::<SidetoneFeature>() {
// Read the current sidetone level (0–100)
let level = feat.get_sidetone_level().await?;
println!("Sidetone level: {level}");
// Lower it by 10, clamped to the valid range
feat.set_sidetone_level(level.saturating_sub(10)).await?;
// Read current per-channel mute state
let mute = feat.get_sidetone_mute().await?;
println!("Mute bitmask: 0b{:08b}", mute.statuses);
// Mute channel 0 (bit 0) without touching other channels
feat.set_sidetone_mute(SidetoneMuteChange {
change_mask: 0b0000_0001,
statuses: 0b0000_0001,
}).await?;
}