Is constant polling in RXTX necessary? - java

While trying to figure out this problem (any help there is appreciated), I ran RXTX while monitoring its activity using PortMon and noticed that RXTX constantly checks if data is available, even when the Java client reads from the gnu.io.SerialPort object only through a SerialPortEventListener.
Why is this? Is it a poor implementation choice by the RXTX folks, a poor API choice by Sun (since RXTX follows the javax.comm API), or a limitation of running Java supported by native code?
Hyperterminal, on the other hand, does no polling (and works without a problem). Does it have access to some hidden Windows system calls that let it do this?

No it's not due to the javax.xomm API. Rxtx can be used through that API or not by the way.
Rxtx internals are a bit different/weird though and has some bugs.
Short version, this is how it is supposed to work: You have two parameters to play with: timeout and threshold. According to the source code setting the timeout to 0 (none) and threshold to 1 (requiring at least 1 byte before returning) should give us normal, by InputStream defined, blocking reads.
The problem is that even when setting it up like this there is a bug in the current stable release (2.1.7r2). The threshold parameter is always set to 0! From the source code:
/* TESTING ttyset.c_cc[ VMIN ] = threshold; */
ttyset.c_cc[ VMIN ] = 0;
The confusing part is that this was also the case in 2004 and reported on the mailing list and fixed, but it was either not really fixed or has come back again (a regression). There is actually a new bug report that for some reason I couldn’t find at first. I eventually found it going throw the pre-release package source code and found an otherwise not published change log (the web page doesn’t show change logs after the last stable version, its available in CVS though).
Solution
It is fixed on HEAD, so you can use the latest pre-release version
(2.2-series) or compile it from CVS.
Make an ugly workaround along the lines of:
int read(InputStream in) throws IOException {
int b;
while ((b=in.read()) == -1) {
try { Thread.sleep(10); } catch (InterruptedException e) { }
}
return b;
}
Then you do: read(in) instead of in.read().
I actually wrote a blog entry about this 2 years ago so I wouldn't forget.

Related

Error importing BioFormats file into Matlab

