Text-to-Speech for Linux

Text-to-Speech for Linux Featured Image

Writing great emails can be tricky at the best of times when you have dyslexia (or any other sort of written communication for that matter!).

Checking your writing with a text-to-speech app is a great help, and you may already be aware of the say programme for TTS on macOS. It can be setup with a keyboard shortcut to speak out loud selected text.

Nowadays they’re not even in a programmatic-robotic voice but using real inflections and picking up on grammar too. This sort of tool is called “Advanced TTS” or Advanced Text-to-Speech and it’s great for checking text and the flow of you’re emails.

Great TTS is harder to obtain on a Linux desktop than macOS. There are a few TTS easy-to-install applications on the various Linux repositories but they’re old-school at best - think 1990s Sci-Fi robot tones - these apps are not the most helpful for checking human inflections and grammar in a chunk of text.

There are some great Firefox Add-ons out there for using some good AI-based TTS for selected text on webpages, but this doesn’t help outside of the web-browser and you’re potentially sacrificing your privacy to the operators offering the addon between you and the advanced TTS providers.

Thankfully all the big players in the cloud now offer their own TTS or Text-to-speech APIs - so we can tap into this pretty easily with a simple hacky script and Google Cloud’s free tier.

Setup Advanced TTS (Text-to-Speech) on Linux

Warning: This is a quick and somewhat-dirty hack, in PHP, built for Linux to speak aloud any text you’ve copied on command. It’ll send any copied text to Google’s TTS API service, download an audio file and play it back to you.

Step 1. Setup a Google Cloud account on the free tier if you don’t already have one - and generate an API token for their TTS API service.

Step 2. Install dependencies on your Linux. php-cli, xclip, play.

e.g. on debian, ubuntu etc sudo apt install php-cli xclip play

Step 3. Copy this script into your home directory and call it gctts.php, editing the code to include your API key.

Note: it’s not good practice to store secrets like API keys in code, usually it’s better to store them in environment variables or dedicated secret vaults, also it’s not great to be writing utility tools like this in PHP - but this is a quick hack after all.

<?php

// show all errors
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

// grab text in the clipboard
exec('xclip -o', $clipboard);

// remove new lines, formatting into one line
$JSON_request['input']['text'] = implode("\n", $clipboard);

// testing...
//var_dump($clipboard);

$GCP_TTS_Key = '<<PASTE_GCP_API_KEY_HERE>>'

// Google Cloud TTS Configuration
$JSON_request['voice']['languageCode'] ="en-GB";
// $JSON_request['voice']['name'] ="en-GB-Standard-C"; // cheaper female
$JSON_request['voice']['name'] ="en-GB-Wavenet-F"; // better female
$JSON_request['voice']['ssmlGender'] ="FEMALE"; // let it pick?
$JSON_request['audioConfig']['audioEncoding']="MP3";
$JSON_request['audioConfig']['speakingRate']="1.1";

// Quick API Function
function googletts_json_api($key = false, $method, $URI, $data) {
	$ch = curl_init();
	
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
	curl_setopt($ch, CURLOPT_URL, $URI.'?key='.$key);

	// (array) will be converted to html form style, or send json string for body
	curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
	curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

	// response should be JSON formatted
	$result = curl_exec($ch);

	var_dump($result);

	// is http error code in 4**/5** error range
	$status = (string) curl_getinfo($ch, CURLINFO_HTTP_CODE);
	if( $status[0] == 4 || $status[0] == 5 ) {
		return false;	
	}
	// curl error
	elseif($result === false) {
		error_log("API ERROR: Connection failure: $URI", 0);
		return false;
	}
	else return json_decode($result, true);

	curl_close($ch);
}

// make the call...
$response = googletts_json_api($GCP_TTS_Key, 'POST', 'https://texttospeech.googleapis.com/v1/text:synthesize', json_encode($JSON_request));

// dump the audio to a temp location (temp is cleared on reboot etc)
file_put_contents('/tmp/gctts.mp3', base64_decode($response['audioContent']));

// play the audio
exec('play -q -t mp3 /tmp/gctts.mp3');

?>

Step 4. Setup a global keyboard shortcut.

Exactly how to do this will depend on your distro of Linux and it’s Desktop environment.

On Linux Mint (using the Cinnamon DE), go to: Settings -> Keyboard -> Shortcuts -> Custom shortcuts -> Add Custom Shortcut.

Name the shortcut something sensible like “Speak” and enter in the command to run the script php /home/<<USERNAME>>/clip-gc-tts.php (replacing <<USERNAME>> with your username).

I usually set the key-binding to “Crtl+`”.

Usage / Known Issues / Gotchas

Simply select the text that you would want to read allowed, then copy the text e.g. Ctrl+C and then use the keyboard shortcut to speak it out loud e.g. “Ctrl+`”.

  • Super hacky code, it should be written better and not have keys in code.
  • Some distros need a specific version of php-cli.
  • You cannot easily stop/pause the playback (so do it in small chunks!)
  • The Google Cloud free tier for TTS is very generous but you may want to setup some hard blocks or billing alerts if you plan to use it a lot. I use it for hours a day without cost usually.

Comments & Questions