Using Microsoft Speech API text-to-speech in java for Android? - java

I am trying to use Microsoft Speech API text-to-speech, in my java project for Android. It's not working. Is it possible to use this API in java?
The speech-to-text is working, I found the Quickstart and had no problem using it.
However, there is no java example for text-to-speech, only in C#, C++ (Windows) and C++ (Linux).
I tried to adapt the code in java, but it's not working and I have no idea why.
public void onTextToSpeechButtonClicked(View v) {
TextView txt = (TextView) this.findViewById(R.id.texttospeech); // 'texttospeech' is the ID of my text view
try {
// THIS LINE ISN'T WORKING
com.microsoft.cognitiveservices.speech.internal.SpeechConfig config = com.microsoft.cognitiveservices.speech.internal.SpeechConfig.FromSubscription(speechSubscriptionKey, serviceRegion);
config.SetSpeechRecognitionLanguage("fr-FR");
assert(config != null);
// Creates a speech synthesizer using the default speaker as audio output
SpeechSynthesizer synthesizer = SpeechSynthesizer.FromConfig(config);
assert(synthesizer != null);
SpeechSynthesizer synthesizer1 = SpeechSynthesizer.FromConfig(config);
SpeechSynthesisResult result = synthesizer.SpeakTextAsync(txt.toString()).Get();
// Checks result
if (result.getReason().equals(ResultReason.SynthesizingAudioCompleted)){
txt.setText("The text has been said.");
}
else if (result.getReason().equals(ResultReason.Canceled)){
SpeechSynthesisCancellationDetails cancellation = SpeechSynthesisCancellationDetails.FromResult(result);
txt.setText("CANCELED: Reason ="+cancellation.getReason());
if(cancellation.getReason().equals(CancellationReason.Error)){
txt.append("ErrorCode = "+cancellation.getErrorCode()+" / ErrorDetails = "+cancellation.getErrorDetails()+" / Did you update the subscription info ?");
}
}
synthesizer.delete();
} catch (Exception ex) {
Log.e("SpeechSDKDemo", "unexpected " + ex.getMessage());
assert(false);
}
}
What I have in the log is that:
E/ples.quickstar: No implementation found for void com.microsoft.cognitiveservices.speech.internal.carbon_javaJNI.swig_module_init() (tried Java_com_microsoft_cognitiveservices_speech_internal_carbon_1javaJNI_swig_1module_1init and Java_com_microsoft_cognitiveservices_speech_internal_carbon_1javaJNI_swig_1module_1init__)
D/AndroidRuntime: Shutting down VM
--------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.microsoft.cognitiveservices.speech.samples.quickstart, PID: 4106
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:389)
at android.view.View.performClick(View.java:6597)
at...
Can someone help me?

I searched if Microsoft Speech API is compatible with Java and the answer is no. It also seems a little obvious because Microsoft = C++ / C# which is nothing similar to Java.
In addition, in your post you mentionned the Quickstart. This uses the Cognitive Services Speech SDK and not Microsoft SAPI.
However, there are native Java libraries allowing Text-To-Speech. Here is a post related to Text-To-Speech engines. Here is more information about it.
There are also libraries available for Android:
Using the Text-To-Speech engine
Android documentation

I would suggest an alternative. Why not try to use windows tts instead by sending the text to a powershell command which can be executed from java code:
String[] command = {"powershell.exe", "Add-Type -AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SpeechSynthesizer).Speak('" + message +"');"};
try {
ProcessBuilder pb = new ProcessBuilder(command);
Process process = pb.start();
System.out.format("Process exit code: %d", process.waitFor());
ProcessInputOutput.readStdnOutput(process);
}
catch (Exception e){
e.printStackTrace();
}

Related

Java AWS Lambda - Jmagick

