Clip.stop() freeze for few seconds - java

I have a class Sample and Clip inside, written in Java. I'm playing it in loop:
public void play() {
clip.loop(Clip.LOOP_CONTINUOUSLY);
}
I have also a stop method:
public void stop() {
clip.stop();
}
and I want to stop it, when the new Sample instance is initialized (and starts to play) using Scala.
def setSample = {
if (sample != null) {
sample.stop
}
sample = new Sample(track, this)
if (isPlay == true) {
sample.play()
}
}
The problem is, that clip.stop() hangs up for few seconds, so the next one isn't played immediately, as I expected. What can I do with that? And why it occurs?
//edit
I tried to use close() method and open clip again before new loop(). The same effect.

I'm not a Java/sound expert just did some spike previously. According to my tests and the literature the Java Sound API on Windows has some limitations. Hence if you are on Windows you may give ASIO a try to get a low latency playback solution. See: http://en.wikipedia.org/wiki/Audio_stream_input_output, specifically you will need the ASIO4ALL driver and the JAsioHost Java wrapper.

Related

Deadlock occurring when using java.nio.file.Paths & jsfml loadFromFile

I've been trying to debug a problem I've had with loading a font from file (a .ttf file) with the java.nio.file.Paths import, using a combination of Paths.get() and loadFromFile(), but can't seem to find a solution.
Here's the problem code:
import java.io.IOException;
import java.nio.file.Paths;
public final Font FONT_UI_BAR = new Font();
public final Font FONT_FREESANS = new Font();
try {
System.out.println("We get here, before loading");
FONT_UI_BAR.loadFromFile(Paths.get("Game/resources/UI/Font.ttf"));
System.out.println("I've loaded the first font");
FONT_FREESANS.loadFromFile(Paths.get("Game/resources/fonts/freesans/freesans.ttf"));
} catch (IOException e2) {
System.out.println("[ERROR] Could not load font");
e.printStackTrace();
}
The program gets to the first print statement but never reaches the second.
I did a thread dump and found there seems to be a deadlock within the code itself that occurs:
"main#1" prio=5 tid=0x1 nid=NA waiting
java.lang.Thread.State: WAITING
at jdk.internal.misc.Unsafe.park(Unsafe.java:-1)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:194)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:885)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1039)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1345)
at java.util.concurrent.Semaphore.acquire(Semaphore.java:318)
at org.jsfml.internal.SFMLErrorCapture.start(Unknown Source:-1)
at org.jsfml.graphics.Font.loadFromFile(Unknown Source:-1)
at assets.FontCatalogue.<init>(FontCatalogue.java:32)
at assets.FontCatalogue.get(FontCatalogue.java:15)
at screens.HomeScreen.<init>(HomeScreen.java:51)
at controllers.Game.<init>(Game.java:74)
at Main.main(Main.java:16)
I'm not exactly sure how to proceed from here. My program won't function how I want it to without loading these fonts. I've tried loading other kinds of fonts and the problem persists.
Weirdly enough the problem didn't occur with loading other files in the past, such as this code:
TEMP_BG_01.loadFromFile(Paths.get("Game/resources/placeholder/full-moon_bg.png"));
It only started once I started trying to load these fonts.
Ideally I'd like to find a solution that still allows me to use this package because otherwise I have a fair amount of code to rewrite. Not the biggest deal but suggesting simply using another package should be a last resort.
Any ideas appreciated.
EDIT: Interesting to note this issue DOES NOT occur on a Windows machine, only my ubuntu-linux one. The rest of my team on Windows have no issues. Obviously one solution is to go and use Windows instead, but who wants to do that :p
EDIT #2: Turns out I'm now getting this error even with loading from the Texture class in JSFML. I have a feeling I updated my JVM when I updated my ubuntu sometime recently and that's suddenly introduced problems. I can't say for sure because I don't recall updating very recently, but it seems as of 21/02/2021 loading from file with JSFML causes a deadlock :/
The first thing you need to do if you want to continue using JSFML is to determine the initial failure that leaves you in a deadlock state.
The code in the SFMLErrorCapture class is not robust. Should SFMLErrorCapture.start() fail in any way, it will leave the semaphore locked. I suspect this is the initial failure that breaks your application and leaves it deadlocked.
I'd recommend adding logging to the class, such as:
public static void start() {
try {
semaphore.acquire();
capturing = true;
nativeStart();
} catch (InterruptedException ex) {
ex.printStackTrace();
} catch (Throwable t) {
t.printStackTrace();
// lots of other logging, probably to a file in /tmp
// rethrow so original program flow isn't changed
throw t;
}
}
You might also want to add more logging to see if you get any InterruptedExceptions. That's another way the semaphore will never get released, but I don't think a simple upgrade is likely to trigger that kind of behavior change.
And, since it's also possible for finish() to fail in the same manner (such as if nativeFinish() returns null, which I'd think is also a likely failure mode...):
public static String finish() {
try {
final String str;
if (capturing) {
str = nativeFinish().trim();
capturing = false;
semaphore.release();
} else {
str = null;
}
return str;
} catch (Throwable t) {
t.printStackTrace();
// lots of logging
throw t;
}
}
You might need to add throws Throwable to both methods.
This might also help:
public static String finish() {
try {
final String str;
if (capturing) {
// chaining calls is BAD CODE!!!!
// Say hello to NPE if you insist cramming
// multiple calls in one line!!
str = nativeFinish();
if ( str != null ) {
str = str.trim();
}
capturing = false;
semaphore.release();
} else {
str = null;
}
return str;
}
}
Limiting asynchronous actions like this to one at a time is fundamentally broken. If only one action can happen at once, the code complexity added to do actions asynchronously is worse than wasted because such complex code is much more bug-prone and when bugs do happen that complexity makes unrecoverable failures much more likely.
If you can only do one at a time, just do the actions serially with one static synchronized method or in one synchronized block on a static final object.

