human/render/audio_render.py
2024-10-21 19:55:04 +08:00

70 lines
1.7 KiB
Python

#encoding = utf8
import logging
import time
from queue import Queue, Empty
from threading import Event, Thread
import numpy as np
from audio_render import AudioRender
from base_render import BaseRender
logger = logging.getLogger(__name__)
class AudioRenderImpl(BaseRender):
def __init__(self, start):
super().__init__(start)
self._queue = Queue()
self._exit_event = Event()
self._thread = Thread(target=self._on_run)
self._exit_event.set()
self._thread.start()
self._audio_render = AudioRender()
self._current_time = 0
self._display_time = 0
def _on_run(self):
logging.info('Audio render run')
while self._exit_event.is_set():
self._run_step()
time.sleep(0.02)
logging.info('Audio render exit')
def _run_step(self):
try:
audio_frames, ps = self._queue.get(block=True, timeout=0.01)
except Empty:
return
self._display_time = time.time()
self._current_time = ps
for audio_frame in audio_frames:
frame, type_ = audio_frame
frame = (frame * 32767).astype(np.int16)
if self._audio_render is not None:
try:
self._audio_render.write(frame.tobytes(), int(frame.shape[0] * 2))
except Exception as e:
logging.error(f'Error writing audio frame: {e}')
def put(self, frame):
ps = time.time() - self._start
self._queue.put_nowait((frame, ps))
def stop(self):
self._exit_event.clear()
self._thread.join()
def play_time(self):
elapsed = time.time() - self._display_time
return self._current_time + elapsed