Detect end of Speak in freeTTS for java - java

I am using freeTTS library for converting text to speech. I am able to program my code using this library where i can play the speech for a particular text using following code:
Voice voice = VoiceManager.getInstance().getVoice("kevin16");
if (voice != null) {
voice.allocate();
}
voice.speak("Hello world");
Is there a way using which i can get a callback when the tts lib has completed the speak process?

I found the answer myself.. we don't need a callback when the lib has completed the speak process. the control goes on the next line only when speak process ends.
that's how i did it:
Thread t = new Thread() {
#Override
public void run() {
super.run();
try {
voice = initializeTTS(); // a func to initialize TTS lib.
voice.speak("Hello world");
// do whatever you want to do from here only.
} catch (Exception e) {
e.printStackTrace();
}
}
};
t.start();

Related

how to run biometric prompt on UI thread and merge back to original thread?

I'm trying to use biometric authentication. However my setup is complex, basically I'm trying to keep the function sync because it is invoked from C++:
User interaction -> C++ function -> Java JNI function -> Biometric Authenticate <- needs to go back
Skipping the C++ code, it calls via JNI the following function:
public String getSeed() throws ExecutionException, InterruptedException {
Context reactContext = this.getReactApplicationContext();
Activity act = this.getCurrentActivity();
act.runOnUiThread(new Runnable() {
#Override
public void run() {
Executor executor = ContextCompat.getMainExecutor(reactContext);
BiometricPrompt.AuthenticationCallback authenticationCallback = new WalletCoreAuthenticationCallback();
BiometricPrompt.PromptInfo info = BiometricUtils.createBiometricPromptInfo("ROPO", "ROPO", "ROPO");
BiometricPrompt prompt = new BiometricPrompt((FragmentActivity) act, executor, authenticationCallback);
prompt.authenticate(info);
}
});
// Here I need a Handler.merge or something similar to pause the execution while the user authenticates and then I retrieve the answer.
try {
return keyStore.getPlainText(getReactApplicationContext(), SEED_KEY);
} catch (FileNotFoundException fnfe) {
Log.w(Constants.TAG, "Could not get seed (file not found)");
return null;
} catch (Exception e) {
Log.w(Constants.TAG, "Could not get seed");
return null;
}
}
The idea is: if the user fails to authenticate I do not fetch the sensitive information (keyStore.getPlainText).
The problem however lies in the fact that the BiometricPrompt needs to be called from the main (UI) thread. I'm an Android noob, so far that was the best I could come up with, it in effect prompts the user for authentication, but I do not know how to pause/join the main java function call, until the user has authenticated.
Is this even possible?
Found one way to make it work that is simple enough, using a Mutex.
Each call to the parent Java creates a mutex (I also added one field to the WalletCoreAuthenticationCallback object to hold the response). Then I release the mutex on inside the calls, and just check for the stored response.
final Semaphore mutex = new Semaphore(0);
// This object now internally saves the response of the authentication callback
WalletCoreAuthenticationCallback authenticationCallback = new WalletCoreAuthenticationCallback(mutex);
act.runOnUiThread(new Runnable() {
#Override
public void run() {
Executor executor = ContextCompat.getMainExecutor(reactContext);
BiometricPrompt.PromptInfo info = BiometricUtils.createBiometricPromptInfo("ROPO", "ROPO", "ROPO");
BiometricPrompt prompt = new BiometricPrompt((FragmentActivity) act, executor, authenticationCallback);
prompt.authenticate(info);
}
});
try {
mutex.acquire();
} catch (InterruptedException e) {
Log.e(Constants.TAG, "INterruped mutex exception");
}
if(!authenticationCallback.isAuthenticated) {
return null;
}
This however has one side-effect, basically locking the calling thread, I'm calling this from a React Native application, which basically means it freezes the app. However since Auth is such a vital step, it's ok to freeze the app since the user cannot continue without authentication anyways.
If anybody has a more elegant solution, happy to check it out.

Share Process / Thread

