Playing audio with sampling rate 96Khz and up in Java - java

My system has USB DAC capable to play formats 24/96 and 24/192, however when I try to play them using Java I am getting line unavailable exception. Accordingly Java sound documentation, Java doesn't bring any limitations for sample and bits rates, and the limitations are coming for underline sound system. So I traced down where the exception coming from and it looks like native function
private static native void nGetFormats(int mixerIndex, int deviceID,
boolean isSource, Vector formats);
doesn't fill formats with corresponding line info above 16/48.
I looked in sources here.
However to prove that the function really doesn't return format I need or it just returns slight different, I have to see actual formats list. But I can't figure out how reach it. Method of DirectDL is private:
private AudioFormat[] getHardwareFormats() {
return hardwareFormats;
}
So my question has two parts:
How can I still get list of supported formats Java gets from hardware? In this case I could just write own DirectAudioDevice.
Is there any other alternative to standard Java sound to manage higher sample rates from Java? For example, Tritonus, but it seems really old and not supported.
I did my testing on Window, so plan to repeat it on Linux using different than Oracle JRE. However I need to find portable solution anyway.

I found some solution so I can listen to 24/96Khz and 24/192Khz recording using Java in FLAC, APE, and Wavpack formats.
After some debugging in Java sound I found that for some reason Java runtime limits bits depth to 16bits, however accepts high sample rates as 96Khz and 192KHz. So I borrowed down sampling solution from MediaChest. I also got JustFLAC which provides 24/192 support for FLAC files. Supporting 24/192 directly through hardware seems not possible without updating Java runtime native libraries that I plan to do soon.
Edit: the latest update is: I looked in native Java runtime and found the following:
static INT32 bitsArray[] = { 8, 16};
....
#define BITS_COUNT sizeof(bitsArray)/sizeof(INT32)
....
for (rateIndex = 0; rateIndex < SAMPLERATE_COUNT; rateIndex++) {
for (channelIndex = 0; channelIndex < CHANNELS_COUNT; channelIndex++) {
for (bitIndex = 0; bitIndex < BITS_COUNT; bitIndex++) {
DAUDIO_AddAudioFormat(creator, bitsArray[bitIndex],
So as you can see 8, and 16 bits are hardcoded and used in supported formats matrix generation. A fix seems to be easy just by adding two more constants, however it leads in creation own copy of Java runtime and it isn't acceptable. So it looks like I need to initiate some community process to make my recommendations accepted by and then included in next Java runtime updates.
Edit: One more update. Linux sound native implementation seems better. It has only limitation 24bits sample size. So if underline sound system (ALSA) allows the sample depth, then Java can play 24 bits/ 192,000 format. I tested it on Raspberry Pi using latest Raspbian and JDK 8 EA. Unfortunately even latest Arch and Pidora do not have the ALSA improvement.

For reading and writing the value in the private field, you can use reflection. The Java Tutorial and a question in StackOverflow.
About your second question, I've found a library called jd3lib that seems recent.

Related

Accessing /dev/mem through Java

I'm trying to use Raspberry PI's PWM from Java, without using WiringPi/Pi4j or any other library. So far I learned that the only way to control the PWMs is by memory-mapping the /dev/mem file and setting appropriate registers there. That's how WiringPi does it (see here) and also people ask about it pretty often on the Raspberry Pi StackExchange.
I'm facing a certain problem that seems to be irrelevant to the Raspberry, that's why I'm asking the question on the general SO forum. I tested the below symptom positive on my Ubuntu laptop.
So, I'm trying with this simple piece of code with seems to be a minimal example that reproduces the problem, runnnig with sudo:
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class Main {
public static void main(String[] args) {
try {
RandomAccessFile file = new RandomAccessFile("/dev/mem", "rw");
long size = 12345; // Anything greater than 0 - it seems to be irrelevant.
MappedByteBuffer out = file.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, size);
// Here I plan to make some writes to the registers.
} catch (Exception e) {
e.printStackTrace();
}
}
}
I'm not even trying to read any data or change the internal pointer position. I'm getting the following stack trace, originating from the call to map(...):
java.io.IOException: Invalid argument
at java.base/sun.nio.ch.FileDispatcherImpl.truncate0(Native Method)
at java.base/sun.nio.ch.FileDispatcherImpl.truncate(FileDispatcherImpl.java:86)
at java.base/sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:987)
at Main.main(Main.java:10)
When debugging the code, I noticed this piece in the implementation of map(...) (in sun/nio/ch/FileChannelImpl.java):
filesize = nd.size(fd);
and the file size is calculated to hava a size of 0. I don't know how to debug deeper because it seems to be already a native call, through JNI.
Checking the size of this file through the command-line reveals 1:
$ ll | grep mem
crw-r----- 1 root kmem 1, 1 lip 2 13:12 mem
I checked the man page: https://man7.org/linux/man-pages/man4/mem.4.html, but it doesn't seem to address this specific prolem.
It got more interesting when I found out that the JDK version matters. It doesn't work on 11.0.1 from Oracle, and OpenJDK 14.0.1. However, it does work (doesn't crash) on 8.0.191 from Oracle. I have some problems with attaching sources of this JDK to my debugger, so I cannot debug it as deeply as with the other version. I also cannot use JDK 8 on my Raspberry, I have some problems installing it. I figured it's better to understand the problem better rather than sticking to a single JDK.
What am I doing wrong? It seems to be so easy to map /dev/mem with C/C++ or Python, I see the examples all around the RPI forum. I'd really like to try to stay pure Java as long as possible. In theory there's also a risk of a bug in the newer JDKs, but I want to get some second opinion before I file a bug, especially that I'm not proficient with low-level Linux.
Thanks,
Peter

Sandboxed java scripting replacement for Nashorn

I've been using Nashorn for awk-like bulk data processing. The idea is, that there's a lot of incoming data, coming row by row, one by another. And each row consists of named fields. These data are processed by user-defined scripts stored somewhere externally and editable by users. Scripts are simple, like if( c>10) a=b+3, where a, b and c are fields in the incoming data rows. The amount of data is really huge. Code is like that (an example to show the use case):
ScriptEngine engine = new NashornScriptEngineFactory().getScriptEngine(
new String[]{"-strict", "--no-java", "--no-syntax-extensions", "--optimistic-types=true"},
null,
scr -> false);
CompiledScript cs;
Invocable inv=(Invocable) engine;
Bindings bd=engine.getBindings(ScriptContext.ENGINE_SCOPE);
bd.remove("load");
bd.remove("loadWithNewGlobal");
bd.remove("exit");
bd.remove("eval");
bd.remove("quit");
String scriptText=readScriptText();
cs = ((Compilable) engine).compile("function foo() {\n"+scriptText+"\n}");
cs.eval();
Map params=readIncomingData();
while(params!=null)
{
Map<String, Object> res = (Map) inv.invokeFunction("foo", params);
writeProcessedData(res);
params=readIncomingData();
}
Now nashorn is obsolete and I'm looking for alternatives. Was googling for a few days but didn't found exact match for my needs. The requirements are:
Speed. There's a lot of data so it shall be really fast. So I assume as well, precompilation is the must
Shall work under linux/openJDK
Support sandboxing at least for data access/code execution
Nice to have:
Simple, c-like syntax (not lua;)
Support sandboxing for CPU usage
So far I found that Rhino is still alive (last release dated 13 Jan 2020) but I'm not sure is it still supported and how fast it is - as I remember, one of reasons Java switched to Nashorn was speed. And speed is very important in my case. Also found J2V8 but linux is not supported. GraalVM looks like a bit overkill, also didn't get how to use it for such a task yet - maybe need to explore further if it is suitable for that, but looks like it is complete jvm replacement and cannot be used as a library.
It's not necessary shall be javascript, maybe there are other alternatives.
Thank you.
GraalVM's JavaScript can be used as a library with the dependencies obtained as any Maven artifact. While the recommended way to run it is to use the GraalVM distribution, there are some explanations how to run it on OpenJDK.
You can restrict things script should have access to, like Java classes, creating threads, etc:
From the documentation:
The following access parameters may be configured:
* Allow access to other languages using allowPolyglotAccess.
* Allow and customize access to host objects using allowHostAccess.
* Allow and customize host lookup to host types using allowHostLookup.
* Allow host class loading using allowHostClassLoading.
* Allow the creation of threads using allowCreateThread.
* Allow access to native APIs using allowNativeAccess.
* Allow access to IO using allowIO and proxy file accesses using fileSystem.
And it is several times faster than Nashorn. Some measurements can be found for example in this article:
GraalVM CE provides performance comparable or superior to Nashorn with
the composite score being 4 times higher. GraalVM EE is even faster.

Access .net DLL from Java

I am new to java and DLL-s
I need to access DLL's methods from java. So go easy on me.
I have tried using JNA to access the DLL here is what I have done.
import com.sun.jna.Library;
public class mapper {
public interface mtApi extends Library {
public boolean IsStopped();
}
public static void main(String []args){
mtApi lib = (mtApi) Native.loadLibrary("MtApi", mtApi.class);
boolean test = lib.IsStopped();
System.out.println(test);
}
}
When I run the code, I am getting the following error:
Exception in thread "main" java.lang.UnsatisfiedLinkError:Error looking up function 'IsStopped':The specified procedure could not be found.
I understand that this error is saying it cannot find the function, but I have no idea how to fix it.
I am trying to use this API mt4api
and here is the method, I am attempting to access MQL4
Can anyone tell me what I am doing wrong?
I have looked at other alternatives, like jni4net, but I cannot get this working either.
If anyone can link me to a tutorial that shows me how to set this up, or knows how to, I would be greatfull.
Trading?Hunting for milliseconds to shave-off?Go rather into Distributed Processing... Definitely safer than relying on API !
While your OP was directed onto how bend java to call .NET DLL-functions,
let me sketch a much future-safer solution.
Using AI/ML-regression based predictors for FOREX trading, I was hunting in the same forest. The best solution found within the last about 12-years, having spent about a few hundreds man*years of experience, was setup in the following manner:
Host A executes trades: operates MetaTrader Terminal 4, with both Script and EA --- the distributed-processing system communicates with with a use of ZeroMQ low-latency messaging/signalling framework ( about a few tens of microseconds needed )
Host B executes AI/ML processing of predictions for a traded instrument ( about a few hundreds of microseconds apply )
Cluster C executes continuous AI/ML predictor re-trainings and HyperParameterSPACE model selections ( many CPU-hours indeed needed, continuous model self-adapting process running 24/7 )
Signalling / Messaging layer with ZeroMQ has ports and/or bindings available and ready for most of the mainstream and many of niche programming languages, including java.
Hidden dangers of going just against a published API:
While the efforts for system integration and testing are immense, the API specifications are always dangerous for specification creeping.
This said, add countless man*months consumed on debugging after a silent change in MT4 language specifications that de-rail your previous tools + libraries. Why? Just imagine. Some time ago, MQL4 stopped to be MQL4 and was silently shifted towards MQL5, under a name New-MQL4. Among other changes in compilation, there were many small and big nails in the coffin -- string surprisingly ceased to be a string and was hidden as an internal struct -- which one could guess what will cause with all DLL-calls.
So, beware of API creepings.
Does it hurt a distributed processing solution?
No.
With a wise message-layout design, there are no adverse effects of MetaTrader Terminal 4 behaviour and all the logic ( incl. the strategy decision ) is put outside this creeping platform.
Doable. Fast and smart. Also could use remote-GPU-cluster processing, if your budget allows.
Does it work even in Strategy Tester?
Yes, it does.
If anyone has the gut to rely on the in-built Strategy Tester, the distributed-processing model still works there. Performance depends on the preferred style of modelling, a full one year, tick-by-tick simulation, with a quite complex AI/ML components took a few days on a common COTS desktops PC-systems ( after years of Quant R&D, we do not use Strategy Tester internally at all, but the request was to batch-test the y/y tick-data, so could be commented here ).

GetDriveType() equivalent in Java

Is there any method which performs similar tasks to the GetDriveType() method of Microsoft Visual C++. I've already gone through the FileSystemView class of Java Swing. But the method available there are limited and does not fulfill my requirement.
So please tell me someone if Java defines any such method for Windows platform or Platform Independent.
You can use File.listRoots() method. It will list all the drives in your system.
And to get detail information about that drive you can use the following code.
List roots = Arrays.asList(File.listRoots());
for(File f:roots)
{
String s = FileSystemView.getFileSystemview().getSystemTypeDescription(f);
}
This code shows the actual information of drives and other PnP devices. Use this link to know more. And according to your question you must be want to know the hardware details of connected drives to PC. Use JNI if you want to do all code in java.
Are you using JDK7?
If so, there is FileStore which returns the type as a String.
However, looking at the source code itself (FileStore.java) there is a warning that the return value might be implementation specific.

What Delta Encoding/Compression Algorithm libraries are there for Java?

So I'm reading up on delta encoding, and I was looking around for some good examples of it. I think Google Chrome uses something like that for patch updates, rsync might, and the Wikipedia article implies that alot of online backup tools use this.
I'm curious if there are any good Java libraries out there that do this kind of work? There seem to be an abundance of *nix and C-based tools, but little or no Java equivalents that do much more than compress data structures.
In any event, this is an entirely new concept for me, so I'm curious to read up on anything about it, with a particular interest in seeing anyone using Java to do it.
I know this is an outrageously old question, but I decided to post this here just incase anyone else stumbles onto the same problem.
This is what I am currently using. It's really simple and works great.
https://code.google.com/p/xdeltaencoder/
You will need to make sure to checksum the source though (in my case fileAJson), as it does not do it automatically for you!
Anyways, code below:
//Create delta
String[] deltaArgs = new String[]{fileAJson.getAbsolutePath(), fileBJson.getAbsolutePath(), fileDelta.getAbsolutePath()};
XDeltaEncoder.main(deltaArgs);
//Apply delta
deltaArgs = new String[]{"-d", fileAJson.getAbsolutePath(), fileDelta.getAbsolutePath(), fileBTarget.getAbsolutePath()};
XDeltaEncoder.main(deltaArgs);
//Trivia, Surpisingly this also works
deltaArgs = new String[]{"-d", fileBJson.getAbsolutePath(), fileDelta.getAbsolutePath(), fileBTarget.getAbsolutePath()};
XDeltaEncoder.main(deltaArgs);
Update data only by difference between files (delta for java)
Wikipedia lists several Java implementations for the VCDIFF delta format.
There also exist Java implementations of the rsync algorithm, which can be used to create binary diffs. They don't seem production-ready, but if you just want to see the code they're fine. See Any good rsync library for Java?.

Categories

Resources