Page updated Jan 16, 2024

Text-to-speech

Set up the backend

Run amplify add predictions, then use the following answers:

? Please select from one of the categories below `Convert` ? What would you like to convert? (Use arrow keys) `Generate speech audio from text` ? Provide a friendly name for your resource `speechGenerator` ? What is the source language? (Use arrow keys) `US English` ? Select a speaker (Use arrow keys) `Joanna - Female` ? Who should have access? (Use arrow keys) `Auth and Guest users`
1? Please select from one of the categories below
2 `Convert`
3? What would you like to convert? (Use arrow keys)
4 `Generate speech audio from text`
5? Provide a friendly name for your resource
6 `speechGenerator`
7? What is the source language? (Use arrow keys)
8 `US English`
9? Select a speaker (Use arrow keys)
10 `Joanna - Female`
11? Who should have access? (Use arrow keys)
12 `Auth and Guest users`

Run amplify push to create the resources in the cloud.

Working with the API

Open MainActivity.java and add the following code:

private final MediaPlayer mp = new MediaPlayer(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Amplify.Predictions.convertTextToSpeech( "I like to eat spaghetti", result -> playAudio(result.getAudioData()), error -> Log.e("MyAmplifyApp", "Conversion failed", error) ); } private void playAudio(InputStream data) { File mp3File = new File(getCacheDir(), "audio.mp3"); try (OutputStream out = new FileOutputStream(mp3File)) { byte[] buffer = new byte[8 * 1_024]; int bytesRead; while ((bytesRead = data.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); } mp.reset(); mp.setOnPreparedListener(MediaPlayer::start); mp.setDataSource(new FileInputStream(mp3File).getFD()); mp.prepareAsync(); } catch (IOException error) { Log.e("MyAmplifyApp", "Error writing audio file", error); } }
1private final MediaPlayer mp = new MediaPlayer();
2
3@Override
4protected void onCreate(Bundle savedInstanceState) {
5 super.onCreate(savedInstanceState);
6 setContentView(R.layout.activity_main);
7
8 Amplify.Predictions.convertTextToSpeech(
9 "I like to eat spaghetti",
10 result -> playAudio(result.getAudioData()),
11 error -> Log.e("MyAmplifyApp", "Conversion failed", error)
12 );
13}
14
15private void playAudio(InputStream data) {
16 File mp3File = new File(getCacheDir(), "audio.mp3");
17
18 try (OutputStream out = new FileOutputStream(mp3File)) {
19 byte[] buffer = new byte[8 * 1_024];
20 int bytesRead;
21 while ((bytesRead = data.read(buffer)) != -1) {
22 out.write(buffer, 0, bytesRead);
23 }
24 mp.reset();
25 mp.setOnPreparedListener(MediaPlayer::start);
26 mp.setDataSource(new FileInputStream(mp3File).getFD());
27 mp.prepareAsync();
28 } catch (IOException error) {
29 Log.e("MyAmplifyApp", "Error writing audio file", error);
30 }
31}

Open MainActivity.kt and add the following code:

private val mp = MediaPlayer() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) convertTextToSpeech() } private fun convertTextToSpeech() { Amplify.Predictions.convertTextToSpeech("I like to eat spaghetti!", { playAudio(it.audioData) }, { Log.e("MyAmplifyApp", "Failed to convert text to speech", it) } ) } private fun playAudio(data: InputStream) { val mp3File = File(cacheDir, "audio.mp3") try { FileOutputStream(mp3File).use { out -> val buffer = ByteArray(8 * 1024) var bytesRead: Int while (data.read(buffer).also { bytesRead = it } != -1) { out.write(buffer, 0, bytesRead) } mp.reset() mp.setOnPreparedListener { obj: MediaPlayer -> obj.start() } mp.setDataSource(FileInputStream(mp3File).fd) mp.prepareAsync() } } catch (error: IOException) { Log.e("MyAmplifyApp", "Error writing audio file.") } }
1private val mp = MediaPlayer()
2
3override fun onCreate(savedInstanceState: Bundle?) {
4 super.onCreate(savedInstanceState)
5 setContentView(R.layout.activity_main)
6 convertTextToSpeech()
7}
8
9private fun convertTextToSpeech() {
10 Amplify.Predictions.convertTextToSpeech("I like to eat spaghetti!",
11 { playAudio(it.audioData) },
12 { Log.e("MyAmplifyApp", "Failed to convert text to speech", it) }
13 )
14}
15
16private fun playAudio(data: InputStream) {
17 val mp3File = File(cacheDir, "audio.mp3")
18 try {
19 FileOutputStream(mp3File).use { out ->
20 val buffer = ByteArray(8 * 1024)
21 var bytesRead: Int
22 while (data.read(buffer).also { bytesRead = it } != -1) {
23 out.write(buffer, 0, bytesRead)
24 }
25 mp.reset()
26 mp.setOnPreparedListener { obj: MediaPlayer -> obj.start() }
27 mp.setDataSource(FileInputStream(mp3File).fd)
28 mp.prepareAsync()
29 }
30 } catch (error: IOException) {
31 Log.e("MyAmplifyApp", "Error writing audio file.")
32 }
33}

