2

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

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

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

这个网站很好地解释了 16 位声音编码的基础知识。但是,对我来说,继续逐字节编辑文件还不够好。如何对 16 位(或更大)的声音文件进行逐字节编辑,同时仍保持其更高的保真度?用每个样本 16 位而不是 8 位编码声音的公式是什么?

4

1 回答 1

0

如何对 16 位(或更大)的声音文件进行逐字节编辑...?

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

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

这让我认为偶数字节包含奇数字节中静态的精确逆,其中包含要播放的实际声音。

这是有道理的。信号处理中“噪声”的定义是你听到的和你想听到的之间的区别。当您将所有奇数字节清零时,您踩到了每个样本的低位部分。通过改变样本,你引入了一些你不想听到的东西(即噪音)。当您将偶数字节归零时,您将杀死所有高位,因此也杀死了大部分信号。保留在低位字节中的内容与您在第一个实验中引入的噪声完全相反。(你的耳朵无法分辨给定声波和同一声波的倒数之间的区别。)

样本值和压力之间没有绝对的映射关系,但您应该知道以下几点:

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

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

于 2014-01-03T15:04:49.293 回答