JavaFx Audio Output Selection - java

I'm looking for a way to specify an output device with JavaFx
I have a similar issue as this question: JavaFX specific Audio Output, but with different needs.
I need a way to get a list of all possible Audio Output devices (like the one you see in your user preferences) and allow the user to select which one they want the audio to come out of in JavaFx. This seems like a really basic feature that should be in any music/media API, and is essential for most audio software.
I'm using the MediaPlayer in JavaFx, though if there is another class I'm happy to use it. Note though that I need the same functionality for video (specifying audio output), so I need a class/solution that works for both.
If there's something in JavaFx 8 that will help, I can always wait until it is released.
What I really expected there to be was the same thing as the Screens class:
Screen.getScreens() // Gets an observable list of all screens.
I'm fine with hackish solutions. Really, anything that works.

For years it has been a very unfortunate limitation of the Java implementation for OS X, being BTW particular for that platform, that "Java Sound Audio Engine" is the only programmatically available output audio line. In consequence, whatever you send to this line, i.e. out from any java application that you make, will always be routed to what has been set as the default output in the OS X, typically internal speakers. So the JSAE is just Java terminology for "default audio out". To our understanding - sadly - this is still the case with latest release.
Why unfortunate ? Because it effectively disables even humble audio routing. We are working with these matters on a daily basis, and it calls for all sorts of added complexity. There are work arounds, but via third party apps as SoundFlower and HiJack Pro. www.soundPimp.com for example.

As assylias has pointed out getmixerinfo method can help you
Info[] mixerInfo = AudioSystem.getMixerInfo();
for(int i = 0; i < mixerInfo.length; i++)
{
System.out.println(mixerInfo[i].getName());
}
You can explore further details here

Related

How to speed up the change of language in the Text to Speech?

Suppose I have activity on which there is a list of 10 items. Each element is a text in some language. Suppose each language has a voice output. If I want to make a button, by clicking on which all texts will be read in their own language, I need to change the language before I start reading each text. The problem is that changing the language takes a lot of time (from 2-3 seconds to 5-7) on some phones that I checked. I saw the application where it happens instantly. How can I implement this without creating another object for each language?
Different phones have different speech engines installed on them (Google, Samsung, PICO, etc)...
The delay is going to vary slightly based on which engine is being used... and a lot based on:
1) Whether any voices are previously installed that correspond to the language you're attempting to speak,
2) Whether the voice being used to speak is a "network voice" (utterance is retrieved via network)
So to get zero delay, the voices must be installed and they must not be network voices.

Using Java to gather specific system information: monitor (screen) details

