OpenLogi

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.

  • SidetoneMuteStatusstatuses: u8 bitmask; a set bit means the corresponding channel is muted.
  • SidetoneMuteChangechange_mask: u8 selects which channels to update; statuses: u8 carries the desired mute state for those channels. Bits absent from change_mask are 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

FunctionHID++ fnSignatureReturns
get_sidetone_level0()u8
set_sidetone_level1(level: u8)()
get_sidetone_mute2()SidetoneMuteStatus
set_sidetone_mute3(change: SidetoneMuteChange)()

All methods are async and return Result<…, Hidpp20Error>.

Types

SidetoneMuteStatus

Per-channel sidetone mute statuses.

FieldTypeDescription
statusesu8Raw mute-status bitmask. A set bit means the channel is muted.

SidetoneMuteChange

Change mask and statuses for sidetone mute settings.

FieldTypeDescription
change_masku8Channels to update. A set bit means the corresponding status bit applies.
statusesu8Desired 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):

ByteFieldNotes
0level (u8)Sidetone level in the range 0..=100.

set_sidetone_level (fn 1)

Request: [level, 0x00, 0x00]

ByteValueNotes
0levelSidetone level to write. Device rejects values outside 0..=100.
1–20x00Padding.

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):

ByteFieldNotes
0SidetoneMuteStatus::statuses (u8)Bitmask; a set bit means that channel is muted.

set_sidetone_mute (fn 3)

Request: [change_mask, statuses, 0x00]

ByteValueNotes
0SidetoneMuteChange::change_maskSelects which channel bits to overwrite on the device.
1SidetoneMuteChange::statusesDesired mute state for the selected channels.
20x00Padding.

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?;
}

On this page