mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-24 08:03:53 +08:00
update: 增加智能体独立音频设置
This commit is contained in:
@@ -6,9 +6,9 @@ import queue
|
||||
import asyncio
|
||||
import traceback
|
||||
import websockets
|
||||
|
||||
from asyncio import Task
|
||||
from config.logger import setup_logging
|
||||
from core.utils import opus_encoder_utils
|
||||
from core.utils.tts import MarkdownCleaner
|
||||
from core.providers.tts.base import TTSProviderBase
|
||||
from core.providers.tts.dto.dto import SentenceType, ContentType, InterfaceType
|
||||
@@ -18,6 +18,12 @@ logger = setup_logging()
|
||||
|
||||
|
||||
class TTSProvider(TTSProviderBase):
|
||||
TTS_PARAM_CONFIG = [
|
||||
("ttsVolume", "volume", 0, 100, 50, int),
|
||||
("ttsRate", "rate", 0.5, 2.0, 1.0, lambda v: round(v, 1)),
|
||||
("ttsPitch", "pitch", 0.5, 2.0, 1.0, lambda v: round(v, 1)),
|
||||
]
|
||||
|
||||
def __init__(self, config, delete_audio_file):
|
||||
super().__init__(config, delete_audio_file)
|
||||
|
||||
@@ -51,6 +57,9 @@ class TTSProvider(TTSProviderBase):
|
||||
pitch = config.get("pitch", "1.0")
|
||||
self.pitch = float(pitch) if pitch else 1.0
|
||||
|
||||
# 应用百分比调整(如果存在),否则使用公有化配置
|
||||
self._apply_percentage_params(config)
|
||||
|
||||
self.header = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
# "user-agent": "your_platform_info", // 可选
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
import uuid
|
||||
import json
|
||||
import hmac
|
||||
import time
|
||||
import hashlib
|
||||
import base64
|
||||
import requests
|
||||
from datetime import datetime
|
||||
from core.providers.tts.base import TTSProviderBase
|
||||
from config.logger import setup_logging
|
||||
import time
|
||||
import uuid
|
||||
|
||||
from urllib import parse
|
||||
from datetime import datetime
|
||||
from config.logger import setup_logging
|
||||
from core.providers.tts.base import TTSProviderBase
|
||||
from core.utils.tts import convert_percentage_to_range
|
||||
|
||||
|
||||
TAG = __name__
|
||||
logger = setup_logging()
|
||||
@@ -84,6 +86,11 @@ class AccessToken:
|
||||
|
||||
|
||||
class TTSProvider(TTSProviderBase):
|
||||
TTS_PARAM_CONFIG = [
|
||||
("ttsVolume", "volume", 0, 100, 50, int),
|
||||
("ttsRate", "speech_rate", -500, 500, 0, int),
|
||||
("ttsPitch", "pitch_rate", -500, 500, 0, int),
|
||||
]
|
||||
|
||||
def __init__(self, config, delete_audio_file):
|
||||
super().__init__(config, delete_audio_file)
|
||||
@@ -110,6 +117,9 @@ class TTSProvider(TTSProviderBase):
|
||||
pitch_rate = config.get("pitch_rate", "0")
|
||||
self.pitch_rate = int(pitch_rate) if pitch_rate else 0
|
||||
|
||||
# 应用百分比调整(如果存在),否则使用公有化配置
|
||||
self._apply_percentage_params(config)
|
||||
|
||||
self.host = config.get("host", "nls-gateway-cn-shanghai.aliyuncs.com")
|
||||
self.api_url = f"https://{self.host}/stream/v1/tts"
|
||||
self.header = {"Content-Type": "application/json"}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import random
|
||||
import os
|
||||
import uuid
|
||||
import json
|
||||
import hmac
|
||||
@@ -8,16 +8,16 @@ import time
|
||||
import queue
|
||||
import asyncio
|
||||
import traceback
|
||||
from asyncio import Task
|
||||
import websockets
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
from asyncio import Task
|
||||
from urllib import parse
|
||||
from datetime import datetime
|
||||
from config.logger import setup_logging
|
||||
from core.utils.tts import MarkdownCleaner
|
||||
from core.providers.tts.base import TTSProviderBase
|
||||
from core.providers.tts.dto.dto import SentenceType, ContentType, InterfaceType
|
||||
from core.utils.tts import MarkdownCleaner
|
||||
from core.utils import opus_encoder_utils, textUtils
|
||||
from config.logger import setup_logging
|
||||
|
||||
|
||||
TAG = __name__
|
||||
logger = setup_logging()
|
||||
@@ -86,6 +86,12 @@ class AccessToken:
|
||||
|
||||
|
||||
class TTSProvider(TTSProviderBase):
|
||||
TTS_PARAM_CONFIG = [
|
||||
("ttsVolume", "volume", 0, 100, 50, int),
|
||||
("ttsRate", "speech_rate", -500, 500, 0, int),
|
||||
("ttsPitch", "pitch_rate", -500, 500, 0, int),
|
||||
]
|
||||
|
||||
def __init__(self, config, delete_audio_file):
|
||||
super().__init__(config, delete_audio_file)
|
||||
|
||||
@@ -115,6 +121,9 @@ class TTSProvider(TTSProviderBase):
|
||||
pitch_rate = config.get("pitch_rate", "0")
|
||||
self.pitch_rate = int(pitch_rate) if pitch_rate else 0
|
||||
|
||||
# 应用百分比调整(如果存在),否则使用公有化配置
|
||||
self._apply_percentage_params(config)
|
||||
|
||||
# WebSocket配置
|
||||
self.host = config.get("host", "nls-gateway-cn-beijing.aliyuncs.com")
|
||||
# 如果配置的是内网地址(包含-internal.aliyuncs.com),则使用ws协议,默认是wss协议
|
||||
|
||||
@@ -13,7 +13,7 @@ from typing import Callable, Any
|
||||
from abc import ABC, abstractmethod
|
||||
from config.logger import setup_logging
|
||||
from core.utils import opus_encoder_utils
|
||||
from core.utils.tts import MarkdownCleaner
|
||||
from core.utils.tts import MarkdownCleaner, convert_percentage_to_range
|
||||
from core.utils.output_counter import add_device_output
|
||||
from core.handle.reportHandle import enqueue_tts_report
|
||||
from core.handle.sendAudioHandle import sendAudioMessage
|
||||
@@ -463,3 +463,10 @@ class TTSProviderBase(ABC):
|
||||
self.processed_chars += len(full_text)
|
||||
return True
|
||||
return False
|
||||
|
||||
def _apply_percentage_params(self, config):
|
||||
"""根据子类定义的 TTS_PARAM_CONFIG 批量应用百分比参数"""
|
||||
for config_key, attr_name, min_val, max_val, base_val, transform in self.TTS_PARAM_CONFIG:
|
||||
if config_key in config:
|
||||
val = convert_percentage_to_range(config[config_key], min_val, max_val, base_val)
|
||||
setattr(self, attr_name, transform(val) if transform else val)
|
||||
|
||||
@@ -2,15 +2,24 @@ import uuid
|
||||
import json
|
||||
import base64
|
||||
import requests
|
||||
|
||||
from config.logger import setup_logging
|
||||
from core.utils.util import check_model_key
|
||||
from core.providers.tts.base import TTSProviderBase
|
||||
from config.logger import setup_logging
|
||||
from core.utils.tts import convert_percentage_to_range
|
||||
|
||||
|
||||
TAG = __name__
|
||||
logger = setup_logging()
|
||||
|
||||
|
||||
class TTSProvider(TTSProviderBase):
|
||||
TTS_PARAM_CONFIG = [
|
||||
("ttsVolume", "volume_ratio", 0.1, 3, 1.0, lambda v: round(float(v), 1)),
|
||||
("ttsRate", "speed_ratio", 0.2, 3, 1.0, lambda v: round(float(v), 1)),
|
||||
("ttsPitch", "pitch_ratio", 0.1, 3, 1.0, lambda v: round(float(v), 1)),
|
||||
]
|
||||
|
||||
def __init__(self, config, delete_audio_file):
|
||||
super().__init__(config, delete_audio_file)
|
||||
if config.get("appid"):
|
||||
@@ -34,6 +43,9 @@ class TTSProvider(TTSProviderBase):
|
||||
self.volume_ratio = float(volume_ratio) if volume_ratio else 1.0
|
||||
self.pitch_ratio = float(pitch_ratio) if pitch_ratio else 1.0
|
||||
|
||||
# 应用百分比调整(如果存在),否则使用公有化配置
|
||||
self._apply_percentage_params(config)
|
||||
|
||||
self.api_url = config.get("api_url")
|
||||
self.authorization = config.get("authorization")
|
||||
self.header = {"Authorization": f"{self.authorization}{self.access_token}"}
|
||||
|
||||
@@ -7,11 +7,10 @@ import traceback
|
||||
import websockets
|
||||
|
||||
from typing import Callable, Any
|
||||
from core.utils.tts import MarkdownCleaner
|
||||
from config.logger import setup_logging
|
||||
from core.utils import opus_encoder_utils
|
||||
from core.utils.util import check_model_key
|
||||
from core.providers.tts.base import TTSProviderBase
|
||||
from core.utils.tts import MarkdownCleaner, convert_percentage_to_range
|
||||
from core.providers.tts.dto.dto import SentenceType, ContentType, InterfaceType
|
||||
|
||||
|
||||
@@ -178,6 +177,22 @@ class TTSProvider(TTSProviderBase):
|
||||
self.additions = {**default_additions, **config.get("additions", {})}
|
||||
self.mix_speaker = {**default_mix_speaker, **config.get("mix_speaker", {})}
|
||||
|
||||
# 应用百分比调整(如果存在),否则使用公有化配置
|
||||
if "ttsVolume" in config:
|
||||
self.audio_params["loudness_rate"] = int(convert_percentage_to_range(
|
||||
config["ttsVolume"], min_val=-50, max_val=100, base_val=0
|
||||
))
|
||||
|
||||
if "ttsRate" in config:
|
||||
self.audio_params["speech_rate"] = int(convert_percentage_to_range(
|
||||
config["ttsRate"], min_val=-50, max_val=100, base_val=0
|
||||
))
|
||||
|
||||
if "ttsPitch" in config:
|
||||
self.additions["post_process"]["pitch"] = int(convert_percentage_to_range(
|
||||
config["ttsPitch"], min_val=-12, max_val=12, base_val=0
|
||||
))
|
||||
|
||||
self.ws_url = config.get("ws_url")
|
||||
self.authorization = config.get("authorization")
|
||||
self.header = {"Authorization": f"{self.authorization}{self.access_token}"}
|
||||
|
||||
@@ -6,12 +6,14 @@ import asyncio
|
||||
import aiohttp
|
||||
import requests
|
||||
import traceback
|
||||
|
||||
from core.utils import textUtils
|
||||
from config.logger import setup_logging
|
||||
from core.utils.tts import MarkdownCleaner
|
||||
from core.utils.util import parse_string_to_list
|
||||
from core.providers.tts.base import TTSProviderBase
|
||||
from core.utils import opus_encoder_utils, textUtils
|
||||
from core.providers.tts.dto.dto import SentenceType, ContentType
|
||||
from core.utils.tts import MarkdownCleaner, convert_percentage_to_range
|
||||
|
||||
|
||||
TAG = __name__
|
||||
logger = setup_logging()
|
||||
@@ -56,6 +58,22 @@ class TTSProvider(TTSProviderBase):
|
||||
if self.voice:
|
||||
self.voice_setting["voice_id"] = self.voice
|
||||
|
||||
# 应用百分比调整(如果存在),否则使用公有化配置
|
||||
if "ttsVolume" in config:
|
||||
self.voice_setting["vol"] = round(convert_percentage_to_range(
|
||||
config["ttsVolume"], min_val=0.1, max_val=10, base_val=1.0
|
||||
), 1)
|
||||
|
||||
if "ttsRate" in config:
|
||||
self.voice_setting["speed"] = round(convert_percentage_to_range(
|
||||
config["ttsRate"], min_val=0.5, max_val=2, base_val=1.0
|
||||
), 1)
|
||||
|
||||
if "ttsPitch" in config:
|
||||
self.voice_setting["pitch"] = int(convert_percentage_to_range(
|
||||
config["ttsPitch"], min_val=-12, max_val=12, base_val=0
|
||||
))
|
||||
|
||||
self.host = "api.minimaxi.com" # 备用地址:api-bj.minimaxi.com
|
||||
self.api_url = f"https://{self.host}/v1/t2a_v2?GroupId={self.group_id}"
|
||||
self.header = {
|
||||
|
||||
@@ -16,6 +16,11 @@ logger = setup_logging()
|
||||
|
||||
|
||||
class TTSProvider(TTSProviderBase):
|
||||
TTS_PARAM_CONFIG = [
|
||||
("ttsVolume", "volume", 0, 3, 1.0, lambda v: round(float(v), 1)),
|
||||
("ttsRate", "speed", 0, 3, 1.0, lambda v: round(float(v), 1)),
|
||||
]
|
||||
|
||||
def __init__(self, config, delete_audio_file):
|
||||
super().__init__(config, delete_audio_file)
|
||||
self.url = config.get("url", "ws://192.168.1.10:8092/paddlespeech/tts/streaming")
|
||||
@@ -33,6 +38,10 @@ class TTSProvider(TTSProviderBase):
|
||||
self.volume = float(volume) if volume else 1.0
|
||||
|
||||
self.delete_audio_file = config.get("delete_audio", True)
|
||||
|
||||
# 应用百分比调整(如果存在),否则使用公有化配置
|
||||
self._apply_percentage_params(config)
|
||||
|
||||
if not self.delete_audio_file:
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
save_path = config.get("save_path")
|
||||
|
||||
@@ -3,6 +3,11 @@ from core.providers.tts.base import TTSProviderBase
|
||||
|
||||
|
||||
class TTSProvider(TTSProviderBase):
|
||||
TTS_PARAM_CONFIG = [
|
||||
("ttsVolume", "gain", -10, 10, 0, int),
|
||||
("ttsRate", "speed", 0.25, 4, 1, lambda v: round(float(v), 1)),
|
||||
]
|
||||
|
||||
def __init__(self, config, delete_audio_file):
|
||||
super().__init__(config, delete_audio_file)
|
||||
self.model = config.get("model")
|
||||
@@ -16,6 +21,9 @@ class TTSProvider(TTSProviderBase):
|
||||
self.speed = float(config.get("speed", 1.0))
|
||||
self.gain = config.get("gain")
|
||||
|
||||
# 应用百分比调整(如果存在),否则使用公有化配置
|
||||
self._apply_percentage_params(config)
|
||||
|
||||
self.host = "api.siliconflow.cn"
|
||||
self.api_url = f"https://{self.host}/v1/audio/speech"
|
||||
|
||||
|
||||
@@ -12,6 +12,12 @@ logger = setup_logging()
|
||||
|
||||
|
||||
class TTSProvider(TTSProviderBase):
|
||||
TTS_PARAM_CONFIG = [
|
||||
("ttsVolume", "volume_change_dB", -10, 10, 0, int),
|
||||
("ttsRate", "speed_factor", 0.5, 2, 0, lambda v: round(float(v), 1)),
|
||||
("ttsPitch", "pitch_factor", -8, 8, 0, lambda v: round(float(v), 1)),
|
||||
]
|
||||
|
||||
def __init__(self, config, delete_audio_file):
|
||||
super().__init__(config, delete_audio_file)
|
||||
self.url = config.get(
|
||||
@@ -34,6 +40,9 @@ class TTSProvider(TTSProviderBase):
|
||||
self.emotion = int(config.get("emotion", 1))
|
||||
self.header = {"Content-Type": "application/json"}
|
||||
|
||||
# 应用百分比调整(如果存在),否则使用公有化配置
|
||||
self._apply_percentage_params(config)
|
||||
|
||||
def generate_filename(self, extension=".mp3"):
|
||||
return os.path.join(
|
||||
self.output_file,
|
||||
|
||||
@@ -9,9 +9,9 @@ import hashlib
|
||||
import asyncio
|
||||
import traceback
|
||||
import websockets
|
||||
|
||||
from asyncio import Task
|
||||
from config.logger import setup_logging
|
||||
from core.utils import opus_encoder_utils
|
||||
from core.utils.tts import MarkdownCleaner
|
||||
from urllib.parse import urlencode, urlparse
|
||||
from core.providers.tts.base import TTSProviderBase
|
||||
@@ -59,6 +59,12 @@ class XunfeiWSAuth:
|
||||
|
||||
|
||||
class TTSProvider(TTSProviderBase):
|
||||
TTS_PARAM_CONFIG = [
|
||||
("ttsVolume", "volume", 0, 100, 50, int),
|
||||
("ttsRate", "speed", 0, 100, 50, int),
|
||||
("ttsPitch", "pitch", 0, 100, 50, int),
|
||||
]
|
||||
|
||||
def __init__(self, config, delete_audio_file):
|
||||
super().__init__(config, delete_audio_file)
|
||||
|
||||
@@ -88,6 +94,9 @@ class TTSProvider(TTSProviderBase):
|
||||
pitch = config.get("pitch", "50")
|
||||
self.pitch = int(pitch) if pitch else 50
|
||||
|
||||
# 应用百分比调整(如果存在),否则使用公有化配置
|
||||
self._apply_percentage_params(config)
|
||||
|
||||
# 音频编码配置
|
||||
self.format = config.get("format", "raw")
|
||||
|
||||
|
||||
@@ -141,4 +141,31 @@ class MarkdownCleaner:
|
||||
# 去除emoji表情
|
||||
text = check_emoji(text)
|
||||
|
||||
return text.strip()
|
||||
return text.strip()
|
||||
|
||||
def convert_percentage_to_range(percentage, min_val, max_val, base_val=None):
|
||||
"""
|
||||
将百分比(-100~100)转换为指定范围的值
|
||||
|
||||
Args:
|
||||
percentage: 百分比值 (-100 到 100)
|
||||
min_val: 目标范围最小值
|
||||
max_val: 目标范围最大值
|
||||
base_val: 基准值(可选,默认为范围中点)
|
||||
|
||||
Returns:
|
||||
转换后的值
|
||||
"""
|
||||
if base_val is None:
|
||||
base_val = (min_val + max_val) / 2
|
||||
|
||||
# 百分比 -100 对应 min_val, 0 对应 base_val, 100 对应 max_val
|
||||
if percentage < 0:
|
||||
# 负百分比:从 base_val 向 min_val 线性插值
|
||||
result = base_val + (base_val - min_val) * (percentage / 100)
|
||||
else:
|
||||
# 正百分比:从 base_val 向 max_val 线性插值
|
||||
result = base_val + (max_val - base_val) * (percentage / 100)
|
||||
|
||||
# 确保结果在有效范围内
|
||||
return max(min_val, min(max_val, result))
|
||||
|
||||
Reference in New Issue
Block a user