繁体   English   中英

24位音频处理

[英]24 bit audio processing

我编写了一些代码,它们根据位深度从音频缓冲区读取数据,对其进行处理并将其写回同一个缓冲区。 我必须处理 16 位和 24 位深度。 16 位的代码工作正常,但 24 位却不行。

这是我为 24 位数据的每个样本所做的事情:

int data = 0;

//read data from buffer
RtlCopyMemory (&data, ((char*)Source) + head, 3);

//scale data for integer

data = data << 8;

//data processing

data = data * m_CurOutVolLevel;

//scaling down the data
data = (data >> 8);

RtlCopyMemory (((char*)Source) + head, &data, 3);

但 output 不合适。 有人可以指出这里有什么问题吗?

谢谢

感谢您的建议。 我实现了你们的建议,但仍然存在一些缺陷:

unsigned __int64 newData;
unsigned char* s = ((unsigned char*)Source) + head;
unsigned int data = ((unsigned int)s[0] << 8) | ((unsigned int)s[1] << 16) |((unsigned int)s[2] << 24);

// data processing
newData = (unsigned __int64)(data * m_pMiniport->m_CurOutVolLevel);
//divide this by 2 to the power 16
newData = (newData >> 16); 

// store back
s[0] = (unsigned char)((newData >> 32)  & 0xff);
s[1] = (unsigned char)((newData >> 40) & 0xff);
s[2] = (unsigned char)((newData >> 48) & 0xff);

有人看到上面的代码有问题吗?

谢谢,安妮

好吧,您使用int ,如果它在 32 位机器上,则通常是 32 位。 如果数据是 24 位,则将其移位意味着您甚至可以使用最高位。 这会导致两件事:

  • 移位的第一个可能重载,因为您的 int 已签名,如果位“24”(数据中的最高位)为 1,则结果中的位 32 将为 1,它将变为负数。

  • 第二个可能的乘法溢出,假设没有发生上述情况,您现在很可能会超出 32 位数字的边界。 假设第 23 位已设置,因此您的数字保持正数,如果 m_curOutVolLevel 甚至仅低至 2,则这等于 exta 位移,并且您再次溢出。 更有可能您甚至会丢失位,因为该数字不能再以 32 位存储。

编辑:可能的解决方案,如果这是问题:使用uint64_t from stdint.h

编辑2 :还请注意,您的代码可能会出现字节顺序问题,因为您只需将 int 编码为字节 stream (除非RtlCopyMemory处理此问题,我对此表示怀疑)。

为多个位深度概括@user786653 答案。

uint32_t sample = 0;
for (int i = 0; i < bit_depth / 8; i++) {
    sample = ((uint32_t)source[i] << (i * 8)) | sample;
}

您不能修改int的某些部分,而只是期望代码能够工作(更不用说可移植了)。

假设数据以无符号小端顺序存储,您可以像这样访问它:

unsigned char* s = ((unsigned char*)Source) + head;
uint32_t data = ((uint32_t)s[0] << 8) | ((uint32_t)s[1] << 16) | ((uint32_t)s[2] << 24);
// use data
// store back
s[0] = (unsigned char)((data >> 8) & 0xff);
s[1] = (unsigned char)((data >> 16) & 0xff);
s[2] = (unsigned char)((data >> 24) & 0xff);

但这将取决于数据的存储方式。

您需要非常小心此类代码的字节顺序问题,将字节复制到多字节单变量中是不安全的。

最好一次读取一个字节,这样您就可以以防字节序的方式表达您希望每个字节到达的值。 当然,这需要您考虑数据中多字节 24 位值的字节顺序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM