2024-10-11 12:09:54 +00:00
|
|
|
#encoding = utf8
|
2024-10-17 15:26:21 +00:00
|
|
|
import heapq
|
|
|
|
import logging
|
2024-10-11 12:09:54 +00:00
|
|
|
import os
|
|
|
|
import shutil
|
2024-11-09 13:00:22 +00:00
|
|
|
from threading import Lock
|
2024-10-11 12:09:54 +00:00
|
|
|
|
2024-11-06 12:31:23 +00:00
|
|
|
from eventbus import EventBus
|
2024-10-16 00:01:11 +00:00
|
|
|
from utils import save_wav
|
2024-10-17 15:26:21 +00:00
|
|
|
from human_handler import AudioHandler
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
2024-10-11 12:09:54 +00:00
|
|
|
|
|
|
|
|
2024-10-15 00:31:43 +00:00
|
|
|
class TTSAudioHandle(AudioHandler):
|
2024-10-16 00:01:11 +00:00
|
|
|
def __init__(self, context, handler):
|
|
|
|
super().__init__(context, handler)
|
2024-10-11 12:09:54 +00:00
|
|
|
self._sample_rate = 16000
|
2024-10-18 00:15:48 +00:00
|
|
|
self._index = -1
|
2024-10-11 12:09:54 +00:00
|
|
|
|
2024-11-06 12:31:23 +00:00
|
|
|
EventBus().register('stop', self._on_stop)
|
2024-11-08 23:39:03 +00:00
|
|
|
EventBus().register('clear_cache', self.on_clear_cache)
|
2024-11-06 12:31:23 +00:00
|
|
|
|
|
|
|
def __del__(self):
|
|
|
|
EventBus().unregister('stop', self._on_stop)
|
2024-11-08 23:39:03 +00:00
|
|
|
EventBus().unregister('clear_cache', self.on_clear_cache)
|
2024-11-06 12:31:23 +00:00
|
|
|
|
|
|
|
def _on_stop(self, *args, **kwargs):
|
|
|
|
self.stop()
|
|
|
|
|
2024-11-08 23:39:03 +00:00
|
|
|
def on_clear_cache(self, *args, **kwargs):
|
2024-11-09 13:00:22 +00:00
|
|
|
self._index = -1
|
2024-11-08 23:39:03 +00:00
|
|
|
|
2024-10-11 12:09:54 +00:00
|
|
|
@property
|
|
|
|
def sample_rate(self):
|
|
|
|
return self._sample_rate
|
|
|
|
|
|
|
|
@sample_rate.setter
|
|
|
|
def sample_rate(self, value):
|
|
|
|
self._sample_rate = value
|
|
|
|
|
2024-10-14 10:20:55 +00:00
|
|
|
def get_index(self):
|
|
|
|
self._index = self._index + 1
|
|
|
|
return self._index
|
|
|
|
|
2024-10-16 00:01:11 +00:00
|
|
|
def on_handle(self, stream, index):
|
|
|
|
pass
|
|
|
|
|
2024-10-17 15:26:21 +00:00
|
|
|
def stop(self):
|
|
|
|
pass
|
|
|
|
|
2024-10-19 10:47:34 +00:00
|
|
|
def pause_talk(self):
|
|
|
|
pass
|
|
|
|
|
2024-10-11 12:09:54 +00:00
|
|
|
|
|
|
|
class TTSAudioSplitHandle(TTSAudioHandle):
|
2024-10-16 00:01:11 +00:00
|
|
|
def __init__(self, context, handler):
|
|
|
|
super().__init__(context, handler)
|
2024-10-17 00:25:53 +00:00
|
|
|
self.sample_rate = self._context.sample_rate
|
|
|
|
self._chunk = self.sample_rate // self._context.fps
|
2024-10-17 15:26:21 +00:00
|
|
|
self._priority_queue = []
|
2024-11-09 13:00:22 +00:00
|
|
|
self._lock = Lock()
|
2024-10-18 00:15:48 +00:00
|
|
|
self._current = 0
|
2024-11-06 12:31:23 +00:00
|
|
|
self._is_running = True
|
2024-10-17 15:26:21 +00:00
|
|
|
logger.info("TTSAudioSplitHandle init")
|
2024-10-11 12:09:54 +00:00
|
|
|
|
2024-10-14 10:20:55 +00:00
|
|
|
def on_handle(self, stream, index):
|
2024-11-06 12:31:23 +00:00
|
|
|
if not self._is_running:
|
|
|
|
logger.info('TTSAudioSplitHandle::on_handle is not running')
|
|
|
|
return
|
2024-10-17 15:26:21 +00:00
|
|
|
# heapq.heappush(self._priority_queue, (index, stream))
|
2024-11-10 06:06:47 +00:00
|
|
|
|
|
|
|
with self._lock:
|
|
|
|
current = self._priority_queue[0][0]
|
|
|
|
if current == 0:
|
|
|
|
self._current = 0
|
|
|
|
self._priority_queue.clear()
|
|
|
|
|
2024-10-17 15:26:21 +00:00
|
|
|
if stream is None:
|
|
|
|
heapq.heappush(self._priority_queue, (index, None))
|
2024-10-18 00:15:48 +00:00
|
|
|
else:
|
|
|
|
stream_len = stream.shape[0]
|
|
|
|
idx = 0
|
|
|
|
chunks = []
|
2024-11-06 12:31:23 +00:00
|
|
|
while stream_len >= self._chunk and self._is_running:
|
2024-10-18 00:15:48 +00:00
|
|
|
# self.on_next_handle(stream[idx:idx + self._chunk], 0)
|
|
|
|
chunks.append(stream[idx:idx + self._chunk])
|
|
|
|
stream_len -= self._chunk
|
|
|
|
idx += self._chunk
|
2024-11-08 23:39:03 +00:00
|
|
|
if not self._is_running:
|
|
|
|
return
|
2024-10-18 00:15:48 +00:00
|
|
|
heapq.heappush(self._priority_queue, (index, chunks))
|
2024-11-09 13:00:22 +00:00
|
|
|
|
2024-11-10 06:06:47 +00:00
|
|
|
print('TTSAudioSplitHandle::on_handle', index, current, self._current, len(self._priority_queue))
|
|
|
|
if current == self._current:
|
|
|
|
self._current = self._current + 1
|
|
|
|
chunks = heapq.heappop(self._priority_queue)[1]
|
|
|
|
if chunks is None:
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
for chunk in chunks:
|
|
|
|
self.on_next_handle(chunk, 0)
|
2024-10-11 12:09:54 +00:00
|
|
|
|
2024-10-17 15:26:21 +00:00
|
|
|
def stop(self):
|
2024-11-06 12:31:23 +00:00
|
|
|
self._is_running = False
|
2024-10-17 15:26:21 +00:00
|
|
|
|
2024-11-08 23:39:03 +00:00
|
|
|
def on_clear_cache(self, *args, **kwargs):
|
2024-11-09 13:00:22 +00:00
|
|
|
super().on_clear_cache()
|
2024-11-08 23:39:03 +00:00
|
|
|
if self._priority_queue is None or len(self._priority_queue) == 0:
|
|
|
|
return
|
2024-11-09 13:00:22 +00:00
|
|
|
|
|
|
|
with self._lock:
|
|
|
|
print('TTSAudioSplitHandle::on_clear_cache', self._current)
|
|
|
|
self._current = 0
|
|
|
|
print('TTSAudioSplitHandle::on_clear_cache', self._current)
|
|
|
|
|
2024-11-08 23:39:03 +00:00
|
|
|
self._priority_queue.clear()
|
|
|
|
|
2024-10-11 12:09:54 +00:00
|
|
|
|
|
|
|
class TTSAudioSaveHandle(TTSAudioHandle):
|
2024-10-17 15:26:21 +00:00
|
|
|
def __init__(self, context, handler):
|
|
|
|
super().__init__(context, handler)
|
2024-10-11 12:09:54 +00:00
|
|
|
self._save_path_dir = '../temp/audio/'
|
|
|
|
self._clean()
|
|
|
|
|
|
|
|
def _clean(self):
|
|
|
|
directory = self._save_path_dir
|
|
|
|
if not os.path.exists(directory):
|
|
|
|
print(f"The directory {directory} does not exist.")
|
|
|
|
return
|
|
|
|
|
|
|
|
for filename in os.listdir(directory):
|
|
|
|
file_path = os.path.join(directory, filename)
|
|
|
|
|
|
|
|
# 如果是文件,删除
|
|
|
|
if os.path.isfile(file_path):
|
|
|
|
os.remove(file_path)
|
|
|
|
print(f"Deleted file: {file_path}")
|
|
|
|
# 如果是文件夹,递归删除所有文件夹中的内容
|
|
|
|
elif os.path.isdir(file_path):
|
|
|
|
shutil.rmtree(file_path)
|
|
|
|
print(f"Deleted directory and its contents: {file_path}")
|
|
|
|
|
2024-10-14 10:20:55 +00:00
|
|
|
def on_handle(self, stream, index):
|
|
|
|
file_name = self._save_path_dir + str(index) + '.wav'
|
2024-10-11 12:09:54 +00:00
|
|
|
save_wav(stream, file_name, self.sample_rate)
|
|
|
|
|
2024-10-17 15:26:21 +00:00
|
|
|
def stop(self):
|
|
|
|
pass
|
|
|
|
|