I am trying to use Jmagick in my AWS Lambda Java code. So far I have done following:
Compiled ImageMagick and Jmagick source on Amazon Linux EC2 and generated .so libraries.
Wrote following code for my Java Lambda on my Windows PC (using ImageMagick and Jmagick for windows).
public String handleRequest(Object input, Context context)
{
System.setProperty("jmagick.systemclassloader","false");
try {
ImageInfo newImageiInfo=new ImageInfo();
newImageiInfo.setFileName("/tmp/oldImage.jpg");
newImageiInfo.setSize("512x512");
newImageiInfo.setUnits(ResolutionType.PixelsPerInchResolution);
newImageiInfo.setColorspace(ColorspaceType.RGBColorspace);
newImageiInfo.setBorderColor(PixelPacket.queryColorDatabase("red"));
newImageiInfo.setDepth(8);
MagickImage addTextImage = new MagickImage();
addTextImage.allocateImage(newImageiInfo);
addTextImage.setYResolution(480);
addTextImage.setXResolution(640);
addTextImage.writeImage(newImageiInfo);
DrawInfo aInfo = new DrawInfo(newImageiInfo);
aInfo.setFont("Arial");
aInfo.setTextAntialias(true);
aInfo.setText("JMagick Tutorial");
addTextImage.annotateImage(aInfo);
addTextImage.setFileName("/tmp/newImage.jpg");
addTextImage.writeImage(newImageiInfo);
}catch (MagickException e) {
e.printStackTrace();
}
UploadtoS3("/tmp/newImage.jpg"); // a simple method for Uploading
return "Hello from Lambda!";
}
Packaged the .so libraries into Lambda deployment package (I am using jar as deployment package).
The code works fine on my PC, but on Lambda it is not generating any image file. Logically there should be one generated at /tmp/newImage.jpg. Also I cannot see any Exception/error in the Lambda logs which.
Is there anything I am doing wrong? What can I do further? If anyone especially with experience in ImagaMagick and Lambda could help, I will be thankful.

Gphoto2 fails to save image when captured via Java .jar (Raspberry Pi - Raspbian)

I'm writing a GUI application which takes an image from a camera using the gphoto2 package in Raspbian. When I enter the command gphoto2 --capture-image-and-download into the terminal manually, the camera takes an image and saves it to the current folder. However, when I execute the same command via a button in my Java code, the camera takes the image but it is not saved. Redirected output from bash says that the image is saved to the camera (which I could cope with) but the image is neither saved to the camera or to the current directory, in fact, it doesn't appear to be saved at all.
Here is the button code:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
Runtime com = getRuntime();
try {
//Reset USB Device to prevent warnings
Process mand = com.exec("../../../usbreset /dev/bus/usb/001/005");
//Capture image
Process get = com.exec("gphoto2 --capture-image-and-download");
Send Bash output(s) to text area
BufferedReader in1 = new BufferedReader(new InputStreamReader(mand.getInputStream()));
BufferedReader in2 = new BufferedReader(new InputStreamReader(get.getInputStream()));
String inputLine1;
while ((inputLine1 = in1.readLine()) != null) {
msgArea.append(inputLine1 + "\n");
}
in1.close();
String inputLine2;
while ((inputLine2 = in2.readLine()) != null) {
msgArea.append(inputLine2 + "\n");
}
in2.close();
} catch (IOException ex) {
Logger.getLogger(Home.class.getName()).log(Level.SEVERE, null, ex);
}
}
I can't work out if the problem resides in my bash commands or my Java code. I've tried both with and without a card present in the camera, and have also tried with a specified filename for the image, all to no avail. I'm not sure if it's significant but the Pi is being controlled via PuTTY ssh with X11 forwarding on a Debian laptop. Java is written in Netbeans 8. GPhoto2 is version 2.4.14 and the camera is a Canon EOS 1100D, though I suspect this last fact is surplus to requirements.
I'd be really grateful if anyone could help - this is an important part of my final year project at University, so I must be able to get it sorted soon!
Thanks in advance,
Guy
OK I've answered my own question.
The output from bash was only being sent up until the point the picture was taken. After that, terminal output was not being sent and so I was missing an error, a Permission Denied jobbie. So the solution was just to add a sudo before the gphoto2 command. Simple solution in the end but a frustrating situation!

How to trace the route of a host using Java? [duplicate]

