我现在无法看到为什么只取高位字节是不够的,即丢弃每个样本的低8位.
那当然假设样品是线性的; 如果它们不是那么可能你需要做一些事情来线性化它们然后丢弃位.
short sixteenBit = 0xfeed;
byte eightBit = sixteenBit >> 8;
// eightBit is now 0xfe.
Run Code Online (Sandbox Code Playgroud)
正如AShelly在评论中所建议的那样,舍入可能是一个好主意,即如果我们丢弃的字节高于其最大值的一半,则加1:
eightBit += eightBit < 0xff && ((sixteenBit & 0xff) > 0x80);
Run Code Online (Sandbox Code Playgroud)
针对0xff的测试实现了钳位,因此我们不会冒险添加1到0xff并将其包装到0x00,这将是不好的.
小智 6
16位采样通常是有符号的,8位采样通常是无符号的,因此最简单的答案是需要转换带有符号的16位采样(16位采样几乎总是存储在-32768范围内) +32767)to unsigned然后取结果的前8位.在C中,这可以表示为output =(unsigned char)((unsigned short)(输入+ 32768)>> 8).这是一个良好的开端,可能足以满足您的需求,但听起来不是很好.由于"量化噪声",它听起来很粗糙.
量化噪声是原始输入和算法输出之间的差异.无论你做什么,你都会产生噪音,平均噪音将是"半个小时".你无能为力,但有办法让噪音不那么明显.
量化噪声的主要问题是它倾向于形成模式.如果输入和输出之间的差异是完全随机的,事情实际上听起来很好,但是输出对于波形的某个部分反复过高而对于下一部分则过低.你的耳朵会接受这种模式.
要获得听起来不错的结果,您需要添加抖动.抖动是一种试图平滑量化噪声的技术.最简单的抖动只是从噪声中去除了模式,因此噪声模式不会分散实际的信号模式.更好的抖动可以更进一步,并采取措施通过将多个样本的误差值加在一起来减少噪声,然后在总误差足够大以便进行校正时添加校正.
您可以在线找到各种抖动算法的解释和代码示例.一个很好的研究领域可能是SoX工具,http://en.wikipedia.org/wiki/SoX.检查信号源的抖动效果,并尝试在启用和不启用抖动的情况下将各种声音从16位转换为8位.转换为8位声音时,抖动可以产生的质量差异会让您感到惊讶.