I'm trying to import .spl files from Slidebook v4.2 into Matlab but I've run into problems.
I downloaded the functions and loci_tools.jar from here. I used them to import one file with minor problems (it got the Z planes and the time points backwards as well as misnaming some of the files with the wrong acquisition channel) but I figured out the pattern to the problems and was able to work around them.
Then I tried to import another file and I got this error which I haven't been able to solve. Any ideas would be greatly appreciated. I'm new to working with java and java in matlab. Here is the error I get:
I = bfopen(‘filename.spl’);
Finding offsets to pixel data
Determining dimensions
Reading series #1
.Error using loci.formats.ChannelSeparator/openBytes
Java exception occurred:
java.lang.IllegalArgumentException: Negative position
at sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:600)
at loci.common.NIOByteBufferProvider.allocateDirect(NIOByteBufferProvider.java:133)
at loci.common.NIOByteBufferProvider.allocate(NIOByteBufferProvider.java:118)
at loci.common.NIOFileHandle.buffer(NIOFileHandle.java:532)
at loci.common.NIOFileHandle.seek(NIOFileHandle.java:254)
at loci.common.RandomAccessInputStream.seek(RandomAccessInputStream.java:140)
at loci.formats.in.SlidebookReader.openBytes(SlidebookReader.java:130)
at loci.formats.ImageReader.openBytes(ImageReader.java:414)
at loci.formats.ChannelFiller.openBytes(ChannelFiller.java:197)
at loci.formats.ChannelSeparator.openBytes(ChannelSeparator.java:226)
at loci.formats.ChannelSeparator.openBytes(ChannelSeparator.java:159)
Error in bfGetPlane (line 75)
plane = r.openBytes(iPlane - 1, ip.Results.x - 1, ip.Results.y - 1, ...
Error in bfopen (line 144)
arr = bfGetPlane(r, i, varargin{:});
Please try the latest version of Bio-Formats 5. You can easily use it in Fiji by enabling the Bio-Formats 5 update site, or in MATLAB using the latest loci_tools.jar from Jenkins.
If you still get an error, feel free to report a bug. That said, the recommended approach is to export your data from the Slidebook software to OME-TIFF format.
Unfortunately, though popular, 3i Slidebook is probably the most arcane and difficult format we try to support in Bio-Formats. We have met with the Slidebook developers on multiple occasions to discuss how best to handle the issue. But the SLD format was never intended for public consumption and it continues to evolve with each iteration of the Slidebook software. So the compromise we settled on is for the Slidebook software to support robust export to OME-TIFF format, which preserves rich microscopy-related metadata. From the Bio-Formats 3i Slidebook page:
We strongly encourage users to export their .sld files to OME-TIFF using the SlideBook software. Bio-Formats is not likely to support the full range of metadata that is included in .sld files, and so exporting to OME-TIFF from SlideBook is the best way to ensure that all metadata is preserved.
I know that is not entirely satisfactory, but it is unlikely to change any time soon. Maybe if many customers expressed a strong preference to the Slidebook team to make the SLD format work better in Bio-Formats, they would take some steps to rework the format...
See also: Bio-Formats FAQ: Why do my Slidebook files take a long time to open?

JavaFx Audio Output Selection

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

Matlab segmentation fault when iterating vector assignment

I've been vectorizing some matlab code I'd previously written, and during this process matlab started crashing due to segmentation faults. I narrowed the problem down to a single type of computation: assigning to multiple struct properties.
For example, even self assignment of this form eventually causes a seg fault when executed several thousand times:
[my_class_instance.my_struct_vector.my_property] = my_class_instance.my_struct_vector.my_property;
I initially assumed this must be a memory leak of some sort, so tried printing out java's free memory after every iteration, but this remained fairly constant.
So yeah, completely at a loss now as to why this breaks :-/
UPDATE: the following changes fixes the seg faulting:
temp = [my_class_instance.my_struct_vector];
[temp.my_property] = temp.my_property;
[my_class_instance.my_struct_vector] = temp;
The question is now why this would fix anything. Something about repeated accessing a handle class rather than a struct list perhaps?
UPDATE 2: THE PLOT THICKENS
I've finally replicated the problem and the work around using a dummy program simple enough to post here:
a simple class:
classdef test_class
properties
test_prop
end
end
And a program that makes a bunch of vector assignments with the class, and will always crash.
test_instance = test_class();
test_instance.test_prop = struct('test_field',{1 1});
for i=1:10000
[test_instance.test_prop.test_field] = test_instance.test_prop.test_field;
end
UPDATE 3: THE PLOT THINS
Turns out I found a bug. According to Matlab tech support, repeated vector assignment of class properties simply won't work in R2011a (and presumably in earlier version). He told me it works fine in R2012a, and then mentioned the same workaround I discovered: use a temporary variable.
So yeah...
pretty sure this question ends with that support ticket, but if any daring individuals want to take a shot as to WHY this bug exists at all, I'd definitely still be interested in such an answer. (learning is fun!)
By far the most likely cause is that the operation is internally using self-modifying code. The problem with this is that modern processors have CPU caches, so if you change code in memory, but the code has already been committed to a cache, it will generate a seg fault.
The reason why it is random is because it depends on whether the modified code is in the cache at the time of modification and other factors.
To avoid this the programmer has to be sure to have the code flush the cache before doing a self-modification.

Java sound api - Scanning for midi devices

I'm working on a java project that receives midi events from midi hardware using the javax.sound.midi library. In the documentation, it says that MidiSystem.getMidiDeviceInfo() returns a list of all connected midi hardware. It works for me, but the problem is, it only works once. It takes a moment the first time to actually scan for the devices, but each time after that it will immediately return that same list even if new devices have been connected. Is there a way to force it to rescan? It will rescan if the application is restarted, but I don't want my users to have to restart if they connect a new midi device.
BTW, I'm using Mac OS X... it's been pointed out that behavior may be different for different OS's.
The MidiSystem.getMidiDeviceInfo() gets the full providers list, and extracts the info of the device from each provider.
The MIDIs provider list is recovered from the JDK underlaying class com.sun.media.sound.JDK13Services, through the static method getProviders()
public static synchronized List getProviders(Class serviceClass)
Obtains a List containing installed
instances of the providers for the
requested service. The List of
providers is cached for the period of
time given by cachingPeriod . During
this period, the same List instance is
returned for the same type of
provider. After this period, a new
instance is constructed and returned.
The returned List is immutable.
So, it seems that this class holds thee Providers list in a cache, wich will be reloaded after a certain period. You can set this period to a custom value using the method setCachingPeriod(int seconds). As long as I know, the default caching period is set to 60 seconds.
As an example, to refresh this cache every second, you coud add this line to your code:
com.sun.media.sound.JDK13Services.setCachingPeriod(1);
Please, note that this solution makes use of a Sun propietary class, so it could not be 100% portable.
Lacking any MIDI devices on my work PC, or indeed any kind of Mac, I doubt I'll be able to test it properly, but...
The MidiSystem class seems to use com.sun.media.sound.JDK13Services.getProviders(Class providerClass) to find the list of devices on the system. The API docs for this class state that the list is recreated on a successive call outside of a cachingPeriod, which can be conveniently set by calling setCachingPeriod(int seconds).
With any luck you can just call this once at the start of your application and set it to 5 seconds or something, and it'll magically work. However, the docs also state "This method is only intended for testing.", so I'm not sure quite how effective this approach will be.
Hopefully this is enough to get you started, and I'll keep poking around in the meantime to see if I can find a cleaner way to do this.
I answered this is Update list of Midi Devices in Java as well, but for folks who wind up here, there's now a library that supports this correctly: https://github.com/DerekCook/CoreMidi4J
The library acts a device provider for the MIDI Subsystem, so it's basically a drop-in and all your existing code will work.
I am not the author, but it works well for my needs, and it took a fair bit of searching to find, so I'm posting it here for others who encounter the problem.
I found a solution which uses the JavaFX thread. For some reason this works at least on MacOSX. On a normal thread it doesn't work.
import fx.FX_Platform;
import javafx.embed.swing.JFXPanel;
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiSystem;
public class miditest {
static public void main( String[] args ) {
// **** Just to init FX platform
new JFXPanel();
new Thread( () -> {
for( int ix=0; ix<1000; ix++ ) {
try {
Thread.sleep(2000);
} catch( InterruptedException e ) {
}
FX_Platform.runLater( () -> {
MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
System.out.println("FOUND: " + infos.length);
for( MidiDevice.Info midiinfo : infos ) {
System.out.println(midiinfo);
}
});
}
}).start();
}
}
This sounds like is could be an OS specifx bug but I can think of a get around.
In java you can run external commands to the OS. (A quick google, gave me this example http://www.javafaq.nu/java-example-code-186.html it looks OK and gives you the idea).
On checking for new devices you could send an external command to run a simple java program that quickly queries the midi devices using MidiSystem.getMidiDeviceInfo() and outputs the results to a text file or you could grab the output from the BufferedReader object.
Also remember that the external program used to query midi devices doesn't have to be written in Java incase Java causes you more problems. Alternatively you could just query the OS for connected devices and use grep to filter the results.
Hope this helps.

VUgen: Recording trivial RMI interaction records invalid script?

After recording just the appearance of the logon window of our Java app in LR/VUgen 9.51 using the RMI protocol, the resulting script replays with a java.lang.ArrayIndexOutOfBoundsException. The code fragment looks like this:
_hashtable2 = new Hashtable();
_object_array3 = ((java.util.Collection)_hashtable2.values()).toArray();
_hashtable2.put("sessionId",(java.lang.String)_object_array3[0]); //yields exception!
_boolean1 = _mopsconstantserverif1.psi_requiresHostCommunication((java.util.Hashtable)_hashtable2, (java.util.Vector)null);
Of course generating an empty hashtable, converting it to an array, and referencing its first array element must yield an ArrayIndexOutOfBoundsException, right? But why does LR generate this kind of code at all? Is this a bug, or what am I doing wrong? I have never seen problems like this one when using RMI and LoadRunner.
Since the cause of the playback error is quite obvious and independent of the remainder of the recorded code (i.e. limited to the four statements shown), I try to ask without showing the whole script...
Ahh, RMI, the bane of my existence. I so dislike the RMI/Java combination in LoadRunner I do as much RMI work in Winsock as I can. You might consider the use of Winsock as a plan B option to avoid the Java issues you are experiencing today as Winsock is a straight C virtual user type. The use of a Windows sockets virtual user avoids the complications of the dark magic of Java and LoadRunner, plus it's lighter weight on the resource front and it's faster as a result. And, I am just a glutton for punishment on the Winsock front plus it keeps the C skills razor sharp!

Categories