added auto mute when holding v so i dont hear myself
This commit is contained in:
+28
-6
@@ -40,7 +40,7 @@ class SoundReceiver:
|
||||
PREBUFFER_CHUNKS = 3
|
||||
SILENCE_CHUNK = b"\x00" * 4096
|
||||
|
||||
def __init__(self, output_device_index=None, mic_gain=8.0):
|
||||
def __init__(self, output_device_index=None, mic_gain=8.0, pyaudio_instance=None):
|
||||
self.running = True
|
||||
self.underrun_count = 0
|
||||
self.chunks_received = 0
|
||||
@@ -48,9 +48,12 @@ class SoundReceiver:
|
||||
self._peak_since_print = 0
|
||||
self._last_status_print = 0
|
||||
self.mic_gain = float(mic_gain)
|
||||
self.muted = False
|
||||
self._owns_pyaudio = False
|
||||
|
||||
if HAS_AUDIO:
|
||||
self.p = pyaudio.PyAudio()
|
||||
self.p = pyaudio_instance if pyaudio_instance is not None else pyaudio.PyAudio()
|
||||
self._owns_pyaudio = pyaudio_instance is None
|
||||
print("🔈 Available output devices:")
|
||||
for i in range(self.p.get_device_count()):
|
||||
info = self.p.get_device_info_by_index(i)
|
||||
@@ -117,6 +120,9 @@ class SoundReceiver:
|
||||
|
||||
def _write_chunk(self, raw_bytes):
|
||||
try:
|
||||
if self.muted:
|
||||
self.stream.write(b"\x00" * len(raw_bytes))
|
||||
return
|
||||
samples = np.frombuffer(raw_bytes, dtype=np.int16).astype(np.float32)
|
||||
if samples.size:
|
||||
amplified = np.clip(samples * self.mic_gain, -32768, 32767)
|
||||
@@ -136,6 +142,7 @@ class SoundReceiver:
|
||||
try:
|
||||
self.stream.stop_stream()
|
||||
self.stream.close()
|
||||
if self._owns_pyaudio:
|
||||
self.p.terminate()
|
||||
except: pass
|
||||
|
||||
@@ -151,7 +158,7 @@ class LiveMicRelay:
|
||||
stop() ends the remote nc process, which ends aplay with it.
|
||||
"""
|
||||
def __init__(self, nao_ip, ssh_user="nao", ssh_password="nao",
|
||||
port=5555, rate=16000, input_device_index=None):
|
||||
port=5555, rate=16000, input_device_index=None, pyaudio_instance=None):
|
||||
self.nao_ip = nao_ip
|
||||
self.ssh_user = ssh_user
|
||||
self.ssh_password = ssh_password
|
||||
@@ -165,7 +172,10 @@ class LiveMicRelay:
|
||||
self._sock = None
|
||||
self._stream = None
|
||||
self._thread = None
|
||||
self._p = pyaudio.PyAudio() if HAS_AUDIO else None
|
||||
# Reuse the app's single PyAudio context - a second independent one
|
||||
# opened from a background thread crashes PortAudio's PulseAudio
|
||||
# backend (pa_atomic_load assertion).
|
||||
self._p = pyaudio_instance if pyaudio_instance is not None else (pyaudio.PyAudio() if HAS_AUDIO else None)
|
||||
|
||||
def start(self):
|
||||
if self.active:
|
||||
@@ -266,8 +276,13 @@ class NaoTeleop:
|
||||
self.mic_channel = mic_channel
|
||||
self.mic_gain = mic_gain
|
||||
|
||||
# One shared PyAudio context for the whole app - SoundReceiver (mic
|
||||
# playback) and LiveMicRelay (push-to-talk capture) both use it,
|
||||
# since two separate contexts crash PortAudio's PulseAudio backend.
|
||||
self._pyaudio = pyaudio.PyAudio() if HAS_AUDIO else None
|
||||
|
||||
self.mic_relay = LiveMicRelay(nao_ip, ssh_user=nao_ssh_user, ssh_password=nao_ssh_password,
|
||||
port=relay_port, rate=relay_rate)
|
||||
port=relay_port, rate=relay_rate, pyaudio_instance=self._pyaudio)
|
||||
self.ptt_active = False
|
||||
|
||||
self.running = True
|
||||
@@ -328,7 +343,8 @@ class NaoTeleop:
|
||||
def _init_mic_stream(self):
|
||||
if not self.audio_device: return
|
||||
try:
|
||||
self.sound_receiver = SoundReceiver(self.audio_device_index, self.mic_gain)
|
||||
self.sound_receiver = SoundReceiver(self.audio_device_index, self.mic_gain,
|
||||
pyaudio_instance=self._pyaudio)
|
||||
self.session.registerService(self.audio_service_name, self.sound_receiver)
|
||||
time.sleep(0.5)
|
||||
self.audio_device.setClientPreferences(self.audio_service_name, 16000, self.mic_channel, 0)
|
||||
@@ -605,9 +621,13 @@ class NaoTeleop:
|
||||
if keys[pygame.K_v] and not self.ptt_active:
|
||||
self.ptt_active = True
|
||||
self.mic_relay.start()
|
||||
if getattr(self, "sound_receiver", None):
|
||||
self.sound_receiver.muted = True
|
||||
elif not keys[pygame.K_v] and self.ptt_active:
|
||||
self.ptt_active = False
|
||||
self.mic_relay.stop()
|
||||
if getattr(self, "sound_receiver", None):
|
||||
self.sound_receiver.muted = False
|
||||
|
||||
speed_changed = False
|
||||
if keys[pygame.K_LEFTBRACKET]:
|
||||
@@ -721,6 +741,8 @@ class NaoTeleop:
|
||||
self._safe("sound receiver close", self.sound_receiver.close)
|
||||
if hasattr(self, 'video') and self.video_client:
|
||||
self._safe("video unsubscribe", lambda: self.video.unsubscribe(self.video_client))
|
||||
if getattr(self, "_pyaudio", None):
|
||||
self._safe("pyaudio terminate", self._pyaudio.terminate)
|
||||
self._safe("rest", self.motion.rest)
|
||||
pygame.quit()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user