Java does not have primitives for ICMPs and traceroute. How to overcome this? Basically I'm building code that should run in *nix and Windows, and need a piece of code that will run in both platforms.
Here's what I wrote today to "implement" the trace route command in Java. I've only tested in windows but it should work in Linux as well although there are several traceroute tools available for Linux so most likely there need to be some checks for the existence of those programs.
public class NetworkDiagnostics{
private final String os = System.getProperty("os.name").toLowerCase();
public String traceRoute(InetAddress address){
String route = "";
try {
Process traceRt;
if(os.contains("win")) traceRt = Runtime.getRuntime().exec("tracert " + address.getHostAddress());
else traceRt = Runtime.getRuntime().exec("traceroute " + address.getHostAddress());
// read the output from the command
route = convertStreamToString(traceRt.getInputStream());
// read any errors from the attempted command
String errors = convertStreamToString(traceRt.getErrorStream());
if(errors != "") LOGGER.error(errors);
}
catch (IOException e) {
LOGGER.error("error while performing trace route command", e);
}
return route;
}
You'll need the jpcap library (maybe the SourceForge jpcap is working too) and use the ICMPPacket class to implement the desired functionality.
Here is the Java traceroute implementation using the jpcap library .

Can Eclipse for Java and Eclipse for WEBMethods be on the same hard drive?

I am new to WEBMethods. I have been working on a Java service for a project. I really need to be able to write some code in regular Java for some quick testing of reading in a simple text expression with some regular expressions. Nothing at all that fancy with the Java part. But eclipse currently is set up for WEBMethods and I need to be in a regular Java mode for Eclipse (If there is such a thing). At home I have the standard eclipse version and have no trouble writting code. But at work I have WEBMethods installed in the Eclipse (Software AG Designer). I think that if I can write the code in regular Java then I can just copy and paste it into the WEBMethods Java services and set up the INPUT and OUTPUT variables and it should work. But currently I cannot find a way to just write Java code like I do from my home computer.
Question: How can I write just a regular Java program (classes, packages, ...etc...) with a machine with WEBMethods installed? Do I have to install another session of Eclipse on my hard drive? (I tried this a while back and there was an issue with having more than one session of Eclipse on the machine).
Java Web Services Code:
package DssAccessBackup.services.flow;
import com.wm.data.*;
import com.wm.util.Values;
import com.wm.app.b2b.server.Service;
import com.wm.app.b2b.server.ServiceException;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public final class new_javaService_SVC
{
/**
* The primary method for the Java service
*
* #param pipeline
* The IData pipeline
* #throws ServiceException
*/
public static final void new_javaService(IData pipeline)
throws ServiceException {
// pipeline
IDataCursor pipelineCursor = pipeline.getCursor();
String inputFileName = IDataUtil.getString( pipelineCursor, "inputFileName" );
pipelineCursor.destroy();
// pipeline
IDataCursor pipelineCursor_1 = pipeline.getCursor();
IDataUtil.put( pipelineCursor_1, "fileName", "fileName" );
// outDoc
IData outDoc = IDataFactory.create();
IDataUtil.put( pipelineCursor_1, "outDoc", outDoc );
pipelineCursor_1.destroy();
String fileName = new String();
fileName = null;
try {
BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\itpr13266\\Desktop\\TestFile.txt"));
String line = null;
//Will read through the file until EOF
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("Try-Catch Message - " + e.getMessage());
e.printStackTrace();
}
}
// --- <<IS-BEGIN-SHARED-SOURCE-AREA>> ---
// --- <<IS-END-SHARED-SOURCE-AREA>> ---
}
You don't need to install another Eclipse for Java development. WebMethods Designer (v9) comes with Java tooling. Just open the Java perspective and use it.
Besides that you should use the Service Development perspective, when developing WebMethods Java Services, because WM Designer handles Java services in a special way, which could make importing standard Java files difficult.
There is no problem running multiple instances of Eclipse at the same time as long as they point to different workspaces.
Normally you get a dialog to choose the workspace when Eclipse starts up. If not, check this answer on how to enable that dialog: https://stackoverflow.com/a/8616216/1599890
So if you download, unzip and set up Eclipse for Java development and point it to another workspace than Software AG Designer uses you should be good to go.

Logging on device to file

How to redirect logging on device to file?
My application is hang on device but works great on emulator - I want to see logging on my device without sdk and its tools.
Look at Android Log Collector.
I found excellent feature of Logcat. It can redirect output to file himself by using simple command parameter "-f ".
To use it you can write Logcat wrapper in your application aLogcat like. Obviously I made this :)
For using logcat at android I wrote this code:
Process proc = null;
try {
proc = Runtime.getRuntime().exec(new String[] { "logcat", <!parametes_here!> });
mReader = new BufferedReader(new InputStreamReader(proc.getInputStream()), 1024);
String line;
while ((line = mReader.readLine()) != null) {
if (line.length() == 0) {
continue;
}
mHandler.sendMessage(mHandler.obtainMessage(Logcat.MSG_READ_LINE, line));
}
} catch (IOException e) {
Log.e(TAG, "Cannot start process", e);
} finally {
if (mReader != null)
try {
mReader.close();
} catch (IOException e) {
Log.e(TAG, "Cannot close stream", e);
}
}
Microlog - A logging framework for Java ME and Android inspired by Log4j.
(c) http://en.wikipedia.org/wiki/Log4j
"Using Microlog for Logging on Android & Viewing the Logs in the Emulator" by Johan Karlsson
Newsflash! Microlog for Android - microlog4android
I am using the application aLogCat downloaded free from android market.
Works very good.
Logging frameworks like log4j already provide features like logging to a file. Using android-logging-log4j it is possible to log to a rotating log file and to logcat. Also see log4j support in Android.

Categories