将24位有符号int信号转换为16位有符号int信号

时间:2015-02-03 04:42:55

标签: c++ audio casting signal-processing

尽可能简单地说出来。

  1. 我从设备接收数据,信号是24位符号int。
  2. 我想创建16位WAV文件。
  3. 为此,我想继续将带有256个样本的即将到来的音频缓冲区写入* .wav文件流。
  4. 如何将[24位有符号整数]中的缓冲区值(以简单指针写入256位元素数组的值)转换为[16位有符号整数]。
  5. 是否有任何缩放值?例如,当我想将[24位有符号整数]转换为[24位有符号双]时,我这样做了:

    for (int i=0; i<256; i++) {
       bufferInDouble = *((int*)bufferRawData[currentPan]+i) / (double)0x7fffffff;
    }
    

    可能有任何类似的方法吗?

2 个答案:

答案 0 :(得分:3)

该方法将根据您是否打包24位数据或只是24位存储在32位字中而有所不同。我会假设它没有打包,并且在整数内是合理的,因为这是最常见的。

该技术只是将数据向下移动到16位数据类型

ABCDEFxx => ABCD 

这里我已经显示了32位整数的半字节,其中ABCDEF包含24位音频数据,xx字节不包含任何值。向右移动16将丢弃EFxx

short outBuffer[256]
int* inBuffer = ((int*)bufferRawData);
for (int i = 0 ; i < 256 ; ++i)
{
    outBuffer[i] = (short)(inBuffer[i] >> 16);
}

另一方面,通常需要在减小位深度时在LSB中添加一些低电平噪声以减少量化失真。这被称为抖动。有关信息,请参阅维基百科Dither

上的这篇文章

答案 1 :(得分:0)

一般答案是除以256.请注意,右移位不能与signed int s(在您的问题中指定)一起移植:{{3} }表示E1 >> E2的行为,其中E1是负的签名值,实现已定义

可以保留更高音质的另一种选择是在现有数据中找到最高振幅值(因此,只有在开始缩放之前接收到所有数据时才能执行此操作) - 让我们称之为M - 然后计算出缩放比例因子F使得该最高值具有高达16位有符号值的新幅度:即32767。

M / F = 32767.0, so
F = M / 32767.0