Исходники
Язык:
php
Делюсь таким простеньким скриптом. Он позволяет отправлять смешанные предложения, содержащие английский и не-английский язык.
Это клиент для Festival TTS server. Преимущество festival - работает локально даже на чайниках железках уровня Intel Celeron x32.
Festival - это многоязычная система синтеза речи, разработанная CSTR (Centre for Speech Technology Research). Она предлагает основу для построения систем синтеза речи, а также включает примеры различных модулей.
Для максимального быстродействия работы с двумя языками на локальной машине надо запустить два инстанса Festival (можно юзать nohup или создать демона):
festival --server '(set! server_port 1314)'
festival --server '(set! server_port 1315)' --language russian
Создать файл festival-tts-client.php с содержимым:
<?php
// by ScorpioT1000 © 2023
class FestivalTTSClient {
	private $socketEn = null;
	private $socketNonEn = null;
	private $mt = 0;
	
	public function __construct(
		string $ipPortEnglish = 'localhost:1314',
		string $ipPortNonEnglish = null
	) {
		$this->mt = microtime(true);
		$this->socketEn = socket_create(\AF_INET, \SOCK_STREAM, \SOL_TCP);
		if(!$this->socketEn) {
			throw new \Exception("Cannot create a socket en");
		}
		if(!socket_connect(
			$this->socketEn,
			explode(':',$ipPortEnglish)[0],
			explode(':',$ipPortEnglish)[1])
		) {
			throw new \Exception("Could not connect to the english server");		
		}
		if($ipPortNonEnglish) {
			$this->socketNonEn = socket_create(\AF_INET, \SOCK_STREAM, \SOL_TCP);
			if(!$this->socketNonEn) {
				throw new \Exception("Cannot create a socket non en");
			}
			if(!socket_connect(
				$this->socketNonEn,
				explode(':',$ipPortNonEnglish)[0],
				explode(':',$ipPortNonEnglish)[1])
			) {
				throw new \Exception("Could not connect to non english server");		
			}
		}
	}
	
	public function __destruct() 
	{
		if($this->socketEn) {
			socket_close($this->socketEn);		
		}
		if($this->socketNonEn) {
			socket_close($this->socketNonEn);		
		}
	}

	public function say(string $text) 
	{
		if(!$this->socketEn) {
			throw new \Exception("No active connection");				
		}
		if(!$this->socketNonEn) {
			$this->sendText($text, $this->socketEn);
		} else {
			$expressions = $this->splitByLanguage($text);
			foreach($expressions as $expr) {
				$this->sendText($expr, $this->isEnglish($expr) ? $this->socketEn : $this->socketNonEn);
			}
		}
	}
	
	private function splitByLanguage(string $text): array
	{
		$words = preg_split('/[\s]+/', $text);
		$expressions = [];
		$expr = '';
		$lang = null;
		foreach($words as $word) {
			if(trim($word)) {
				$thisLang = $this->isEnglish($word);
				if($lang === $thisLang) {
					$expr .= ' '.$word;
				} else {
					$expressions[] = $expr;
					$expr = $word;
					$lang = $thisLang;
				}
			}
		}
		if($expr) {
			$expressions[] = $expr;
		}
		return $expressions;
	}
	
	private function isEnglish(string $text): bool
	{
		return !ctype_digit(trim($text)) && !preg_match('/[^\x20-\x7e]/', $text);
	}
	
	private function sendText(string $text, $socket)
	{
		if(!trim($text)) { return; }
		$this->send('(SayText "'.addslashes($text).'")', $socket);		
	}
	
	private function send(string $message, $socket) 
	{
		echo '['.number_format(microtime(true)-$this->mt, 4, '.', '').'] Request: '.$message.PHP_EOL;
		if(socket_write($socket, $message) === false) {
			throw new \Exception('Could not write to socket');
		}
		for($i = 0; $i < 3; ++$i) {
			$resp = socket_read($socket, 1024);
			echo '['.number_format(microtime(true)-$this->mt, 4, '.', '').'] Response: '.($resp === false ? '(false returned)' : $resp).PHP_EOL;
			if(strpos($resp, 'OK') !== false || strpos($resp, 'ER') !== false || $resp === false) {
				break;
			}
		}
	}
}

$options = getopt('', ['text:', 'server-eng:', 'server-non-eng::']);
if(empty($options['server-eng'])) {
	echo 'Privide --server-eng=IP:PORT as an argument'.PHP_EOL;
	exit(1);	
}
$client = new FestivalTTSClient($options['server-eng'], ($options['server-non-eng'] ?? null) ?: null);
$text = $options['text'] ?? '';
if($text) {
	$client->say($text);
} else {
	echo 'Privide --text as an argument'.PHP_EOL;
	exit(1);
}

Затем выполнить данный скрипт на php 7+ (apt-get install php будет достаточно):
php festival-tts-client.php --server-eng="localhost:1314" --server-non-eng="localhost:1315" --text="Moskau! Раз два три! Moskau! Посмотри!"
Результат:
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.