将32位signed int转换为24位为音频数据签名

时间:2018-03-20 23:19:20

标签: c audio types

我正在尝试将32位带符号int的音频数据转换为24位有符号。 目标是编写Wave文件。我已经设法编写了具有8位,16位和32位深度的正确Wave文件,但出于某种原因我苦苦挣扎着24位。声音输出听起来像8位(大量噪音),这似乎意味着只有MSB被正确解释,24位值的第二和第三个字节似乎无法正常工作。

代码:

int buffer_32[1024];
unsigned char buffer_24[1024*3];

for (unsigned i = 0; i < 1024; i++)
{
    buffer_24[i*3] = (unsigned char)((buffer_32[i] & 0xff0000) >> 16);
    buffer_24[i*3+1] = (unsigned char)((buffer_32[i] & 0xff00) >> 8);
    buffer_24[i*3+2] = (unsigned char)(buffer_32[i] & 0xff);
}

基本上,我操纵字节来创建一个24位流('24bit packed')。

我不知道我的转换算法有什么问题:你能帮助我吗?

编辑:我忘了说,在进入这个转换循环之前,我的int值已经正确地缩放到-8388608,8388607(24位有符号整数)范围内。

2 个答案:

答案 0 :(得分:2)

它听起来像是噪音的原因是你正在从数据中剥离MSB。

请改为尝试:

buffer_24[i*3] = (unsigned char)((buffer_32[i] & 0xff000000) >> 24);
buffer_24[i*3+1] = (unsigned char)((buffer_32[i] & 0xff0000) >> 16);
buffer_24[i*3+2] = (unsigned char)((buffer_32[i] & 0xff00) >> 8);

答案 1 :(得分:0)

我做这种事已经30多年了,所以忍受我:

  1. 如果你的音频是多路复用立体声,那么我怀疑你在做什么。
  2. 如果签名位是左右,那么你应该工作(AND)签出并使用结果,然后重新附加(或)重新签名。
  3. 如果您只是想删除顶部字节,那么您应该使用0x00ffffffff(四个字节)与顶部字节进行AND运算。
  4. 如果是纯模拟样本,我会降低分辨率(软件重采样),具体取决于我想要的质量类型,减小音量等。

    相信这有帮助。