|
12 | 12 | // See the License for the specific language governing permissions and |
13 | 13 | // limitations under the License. |
14 | 14 |
|
| 15 | +use std::borrow::Cow; |
15 | 16 | use std::time::Duration; |
16 | 17 |
|
17 | 18 | use futures_util::StreamExt; |
@@ -135,6 +136,9 @@ impl FfiAudioStream { |
135 | 136 | server.watch_handle_dropped(new_stream.track_handle), |
136 | 137 | true, |
137 | 138 | info, |
| 139 | + new_stream.frame_size_ms, |
| 140 | + sample_rate.try_into().unwrap(), |
| 141 | + num_channels.try_into().unwrap(), |
138 | 142 | )); |
139 | 143 | server.watch_panic(handle); |
140 | 144 | Ok::<FfiAudioStream, FfiError>(audio_stream) |
@@ -312,6 +316,9 @@ impl FfiAudioStream { |
312 | 316 | handle_dropped_rx, |
313 | 317 | false, |
314 | 318 | info, |
| 319 | + request.frame_size_ms, |
| 320 | + sample_rate.try_into().unwrap(), |
| 321 | + num_channels.try_into().unwrap(), |
315 | 322 | ) |
316 | 323 | .await; |
317 | 324 | let _ = done_tx.send(()); |
@@ -348,7 +355,14 @@ impl FfiAudioStream { |
348 | 355 | mut handle_dropped_rx: oneshot::Receiver<()>, |
349 | 356 | send_eos: bool, |
350 | 357 | mut filter_info: Option<AudioFilterInfo>, |
| 358 | + frame_size_ms: Option<u32>, |
| 359 | + sample_rate: u32, |
| 360 | + num_channels: u32, |
351 | 361 | ) { |
| 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 | + |
352 | 366 | loop { |
353 | 367 | tokio::select! { |
354 | 368 | _ = &mut self_dropped_rx => { |
@@ -377,26 +391,59 @@ impl FfiAudioStream { |
377 | 391 | } |
378 | 392 | } |
379 | 393 |
|
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 | + )), |
393 | 419 | }, |
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 | + } |
399 | 445 | } |
| 446 | + |
400 | 447 | } |
401 | 448 | } |
402 | 449 | } |
|
0 commit comments