I am facing a problem regarding Process and Threads. My Scenario is:
My Java Application, call it 'Starter-App', starts another exe Application (Diagnosis.exe) with ProcessBuilder within a named Thread:
Thread startGXThread = new Thread(new Runnable() {
#Override
public void run() {
try {
...
File gxExe = new File(pathToGX); // Path to Diagnosis.exe
gxp = pb.start();
gxp.waitFor();
} catch (IOException e) {
LOG.error("Can't start module");
LOG.error(e.getMessage(), e);
} catch (InterruptedException e) {
LOG.debug("thread interrupted. Destroy process");
LOG.debug(e.getMessage(), e);
if (gxp != null) {
gxp.destroy();
LOG.debug("process exit value: " + gxp.exitValue());
}
}
}
}, "diag_thrd");
Afterwards a jetty webserver (ServiceWebApp) is started with a webapp.
start chromium and 'Starter-App' listen when its closed.
Once chromium closes 'Starter-App' recognizes this and stops jetty and also terminate the startet application.Diagnosis.exe. This is done by:
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
stopAsync();
}
});
public static void stopAsync() {
Thread diag = getThread("diag_thrd");
if (diag != null) {
diag.interrupt();
}
if (gxp != null) {
gxp.destroy();
LOG.debug("process exit value: " + gxp.exitValue());
}
}
Question:
I need to be able to stop the startet Diagnosis.exe from within the webapp and start it again, while still be able to destroy/shutdown the Diagnosis.exe once chromium stops within 'Starter-App'.
I hope I could explain my problem and hope for suggestions.
Building on Anands answer, I think you need some form of IPC between the Diagnosis.exe and your Starter-App, using websockets, or a number of other options, for some ideas: How to have 2 JVMs talk to one another.
The webapp would send a request for restarting Diagnosis.exe to the Starter-App and the Starter-App would stay in charge of managing the application trio at all time.
I think there is a solution but a but tricky to implement.
You can always use *nix api's like ps kill #pid as explained in the example here Killing a process using Java
But your webserver has to know which PID's to look for. The only option I see to implement such thing is using sockets or webservices. So you keep track of what is the current pid of Diagnosis.exe process, and use that Id before killing.

JavaFX GUI stuck when DataInputStream is in while loop

I've been trying to figure it out for some time,
I'm trying to write a chat - server app, just for learning.
I have an obstacle that I cannot understand,
The while loop inside of the GUI class freeze, but just when it trying to read:
public void run(){
Platform.runLater(() -> {
do {
try {
msg = getFromServer.readUTF(); // <--- freeze GUI
chatWindow.appendText(msg);
} catch (IOException e) {
e.printStackTrace();
}
} while (true);
});
}
You can see that it's running in a thread, but i did try to run it in other ways...
Only the DataInputStream make it stuck,
msg = getFromServer.readUTF();
And this it the methud that it's coming from:
public void connectToServer(){
try {
serverConectionState = new Socket("127.0.0.1", 6789);
getFromServer = new DataInputStream(serverConectionState.getInputStream());
sendToServer = new DataOutputStream(serverConectionState.getOutputStream());
onlineOffline.setText("Online");
onlineOffline.setTextFill(javafx.scene.paint.Color.web("#0076a3"));
} catch (IOException ex){
chatWindow.appendText("server connection fail\n");
}
}
This class, is the Controller.class - if it's make any diffrent.
My first question in stackoverflow, after a lot of help from the community.
Thanks in advance
I'm assuming the run method you showed is part of a Runnable that is executed in a background thread.
You are running the entire loop on the FX Application Thread (by using Platform.runLater()). So you block that thread and prevent it from repainting. You should run only the UI updates on the FX Application Thread:
public void run(){
do {
try {
String msg = getFromServer.readUTF(); // <--- freeze GUI
Platform.runLater(() -> chatWindow.appendText(msg));
} catch (IOException e) {
e.printStackTrace();
}
} while (true);
}
instead of using platform.runlater you should use java task, so that you can run the code in different thread, without freezing the UI thread

Using AudioClip in Java freezes the program terribly?

