Text-to-Speech for Linux

Text-to-Speech for Linux Featured Image

Those of us with dyslexia know that writing great emails (or any other written communication for that matter!) can be tricky at the best of times.

Being able to check 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 aloud any selected text.

You can even get real human-sounding voices, rather than programmatic-robotic voices from back-in-the-day, they use real inflections and pick up on grammar too. This sort of tool is called “Advanced TTS” or Advanced Text-to-Speech, and it’s great for checking the flow of your emails.

However, a great TTS is harder to get on a Linux desktop. There are a few easy-to-install TTS applications on the various Linux repositories, but they’re old-school at best (think 1990s Sci-Fi robot tones). These sorts of TTS apps are not the most helpful for checking human inflections and grammar in a chunk of text.

There are some great Firefox web-browser add-ons for using advanced AI-based TTS for selected text on webpages. However, these add-ons won’t help outside the web-browser, and you may be sacrificing your privacy to the operators of the add-on as they sit between you and the advanced TTS providers like Google Cloud.

Thankfully, all the big-players in the cloud now offer their own TTS or Text-to-speech APIs. This means that we can use them pretty easily on Linux, with just hacky script, some dependencies, 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 a temporary audio file and play it back to you.

Step 1. Set up 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. i.e. php, xclip, play.

e.g. on Debian, Ubuntu etc sudo apt install php-cli php-curl xclip sox libsox-fmt-mp3

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. Set up 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 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 aloud, 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 set up 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

Reply by email to send in your thoughts.

Comments may be featured here unless you say otherwise. You can encrypt emails with PGP too, learn more about my email replies here.

PGP: 9ba2c5570aec2933970053e7967775cb1020ef23