check file existance in runtime in java

I want to check whether file exists at required location or not.
I am creating one text file from java e.g. abc.txt. I am going to use this file in some other program let's say a CAD program to generate a drawing. After completion of CAD process, it generates a file with some extension e.g. '.cad'. This drawing generation will take some time.
I am going to use the same '.cad' file in another program let's say an analysis software to analyse the generated drawing.
Now my problem is, I want to check whether the '.cad' file is generated or not. As the generation of .cad file takes time, without this file I can't proceed further i.e. I can't provide this file to next step (i.e. to analysis software).
So, is there any way in java, such that I can check for existence of .cad file for some time (let's say 120 seconds). And if I find the file then only proceed to next step.
I searched about the method file.exists() but it checks only once.
Please give me some hint.
Thank you all in advance!
I guess that you could use daemon for make your task at the background, hope it be helpful friend!
public class DaemonFolder extends Thread {
#SuppressWarnings("deprecation") // stop();
public static void main(String[] args) {
System.out.println("Pulsar enter para finalizar");
DaemonFolder daemonn= new DaemonFolder();
Scanner finalize= new Scanner(System.in);
finalize.nextLine();
daemonn.stop();
finalize.close();
System.out.println("Programa finalizado!");
}
public DaemonFolder() {
setDaemon(true); // Daemon threads in Java are like a service providers for other threads or objects running in the same process as the daemon thread
start();
}
#Override
public void run() {
while (true) {
try {
sleep(5000);
if (new File("anonymous.txt").exists()){
System.out.println("exists");
//DO SOMETHING
} else {
System.out.println("not exists");
}
} catch (Exception e){
e.printStackTrace();
}
}
}
}
You could for example write a for-loop that counts from 0 to 119 and there do the exists check, if it was successful call the next step, if not call Thread.sleep(1000) to wait a second before the next check.
Or you could for example schedule a TimerTask in a Timer to be run each second and in the TimerTask do the exists check and if maximum time is elapsed abort or if check goes well do the next step and abort.
There are plenty ways to do it, these were just two of them.
You need create cycle with your method and Thread.sleep(120000).
Snmth. like this:
while(true) {
if (file.exists()) {
break;
} else {
Thread.sleep(120000);
}
}

Execute method from a different thread than the one it's called from

I am working on a game using the thread-per-client model. The game operates so that every half a second all of the players need to be updated. The updates all have to happen within the half a second interval, so they need to all be executed at the same time. My idea is to have a class that keeps track of when the "global update" needs to happen and then when the time comes, go through all of the players and tell it to update:
for(Player p : currentPlayers) {
p.update();
}
The problem is that since every player has their own thread, I want the player to take advantage of that fact since it is already there. If I go through the updates from a different class, then there is one thread executing what a couple hundred threads could be doing individually. How can I design it so that if a thread calls method 'update()' in class Player, a different thread than the one that called it executes it, or perhaps a different approach that can achieve the same goal?
If you need any clarification, please ask! Thanks a lot!
UPDATE: What do you guys think of this (I can't figure out how to format long amounts of code in posts!):
UPDATE 2: Just realized I would need to know when all of the players finish updating to reset the last time...
public class PseudoExample implements Runnable
{
// Assume 'players' is full of active players.
private Player[] players = new Player[100];
private long lastUpdate = System.currentTimeMillis();
public void run()
{
while (true)
{
if (System.currentTimeMillis() - lastUpdate >= 500)
{
for (Player p : players)
{
p.update = true;
}
}
try
{
Thread.sleep(10);
} catch (InterruptedException e)
{
}
}
}
private class Player implements Runnable
{
private boolean update = false;
public void run()
{
while (true)
{
if (update)
{
// Do updating here ...
}
try
{
Thread.sleep(10);
} catch (InterruptedException e)
{
}
}
}
}
}
I think the best way to handle this would be instead of calling p.update(), you could send an asynchronous message to p. This would use the Handler functionality. This is probably the cleanest way, although I believe some (likely trivial) overhead will occur from the message passing.
So, in your ticking thread (i.e. the one that calls the global update), you would have a reference to a Handler object for each client thread. Then, you look would look like
for (Player p : currentPlayers) {
p.handler().sendMessage(); // this isn't exactly the syntax
}
and in your Player, you would have a PlayerHandler object that extends Handler and overrides handleMessage(Message).
EDIT: the comments on the question are good ones - don't use more threads than you need to. They might seem to be the "right" abstraction, but they introduce a ton of potentially tricky issues. If all of your computation needs to be done in between ticks, it might not matter whether it's done sequentially or not.

Perl launched from Java takes forever

I know this is an absolute shot in the dark, but we're absolutely perplexed.
A perl (5.8.6) script run by Java (1.5) is taking more than an hour to complete. The same script, when run manually from the command line takes 12 minutes to complete. This is on a Linux host.
Logging is the same in both cases and the script is run with the same parameters in both cases.
The script does some complex stuff like Oracle DB access, some scp's, etc, but again, it does the exact same actions in both cases.
We're stumped. Has anyone ever run into a similar situation? If not and if you were faced with the same situation, how would you consider debugging it?
Sub-proceses which produce console output can block (and deadlock) if their stdout/stderror streams are not flushed. #gustafc, the code posed will eventually block the sub-process when it tries to write to stdout/stderror, and there is no room in the stream (and the stream is not being serviced by java).
Process p = startProcess();
final InputStream stdout = p.getInputStream();
final InputStream sterr = p.getErrorStream();
new Thread() {
public void run() {
int c;
while ((c = sterr.read()) != -1) {
System.out.print((char)c);
}
}
}.start();
new Thread() {
public void run() {
int c;
while ((c = sterr.read()) != -1) {
System.out.print((char)c);
}
}
}.start();
I assume you've discarded the possibility that the Java wrapper happens to run simultaneously as something else which causes huge contention over some scarce resource? Good.
If you have a simple class like this:
public class Exec {
public static void main(String[] args) throws Throwable{
class Transfer implements Runnable {
private final InputStream in;
private final OutputStream out;
public Transfer(InputStream i, OutputStream o){
in = i;
out = o;
}
public void run(){
try {
for (int i; (i = in.read()) != -1;) out.write(i);
out.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Process proc = new ProcessBuilder(args).start();
new Thread(new Transfer(System.in, proc.getOutputStream())).start();
new Thread(new Transfer(proc.getInputStream(), System.out)).start();
new Thread(new Transfer(proc.getErrorStream(), System.err)).start();
System.exit(proc.waitFor());
}
}
... and you compare time perl script.pl insert args here and time java Exec perl script.pl insert args here, what happens? If the world is sane, they take about the same time (except that the second one needs a few seconds extra for Java to start), and if that's the case, gradually start adapting the Exec class to look more and more like your deployment environment, and see when it starts taking a really long time.
If Exec above really does take longer time, start logging like crazy in the Perl script, so you see which actions take longer time. And btw, log in the Java wrapper, too, so you see if the Perl startup takes a really long time or something.
One possibility is that you are making the system thrash by trying to run a large Java app and a large Perl app on a system that doesn't have enough memory.
It would be a good idea to use monitoring utilities like top vmstat -5 iostat -5 etc to try and figure out if the slowness corresponds to some OS-level pathology.
To bring this thread to a close, the eventual cause was rogue processes consuming too much CPU. When launched from the command-line, the script had normal priority. When launched from Java, the script had low priority and thus took forever to execute. What threw us off was that the Java code was not just executing the script, it was issuing the same commands via SSH that we issued interactively. Thus, we didn't expect the difference in priority.

do I need to close an audio Clip?

have an application that processes real-time data and is supposed to beep when a certain event occurs. The triggering event can occur multiple times per second, and if the beep is already playing when another event triggers the code is just supposed to ignore it (as opposed to interrupting the current beep and starting a new one). Here is the basic code:
Clip clickClip
public void prepareProcess() {
super.prepareProcess();
clickClip = null;
try {
clipFile = new File("C:/WINDOWS/Media/CHIMES.wav");
ais = AudioSystem.getAudioInputStream(clipFile);
clickClip = AudioSystem.getClip();
clickClip.open(ais);
fileIsLoaded = true;
} catch (Exception ex) {
clickClip = null;
fileIsLoaded = false;
}
}
public void playSound() {
if (fileIsLoaded) {
if ((clickClip==null) || (!clickClip.isRunning())) {
try {
clickClip.setFramePosition(0);
clickClip.start();
} catch (Exception ex) {
System.out.println("Cannot play click noise");
ex.printStackTrace();
}
}
}
The prepareProcess method gets run once in the beginning, and the playSound method is called every time a triggering event occurs. My question is: do I need to close the clickClip object? I know I could add an actionListener to monitor for a Stop event, but since the event occurs so frequently I'm worried the extra processing is going to slow down the real-time data collection.
The code seems to run fine, but my worry is memory leaks. The code above is based on an example I found while searching the net, but the example used an actionListener to close the Clip specifically "to eliminate memory leaks that would occur when the stop method wasn't implemented". My program is intended to run for hours so any memory leaks I have will cause problems.
I'll be honest: I have no idea how to verify whether or not I've got a problem. I'm using Netbeans, and running the memory profiler just gave me a huge list of things that I don't know how to read. This is supposed to be the simple part of the program, and I'm spending hours on it. Any help would be greatly appreciated!
Michael
yes, closing is necessary
myClip.addLineListener(new LineListener() {
public void update(LineEvent myLineEvent) {
if (myLineEvent.getType() == LineEvent.Type.STOP)
myClip.close();
}
});
or by
if (!myClip.isRunning())
myClip.close();
In my application (written before the advent of util.concurrent), this is the clip closing mechanism.
public static final Vector<Clip> vector = new Vector<Clip>();
static final int vector_size = 5;
// typically called before calling play()
static synchronized void consolidate() {
while (vector_size < vector.size()) {
Clip myClip = vector.get(0);
if (myClip.isRunning())
break;
myClip.close();
vector.remove(0);
}
if (vector_size * 2 < vector.size())
System.out.println("warning: audio consolidation lagging");
}
public static void play(final File myFile) {
try {
AudioInputStream myAudioInputStream = AudioSystem.getAudioInputStream(myFile);
final Clip myClip = AudioSystem.getClip();
vector.add(myClip);
myClip.open(myAudioInputStream);
myClip.start();
} catch (Exception myException) {
myException.printStackTrace();
}
}
As one of the comments suggest, it may delay the playback of new clips, but I cannot remember as a few ms delay were not important in my application.
Memory leaks in Java have to do with objects that are still being referenced even after their useful lives have ended. In many cases, this will be due to something like repeatedly making 50 objects but only eliminating references to 49 of them later on.
Nothing like that seems to be going on in your code. Since prepareProcess() only runs once, it's not highly suspect. That leaves playSound(), which doesn't contain any object instantiation at all, much less a faulty reference elimination loop.
The caveat is that I'm not sure what goes on behind the scenes in your sound clip object, and it's hard to check because majuscule-C Clip is only an interface. Unless you're using third-party code, though, I'd be very surprised to find a leak there.
Long story short, I wouldn't worry about it unless and until you actually see something like an OutOfMemoryError.

Categories