我写了一些代码,根据位深度从音频缓冲区读取数据,对其进行处理,然后将其写回相同的缓冲区。我必须处理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);但是输出是不正确的。谁能指出这里出了什么问题??
谢谢
谢谢你的建议。我实现了你们的建议,但仍然有一些缺陷:
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);有没有人看到上面的代码有问题?
谢谢,安妮
发布于 2011-07-15 20:38:25
您不能修改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);但这将取决于数据的存储方式。
发布于 2011-07-15 20:39:13
使用这样的代码,你需要非常小心endianness issues,字节复制到一个多字节的单变量是不安全的。
最好是一次读取一个字节,这样您就可以用防止字符顺序的方式来表示您希望每个字节到达的值的位置。当然,这要求您考虑源数据中多字节24位值的字节排序。
发布于 2020-08-16 11:51:10
将@user786653答案泛化为多个位深度。
uint32_t sample = 0;
for (int i = 0; i < bit_depth / 8; i++) {
sample = ((uint32_t)source[i] << (i * 8)) | sample;
}https://stackoverflow.com/questions/6706881
复制相似问题