From 99d1092043b74120e8885d0d16a8ba305817a8ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Wed, 1 Oct 2025 10:56:54 +0200 Subject: [PATCH 1/3] refactor(sdk): Allow to send waveform for any audio message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By moving the waveform declaration into `BaseAudioInfo`. Signed-off-by: Kévin Commaille --- bindings/matrix-sdk-ffi/src/ruma.rs | 2 +- bindings/matrix-sdk-ffi/src/timeline/mod.rs | 10 ++++----- crates/matrix-sdk/src/attachment.rs | 23 ++++++++------------- crates/matrix-sdk/src/room/mod.rs | 16 +++++++------- 4 files changed, 22 insertions(+), 29 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/ruma.rs b/bindings/matrix-sdk-ffi/src/ruma.rs index b44414abd3d..bd167f90669 100644 --- a/bindings/matrix-sdk-ffi/src/ruma.rs +++ b/bindings/matrix-sdk-ffi/src/ruma.rs @@ -736,7 +736,7 @@ impl TryFrom<&AudioInfo> for BaseAudioInfo { let size = UInt::try_from(value.size.ok_or(MediaInfoError::MissingField)?) .map_err(|_| MediaInfoError::InvalidField)?; - Ok(BaseAudioInfo { duration: Some(duration), size: Some(size) }) + Ok(BaseAudioInfo { duration: Some(duration), size: Some(size), waveform: None }) } } diff --git a/bindings/matrix-sdk-ffi/src/timeline/mod.rs b/bindings/matrix-sdk-ffi/src/timeline/mod.rs index da39abf5736..11076b1b9d0 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/mod.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/mod.rs @@ -424,12 +424,10 @@ impl Timeline { audio_info: AudioInfo, waveform: Vec, ) -> Result, RoomError> { - let attachment_info = AttachmentInfo::Voice { - audio_info: BaseAudioInfo::try_from(&audio_info) - .map_err(|_| RoomError::InvalidAttachmentData)?, - waveform: Some(waveform), - }; - self.send_attachment(params, attachment_info, audio_info.mimetype, None) + let mut info = + BaseAudioInfo::try_from(&audio_info).map_err(|_| RoomError::InvalidAttachmentData)?; + info.waveform = Some(waveform); + self.send_attachment(params, AttachmentInfo::Voice(info), audio_info.mimetype, None) } pub fn send_file( diff --git a/crates/matrix-sdk/src/attachment.rs b/crates/matrix-sdk/src/attachment.rs index f93481eb192..71c060c97d7 100644 --- a/crates/matrix-sdk/src/attachment.rs +++ b/crates/matrix-sdk/src/attachment.rs @@ -66,6 +66,8 @@ pub struct BaseAudioInfo { pub duration: Option, /// The file size of the audio clip in bytes. pub size: Option, + /// The waveform of the audio clip. + pub waveform: Option>, } /// Base metadata about a file. @@ -87,12 +89,7 @@ pub enum AttachmentInfo { /// The metadata of a file. File(BaseFileInfo), /// The metadata of a voice message - Voice { - /// The audio info - audio_info: BaseAudioInfo, - /// The waveform of the voice message - waveform: Option>, - }, + Voice(BaseAudioInfo), } impl From for ImageInfo { @@ -128,14 +125,12 @@ impl From for VideoInfo { impl From for AudioInfo { fn from(info: AttachmentInfo) -> Self { match info { - AttachmentInfo::Audio(info) => assign!(AudioInfo::new(), { - duration: info.duration, - size: info.size, - }), - AttachmentInfo::Voice { audio_info, .. } => assign!(AudioInfo::new(), { - duration: audio_info.duration, - size: audio_info.size, - }), + AttachmentInfo::Audio(info) | AttachmentInfo::Voice(info) => { + assign!(AudioInfo::new(), { + duration: info.duration, + size: info.size, + }) + } _ => AudioInfo::new(), } } diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index 0c11ea8f356..7a1ad595d26 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -324,14 +324,14 @@ macro_rules! make_media_type { filename }); - if let Some(AttachmentInfo::Voice { audio_info, waveform: Some(waveform_vec) }) = - &$info - { - if let Some(duration) = audio_info.duration { - let waveform = waveform_vec.iter().map(|v| (*v).into()).collect(); - content.audio = - Some(UnstableAudioDetailsContentBlock::new(duration, waveform)); - } + if let Some(AttachmentInfo::Audio(audio_info) | AttachmentInfo::Voice(audio_info)) = &$info && + let Some(duration) = audio_info.duration && let Some(waveform_vec) = &audio_info.waveform { + let waveform = waveform_vec.iter().map(|v| (*v).into()).collect(); + content.audio = + Some(UnstableAudioDetailsContentBlock::new(duration, waveform)); + } + + if matches!($info, Some(AttachmentInfo::Voice(_))) { content.voice = Some(UnstableVoiceContentBlock::new()); } From 3304303654e4744bb5be2d91ee9c8f91fe1f9083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Wed, 1 Oct 2025 11:16:44 +0200 Subject: [PATCH 2/3] refactor(sdk): Change waveform to be a list of values between 0 and 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most clients will probably work with values between 0 and 1 and need to convert it just to send it, so we can move that conversion into the SDK. This is also more forwards-compatible, because MSC3246 now has a different max value for the amplitude, so when this becomes stable, the only change needed will be in the SDK. Signed-off-by: Kévin Commaille --- bindings/matrix-sdk-ffi/src/timeline/mod.rs | 2 +- crates/matrix-sdk/src/attachment.rs | 4 +++- crates/matrix-sdk/src/room/mod.rs | 10 +++++++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/timeline/mod.rs b/bindings/matrix-sdk-ffi/src/timeline/mod.rs index 11076b1b9d0..3f05a11c1a9 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/mod.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/mod.rs @@ -422,7 +422,7 @@ impl Timeline { self: Arc, params: UploadParameters, audio_info: AudioInfo, - waveform: Vec, + waveform: Vec, ) -> Result, RoomError> { let mut info = BaseAudioInfo::try_from(&audio_info).map_err(|_| RoomError::InvalidAttachmentData)?; diff --git a/crates/matrix-sdk/src/attachment.rs b/crates/matrix-sdk/src/attachment.rs index 71c060c97d7..9dee703342d 100644 --- a/crates/matrix-sdk/src/attachment.rs +++ b/crates/matrix-sdk/src/attachment.rs @@ -67,7 +67,9 @@ pub struct BaseAudioInfo { /// The file size of the audio clip in bytes. pub size: Option, /// The waveform of the audio clip. - pub waveform: Option>, + /// + /// Must only includes values between 0 and 1. + pub waveform: Option>, } /// Base metadata about a file. diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index 7a1ad595d26..d1689971578 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -116,8 +116,8 @@ use ruma::{ message::{ AudioInfo, AudioMessageEventContent, FileInfo, FileMessageEventContent, FormattedBody, ImageMessageEventContent, MessageType, RoomMessageEventContent, - UnstableAudioDetailsContentBlock, UnstableVoiceContentBlock, VideoInfo, - VideoMessageEventContent, + UnstableAmplitude, UnstableAudioDetailsContentBlock, UnstableVoiceContentBlock, + VideoInfo, VideoMessageEventContent, }, name::RoomNameEventContent, pinned_events::RoomPinnedEventsEventContent, @@ -326,7 +326,11 @@ macro_rules! make_media_type { if let Some(AttachmentInfo::Audio(audio_info) | AttachmentInfo::Voice(audio_info)) = &$info && let Some(duration) = audio_info.duration && let Some(waveform_vec) = &audio_info.waveform { - let waveform = waveform_vec.iter().map(|v| (*v).into()).collect(); + let waveform = waveform_vec + .iter() + .map(|v| ((*v).clamp(0.0, 1.0) * UnstableAmplitude::MAX as f32) as u16) + .map(Into::into) + .collect(); content.audio = Some(UnstableAudioDetailsContentBlock::new(duration, waveform)); } From ab7b887bc28819f022b68fc1741ce961813ecec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Wed, 1 Oct 2025 11:31:20 +0200 Subject: [PATCH 3/3] Add changelog for waveform changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Commaille --- bindings/matrix-sdk-ffi/CHANGELOG.md | 8 ++++++-- crates/matrix-sdk/CHANGELOG.md | 9 +++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/bindings/matrix-sdk-ffi/CHANGELOG.md b/bindings/matrix-sdk-ffi/CHANGELOG.md index 1dec9d79900..5315c713044 100644 --- a/bindings/matrix-sdk-ffi/CHANGELOG.md +++ b/bindings/matrix-sdk-ffi/CHANGELOG.md @@ -8,6 +8,10 @@ All notable changes to this project will be documented in this file. ### Breaking changes: +- The `waveform` parameter in `Timeline::send_voice_message` format changed to a list of `f32` + between 0 and 1. + ([#5732](https://github.com/matrix-org/matrix-rust-sdk/pull/5732)) + - The `normalized_power_level` field has been removed from the `RoomMember` struct. ([#5635](https://github.com/matrix-org/matrix-rust-sdk/pull/5635)) @@ -24,8 +28,8 @@ All notable changes to this project will be documented in this file. ### Features: -- Add `LowPriority` and `NonLowPriority` variants to `RoomListEntriesDynamicFilterKind` for filtering - rooms based on their low priority status. These filters allow clients to show only low priority rooms +- Add `LowPriority` and `NonLowPriority` variants to `RoomListEntriesDynamicFilterKind` for filtering + rooms based on their low priority status. These filters allow clients to show only low priority rooms or exclude low priority rooms from the room list. ([#5508](https://github.com/matrix-org/matrix-rust-sdk/pull/5508)) - Add `room_version` and `privileged_creators_role` to `RoomInfo` ([#5449](https://github.com/matrix-org/matrix-rust-sdk/pull/5449)). diff --git a/crates/matrix-sdk/CHANGELOG.md b/crates/matrix-sdk/CHANGELOG.md index 2bf7da3bdb9..4709682a583 100644 --- a/crates/matrix-sdk/CHANGELOG.md +++ b/crates/matrix-sdk/CHANGELOG.md @@ -9,6 +9,11 @@ All notable changes to this project will be documented in this file. ### Features ### Refactor + +- [**breaking**]: The `waveform` field was moved from `AttachmentInfo::Voice` to `BaseAudioInfo`, + allowing to set it for any audio message. Its format also changed, and it is now a list of `f32` + between 0 and 1. + ([#5732](https://github.com/matrix-org/matrix-rust-sdk/pull/5732)) - The Matrix SDK crate now uses the 2024 edition of Rust. ([#5677](https://github.com/matrix-org/matrix-rust-sdk/pull/5677)) @@ -60,9 +65,9 @@ All notable changes to this project will be documented in this file. - [**breaking**] `OAuth::login` now allows requesting additional scopes for the authorization code grant. ([#5395](https://github.com/matrix-org/matrix-rust-sdk/pull/5395)) -- [**breaking**] `ThreadedEventsLoader::new` now takes optional `tokens` parameter to customise where the pagination +- [**breaking**] `ThreadedEventsLoader::new` now takes optional `tokens` parameter to customise where the pagination begins ([#5678](https://github.com/matrix-org/matrix-rust-sdk/pull/5678). -- Make `PaginationTokens` `pub`, as well as its `previous` and `next` tokens so they can be assigned from other files +- Make `PaginationTokens` `pub`, as well as its `previous` and `next` tokens so they can be assigned from other files ([#5678](https://github.com/matrix-org/matrix-rust-sdk/pull/5678). ### Refactor