Java 16+;位音频格式有效吗?

Java 16+;位音频格式有效吗?,java,audio,bytearray,wav,Java,Audio,Bytearray,Wav,我试图用Java编写一些基本的声音编辑程序,但是我的16位WAVE文件格式遇到了很多麻烦 当我问Java它认为我的声音文件有多少个样本时,它给出的数字是我预期的两倍。当我告诉Java生成80000字节采样的正弦波时,它播放了1秒而不是2秒(尽管采样率约为每秒40000次) 在进一步搜索之后,我意识到我的文件的“帧大小”是2,“样本”实际上是2字节而不是1字节,这被称为16位音频文件。作为一个实验,我将声音文件写入一个字节数组,将每隔一个字节设置为0,然后播放结果。当我只保留奇数个样本时,声音文件

我试图用Java编写一些基本的声音编辑程序,但是我的16位WAVE文件格式遇到了很多麻烦

当我问Java它认为我的声音文件有多少个样本时,它给出的数字是我预期的两倍。当我告诉Java生成80000字节采样的正弦波时,它播放了1秒而不是2秒(尽管采样率约为每秒40000次)

在进一步搜索之后,我意识到我的文件的“帧大小”是2,“样本”实际上是2字节而不是1字节,这被称为16位音频文件。作为一个实验,我将声音文件写入一个字节数组,将每隔一个字节设置为0,然后播放结果。当我只保留奇数个样本时,声音文件播放时带有一点点静态噪音。当我只保留偶数时,静态噪音会在没有声音文件的情况下自行播放。这使我认为偶数字节包含与奇数字节中静态的完全相反的内容,奇数字节包含要播放的实际声音。当一起播放时,偶数字节会使奇数字节中的静电静音,从而提高声音的保真度

对16位声音编码的基础知识有很好的解释。但是,对我来说,开始逐字节编辑文件还不够好。如何对16位(或更大)的声音文件进行逐字节编辑,同时保持其较高的保真度?用16位而不是8位来编码声音的公式是什么

如何逐字节编辑16位(或更大)的声音文件

这个问题毫无意义。当你说“逐字节编辑”时,你真的应该说“逐样本”。在这种情况下,每个样本是16位(或两个字节),将样本分开是没有意义的。这就像在文本编辑器中只编辑每个字母的上半部分一样

数字音频流的单个通道是一个数字序列(也称为样本)。每个样本都代表了声波在某个瞬间施加在话筒振膜上的压力。在8位声音文件中,只有256个可能值,而在16位声音文件中,有65536个可能值。16位文件具有更高的分辨率

这使我认为偶数字节包含与奇数字节中静态的完全相反的内容,奇数字节包含要播放的实际声音

这是一个真理的核心。信号处理中“噪声”的定义是你听到的和你想听到的之间的区别。当您将所有奇数字节归零时,您正在对每个示例的低阶部分进行踩踏。通过更改样本,您引入了一些您不想听的内容(即噪音)。当您将偶数字节归零时,您将删除所有高阶位,从而删除大部分信号。低阶字节中剩下的是与您在第一次实验中引入的噪声完全相反的噪声。(你的耳朵分辨不出给定声波和同一声波的相反方向之间的区别。)

采样值和压力之间没有绝对映射,但有几件事你应该知道:

1) 这些样品是有签名的还是没有签名的?每个样本都有一个值,该值必须介于某个最小值和某个最大值之间。如果(16位)样本被签名,则最小值为-32768(0x8000),最大值为32767(0x7FFF),0位于中间。如果样本是无符号的,则最小值为0,最大值为65535(0xFFFF)。如果弄错了,你会马上知道,因为你所听到的只是巨大的噪音


2) 样本是线性的吗?样本值总是与某些东西成比例的。如果它们与声压级成正比,那就是所谓的“线性编码”。但它们可能与声压的对数成正比,或者与声压的其他函数成正比。非线性编码几乎总是8位的,而且通常只在电话等特殊应用中遇到。如果您处理的是16位或更大的样本,那么它们几乎肯定是线性的。

您使用什么类型的样本?听起来很像你把它们当作8位的,但是读写16位的样本。我一直在逐字节读取每个音频文件,并将文件存储在字节数组中(字节[])。是的,我把每个样本都当作8位而不是16位。