我正在使用Javax Sound API来实现基于的简单控制台播放程序 http://www.jsresources.org/examples/audioplayer.html.

使用24位坡道文件对其进行了测试(每个示例是整个24位范围内的最后一个样本加1),很明显,在播放期间发生了一些奇数。记录的输出不是文件的内容(我有一个数字回扣来验证这一点)。

它似乎以某种方式误解了样本,这会导致左通道看起来像是对其应用了一定的增益,并且正确的频道看起来好像正在减弱。

我已经研究了平底锅和平衡控制是否需要设置,但是这些都不可用,并且已经检查了Windows XP音响系统设置。该坡道文件的任何其他形式的播放形式都可以。

如果我使用16位文件进行相同的测试,则可以正确执行,而没有流的损坏。

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

有帮助吗?

解决方案

Java播放24位音频的问题实际上是Microsoft DirectSound和/或Windows Java声音的实现。使用Linux与Java Sound和ALSA,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位,然后由SoundCard备份到24位。因此,为什么数据输出不正确。在Windows 7中,我发现它只是拒绝播放24位音频(如果它要做的就是跌至16位,则可能更明智)。

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

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, 

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

因此,只要OS特定(可能是特定于设备的),似乎24位播放确实可以与Java Sound一起使用,但我迄今为止尝试过的设备之间还没有发现任何变化)将其列出为支持的音频格式。我的测试表明Linux(ALSA)确实支持它,而Windows(DirectSound)则没有。

希望这对某人有帮助。我在网上找不到有关此的其他任何信息,这就是为什么我在这样一个古老的问题上发布的原因。

以下是我刚刚回答的最初问题(我已将其保留供参考):


我不确定这是否是解决旧问题的正确过程,但是从阅读常见问题解答,它看起来更喜欢发布新问题。我已经在其他几个地方(包括Oracle Java Sound论坛)发布了这个问题,但是到目前为止没有回答,这个问题听起来与我遇到的问题完全相同:

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

有关设置的更多信息:-Java JRE最新版本(我认为7U7),在Windows XP SP3上运行。 - 使用Audioplayer示例(如主题中提到的)播放的声音(我首先尝试使用自己的代码,但在我犯了一个错误的情况下切换到了,这两者都相同)。 - 音频是通过数字(S/PDIF)在M-Audio SoundCard上播放的,该数字(S/PDIF)直接连接(通过外部电缆)与lynx SoundCard(在同一PC中)上的数字连接在一起,录制(使用Sony Sound Forge)。 - 然后将记录的文件与输入波文件进行比较。

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

使用ASIO播放测试文件,所有四个文件都产生了正确的输出(记录的数据与BYTE的输入Wave文件数据字节匹配,在对齐时间之间的启动位置和按下播放之间的时间之后)。

使用Java播放测试文件,16位(44.1 kHz和48 kHz)产生了正确的输出,而24位(44.1 kHz和48 kHz)则没有。不仅如此,而且输出不正确的方式是不一致的(如果我两次运行测试,它每次都会产生不同的输出,两者都不接近与输入文件匹配)。因此,Java Sound不仅播放24位文件,而且每次都以不同的方式进行操作。如果有帮助,我可以与输入文件(预期输出)进行Java声音输出的屏幕截图。

重现的最简单方法是使用上面提到的AudioPlayer示例,播放24位文件并记录输出(如果您只有一个声卡,则可以使用其混音器适当地路由数据以适当地路由以允许它为捕获)。虽然我能听到任何差异还不够错误,但如果以某种意想不到的方式更改了数据,它确实会击败高分辨率音频的目的(您有可能因使用16位的24位而失去任何收益,尽管我真的不想在这里参与该论点)。

因此,要将其作为一个问题 - 如何使Java声音正确播放24位音频?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top