I'm trying to use Java to play audio files but I've noticed that it does not correctly play 24 bit files, in that the output data from the soundcard does not match the data input from the file. It works fine for 16 bit (and 8 bit) files - it's only 24 bit files where Java appears to do some extra (and unwanted) processing. I know it's Java that is the issue because if I use ASIO to play the file then the data does match as expected.

A bit more detail on the situation:
- I'm running the latest version of the Java JRE on Windows XP.
- The audio is played using an M-Audio soundcard, on the digital out (S/PDIF), which is then connected directly to a digital in on a Lynx soundcard (in the same PC), and recorded using Sony Sound Forge.
- The captured file is then compared with the input Wave file.

Using ASIO to play back the test files, all four of the files produce the correct output (the recorded data matches the input Wave file data byte for byte).

Using Java to play back the test files, the 16 bit ones (both 44.1 kHz and 48 kHz) produce the correct output, whereas the 24 bit ones (both sample rates) do not. Furthermore, the way in which the output is incorrect is inconsistent (I've run the test twice, and neither matched the input, nor even each other). So not only is Java playing the 24 bit files wrongly, it is doing it wrongly in a different way each time.

The easiest way to reproduce this issue is to use the player code [AudioPlayer on jsresouces.org|http://www.jsresources.org/examples/AudioPlayer.html] and try to play a 24 bit audio file, capturing the output from the soundcard (or re-routing it internally using the soundcard mixer). It's not wrong enough that you can hear it, but it does kind of defeat the purpose of hi-resolution audio if the data is being altered in some unexpected way.

So I guess my question is - how can I get Java to play back 24 bit audio correctly?

Thanks in advance for any help,

Alex

PS: A thorough search of the forum brings [this thread|https://forums.oracle.com/forums/thread.jspa?messageID=9361370] from over a year and a half ago which seems to be the same problem, but with no solution given ("use ASIO" isn't really a solution as it defeats the point of using Java - that it works cross-platform).

I've finally made some progress with this. It seems the issue was Windows-specific, in that Java Sound works perfectly (producing bit perfect data) in Linux. So the problem was either with Windows DirectSound, or the Java Sound implementation of DirectSound (I can't tell which). I'll update this post with more specific information tomorrow, and then mark it as answered. :)

Edit: The following outlines the testing and results using Java Sound with the same PC and sound card(s) using Linux, Windows XP and Windows 7 (all 64 bit).

The set up is similar to before, with the test player PC connected directly (via S/PDIF out) to a recorder PC (with a Lynx soundcard). The player PC uses a ESI Juli@ soundcard (as it has Linux ALSA support).

With Linux (Fedora 17 to be precise), 16 bit and 24 bit audio plays perfectly using Java Sound with the default ALSA driver for the ESI soundcard. In fact, it even works perfectly using the onboard Realtek sound chip via its (RCA) S/PDIF out.

With Windows XP, the same results are seen as before: 16 bit audio plays perfectly using Java Sound but 24 bit audio is processed in some way.

With Windows 7, it's even worse: 16 bit audio plays (but some kind of processing is done) and 24 bit audio refuses to play at all.

This prompted me to check the supported audio formats for a given device line in Java using:

DataLine.Info dataLineInfo = (DataLine.Info) lineInfo;

and then looping through:

for (AudioFormat lineFormat : dataLineInfo.getFormats())

I didn't do this before as I didn't realise that casting to DataLine.Info exposed more information.

Seeing as the supported audio formats appear to be the same regardless of soundcard and that both soundcards work perfectly using Linux, the lack of 24 bit playback seems to be a limitation of DirectSound and/or the Windows Java Sound implementation rather than device drivers or Java Sound more generally.

Hope this is helpful - I'm marking it as answered even though it isn't fully solved (doesn't work in Windows, works fine in Linux). :)

I don't think JavaSound uses DirectSound in any way, DirectSound is a legacy API. It probably just uses the windows software sound services, which work just fine. Could be that there is a problem in the windows specific implementation of JavaSound of course, its not the best API in the world.

You might want to look into Paul's Sound System. It has JavaSound support and has numerous workarounds for issues built into it, but it also provides sound output through OpenAL / JOAL as an alternative which might work better for you.

Thank you for your reply - I'll have a look at Paul's Sound System. :)

I thought it was using DirectSound in Windows because that's what it says here (the devices list as Direct Audio Device):
http://jsresources.org/faq_audio.html#which_driver_possible
But that website is a few years old so I guess it might not be up to date.