# import ffmpeg # import tempfile # import os # import subprocess # import urllib.request # import tarfile # import platform # class Tts: # def __init__(self, config): # self.piper_directory = "" # self.install(config["service_directory"]) # def tts(self, text): # with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as temp_file: # output_file = temp_file.name # piper_dir = self.piper_directory # subprocess.run([ # os.path.join(piper_dir, 'piper'), # '--model', os.path.join(piper_dir, os.getenv('PIPER_VOICE_NAME', 'en_US-lessac-medium.onnx')), # '--output_file', output_file # ], input=text, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) # # TODO: hack to format audio correctly for device # outfile = tempfile.gettempdir() + "/" + "raw.dat" # ffmpeg.input(temp_file.name).output(outfile, f="s16le", ar="16000", ac="1", loglevel='panic').run() # return outfile # def install(self, service_directory): # PIPER_FOLDER_PATH = service_directory # self.piper_directory = os.path.join(PIPER_FOLDER_PATH, 'piper') # if not os.path.isdir(self.piper_directory): # Check if the Piper directory exists # os.makedirs(PIPER_FOLDER_PATH, exist_ok=True) # # Determine OS and architecture # OS = platform.system().lower() # ARCH = platform.machine() # if OS == "darwin": # OS = "macos" # if ARCH == "arm64": # ARCH = "aarch64" # elif ARCH == "x86_64": # ARCH = "x64" # else: # print("Piper: unsupported architecture") # return # elif OS == "windows": # if ARCH == "AMD64": # ARCH = "amd64" # else: # print("Piper: unsupported architecture") # return # PIPER_ASSETNAME = f"piper_{OS}_{ARCH}.tar.gz" # PIPER_URL = "https://github.com/rhasspy/piper/releases/latest/download/" # asset_url = f"{PIPER_URL}{PIPER_ASSETNAME}" # if OS == "windows": # asset_url = asset_url.replace(".tar.gz", ".zip") # # Download and extract Piper # urllib.request.urlretrieve(asset_url, os.path.join(PIPER_FOLDER_PATH, PIPER_ASSETNAME)) # # Extract the downloaded file # if OS == "Windows": # import zipfile # with zipfile.ZipFile(os.path.join(PIPER_FOLDER_PATH, PIPER_ASSETNAME), 'r') as zip_ref: # zip_ref.extractall(path=PIPER_FOLDER_PATH) # else: # with tarfile.open(os.path.join(PIPER_FOLDER_PATH, PIPER_ASSETNAME), 'r:gz') as tar: # tar.extractall(path=PIPER_FOLDER_PATH) # PIPER_VOICE_URL = os.getenv('PIPER_VOICE_URL', # 'https://huggingface.co/rhasspy/piper-voices/resolve/main/en/en_US/lessac/medium/') # PIPER_VOICE_NAME = os.getenv('PIPER_VOICE_NAME', 'en_US-lessac-medium.onnx') # # Download voice model and its json file # urllib.request.urlretrieve(f"{PIPER_VOICE_URL}{PIPER_VOICE_NAME}", # os.path.join(self.piper_directory, PIPER_VOICE_NAME)) # urllib.request.urlretrieve(f"{PIPER_VOICE_URL}{PIPER_VOICE_NAME}.json", # os.path.join(self.piper_directory, f"{PIPER_VOICE_NAME}.json")) # # Additional setup for macOS # if OS == "macos": # if ARCH == "x64": # subprocess.run(['softwareupdate', '--install-rosetta', '--agree-to-license']) # PIPER_PHONEMIZE_ASSETNAME = f"piper-phonemize_{OS}_{ARCH}.tar.gz" # PIPER_PHONEMIZE_URL = "https://github.com/rhasspy/piper-phonemize/releases/latest/download/" # urllib.request.urlretrieve(f"{PIPER_PHONEMIZE_URL}{PIPER_PHONEMIZE_ASSETNAME}", # os.path.join(self.piper_directory, PIPER_PHONEMIZE_ASSETNAME)) # with tarfile.open(os.path.join(self.piper_directory, PIPER_PHONEMIZE_ASSETNAME), 'r:gz') as tar: # tar.extractall(path=self.piper_directory) # PIPER_DIR = self.piper_directory # subprocess.run(['install_name_tool', '-change', '@rpath/libespeak-ng.1.dylib', # f"{PIPER_DIR}/piper-phonemize/lib/libespeak-ng.1.dylib", f"{PIPER_DIR}/piper"]) # subprocess.run(['install_name_tool', '-change', '@rpath/libonnxruntime.1.14.1.dylib', # f"{PIPER_DIR}/piper-phonemize/lib/libonnxruntime.1.14.1.dylib", f"{PIPER_DIR}/piper"]) # subprocess.run(['install_name_tool', '-change', '@rpath/libpiper_phonemize.1.dylib', # f"{PIPER_DIR}/piper-phonemize/lib/libpiper_phonemize.1.dylib", f"{PIPER_DIR}/piper"]) # print("Piper setup completed.") # else: # print("Piper already set up. Skipping download.") import ffmpeg import tempfile import os import subprocess import urllib.request import tarfile import platform import zipfile class Tts: def __init__(self, config): self.piper_directory = "" self.install(config["service_directory"]) def tts(self, text): with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as temp_file: output_file = temp_file.name piper_dir = self.piper_directory subprocess.run([ os.path.join(piper_dir, 'piper'), '--model', os.path.join(piper_dir, os.getenv('PIPER_VOICE_NAME', 'en_US-lessac-medium.onnx')), '--output_file', output_file ], input=text, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) # TODO: hack to format audio correctly for device outfile = tempfile.gettempdir() + "/" + "raw.dat" ffmpeg.input(temp_file.name).output(outfile, f="s16le", ar="16000", ac="1", loglevel='panic').run() return outfile def install(self, service_directory): PIPER_FOLDER_PATH = service_directory self.piper_directory = os.path.join(PIPER_FOLDER_PATH, 'piper') if not os.path.isdir(self.piper_directory): # Check if the Piper directory exists os.makedirs(PIPER_FOLDER_PATH, exist_ok=True) # Determine OS and architecture OS = platform.system() ARCH = platform.machine() if OS == "Darwin": OS = "macos" if ARCH == "arm64": ARCH = "aarch64" elif ARCH == "x86_64": ARCH = "x64" else: print("Piper: unsupported architecture") return elif OS == "Windows": if ARCH == "AMD64": ARCH = "x64" else: print("Piper: unsupported architecture") return PIPER_ASSETNAME = f"piper_{OS}_{ARCH}.tar.gz" PIPER_URL = "https://github.com/rhasspy/piper/releases/latest/download/" asset_url = f"{PIPER_URL}{PIPER_ASSETNAME}" # Assign asset_url here if OS == "windows": asset_url = asset_url.replace(".tar.gz", ".zip") # Download and extract Piper urllib.request.urlretrieve(asset_url, os.path.join(PIPER_FOLDER_PATH, PIPER_ASSETNAME)) # Extract the downloaded file if OS == "windows": with zipfile.ZipFile(os.path.join(PIPER_FOLDER_PATH, PIPER_ASSETNAME), 'r') as zip_ref: zip_ref.extractall(path=PIPER_FOLDER_PATH) else: with tarfile.open(os.path.join(PIPER_FOLDER_PATH, PIPER_ASSETNAME), 'r:gz') as tar: tar.extractall(path=PIPER_FOLDER_PATH) # Rest of the code remains unchanged print("Piper setup completed.") else: print("Piper already set up. Skipping download.")