Skip to content

Commit 81a3151

Browse files
authored
add frame-size-ms to AudioStream (#658)
1 parent 1a238a1 commit 81a3151

File tree

3 files changed

+71
-18
lines changed

3 files changed

+71
-18
lines changed

livekit-ffi/protocol/audio_frame.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ message NewAudioStreamRequest {
2929
optional uint32 num_channels = 4;
3030
optional string audio_filter_module_id = 5; // Unique identifier passed in LoadAudioFilterPluginRequest
3131
optional string audio_filter_options = 6;
32+
optional uint32 frame_size_ms = 7;
3233
}
3334
message NewAudioStreamResponse { required OwnedAudioStream stream = 1; }
3435

@@ -40,6 +41,7 @@ message AudioStreamFromParticipantRequest {
4041
optional uint32 num_channels = 6;
4142
optional string audio_filter_module_id = 7;
4243
optional string audio_filter_options = 8;
44+
optional uint32 frame_size_ms = 9;
4345
}
4446

4547
message AudioStreamFromParticipantResponse { required OwnedAudioStream stream = 1; }

livekit-ffi/src/livekit.proto.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4126,6 +4126,8 @@ pub struct NewAudioStreamRequest {
41264126
pub audio_filter_module_id: ::core::option::Option<::prost::alloc::string::String>,
41274127
#[prost(string, optional, tag="6")]
41284128
pub audio_filter_options: ::core::option::Option<::prost::alloc::string::String>,
4129+
#[prost(uint32, optional, tag="7")]
4130+
pub frame_size_ms: ::core::option::Option<u32>,
41294131
}
41304132
#[allow(clippy::derive_partial_eq_without_eq)]
41314133
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -4150,6 +4152,8 @@ pub struct AudioStreamFromParticipantRequest {
41504152
pub audio_filter_module_id: ::core::option::Option<::prost::alloc::string::String>,
41514153
#[prost(string, optional, tag="8")]
41524154
pub audio_filter_options: ::core::option::Option<::prost::alloc::string::String>,
4155+
#[prost(uint32, optional, tag="9")]
4156+
pub frame_size_ms: ::core::option::Option<u32>,
41534157
}
41544158
#[allow(clippy::derive_partial_eq_without_eq)]
41554159
#[derive(Clone, PartialEq, ::prost::Message)]

livekit-ffi/src/server/audio_stream.rs

Lines changed: 65 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
use std::borrow::Cow;
1516
use std::time::Duration;
1617

1718
use futures_util::StreamExt;
@@ -135,6 +136,9 @@ impl FfiAudioStream {
135136
server.watch_handle_dropped(new_stream.track_handle),
136137
true,
137138
info,
139+
new_stream.frame_size_ms,
140+
sample_rate.try_into().unwrap(),
141+
num_channels.try_into().unwrap(),
138142
));
139143
server.watch_panic(handle);
140144
Ok::<FfiAudioStream, FfiError>(audio_stream)
@@ -312,6 +316,9 @@ impl FfiAudioStream {
312316
handle_dropped_rx,
313317
false,
314318
info,
319+
request.frame_size_ms,
320+
sample_rate.try_into().unwrap(),
321+
num_channels.try_into().unwrap(),
315322
)
316323
.await;
317324
let _ = done_tx.send(());
@@ -348,7 +355,14 @@ impl FfiAudioStream {
348355
mut handle_dropped_rx: oneshot::Receiver<()>,
349356
send_eos: bool,
350357
mut filter_info: Option<AudioFilterInfo>,
358+
frame_size_ms: Option<u32>,
359+
sample_rate: u32,
360+
num_channels: u32,
351361
) {
362+
let mut buf = Vec::new();
363+
let target_samples = frame_size_ms
364+
.map(|ms| sample_rate as usize * ms as usize / 1000 * num_channels as usize);
365+
352366
loop {
353367
tokio::select! {
354368
_ = &mut self_dropped_rx => {
@@ -377,26 +391,59 @@ impl FfiAudioStream {
377391
}
378392
}
379393

380-
let handle_id = server.next_id();
381-
let buffer_info = proto::AudioFrameBufferInfo::from(&frame);
382-
server.store_handle(handle_id, frame);
383-
384-
if let Err(err) = server.send_event(proto::ffi_event::Message::AudioStreamEvent(
385-
proto::AudioStreamEvent {
386-
stream_handle: stream_handle_id,
387-
message: Some(proto::audio_stream_event::Message::FrameReceived(
388-
proto::AudioFrameReceived {
389-
frame: proto::OwnedAudioFrameBuffer {
390-
handle: proto::FfiOwnedHandle { id: handle_id },
391-
info: buffer_info,
392-
},
394+
if let Some(target) = target_samples {
395+
buf.extend_from_slice(&frame.data);
396+
while buf.len() >= target {
397+
let data = buf.split_off(target);
398+
let mut frame_data = std::mem::replace(&mut buf, data);
399+
let new_frame = AudioFrame {
400+
data: Cow::Owned(frame_data),
401+
sample_rate,
402+
num_channels,
403+
samples_per_channel: target as u32 / num_channels,
404+
};
405+
let handle_id = server.next_id();
406+
let buffer_info = proto::AudioFrameBufferInfo::from(&new_frame);
407+
server.store_handle(handle_id, new_frame);
408+
if let Err(err) = server.send_event(proto::ffi_event::Message::AudioStreamEvent(
409+
proto::AudioStreamEvent {
410+
stream_handle: stream_handle_id,
411+
message: Some(proto::audio_stream_event::Message::FrameReceived(
412+
proto::AudioFrameReceived {
413+
frame: proto::OwnedAudioFrameBuffer {
414+
handle: proto::FfiOwnedHandle { id: handle_id },
415+
info: buffer_info,
416+
},
417+
},
418+
)),
393419
},
394-
)),
395-
},
396-
)) {
397-
server.drop_handle(handle_id);
398-
log::warn!("failed to send audio frame: {}", err);
420+
)) {
421+
server.drop_handle(handle_id);
422+
log::warn!("failed to send audio frame: {}", err);
423+
}
424+
}
425+
} else {
426+
let handle_id = server.next_id();
427+
let buffer_info = proto::AudioFrameBufferInfo::from(&frame);
428+
server.store_handle(handle_id, frame);
429+
if let Err(err) = server.send_event(proto::ffi_event::Message::AudioStreamEvent(
430+
proto::AudioStreamEvent {
431+
stream_handle: stream_handle_id,
432+
message: Some(proto::audio_stream_event::Message::FrameReceived(
433+
proto::AudioFrameReceived {
434+
frame: proto::OwnedAudioFrameBuffer {
435+
handle: proto::FfiOwnedHandle { id: handle_id },
436+
info: buffer_info,
437+
},
438+
},
439+
)),
440+
},
441+
)) {
442+
server.drop_handle(handle_id);
443+
log::warn!("failed to send audio frame: {}", err);
444+
}
399445
}
446+
400447
}
401448
}
402449
}

0 commit comments

Comments
 (0)