Add --mic-channel-index
This commit is contained in:
@@ -85,6 +85,11 @@ async def main() -> None:
|
|||||||
action="store_true",
|
action="store_true",
|
||||||
help="Don't mute the microphone while awake wav is being played",
|
help="Don't mute the microphone while awake wav is being played",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--mic-channel-index",
|
||||||
|
type=int,
|
||||||
|
help="Take microphone input from a specific channel (first channel is 0)",
|
||||||
|
)
|
||||||
|
|
||||||
# Sound output
|
# Sound output
|
||||||
parser.add_argument("--snd-uri", help="URI of Wyoming sound service")
|
parser.add_argument("--snd-uri", help="URI of Wyoming sound service")
|
||||||
@@ -321,6 +326,7 @@ async def main() -> None:
|
|||||||
noise_suppression=args.mic_noise_suppression,
|
noise_suppression=args.mic_noise_suppression,
|
||||||
seconds_to_mute_after_awake_wav=args.mic_seconds_to_mute_after_awake_wav,
|
seconds_to_mute_after_awake_wav=args.mic_seconds_to_mute_after_awake_wav,
|
||||||
mute_during_awake_wav=(not args.mic_no_mute_during_awake_wav),
|
mute_during_awake_wav=(not args.mic_no_mute_during_awake_wav),
|
||||||
|
channel_index=args.mic_channel_index,
|
||||||
),
|
),
|
||||||
vad=VadSettings(
|
vad=VadSettings(
|
||||||
enabled=args.vad,
|
enabled=args.vad,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
"""Satellite code."""
|
"""Satellite code."""
|
||||||
|
import array
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
import math
|
import math
|
||||||
@@ -458,15 +459,36 @@ class SatelliteBase:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# Audio processing
|
# Audio processing
|
||||||
if self.settings.mic.needs_processing and AudioChunk.is_type(
|
if (
|
||||||
event.type
|
self.settings.mic.needs_processing
|
||||||
|
or (self.settings.mic.channel_index is not None)
|
||||||
|
and AudioChunk.is_type(event.type)
|
||||||
):
|
):
|
||||||
chunk = AudioChunk.from_event(event)
|
chunk = AudioChunk.from_event(event)
|
||||||
audio_bytes = self._process_mic_audio(chunk.audio)
|
if self.settings.mic.channel_index is not None:
|
||||||
|
if chunk.width != 2:
|
||||||
|
raise ValueError(
|
||||||
|
"Mic channel index selection requires 16-bit samples"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Convert to unsigned 16-bit array to make channel extraction easier
|
||||||
|
audio_array = array.array("H", chunk.audio)
|
||||||
|
audio_bytes = audio_array[
|
||||||
|
self.settings.mic.channel_index :: chunk.channels
|
||||||
|
].tobytes()
|
||||||
|
|
||||||
|
if self.settings.mic.needs_processing:
|
||||||
|
if audio_bytes is None:
|
||||||
|
audio_bytes = chunk.audio
|
||||||
|
|
||||||
|
audio_bytes = self._process_mic_audio(chunk.audio)
|
||||||
|
|
||||||
event = AudioChunk(
|
event = AudioChunk(
|
||||||
rate=chunk.rate,
|
rate=chunk.rate,
|
||||||
width=chunk.width,
|
width=chunk.width,
|
||||||
channels=chunk.channels,
|
channels=chunk.channels
|
||||||
|
if (self.settings.mic.channel_index is None)
|
||||||
|
else 1,
|
||||||
audio=audio_bytes,
|
audio=audio_bytes,
|
||||||
).event()
|
).event()
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ class MicSettings(ServiceSettings):
|
|||||||
seconds_to_mute_after_awake_wav: float = 0.5
|
seconds_to_mute_after_awake_wav: float = 0.5
|
||||||
"""Extra second(s) of microphone audio to mute after awake WAV has finished playing."""
|
"""Extra second(s) of microphone audio to mute after awake WAV has finished playing."""
|
||||||
|
|
||||||
|
channel_index: Optional[int] = None
|
||||||
|
"""Index of microphone channel to use. When not set, all input channels are used as-is."""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def needs_webrtc(self) -> bool:
|
def needs_webrtc(self) -> bool:
|
||||||
"""True if webrtc audio enhancements are needed."""
|
"""True if webrtc audio enhancements are needed."""
|
||||||
|
|||||||
Reference in New Issue
Block a user