1

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:

  1. How can I still get list of supported formats Java gets from hardware? In this case I could just write own DirectAudioDevice.

  2. 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.

Don Cesar D'Bazar
  • 321
  • 1
  • 2
  • 9
  • I've had way too many troubles with java audio while developing https://github.com/tulskiy/musique, especially on linux. If you need reliable sound, java is just not good enough. – Denis Tulskiy Jun 11 '13 at 07:35
  • It looks like situation changed recent time. I found Java very convenient for playing music and incredibly portable, same code runs under Mac, Windows, Linux and ARM Linux versions. Besides of the hardcoded 16 bits limitation in Java runtime, I didn't observe any problems. Certainly I have performance issues with WAVPACK and APE on high sample rates music, however I believe it is problem in decoder code quality, so I am planning to borrow your decoders for sure. – Don Cesar D'Bazar Jun 13 '13 at 21:21
  • one of the biggest problems I've found is that sound pauses whenever there's an old GC collection :) which is kind of a bummer - I had to profile a lot of code to avoid extra memory usage. And still now I'm getting some pauses in sound on linux and no time to figure them out. – Denis Tulskiy Jun 14 '13 at 05:05
  • but yeah, feel free to use any code from the project, it would be nice knowing it helped somebody :) – Denis Tulskiy Jun 14 '13 at 05:06
  • It is really strange you observe GC impact problems. I use IcedTea JVM on Linux (slowest one accordingly official benchmarks) and my machine is Celeron based, and playback is smooth in any format up to 24/192. Say more I do dynamic downsampling in Java since Java refused to accept 24bits. I worked with Peter who did wavpack port in Java on improving performance and reduce memory allocations. I got some acceptable results on Raspberry PI, but still 24/192 not playable so I will give try your modifications. BTW I am from Moscow. – Don Cesar D'Bazar Jun 14 '13 at 05:26
  • well, if you ever plan to open-source your code, let me know – Denis Tulskiy Jun 14 '13 at 05:38
  • I think general improvements of sound playback happened after switching to JDK 7. I guess you struggled mostly because of JDK 6 JVM imperfection. All my code is open. General playback is implemented in MediaChest, and web interfaced player (Raspberry Pi version) is Music Barrel. Both the projects're hosted at sourceforge. Currently I am working on Android version of the player. So I expect new challenges of a different sound API and Dalvik JVM. – Don Cesar D'Bazar Jun 14 '13 at 17:44
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/31777/discussion-between-denis-tulskiy-and-don-cesar-dbazar) – Denis Tulskiy Jun 14 '13 at 18:23

2 Answers2

1

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.

Don Cesar D'Bazar
  • 321
  • 1
  • 2
  • 9
  • I'm wondering which Java runtime that code is from? Win/Linux/OSX? Version? Besides using JCP, you could also simply file a bug report at [bugreport](http://bugreport.sun.com/bugreport/). – Hendrik Nov 11 '13 at 09:25
  • Don Cesar, have you tried to talk to responsible persons inside Oracle about this ? There is nothing wrong with JavaSound except this outdated 16bit samplesize limitation. I would be interested in a joint effort to request an update of that native part – carl Dec 01 '14 at 20:05
0

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.

Community
  • 1
  • 1
Igor Rodriguez
  • 1,196
  • 11
  • 16