I know it is possible to get system information in Java and have searched SO for this particular question but have come up empty.
Question:
Can I gather complete system information about all attached monitors? Particularly I am hoping to get a unique ID, model number, or manufacturer of each monitor.
Wayan Saryada for example demonstrated a simple example here that gets basic information about all connected monitors. Code follows to protect from link rot:
//
// Get local graphics environment
//
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] devices = env.getScreenDevices();
int sequence = 1;
for (GraphicsDevice device : devices) {
System.out.println("Screen Number [" + (sequence++) + "]");
System.out.println("Width : " + device.getDisplayMode().getWidth());
System.out.println("Height : " + device.getDisplayMode().getHeight());
System.out.println("Refresh Rate: " + device.getDisplayMode().getRefreshRate());
System.out.println("Bit Depth : " + device.getDisplayMode().getBitDepth());
System.out.println("");
}
This code however produces nothing unique. Its just generic information that is helpful but does not meet my end goal.
Use Case / End Goal:
My intentions is to make a portable application that tracks (detects) what computer/ computer setup you are using and displays the appropriate desktop. One example is on my work computer with a large monitor it lays out my desktop one way and then on my laptop it hides some things; long story short it would show an alternate desktop display (less icons, only the ones I need for work/ home).
I have all that extra stuff worked out but I need a way to track not just what computer I am on but which monitors I have attached at the time. Essentially a "MAC address" for attached monitors; I know that is not a thing. This way on a triple monitor setup for example my application knows what goes where. Then if I remove one monitor it knows what to change to.
So long story short there just is no way to accurately detect in Java which monitor is which in the GraphicsDevice API. There are several other ways to detect this information but again Java runs into the same problem. Java just auto increments the monitors it finds like so:
Display0,
Display1,
Display2
...And so on.
Each time the computer turns on different monitor assignments can happen and each time a monitor turns off the order can change. The same is true if the graphics driver crashes or reboots while in use.
One Solution
This does not solve my original issue: The OP's questions. However I know it is extremely hard to get full human readable system information with Java, especially all attached monitors. I put in a request to dbwiddis on GitHub and he was able to add this feature to Oshi. His Java library pulls everything you need to know about every attached monitor to a computer. A perfect all in one solution for Network Admins.
The Issue Still / Hack
There still is no way (including using other API's accessible through other programming languages) to detect which monitor is which. The "MAC Address" of all your attached monitors if you will. The only way to do this reliably (really a hack) is to pop up a terminal that outputs information that you then can grab with Java. This way Java can manually make the matches. It can go out to Display2 and read the terminal window that is open on it and now we know which monitor is Display2.
I have no code for this right now because it is extremely unreliable and not guaranteed to be cross OS compatible. It should work fine in windows but your will need to execute a batch file or powershell script to get the terminals on the monitors you want.
Just look at the GraphicsDevice API:
https://docs.oracle.com/javase/7/docs/api/java/awt/GraphicsDevice.html#getIDstring%28%29

In Java how to say speak/read instead of println/system.in

Just curious to know what it will take for me to have human capability to my java programs. Currently to display a message i use System.out.println and to read user's input i may use something like System.in. Wondering if there is a way for me to say System.out.speak() and System.hear();
If not possible with Java i'm okay to learn other languages please help.
Wondering if there is a way for me to say System.out.speak() and System.hear();
Literally, no.
System.out is a PrintWriter and there is no speak() method.
There is no System.hear() method.
Adding such methods would entail hacking on standard system classes ... making the resulting library "NOT Java(tm)".
Furthermore, there are no standard APIs in the Java libraries for text to speech or speech to text. (And I'm not aware of any other language that offers this functionality as a standard feature.)
However, I'm sure that if you looked hard enough you could find 3rd-party tools for doing this that could be integrated with Java, one way or another.
UPDATE
In fact, you have found the standard Android (as distinct from Java) APIs for this:
Speech recognition: android.speech
Text to speech: android.speech.tts
From a design perspective, I think it would be a better idea to support this kind of thing in the OS's user interface framework (where the user can control it), and not embed it in individual applications.
So it sounds like this is what you want:
"System.out.speak()" -- as you know by now, that's not a real thing. I think I could propose a high-level, temporary solution.
It sounds like you just want to be audibly notified when you reach a certain part in your code. Perhaps you could just record a wav or mp3 of yourself saying whatever it is you want to hear as an alert, and then import the wav/mp3 into your project directory. Refer to this article to figure out how to playback that audio:
Playing .mp3 and .wav in Java?
You could simply make a static method that takes in a string representing the desired audio playback and then does so by however the link above suggests.
If you want it to take in a string, and then have some sort of computer voice (e.g. Microsoft Sam) speak that string, that's a lot more complicated. I have no idea how to do that haha. But I'm guessing it's not as hard as your idea of "System.in.hear()"
"System.in.hear()" -- This is definitely not a thing. This requires knowledge in the field of Speech-To-Text (STT). This is basically how Siri or Google Now parses what you say to them. I'm sure there are libraries you could find that do this, but I'm too lazy to look for you :(
I hope this helps a little bit. I'm doing a little bit of research right now on STT and I saw your question pop up. I'm not very knowledgeable in the area, but I hope you figure out a way to get audio feedback instead of having to put println's everywhere. You should figure that out and reuse it.
Happy programming!

Play frequencies of sound in Java dos style

In Turbo C++ we have a header file called dos.h which exposes three functions sound, nosound and delay. Using these three functions it was possible to write a rudimentary piano program in C++.
I wanted to achieve the same result using Java. My options were either to use the library provided by jfugue or javax.sound.sampled. The problem is that I don't know the duration each note is played beforehand.
I want to start playing a certain frequency when the user presses a certain key and stop only when the user releases it. How may I tackle this problem?
The Java tutorials have an example where a boolean is consulted in the innermost while loop where one is packaging the bytes and handing them off to the SourceDataLine for playback.
Thus, your event, perhaps a key-off event, can be written to change this boolean. Since the sound playback is in its own thread, it is good to make the boolean "volatile", and to use this method of messaging rather than trying to directly control the playback.
Let's see if I can find the tutorial example...
http://docs.oracle.com/javase/tutorial/sound/playing.html
Notice in the example in the section "Using a Source Data Line" there is a while loop with the expression "!stopped" as one of the conditions. The base class for the playback in this example most certainly has a boolean "stopped", and probably has it marked "volatile".

Detect frequency of audio input - Java?

I've been researching this off-and-on for a few months.
I'm looking for a library or working example code to detect the frequency in sound card audio input, or detect presence of a given set of frequencies. I'm leaning towards Java, but the real requirement is that it should be something higher-level/simpler than C, and preferably cross-platform. Linux will be the target platform but I want to leave options open for Mac or possibly even Windows. Python would be acceptable too, and if anyone knows of a language that would make this easier/has better pre-written libraries, I'd be willing to consider it.
Essentially I have a defined set of frequency pairs that will appear in the soundcard audio input and I need to be able to detect this pair and then... do something, such as for example record the following audio up to a maximum duration, and then perform some action. A potential run could feature say 5-10 pairs, defined at runtime, can't be compiled in: something like frequency 1 for ~ 1 second, a maximum delay of ~1 second, frequency 2 for ~1 second.
I found suggestions of either doing an FFT or Goertzel algorithm, but was unable to find any more than the simplest example code that seemed to give no useful results. I also found some limitations with Java audio and not being able to sample at a high enough rate to get the resolution I need.
Any suggestions for libraries to use or maybe working code? I'll admit that I'm not the most mathematically inclined, so I've been lost in some of the more technical descriptions of how the algorithms actually work.
If you are aiming at detecting frequency pairs then your job is very similar to a DTMF detector.
Try searching for DTMF in places like sourgeforge, you'll find detectors in many programming languages. The frequency pairs placing along the spectrum seems to be even more stringent than your specs so you should be fine adapting a DTMF detector to your input.
Check out SNDPeek, its a cross-platform C++ application that extracts all kinds of information from live audio; https://github.com/RobQuistNL/sndpeek

Categories