Android Ultimate Plugin tutorial part 6 – Text to speech

Hello Everyone, today I’m going to show you on how quickly you can use our Text to Speech feature.

Quick Note: this plugin will only work if your android device is Android API 15 or ICE_CREAM_SANDWICH_MR1 or 4.0.3 or 4.0.4 or above if not sorry it will not work, so read this first before purchasing.

for Android API or version info visit this link

http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels

for more information please read this documentation from android developer websites

http://developer.android.com/reference/android/speech/tts/UtteranceProgressListener.html

and here we go, lets start now!

Permission needed on your Android Manifest file without this it will not work or it will produce an error.

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>

First we must get the instance on TextToSpeechPlugin

private TextToSpeechPlugin textToSpeechPlugin= TextToSpeechPlugin.GetInstance();

Next change the SetDebug method to 1 if you want to see  toast debug messages and 0 if  you don’t want to see toast debug messages.

textToSpeechPlugin.SetDebug(0);

Then we need to initialized it

textToSpeechPlugin.Initialize();

If you want to check if TTS data Activity is Available on your device you can call this method

//this will return a bool if true it is available else its not
textToSpeechPlugin.CheckTTSDataActivity()

After initialization we need to setup a Callback listener for TextToSpeech Event

textToSpeechPlugin.OnInit+=OnInit;
textToSpeechPlugin.OnChangeLocale+=OnSetLocale;
textToSpeechPlugin.OnStartSpeech+=OnStartSpeech;
textToSpeechPlugin.OnEndSpeech+=OnEndSpeech;
textToSpeechPlugin.OnErrorSpeech+=OnErrorSpeech;

private void OnInit(int status){
    Debug.Log("[TextToSpeechDemo] OnInit status: " + status);
    
    if(status == 1){
        //init successful
    }else{
        //init Failed
    }
}

private void OnSetLocale(int status){
    Debug.Log("[TextToSpeechDemo] OnSetLocale status: " + status);
    if(status == 1){
        //set locale sucessful
    }else{
        //set locale failed
    }
}

private void OnStartSpeech(string utteranceId){        
    Debug.Log("[TextToSpeechDemo] OnStartSpeech utteranceId: " + utteranceId);
}

private void OnEndSpeech(string utteranceId){
    UpdateStatus("End Speech...");
    Debug.Log("[TextToSpeechDemo] OnDoneSpeech utteranceId: " + utteranceId);        
}

private void OnErrorSpeech(string utteranceId){
    Debug.Log("[TextToSpeechDemo] OnErrorSpeech utteranceId: " + utteranceId);
}

Take Note that OnInit Event you can setup the Volume, Speech Rate, Speech Pitch and Locale by calling this methods

//Sets the locale to US
textToSpeechPlugin.SetLocale(SpeechLocale.US);

//Sets the Volume to max
textToSpeechPlugin.IncreaseMusicVolumeByValue(15);

//Set the Speech Pitch to 0.95f max is 2f
textToSpeechPlugin.SetPitch(.95f);

//Set the Speech Rate to 0.95f max is 2f
textToSpeechPlugin.SetSpeechRate(.95f);

You can now test it by calling SpeakOut Method and pass String to say or  to speak and the Utterance ID , take note this ID is important this ID must always be Unique

string whatToSay = "How are you?";

//this id is important and make it unique every time you used it
string utteranceId  = "test-utteranceId";

textToSpeechPlugin.SpeakOut(whatToSay,utteranceId);	

Then when pausing or resuming yourr application you need to do this to reduce process consumption on device

private void OnApplicationPause(bool val){
   //for text to speech events
   if(textToSpeechPlugin!=null){
          if(hasInit){
              if(val){
                  textToSpeechPlugin.UnRegisterBroadcastEvent();
              }else{
                  textToSpeechPlugin.RegisterBroadcastEvent();
              }
          }
     }
}

then if you are done using it you need to release the Text to Speech Service on Android device by calling this method

textToSpeechPlugin.ShutDownTextToSpeechService();

New feature

To Use Extra Locale

Note: Extra locale is alwasy depends on your device if its available it will work , if not it will now work

public void SpeakUsingExtraLocale(){
		
	//on this example we will use spain locale
	TTSLocaleCountry ttsLocaleCountry = TTSLocaleCountry.SPAIN;
	
	//check if this extra locale is available on the device
	bool isLanguageAvailanble =  textToSpeechPlugin.CheckLocale(ttsLocaleCountry);
		
	if(isLanguageAvailanble){
		//gets the CountryISO code equivalent
		string countryISO2Alpha = textToSpeechPlugin.GetCountryISO2Alpha(ttsLocaleCountry);
		
		//set Extra Locale to Spain
		textToSpeechPlugin.SetLocaleByCountry(countryISO2Alpha);
		
		//Now we test it
		string whatToSay = inputField.text;
		string utteranceId  = "test-utteranceId";
		textToSpeechPlugin.SpeakOut(whatToSay,utteranceId);
	}
}