I don't have any code to show in particular to link because this is quite a general question...you see, I made a small game applet with 8 AudioClip variables, and these were supposed to play every time a certain action was taken by the user. Ex: Player clicks = Shooting sound plays. The thing is, the moment I added these AudioClip files my program just freezes terribly and becomes borderline unplayable if the freezing is particularly bad.
The simple way I did it is here (From the book, actually)
AudioClip playerShooting;
playerShooting=getAudioClip(getDocumentBase(),"PlayerShooting.wav");
Then I would just use the following whenever the user clicked:
playerShooting.play():
My program worked smoothly before I added these wav files. They aren't even that long. Where did I go wrong here, and, how can I remove the random freezing?
EDIT:
This is the code I am running:
public void mouseClicked(MouseEvent e)
{
if(playerAlive)
{
timeShotsAfter=System.currentTimeMillis();
if((timeShotsAfter-timeShotsBefore)>=100)
{
if(shotIndex<10)
{
playerShooting(); //Here is where I call the function
shotFiredX[shotIndex]=currentX;
shotFiredY[shotIndex]=currentY;
shotSize[shotIndex]=20;
}
if(shotIndex<10)
shotIndex++;
else
shotIndex=0;
timeShotsBefore=System.currentTimeMillis();
}
else{}
toggleShooting=false;
}
}
This is the function:
public void playerShooting()
{
new Thread(
new Runnable() {
public void run() {
try {
playerShooting.play();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
I was having the same problem a while back. What I did to solve my problem was update to JDK 8. In previous JDK versions, audio files appear to have been an afterthought and can be buggy. If you are still having problems, JDK 8 has the ability to play mp3 files which are significantly smaller than wav (you may want to try this). Make sure you use sound.stop() when your clips are done as this might free up some memory.
Play the audio clip in another thread?
EDIT:
new Thread(
new Runnable() {
public void run() {
try {
playerShooting.play():
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
Edit:
I'm not quite sure if this part is correct:
getAudioClip(getDocumentBase(),"PlayerShooting.wav");
Try adding System.out.println(getDocumentBase()); to see whether the location is correct.

Decompressing .zip file in service makes app freeze until it finish decompressing, why?

I implemented the code to work with a async task and it works perfectly, but if user exits app it will get killed very fast, so I decided to try it with a service, it works perfectly, but it makes the app freeze.
So here's my decompress class:
public class Decompress {
private String _zipFile;
private String _location;
ZipEntry ze = null;
public Decompress(String zipFile, String location) {
_zipFile = zipFile;
_location = location;
_dirChecker("");
}
public void unzip() {
try {
FileInputStream fin = new FileInputStream(_zipFile);
ZipInputStream zin = new ZipInputStream(fin);
while ((ze = zin.getNextEntry()) != null) {
//Log.v("Decompress", "Unzipping " + ze.getName());
if(ze.isDirectory()) {
_dirChecker(ze.getName());
} else {
FileOutputStream fout = new FileOutputStream(_location + ze.getName());
for (int c = zin.read(); c != -1; c = zin.read()) {
fout.write(c);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
} catch(Exception e) {
Log.e("Decompress", "unzip", e);
}
}
private void _dirChecker(String dir) {
File f = new File(_location + dir);
if(!f.isDirectory()) {
f.mkdirs();
}
}
}
Here is my service call for unzip:
#Override
public void onStart(Intent intent, int startid)
{
try
{
zipFile = intent.getStringExtra("zipFile");
zipLocation = intent.getStringExtra("unzipLocation");
String fileS = intent.getStringExtra("file");
file = new File(fileS);
fin = new FileInputStream(zipFile);
zin = new ZipInputStream(fin);
while (zin.getNextEntry() != null) {
numFiles++;
}
}
catch (FileNotFoundException e)
{}
catch (IOException e)
{}
d = new Decompress(zipFile, zipLocation);
d.unzip();
}
Now here's how I ussed to call it with async task:
#Override
protected Void doInBackground(Void... params) {
d.unzip();
return null;
}
now my question is, why with async tsk my app don't get freeze and it will keep unzipping letting me cancel it with a button, but with service it makes the app lags? I even got a message about MyApp not responding, Would you like to close it?
EDIT: My service call for Start
#Override
protected Void doInBackground(Void... params) {
Intent intent = new Intent(DownloadFiles.this, MyService.class);
String unzipLocation = Environment.getExternalStorageDirectory().toString()+"/Android/data/";
String zipFile = Environment.getExternalStorageDirectory().toString()+"/Android/data/test.zip";
intent.putExtra("zipFile", zipFile);
intent.putExtra("unzipLocation", unzipLocation);
intent.putExtra("file", Environment.getExternalStorageDirectory().toString()+"/Android/data/");
startService(intent);
try {
FileInputStream fin = new FileInputStream(zipFile);
ZipInputStream zin = new ZipInputStream(fin);
while (zin.getNextEntry() != null) {
numFiles++;
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
Services also run in the UI (main) Thread, so you need to implement an AsyncTask or sepearate Thread approach there too.
The docs say it all under What is a Service?
A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors).
Edit: Note that if you start a Service from a background thread, the service is still running in the main thread. As per this SO answer. This should make sense as the docs say:
When a Service component is actually created, for either of these
reasons, all that the system actually does is instantiate the
component and call its onCreate() and any other appropriate callbacks
on the main thread. It is up to the Service to implement these with
the appropriate behavior, such as creating a secondary thread in which
it does its work.
This ultimately means that you should always implement a seperate AsyncTask/Thread approach in Services as well, no matter how you start the Service.
Try running it in a separate background thread if you don't need the onPreExecute() and onPostExecute() methods of the AsyncTask, but still have a problem with the operation blocking the UI Thread.
Thread t = new Thread() {
public void run() {
d = new Decompress(zipFile, zipLocation);
d.unzip();
}
};
t.start();
Simply starting the service from a background thread doesn't mean that it will be started off of the main UI thread. That is the default for its start, and you must create a new thread within the Service to get around it.
Expanding on A--C's point:
You need to create the background thread to unzip the file from inside the service, because the service is created and runs on the main thread, whether you start it inside another thread or not.
You basically need to do in the service exactly what you did outside the service (i.e. put the 'unzip' call inside the AsyncTask, and execute the task).
(Addendum)
The point of using a service is not to create a separate thread, but rather to split time-consuming processing from a UI-based application. It means that the UI can be destroyed by the OS and the resources recovered, and all the while the service is still running.
Thus, the decision about whether to use an AsyncTask (or thread) within the app itself vs within a service is really about whether the action should continue independently of the app interface or not. Restoring apps using TitaniumBackup is a good example of this: once you've started a restore, the app UI isn't really needed any more.

Categories

Resources