package cri.sanity;
import cri.sanity.util.*;
import java.util.HashMap;
import android.media.AudioManager;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.*;
public class TTS implements OnInitListener, OnUtteranceCompletedListener
{
public final static int STREAM1_INT = AudioManager.STREAM_NOTIFICATION;
public final static int STREAM2_INT = AudioManager.STREAM_ALARM;
public final static int STREAM3_INT = AudioManager.STREAM_SYSTEM;
private final static String STREAM1_STR = "5"; // string value of STREAM1_INT
private final static String STREAM2_STR = "4"; // string value of STREAM2_INT
private final static String STREAM3_STR = "1"; // string value of STREAM3_INT
protected TextToSpeech tts;
protected String id;
protected int vol = -1;
protected int repeat = 0;
protected int pause;
protected int stream;
protected boolean solo = false;
protected boolean force = false;
protected boolean filter;
protected boolean sms;
protected HashMap<String,String> pars;
public TTS(String text, boolean filterNum, boolean ringOnly, boolean smsSpeak)
{
id = text;
filter = filterNum;
force = !ringOnly;
sms = smsSpeak;
tts = new TextToSpeech(A.app(), this);
}
public final void stop()
{
repeat = 0;
tts.stop();
}
public final void shutdown()
{
stop();
tts.shutdown();
if(vol >= 0) A.audioMan().setStreamVolume(stream, vol, 0);
if(solo)
if(sms) A.audioMan().setStreamSolo(stream, false);
else A.audioMan().setStreamMute(AudioManager.STREAM_RING, false);
}
protected void onError() { A.notify(A.s(R.string.err_tts_init)); }
@Override
public void onInit(int status)
{
if(status != TextToSpeech.SUCCESS) { onError(); off(); return; }
if(filter) {
final CallFilter cf = CallFilter.instance();
if(!cf.includes(id, "tts", true)) return;
if(A.empty(id)) {
id = A.gets(K.TTS_ANONYM);
if(id.length() <= 0) return;
} else {
id = cf.searchName(id);
if(A.empty(id)) {
id = A.gets(K.TTS_UNKNOWN);
if(id.length() <= 0) return;
}
}
}
if(!force && !Dev.isRinging()) return;
// volume setup
String streamStr;
if(A.is(K.TTS_STREAM)) { stream = STREAM2_INT; streamStr = STREAM2_STR; }
else if(!sms) { stream = STREAM1_INT; streamStr = STREAM1_STR; }
else { stream = STREAM3_INT; streamStr = STREAM3_STR; }
final AudioManager audioMan = A.audioMan();
// tone setup
final int tone = A.geti(K.TTS_TONE);
if(tone > 0) tts.setPitch(tone * (1f/100f));
// what and how announce
String keyPrefix, keySuffix;
int vol;
if(sms) {
if(solo = A.is(K.TTS_SOLO)) audioMan.setStreamSolo(stream, true);
keyPrefix = K.TTS_SMS_PREFIX;
keySuffix = K.TTS_SMS_SUFFIX;
repeat = 1;
vol = A.geti(K.TTS_SMS_VOL);
} else {
if(solo = A.is(K.TTS_SOLO)) audioMan.setStreamMute(AudioManager.STREAM_RING, true);
keyPrefix = K.TTS_PREFIX;
keySuffix = K.TTS_SUFFIX;
repeat = A.geti(K.TTS_REPEAT);
pause = A.geti(K.TTS_PAUSE);
vol = A.geti(K.TTS_VOL);
}
if(vol >= 0) {
this.vol = audioMan.getStreamVolume(stream);
audioMan.setStreamVolume(stream, vol, 0);
}
id = (A.gets(keyPrefix) + id + A.gets(keySuffix)).trim();
// finally speak!
pars = new HashMap<String,String>();
pars.put(Engine.KEY_PARAM_UTTERANCE_ID, streamStr);
pars.put(Engine.KEY_PARAM_STREAM , streamStr);
tts.setOnUtteranceCompletedListener(this);
tts.speak(id, TextToSpeech.QUEUE_FLUSH, pars);
}
@Override
public void onUtteranceCompleted(String idUtter)
{
if(--repeat>0 && (force || Dev.isRinging())) {
tts.playSilence(pause, TextToSpeech.QUEUE_ADD, null);
tts.speak (id , TextToSpeech.QUEUE_ADD, pars);
} else if(solo) {
new Task(){ public void run(){
A.audioMan().setStreamMute(AudioManager.STREAM_RING, solo = false);
}}.exec(Conf.TTS_UNMUTE_DELAY);
} else off();
}
private void off()
{
if(!sms) return;
shutdown();
}
}