feat(server): add volume support (#641)

Add server messages and API to support setting client volume.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
Marc-Andre Lureau 2025-01-27 17:10:15 +04:00 committed by GitHub
parent 0f9877ad39
commit a6c36511f6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 28 additions and 1 deletions

View file

@ -17,6 +17,10 @@ impl<T> RdpsndError for T where T: std::error::Error + Send + Sync + 'static {}
pub enum RdpsndServerMessage {
/// Wave data, with timestamp
Wave(Vec<u8>, u32),
SetVolume {
left: u16,
right: u16,
},
Close,
/// Failure received from the OS event loop.
///
@ -70,11 +74,20 @@ impl RdpsndServer {
let client_format = self
.client_format
.as_ref()
.ok_or_else(|| pdu_other_err!("invalid state - no version"))?;
.ok_or_else(|| pdu_other_err!("invalid state, client format not yet received"))?;
Ok(client_format.version)
}
pub fn flags(&self) -> PduResult<pdu::AudioFormatFlags> {
let client_format = self
.client_format
.as_ref()
.ok_or_else(|| pdu_other_err!("invalid state, client format not yet received"))?;
Ok(client_format.flags)
}
pub fn training_pdu(&mut self) -> PduResult<RdpsndSvcMessages> {
let pdu = pdu::TrainingPdu {
timestamp: 4231, // a random number
@ -116,6 +129,19 @@ impl RdpsndServer {
Ok(msg)
}
pub fn set_volume(&mut self, volume_left: u16, volume_right: u16) -> PduResult<RdpsndSvcMessages> {
if !self.flags()?.contains(pdu::AudioFormatFlags::VOLUME) {
return Err(pdu_other_err!("client doesn't support volume"));
}
let pdu = pdu::VolumePdu {
volume_left,
volume_right,
};
Ok(RdpsndSvcMessages::new(vec![
pdu::ServerAudioOutputPdu::Volume(pdu).into()
]))
}
pub fn close(&mut self) -> PduResult<RdpsndSvcMessages> {
Ok(RdpsndSvcMessages::new(vec![pdu::ServerAudioOutputPdu::Close.into()]))
}

View file

@ -496,6 +496,7 @@ impl RdpServer {
wave_limit -= 1;
rdpsnd.wave(data, ts)
}
RdpsndServerMessage::SetVolume { left, right } => rdpsnd.set_volume(left, right),
RdpsndServerMessage::Close => rdpsnd.close(),
RdpsndServerMessage::Error(error) => {
error!(?error, "Handling rdpsnd event");