There’s a lot of changes since the last update, the Text to Speech has a lot more features and for Reference here’s the Updated code that we used on Text To Speech Demo

Note: you need  Input Field, Text, Button and Slider UI on this code to make it run, just drag it on this code inspector

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;

public class TextToSpeechDemo : MonoBehaviour {

	private const string TAG = "[TextToSpeechDemo]: ";

	public InputField inputField;

	public Text statusText;
	public Text ttsDataActivityStatusText;
	public Text localeText;
	public Slider localeSlider;

	public Text pitchText;
	public Slider pitchSlider;

	public Text speechRateText;
	public Slider speechRateSlider;

	public Text volumeText;
	public Slider volumeSlider;

	private SpeechPlugin speechPlugin;
	private TextToSpeechPlugin textToSpeechPlugin;
	private float waitingInterval = 2f;

	private void Awake(){
		speechPlugin = SpeechPlugin.GetInstance();
		speechPlugin.SetDebug(0);
		
		textToSpeechPlugin = TextToSpeechPlugin.GetInstance();
		textToSpeechPlugin.SetDebug(0);
		textToSpeechPlugin.Initialize();
		
		textToSpeechPlugin.OnInit+=OnInit;
		textToSpeechPlugin.OnChangeLocale+=OnSetLocale;
		textToSpeechPlugin.OnStartSpeech+=OnStartSpeech;
		textToSpeechPlugin.OnEndSpeech+=OnEndSpeech;
		textToSpeechPlugin.OnErrorSpeech+=OnErrorSpeech;
	}

	// Use this for initialization
	void Start (){
		CheckTTSDataActivity();
		UpdateSettingsValue();
	}

	private void OnApplicationPause(bool val){
		//for text to speech events
		if(textToSpeechPlugin!=null){
			if(textToSpeechPlugin.isInitialized()){
				if(val){
					textToSpeechPlugin.UnRegisterBroadcastEvent();
				}else{
					textToSpeechPlugin.RegisterBroadcastEvent();
				}
			}
		}
	}

	private void UpdateSettingsValue(){
		UpdateSpeechLocaleSetting();
		UpdatePitchSetting();
		UpdateSpeechRateSetting();
		UpdateVolumeSetting();
	}

	private void WaitingMode(){
		UpdateStatus("Waiting...");
	}

	private void UpdateStatus(string status){
		if(statusText!=null){
			statusText.text = String.Format("Status: {0}",status);	
		}
	}

	private void UpdateTTSDataActivityStatus(string status){
		if(ttsDataActivityStatusText!=null){
			ttsDataActivityStatusText.text = String.Format("TTS Data Activity Status: {0}",status);
		}
	}

	private void UpdateLocale(SpeechLocale locale){
		if(localeText!=null){
			localeText.text = String.Format("Locale: {0}",locale);
			textToSpeechPlugin.SetLocale(locale);
		}
	}

	private void UpdatePitch(float pitch){
		if(pitchText!=null){
			pitchText.text = String.Format("Pitch: {0}",pitch);
			textToSpeechPlugin.SetPitch(pitch);
		}
	}

	private void UpdateSpeechRate(float speechRate){
		if(speechRateText!=null){
			speechRateText.text = String.Format("Speech Rate: {0}",speechRate);
			textToSpeechPlugin.SetSpeechRate(speechRate);
		}
	}

	private void UpdateVolume(int volume){
		if(volumeText!=null){
			volumeText.text = String.Format("Volume: {0}",volume);
			textToSpeechPlugin.IncreaseMusicVolumeByValue(volume);
		}
	}

	public void SpeakOut(){
		if(inputField!=null){
			string whatToSay = inputField.text;
			string utteranceId  = "test-utteranceId";

			if(textToSpeechPlugin.isInitialized()){
				UpdateStatus("Trying to speak...");
				Debug.Log(TAG + "SpeakOut whatToSay: " + whatToSay  + " utteranceId " + utteranceId);
				textToSpeechPlugin.SpeakOut(whatToSay,utteranceId);	
			}
		}
	}

	//checks if speaking
	public bool IsSpeaking(){
		return textToSpeechPlugin.IsSpeaking();
	}

