Always emit quality format updates with fallbacks
Send file/device audio-quality notifications even when stream metadata is incomplete by deriving sane defaults from the requested quality level, so controller quality icons stay in sync.
This commit is contained in:
@@ -418,6 +418,16 @@ fn msg_device_audio_quality_changed(
|
|||||||
build_qconnect_message(27, &payload)
|
build_qconnect_message(27, &payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn quality_fallback_audio_params(quality: u32) -> (u32, u32, u32) {
|
||||||
|
match quality {
|
||||||
|
1 => (44100, 16, 2), // MP3
|
||||||
|
2 => (44100, 16, 2), // CD
|
||||||
|
3 => (96000, 24, 2), // Hi-Res up to 96kHz
|
||||||
|
4 | 5 => (192000, 24, 2), // Hi-Res up to 192/384kHz (use 192kHz fallback)
|
||||||
|
_ => (44100, 16, 2),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// RNDR_SRVR_VOLUME_MUTED (29): renderer confirms mute state.
|
/// RNDR_SRVR_VOLUME_MUTED (29): renderer confirms mute state.
|
||||||
fn msg_volume_muted(muted: bool) -> Vec<u8> {
|
fn msg_volume_muted(muted: bool) -> Vec<u8> {
|
||||||
let payload = encode_field_varint(1, if muted { 1 } else { 0 });
|
let payload = encode_field_varint(1, if muted { 1 } else { 0 });
|
||||||
@@ -1117,24 +1127,26 @@ async fn run_connection(
|
|||||||
duration_ms,
|
duration_ms,
|
||||||
start_position_ms: requested_pos.unwrap_or(0),
|
start_position_ms: requested_pos.unwrap_or(0),
|
||||||
});
|
});
|
||||||
if let (Some(sr), Some(bits)) = (stream_sr, stream_bits) {
|
let (fallback_sr, fallback_bits, fallback_ch) =
|
||||||
let ch = stream_ch.unwrap_or(2).max(1);
|
quality_fallback_audio_params(max_audio_quality);
|
||||||
let file_msg = msg_file_audio_quality_changed(
|
let sr = stream_sr.unwrap_or(fallback_sr).max(1);
|
||||||
sr as u64,
|
let bits = stream_bits.unwrap_or(fallback_bits).max(1);
|
||||||
bits as u64,
|
let ch = stream_ch.unwrap_or(fallback_ch).max(1);
|
||||||
ch as u64,
|
let file_msg = msg_file_audio_quality_changed(
|
||||||
max_audio_quality as u64,
|
sr as u64,
|
||||||
);
|
bits as u64,
|
||||||
ws_tx.send(Message::Binary(build_payload_frame(msg_id, &file_msg).into())).await?;
|
ch as u64,
|
||||||
msg_id += 1;
|
max_audio_quality as u64,
|
||||||
let dev_msg = msg_device_audio_quality_changed(
|
);
|
||||||
sr as u64,
|
ws_tx.send(Message::Binary(build_payload_frame(msg_id, &file_msg).into())).await?;
|
||||||
bits as u64,
|
msg_id += 1;
|
||||||
ch as u64,
|
let dev_msg = msg_device_audio_quality_changed(
|
||||||
);
|
sr as u64,
|
||||||
ws_tx.send(Message::Binary(build_payload_frame(msg_id, &dev_msg).into())).await?;
|
bits as u64,
|
||||||
msg_id += 1;
|
ch as u64,
|
||||||
}
|
);
|
||||||
|
ws_tx.send(Message::Binary(build_payload_frame(msg_id, &dev_msg).into())).await?;
|
||||||
|
msg_id += 1;
|
||||||
current_buffer_state = 2; // OK
|
current_buffer_state = 2; // OK
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -1374,24 +1386,26 @@ async fn run_connection(
|
|||||||
duration_ms,
|
duration_ms,
|
||||||
start_position_ms: 0,
|
start_position_ms: 0,
|
||||||
});
|
});
|
||||||
if let (Some(sr), Some(bits)) = (stream_sr, stream_bits) {
|
let (fallback_sr, fallback_bits, fallback_ch) =
|
||||||
let ch = stream_ch.unwrap_or(2).max(1);
|
quality_fallback_audio_params(*quality);
|
||||||
let file_msg = msg_file_audio_quality_changed(
|
let sr = stream_sr.unwrap_or(fallback_sr).max(1);
|
||||||
sr as u64,
|
let bits = stream_bits.unwrap_or(fallback_bits).max(1);
|
||||||
bits as u64,
|
let ch = stream_ch.unwrap_or(fallback_ch).max(1);
|
||||||
ch as u64,
|
let file_msg = msg_file_audio_quality_changed(
|
||||||
*quality as u64,
|
sr as u64,
|
||||||
);
|
bits as u64,
|
||||||
ws_tx.send(Message::Binary(build_payload_frame(msg_id, &file_msg).into())).await?;
|
ch as u64,
|
||||||
msg_id += 1;
|
*quality as u64,
|
||||||
let dev_msg = msg_device_audio_quality_changed(
|
);
|
||||||
sr as u64,
|
ws_tx.send(Message::Binary(build_payload_frame(msg_id, &file_msg).into())).await?;
|
||||||
bits as u64,
|
msg_id += 1;
|
||||||
ch as u64,
|
let dev_msg = msg_device_audio_quality_changed(
|
||||||
);
|
sr as u64,
|
||||||
ws_tx.send(Message::Binary(build_payload_frame(msg_id, &dev_msg).into())).await?;
|
bits as u64,
|
||||||
msg_id += 1;
|
ch as u64,
|
||||||
}
|
);
|
||||||
|
ws_tx.send(Message::Binary(build_payload_frame(msg_id, &dev_msg).into())).await?;
|
||||||
|
msg_id += 1;
|
||||||
// Re-emit quality confirmation after successful restart
|
// Re-emit quality confirmation after successful restart
|
||||||
// so controllers observing the currently active stream update promptly.
|
// so controllers observing the currently active stream update promptly.
|
||||||
let confirm = msg_max_audio_quality_changed(*quality as u64, None);
|
let confirm = msg_max_audio_quality_changed(*quality as u64, None);
|
||||||
|
|||||||
Reference in New Issue
Block a user