2222import threading
2323
2424if TYPE_CHECKING :
25- import sounddevice as sd # type: ignore[import-not-found, import-untyped ]
25+ import sounddevice as sd # type: ignore[import-not-found]
2626
2727from . import AudioSource
2828from .audio_frame import AudioFrame
@@ -163,7 +163,7 @@ def __init__(
163163 output_device : Optional [int ] = None ,
164164 delay_estimator : Optional [_APMDelayEstimator ] = None ,
165165 ) -> None :
166- import sounddevice as sd # type: ignore[import-not-found, import-untyped]
166+ import sounddevice as sd
167167
168168 self ._sample_rate = sample_rate
169169 self ._num_channels = num_channels
@@ -303,16 +303,17 @@ async def start(self) -> None:
303303 if self ._mixer is None :
304304 self ._mixer = AudioMixer (sample_rate = self ._sample_rate , num_channels = self ._num_channels )
305305
306- async def _playback_loop ():
306+ async def _playback_loop () -> None :
307307 """Internal playback loop that consumes frames from the mixer."""
308308 self ._running = True
309309 self ._stream .start ()
310310 try :
311- async for frame in self ._mixer :
312- if not self ._running :
313- break
314- # Append raw PCM bytes for callback consumption
315- self ._buffer .extend (frame .data .tobytes ())
311+ if self ._mixer is not None :
312+ async for frame in self ._mixer :
313+ if not self ._running :
314+ break
315+ # Append raw PCM bytes for callback consumption
316+ self ._buffer .extend (frame .data .tobytes ())
316317 finally :
317318 self ._running = False
318319 try :
@@ -402,7 +403,7 @@ def list_input_devices(self) -> list[dict[str, Any]]:
402403 Returns a list of dictionaries with the `sounddevice` metadata and an
403404 added `index` key corresponding to the device index.
404405 """
405- import sounddevice as sd # type: ignore[import-not-found, import-untyped]
406+ import sounddevice as sd
406407
407408 devices = sd .query_devices ()
408409 result : list [dict [str , Any ]] = []
@@ -413,7 +414,7 @@ def list_input_devices(self) -> list[dict[str, Any]]:
413414
414415 def list_output_devices (self ) -> list [dict [str , Any ]]:
415416 """List available output devices with indices."""
416- import sounddevice as sd # type: ignore[import-not-found, import-untyped]
417+ import sounddevice as sd
417418
418419 devices = sd .query_devices ()
419420 result : list [dict [str , Any ]] = []
@@ -424,14 +425,14 @@ def list_output_devices(self) -> list[dict[str, Any]]:
424425
425426 def default_input_device (self ) -> Optional [int ]:
426427 """Return the default input device index (or None)."""
427- import sounddevice as sd # type: ignore[import-not-found, import-untyped]
428+ import sounddevice as sd
428429
429430 dev = sd .default .device
430431 return dev [0 ] if isinstance (dev , (list , tuple )) else None
431432
432433 def default_output_device (self ) -> Optional [int ]:
433434 """Return the default output device index (or None)."""
434- import sounddevice as sd # type: ignore[import-not-found, import-untyped]
435+ import sounddevice as sd
435436
436437 dev = sd .default .device
437438 return dev [1 ] if isinstance (dev , (list , tuple )) else None
@@ -471,7 +472,7 @@ def open_input(
471472 Returns:
472473 InputCapture: Holder with `source`, `apm`, and `aclose()`.
473474 """
474- import sounddevice as sd # type: ignore[import-not-found, import-untyped]
475+ import sounddevice as sd
475476
476477 loop = self ._loop
477478 source = AudioSource (self ._in_sr , self ._channels , loop = loop )
0 commit comments