@@ -279,21 +279,26 @@ impl AudioContext {
279279 /// is currently not implemented.
280280 #[ allow( clippy:: needless_collect, clippy:: missing_panics_doc) ]
281281 pub fn set_sink_id_sync ( & self , sink_id : String ) -> Result < ( ) , Box < dyn Error > > {
282+ log:: debug!( "SinkChange requested" ) ;
282283 if self . sink_id ( ) == sink_id {
284+ log:: debug!( "SinkChange: no-op" ) ;
283285 return Ok ( ( ) ) ; // sink is already active
284286 }
285287
286288 if !is_valid_sink_id ( & sink_id) {
287289 Err ( format ! ( "NotFoundError: invalid sinkId {sink_id}" ) ) ?;
288290 } ;
289291
292+ log:: debug!( "SinkChange: locking backend manager" ) ;
290293 let mut backend_manager_guard = self . backend_manager . lock ( ) . unwrap ( ) ;
291294 let original_state = self . state ( ) ;
292295 if original_state == AudioContextState :: Closed {
296+ log:: debug!( "SinkChange: context is closed" ) ;
293297 return Ok ( ( ) ) ;
294298 }
295299
296300 // Acquire exclusive lock on ctrl msg sender
301+ log:: debug!( "SinkChange: locking message channel" ) ;
297302 let ctrl_msg_send = self . base . lock_control_msg_sender ( ) ;
298303
299304 // Flush out the ctrl msg receiver, cache
@@ -303,13 +308,17 @@ impl AudioContext {
303308 let graph = if matches ! ( pending_msgs. first( ) , Some ( ControlMessage :: Startup { .. } ) ) {
304309 // Handle the edge case where the previous backend was suspended for its entire lifetime.
305310 // In this case, the `Startup` control message was never processed.
311+ log:: debug!( "SinkChange: recover unstarted graph" ) ;
312+
306313 let msg = pending_msgs. remove ( 0 ) ;
307314 match msg {
308315 ControlMessage :: Startup { graph } => graph,
309316 _ => unreachable ! ( ) ,
310317 }
311318 } else {
312319 // Acquire the audio graph from the current render thread, shutting it down
320+ log:: debug!( "SinkChange: recover graph from render thread" ) ;
321+
313322 let ( graph_send, graph_recv) = crossbeam_channel:: bounded ( 1 ) ;
314323 let message = ControlMessage :: CloseAndRecycle { sender : graph_send } ;
315324 ctrl_msg_send. send ( message) . unwrap ( ) ;
@@ -321,6 +330,7 @@ impl AudioContext {
321330 graph_recv. recv ( ) . unwrap ( )
322331 } ;
323332
333+ log:: debug!( "SinkChange: closing audio stream" ) ;
324334 backend_manager_guard. close ( ) ;
325335
326336 // hotswap the backend
@@ -330,10 +340,12 @@ impl AudioContext {
330340 sink_id,
331341 render_size_hint : AudioContextRenderSizeCategory :: default ( ) , // todo reuse existing setting
332342 } ;
343+ log:: debug!( "SinkChange: starting audio stream" ) ;
333344 * backend_manager_guard = io:: build_output ( options, self . render_thread_init . clone ( ) ) ;
334345
335346 // if the previous backend state was suspend, suspend the new one before shipping the graph
336347 if original_state == AudioContextState :: Suspended {
348+ log:: debug!( "SinkChange: suspending audio stream" ) ;
337349 backend_manager_guard. suspend ( ) ;
338350 }
339351
@@ -352,6 +364,7 @@ impl AudioContext {
352364 // trigger event when all the work is done
353365 let _ = self . base . send_event ( EventDispatch :: sink_change ( ) ) ;
354366
367+ log:: debug!( "SinkChange: done" ) ;
355368 Ok ( ( ) )
356369 }
357370
@@ -422,6 +435,7 @@ impl AudioContext {
422435 /// * The audio device is not available
423436 /// * For a `BackendSpecificError`
424437 pub async fn suspend ( & self ) {
438+ log:: debug!( "Suspend called" ) ;
425439 // First, pause rendering via a control message
426440 let ( sender, receiver) = oneshot:: channel ( ) ;
427441 let notify = OneshotNotify :: Async ( sender) ;
@@ -430,10 +444,13 @@ impl AudioContext {
430444
431445 // Wait for the render thread to have processed the suspend message.
432446 // The AudioContextState will be updated by the render thread.
447+ log:: debug!( "Suspending audio graph, waiting for signal.." ) ;
433448 receiver. await . unwrap ( ) ;
434449
435450 // Then ask the audio host to suspend the stream
451+ log:: debug!( "Suspended audio graph. Suspending audio stream.." ) ;
436452 self . backend_manager . lock ( ) . unwrap ( ) . suspend ( ) ;
453+ log:: debug!( "Suspended audio stream" ) ;
437454 }
438455
439456 /// Resumes the progression of time in an audio context that has previously been
@@ -446,10 +463,12 @@ impl AudioContext {
446463 /// * The audio device is not available
447464 /// * For a `BackendSpecificError`
448465 pub async fn resume ( & self ) {
466+ log:: debug!( "Resume called" ) ;
449467 // First ask the audio host to resume the stream
450468 self . backend_manager . lock ( ) . unwrap ( ) . resume ( ) ;
451469
452470 // Then, ask to resume rendering via a control message
471+ log:: debug!( "Resumed audio stream, waking audio graph" ) ;
453472 let ( sender, receiver) = oneshot:: channel ( ) ;
454473 let notify = OneshotNotify :: Async ( sender) ;
455474 self . base
@@ -458,6 +477,7 @@ impl AudioContext {
458477 // Wait for the render thread to have processed the resume message
459478 // The AudioContextState will be updated by the render thread.
460479 receiver. await . unwrap ( ) ;
480+ log:: debug!( "Resumed audio graph" ) ;
461481 }
462482
463483 /// Closes the `AudioContext`, releasing the system resources being used.
@@ -469,22 +489,26 @@ impl AudioContext {
469489 ///
470490 /// Will panic when this function is called multiple times
471491 pub async fn close ( & self ) {
492+ log:: debug!( "Close called" ) ;
493+
472494 // First, stop rendering via a control message
473495 let ( sender, receiver) = oneshot:: channel ( ) ;
474496 let notify = OneshotNotify :: Async ( sender) ;
475497 self . base . send_control_msg ( ControlMessage :: Close { notify } ) ;
476498
477499 // Wait for the render thread to have processed the suspend message.
478500 // The AudioContextState will be updated by the render thread.
501+ log:: debug!( "Suspending audio graph, waiting for signal.." ) ;
479502 receiver. await . unwrap ( ) ;
480503
481504 // Then ask the audio host to close the stream
505+ log:: debug!( "Suspended audio graph. Closing audio stream.." ) ;
482506 self . backend_manager . lock ( ) . unwrap ( ) . close ( ) ;
483507
484508 // Stop the AudioRenderCapacity collection thread
485509 self . render_capacity . stop ( ) ;
486510
487- // TODO stop the event loop <https://github.com/orottier/web- audio-api-rs/issues/421>
511+ log :: debug! ( "Closed audio stream" ) ;
488512 }
489513
490514 /// Suspends the progression of time in the audio context.
@@ -502,6 +526,7 @@ impl AudioContext {
502526 /// * The audio device is not available
503527 /// * For a `BackendSpecificError`
504528 pub fn suspend_sync ( & self ) {
529+ log:: debug!( "Suspend_sync called" ) ;
505530 // First, pause rendering via a control message
506531 let ( sender, receiver) = crossbeam_channel:: bounded ( 0 ) ;
507532 let notify = OneshotNotify :: Sync ( sender) ;
@@ -510,10 +535,13 @@ impl AudioContext {
510535
511536 // Wait for the render thread to have processed the suspend message.
512537 // The AudioContextState will be updated by the render thread.
538+ log:: debug!( "Suspending audio graph, waiting for signal.." ) ;
513539 receiver. recv ( ) . ok ( ) ;
540+ log:: debug!( "Suspended audio graph. Suspending audio stream.." ) ;
514541
515542 // Then ask the audio host to suspend the stream
516543 self . backend_manager . lock ( ) . unwrap ( ) . suspend ( ) ;
544+ log:: debug!( "Suspended audio stream" ) ;
517545 }
518546
519547 /// Resumes the progression of time in an audio context that has previously been
@@ -529,10 +557,12 @@ impl AudioContext {
529557 /// * The audio device is not available
530558 /// * For a `BackendSpecificError`
531559 pub fn resume_sync ( & self ) {
560+ log:: debug!( "Resume_sync called" ) ;
532561 // First ask the audio host to resume the stream
533562 self . backend_manager . lock ( ) . unwrap ( ) . resume ( ) ;
534563
535564 // Then, ask to resume rendering via a control message
565+ log:: debug!( "Resumed audio stream, waking audio graph" ) ;
536566 let ( sender, receiver) = crossbeam_channel:: bounded ( 0 ) ;
537567 let notify = OneshotNotify :: Sync ( sender) ;
538568 self . base
@@ -541,6 +571,7 @@ impl AudioContext {
541571 // Wait for the render thread to have processed the resume message
542572 // The AudioContextState will be updated by the render thread.
543573 receiver. recv ( ) . ok ( ) ;
574+ log:: debug!( "Resumed audio graph" ) ;
544575 }
545576
546577 /// Closes the `AudioContext`, releasing the system resources being used.
@@ -555,22 +586,26 @@ impl AudioContext {
555586 ///
556587 /// Will panic when this function is called multiple times
557588 pub fn close_sync ( & self ) {
589+ log:: debug!( "Close_sync called" ) ;
590+
558591 // First, stop rendering via a control message
559592 let ( sender, receiver) = crossbeam_channel:: bounded ( 0 ) ;
560593 let notify = OneshotNotify :: Sync ( sender) ;
561594 self . base . send_control_msg ( ControlMessage :: Close { notify } ) ;
562595
563596 // Wait for the render thread to have processed the suspend message.
564597 // The AudioContextState will be updated by the render thread.
598+ log:: debug!( "Suspending audio graph, waiting for signal.." ) ;
565599 receiver. recv ( ) . ok ( ) ;
566600
567601 // Then ask the audio host to close the stream
602+ log:: debug!( "Suspended audio graph. Closing audio stream.." ) ;
568603 self . backend_manager . lock ( ) . unwrap ( ) . close ( ) ;
569604
570605 // Stop the AudioRenderCapacity collection thread
571606 self . render_capacity . stop ( ) ;
572607
573- // TODO stop the event loop <https://github.com/orottier/web- audio-api-rs/issues/421>
608+ log :: debug! ( "Closed audio stream" ) ;
574609 }
575610
576611 /// Creates a [`MediaStreamAudioSourceNode`](node::MediaStreamAudioSourceNode) from a
0 commit comments