This discussion is archived
5 Replies Latest reply: Oct 6, 2012 4:06 PM by 960264 RSS

Incorrect Playback of 24 bit Audio (data mismatch / unwanted processing)

960264 Newbie
Currently Being Moderated
Hi all,

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.

For the test, four input Wave files are used:
- 16 bit, 44.1 kHz
- 16 bit, 48 kHz
- 24 bit, 44.1 kHz
- 24 bit, 48 kHz

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).
  • 1. Re: Incorrect Playback of 24 bit Audio (data mismatch / unwanted processing)
    960264 Newbie
    Currently Being Moderated
    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.

    In Windows 7 the supported audio formats are reported as:
    ---
    Format #1: PCM_UNSIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
    Format #2: PCM_SIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
    Format #3: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, little-endian
    Format #4: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, big-endian
    Format #5: PCM_UNSIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
    Format #6: PCM_SIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
    Format #7: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, little-endian
    Format #8: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian
    ---
    And it's the same list for both the ESI and Realtek devices, so this seems to be due to the Windows Java Sound implementation and/or DirectSound.
    It also explains why 24 bit refuses to play, because it is not a supported format.

    In Windows XP the supported audio formats are reported as (again the same for both devices):
    ---
    Format #1: PCM_UNSIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
    Format #2: PCM_SIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
    Format #3: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, little-endian
    Format #4: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, big-endian
    Format #5: PCM_UNSIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
    Format #6: PCM_SIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
    Format #7: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, little-endian
    Format #8: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian
    ---
    So the reported formats are the same as for Windows 7, but the difference is that Java Sound will let you play 24 bit audio data even though it isn't on the list of supported audio formats.
    My guess is that Windows Java Sound / DirectSound doesn't actually support 24 bit, but accepts that format and presumably converts down to 16 bit, which the soundcard then processes to 24 bit, hence the incorrect data output.

    In Linux (Fedora 17), the supported audio formats are reported as:
    ---
    Format #1: PCM_SIGNED unknown sample rate, 32 bit, mono, 4 bytes/frame, little-endian
    Format #2: PCM_SIGNED unknown sample rate, 32 bit, mono, 4 bytes/frame, big-endian
    Format #3: PCM_SIGNED unknown sample rate, 32 bit, stereo, 8 bytes/frame, little-endian
    Format #4: PCM_SIGNED unknown sample rate, 32 bit, stereo, 8 bytes/frame, big-endian
    Format #5: PCM_SIGNED unknown sample rate, 24 bit, mono, 4 bytes/frame, little-endian
    Format #6: PCM_SIGNED unknown sample rate, 24 bit, mono, 4 bytes/frame, big-endian
    Format #7: PCM_SIGNED unknown sample rate, 24 bit, stereo, 8 bytes/frame, little-endian
    Format #8: PCM_SIGNED unknown sample rate, 24 bit, stereo, 8 bytes/frame, big-endian
    Format #9: PCM_SIGNED unknown sample rate, 24 bit, mono, 3 bytes/frame, little-endian
    Format #10: PCM_SIGNED unknown sample rate, 24 bit, mono, 3 bytes/frame, big-endian
    Format #11: PCM_SIGNED unknown sample rate, 24 bit, stereo, 6 bytes/frame, little-endian
    Format #12: PCM_SIGNED unknown sample rate, 24 bit, stereo, 6 bytes/frame, big-endian
    Format #13: PCM_SIGNED unknown sample rate, 20 bit, mono, 3 bytes/frame, little-endian
    Format #14: PCM_SIGNED unknown sample rate, 20 bit, mono, 3 bytes/frame, big-endian
    Format #15: PCM_SIGNED unknown sample rate, 20 bit, stereo, 6 bytes/frame, little-endian
    Format #16: PCM_SIGNED unknown sample rate, 20 bit, stereo, 6 bytes/frame, big-endian
    Format #17: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, little-endian
    Format #18: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, big-endian
    Format #19: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, little-endian
    Format #20: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian
    Format #21: PCM_SIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
    Format #22: PCM_UNSIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
    Format #23: PCM_SIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
    Format #24: PCM_UNSIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
    ---
    Again with the same list for both devices, but reported in a different order.

    So Linux Java Sound / ALSA properly supports 24 bit audio, which explains why it handles it perfectly whereas Windows does not.

    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). :)

    Edited by: alexdw on Sep 27, 2012 12:29 PM
  • 3. Re: Incorrect Playback of 24 bit Audio (data mismatch / unwanted processing)
    gimbal2 Guru
    Currently Being Moderated
    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.

    http://www.paulscode.com/forum/index.php?topic=4.0
  • 4. Re: Incorrect Playback of 24 bit Audio (data mismatch / unwanted processing)
    960264 Newbie
    Currently Being Moderated
    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.
  • 5. Re: Incorrect Playback of 24 bit Audio (data mismatch / unwanted processing)
    960264 Newbie
    Currently Being Moderated
    Just a quick message to say that it also works fine on Mac, so it's only Windows where there's a problem.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points