24位音频的Java播放不正确

24位音频的Java播放不正确,java,audio,24-bit,Java,Audio,24 Bit,我正在使用javaxsoundapi实现一个基于javax的简单控制台播放程序 使用24位斜坡文件(每个样本是最后一个样本加上24位范围内的1)对其进行测试后,很明显在播放过程中发生了一些奇怪的事情。记录的输出不是文件的内容(我有一个数字环回来验证这一点) 它似乎以某种方式对样本进行了错误解释,导致左通道看起来好像应用了一些增益,而右通道看起来好像正在衰减 我已经研究了平移和平衡控件是否需要设置,但这些控件不可用,我已经检查了windows xp音响系统设置。此渐变文件的任何其他播放形式都可以

我正在使用javaxsoundapi实现一个基于javax的简单控制台播放程序

使用24位斜坡文件(每个样本是最后一个样本加上24位范围内的1)对其进行测试后,很明显在播放过程中发生了一些奇怪的事情。记录的输出不是文件的内容(我有一个数字环回来验证这一点)

它似乎以某种方式对样本进行了错误解释,导致左通道看起来好像应用了一些增益,而右通道看起来好像正在衰减

我已经研究了平移和平衡控件是否需要设置,但这些控件不可用,我已经检查了windows xp音响系统设置。此渐变文件的任何其他播放形式都可以

如果我对一个16位文件进行相同的测试,它将正确执行,不会损坏流


那么,有人知道为什么Java Sound API会修改我的音频流吗?

24位音频的Java播放问题实际上与Microsoft DirectSound和/或其Windows Java Sound实现有关。使用带有Java声音和ALSA的Linux,24位音频可以完美播放(记录输出显示与输入文件有点完美匹配)

要了解它在Windows中不起作用的原因,您可以使用查询您要在Java中播放的输出行的支持音频格式(其中
lineInfo
是输出行的
line.Info
):

DataLine.Info dataLineInfo=(DataLine.Info)lineInfo

然后循环使用支持的格式:

for(AudioFormat-lineFormat:dataLineInfo.getFormats())

对于Windows,我得到了如下结果:

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
它不支持24位格式。但在Windows XP中,它仍然允许我播放24位音频,但可能通过Java/DirectSound将其处理到16位,然后通过声卡将其备份到24位。因此,数据输出不正确。在Windows7中,我发现它只是拒绝播放24位音频(如果它所要做的只是降低到16位,可能更明智)

对于Linux(Fedora 17),我得到了类似的东西(在同一台PC上使用完全相同的声卡,一个ESI Juli@):

其支持的格式为24位。因此,这是预期的,没有多余的额外处理

因此,似乎24位播放确实适用于Java声音,前提是特定于操作系统(可能是特定于设备,但我迄今为止还没有发现我尝试过的设备之间存在任何差异)的实现将其列为受支持的音频格式。我的测试表明Linux(ALSA)确实支持它,而Windows(DirectSound)则不支持

希望这对别人有帮助;我在网上找不到关于这个问题的任何其他信息,这就是为什么我发布了这样一个老问题

以下是我的第一个问题,我刚刚回答了(我把它留作参考):


我不确定这是否是一个正确的程序来处理旧问题,但从阅读常见问题来看,这似乎比发布新问题更可取。我已经在其他几个地方(包括Oracle Java Sound论坛)发布了这个问题,但到目前为止没有任何回应,这个问题听起来与我遇到的问题完全相同:

我使用Java声音播放音频文件(标准PCM格式),但我注意到它不能正确播放24位数据,因为声卡输出的数据与文件输入不匹配。它适用于16位(甚至8位)音频数据,但不适用于24位(大概是32位,但我没有真正的32位音频文件要测试)文件。从输出中可以看出,Java Sound在将音频数据传递到声卡之前,正在对音频数据进行一些额外(和不需要的)处理。我可以肯定地说,是Java声音在这样做,因为如果我使用ASIO运行相同的测试来播放文件,那么就不会有问题,数据也会如预期的那样匹配

有关设置的更多信息: -JavaJRE最新版本(我想是7u7),运行在WindowsXPSP3上。 -在jsresources.org上使用AudioPlayer示例(如主要问题中所述)播放声音(我首先尝试使用自己的代码,但如果我犯了错误,则切换到该示例,两个示例的结果相同)。 -音频通过数字(S/PDIF)输出在M-audio声卡上播放,数字(S/PDIF)输出直接连接(通过外部电缆)到Lynx声卡(在同一台PC中)上的数字输入,并在那里录制(使用Sony Sound Forge)。 -然后将记录的文件与输入波形文件进行比较

对于测试,使用四个不同的输入波形文件(从同一源文件生成): -16位,44.1千赫; -16位,48kHz; -24位,44.1千赫; -24位,48千赫

使用ASIO回放测试文件,所有四个文件都产生了正确的输出(在按record和play之间对齐起始位置后,记录的数据逐字节匹配输入波形文件数据)

使用Java回放测试文件,16位(44.1 kHz和48 kHz)产生正确的输出,而24位(44.1 kHz和48 kHz)不产生正确的输出。不仅如此,输出不正确的方式也是不一致的(如果我运行测试两次,每次都会产生不同的输出,两者都与输入文件不匹配)。因此,Java声音不仅错误地播放了24位文件,而且每次都以不同的方式错误地播放。如果有帮助,我可以将Java声音输出截图与输入文件(预期输出)进行比较

再现这一点的最简单方法是使用上面提到的AudioPlayer示例,播放24位文件并记录输出(如果您只有一个声卡,则可以使用其混音器适当地路由数据,以便捕获数据)。当它
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,