Open MainActivity.kt and add the following code:

private val mp = MediaPlayer() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) convertTextToSpeech() } private fun convertTextToSpeech() = activityScope.launch { val text = "I like to eat spaghetti!" try { val result = Amplify.Predictions.convertTextToSpeech(text) playAudio(result.audioData) } catch (error: PredictionsException) { Log.e("MyAmplifyApp", "Failed to convert text to speech", error) } } private fun playAudio(data: InputStream) { val mp3File = File(cacheDir, "audio.mp3") try { FileOutputStream(mp3File).use { out -> val buffer = ByteArray(8 * 1024) var bytesRead: Int while (data.read(buffer).also { bytesRead = it } != -1) { out.write(buffer, 0, bytesRead) } mp.reset() mp.setOnPreparedListener { obj: MediaPlayer -> obj.start() } mp.setDataSource(FileInputStream(mp3File).fd) mp.prepareAsync() } } catch (error: IOException) { Log.e("MyAmplifyApp", "Error writing audio file.") } }
1private val mp = MediaPlayer()
2
3override fun onCreate(savedInstanceState: Bundle?) {
4 super.onCreate(savedInstanceState)
5 setContentView(R.layout.activity_main)
6 convertTextToSpeech()
7}
8
9private fun convertTextToSpeech() = activityScope.launch {
10 val text = "I like to eat spaghetti!"
11 try {
12 val result = Amplify.Predictions.convertTextToSpeech(text)
13 playAudio(result.audioData)
14 } catch (error: PredictionsException) {
15 Log.e("MyAmplifyApp", "Failed to convert text to speech", error)
16 }
17}
18
19private fun playAudio(data: InputStream) {
20 val mp3File = File(cacheDir, "audio.mp3")
21 try {
22 FileOutputStream(mp3File).use { out ->
23 val buffer = ByteArray(8 * 1024)
24 var bytesRead: Int
25 while (data.read(buffer).also { bytesRead = it } != -1) {
26 out.write(buffer, 0, bytesRead)
27 }
28 mp.reset()
29 mp.setOnPreparedListener { obj: MediaPlayer -> obj.start() }
30 mp.setDataSource(FileInputStream(mp3File).fd)
31 mp.prepareAsync()
32 }
33 } catch (error: IOException) {
34 Log.e("MyAmplifyApp", "Error writing audio file.")
35 }
36}

Open MainActivity.java and add the following code:

private final MediaPlayer mp = new MediaPlayer(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RxAmplify.Predictions.convertTextToSpeech("I like to eat spaghetti") .subscribe( result -> playAudio(result.getAudioData()), error -> Log.e("MyAmplifyApp", "Conversion failed", error) ); } private void playAudio(InputStream data) { File mp3File = new File(getCacheDir(), "audio.mp3"); try (OutputStream out = new FileOutputStream(mp3File)) { byte[] buffer = new byte[8 * 1_024]; int bytesRead; while ((bytesRead = data.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); } mp.reset(); mp.setOnPreparedListener(MediaPlayer::start); mp.setDataSource(new FileInputStream(mp3File).getFD()); mp.prepareAsync(); } catch (IOException error) { Log.e("MyAmplifyApp", "Error writing audio file", error); } }
1private final MediaPlayer mp = new MediaPlayer();
2
3@Override
4protected void onCreate(Bundle savedInstanceState) {
5 super.onCreate(savedInstanceState);
6 setContentView(R.layout.activity_main);
7
8 RxAmplify.Predictions.convertTextToSpeech("I like to eat spaghetti")
9 .subscribe(
10 result -> playAudio(result.getAudioData()),
11 error -> Log.e("MyAmplifyApp", "Conversion failed", error)
12 );
13}
14
15private void playAudio(InputStream data) {
16 File mp3File = new File(getCacheDir(), "audio.mp3");
17
18 try (OutputStream out = new FileOutputStream(mp3File)) {
19 byte[] buffer = new byte[8 * 1_024];
20 int bytesRead;
21 while ((bytesRead = data.read(buffer)) != -1) {
22 out.write(buffer, 0, bytesRead);
23 }
24 mp.reset();
25 mp.setOnPreparedListener(MediaPlayer::start);
26 mp.setDataSource(new FileInputStream(mp3File).getFD());
27 mp.prepareAsync();
28 } catch (IOException error) {
29 Log.e("MyAmplifyApp", "Error writing audio file", error);
30 }
31}

This example works on all supported versions of Android. Android API 23 added support for MediaDataSource, which allows for InputStream from Amplify to be read directly without writing to a file.

As a result of running this code, you will hear audio of the text being emitted from your device.