	private void CheckTTSDataActivity(){
		if(textToSpeechPlugin!=null){
			if(textToSpeechPlugin.CheckTTSDataActivity()){
				UpdateTTSDataActivityStatus("Available");
			}else{
				UpdateTTSDataActivityStatus("Not Available");
			}
		}
	}

	public void SpeakUsingAvailableLocaleOnDevice(){

		//on this example we will use spain locale
		TTSLocaleCountry ttsLocaleCountry = TTSLocaleCountry.SPAIN;
		
		//check if available
		bool isLanguageAvailanble =  textToSpeechPlugin.CheckLocale(ttsLocaleCountry);
		
		if(isLanguageAvailanble){
			string countryISO2Alpha = textToSpeechPlugin.GetCountryISO2Alpha(ttsLocaleCountry);
			
			//set spain language
			textToSpeechPlugin.SetLocaleByCountry(countryISO2Alpha);
			Debug.Log(TAG + "locale set," + ttsLocaleCountry.ToString() + "locale is available");

			SpeakOut();
		}else{
			Debug.Log(TAG + "locale not set," + ttsLocaleCountry.ToString() + "locale is  notavailable");
		}
	}

	private void OnDestroy(){
		//call this of your not going to used TextToSpeech Service anymore
		textToSpeechPlugin.ShutDownTextToSpeechService();
	}

	public void OnLocaleSliderChange(){
		Debug.Log(TAG + "OnLocaleSliderChange");
		UpdateSpeechLocaleSetting();
	}

	private void UpdateSpeechLocaleSetting(){
		if(localeSlider!=null){
			SpeechLocale locale = (SpeechLocale)localeSlider.value;
			UpdateLocale(locale);
		}
	}

	private void UpdatePitchSetting(){
		if(pitchSlider!=null){
			float pitch = pitchSlider.value;
			UpdatePitch(pitch);
		}
	}
	
	public void OnPitchSliderChange(){
		Debug.Log(TAG + "OnPitchSliderChange");
		UpdatePitchSetting();
	}
	
	public void OnSpeechRateSliderChange(){
		Debug.Log(TAG + "OnSpeechRateSliderChange");
		UpdateSpeechRateSetting();
	}
	
	private void UpdateSpeechRateSetting(){
		if(speechRateSlider!=null){
			float speechRate = speechRateSlider.value;
			UpdateSpeechRate(speechRate);
		}
	}
	
	public void OnVolumeSliderChange(){
		Debug.Log(TAG + "OnLocaleSliderChange");
		UpdateVolumeSetting();
	}
	
	private void UpdateVolumeSetting(){
		if(volumeSlider!=null){
			int volume = (int)volumeSlider.value;
			UpdateVolume(volume);
		}
	}

	private void OnInit(int status){
		Debug.Log(TAG + "OnInit status: " + status);

		if(status == 1){
			UpdateStatus("init speech service successful!");

			//get available locale on android device
			//textToSpeechPlugin.GetAvailableLocale();

			UpdateLocale(SpeechLocale.US);
			UpdatePitch(1f);
			UpdateSpeechRate(1f);

			CancelInvoke("WaitingMode");
			Invoke("WaitingMode",waitingInterval);
		}else{
			UpdateStatus("init speech service failed!");

			CancelInvoke("WaitingMode");
			Invoke("WaitingMode",waitingInterval);
		}
	}

	private void OnSetLocale(int status){
		Debug.Log(TAG + "OnSetLocale status: " + status);
		if(status == 1){
			//float pitch = Random.Range(0.1f,2f);
			//textToSpeechPlugin.SetPitch(pitch);
		}
	}
	
	private void OnStartSpeech(string utteranceId){
		UpdateStatus("Start Speech...");
		Debug.Log(TAG + "OnStartSpeech utteranceId: " + utteranceId);

		if(IsSpeaking()){
			UpdateStatus("speaking...");
		}
	}
	
	private void OnEndSpeech(string utteranceId){
		UpdateStatus("Done Speech...");
		Debug.Log(TAG + "OnDoneSpeech utteranceId: " + utteranceId);

		CancelInvoke("WaitingMode");
		Invoke("WaitingMode",waitingInterval);
	}
	
	private void OnErrorSpeech(string utteranceId){
		UpdateStatus("Error Speech...");

		CancelInvoke("WaitingMode");
		Invoke("WaitingMode",waitingInterval);

		Debug.Log(TAG + "OnErrorSpeech utteranceId: " + utteranceId);
	}
}

and that’s all, see it’s so super quick and easy to used.

Thank you for reading and Happy Coding 🙂

if the above code does not work or if you encounter any problems or bugs or errors or if you have questions or you don’t get it at all, please email us at gigadrillgames@gmail.com or you can comment below.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.