我将不得不在24位音频数据方面做很多工作。它只是无符号整数,而不是32位,而是24位。那么在C中定义和处理24位数据的更简单的方法是什么呢?
发布于 2011-09-14 13:10:33
根据需要,我可能会使用一个位字段:
struct int24{
unsigned int data : 24;
};
或者,如果分隔更容易,只需使用3个字节(unsigned char
)。如果你不想填充结构,你可以强制它被打包。
编辑:我看到C++
标签被删除了,但不管你是否更习惯使用C++,我还是把它留在这里,你可以使用如下内容:
const int INT24_MAX = 8388607;
class Int24
{
protected:
unsigned char value[3];
public:
Int24(){}
Int24( const Int24& val )
{
*this = val;
}
operator int() const
{
/* Sign extend negative quantities */
if( value[2] & 0x80 ) {
return (0xff << 24) | (value[2] << 16)
| (value[1] << 8)
| value[0];
} else {
return (value[2] << 16)
| (value[1] << 8)
| value[0];
}
}
Int24& operator= (const Int24& input)
{
value[0] = input.value[0];
value[1] = input.value[1];
value[2] = input.value[2];
return *this;
}
Int24& operator= (const int input)
{
value[0] = ((unsigned char*)&input)[0];
value[1] = ((unsigned char*)&input)[1];
value[2] = ((unsigned char*)&input)[2];
return *this;
}
Int24 operator+ (const Int24& val) const
{
return Int24( (int)*this + (int)val );
}
Int24 operator- (const Int24& val) const
{
return Int24( (int)*this - (int)val );
}
Int24 operator* (const Int24& val) const
{
return Int24( (int)*this * (int)val );
}
Int24 operator/ (const Int24& val) const
{
return Int24( (int)*this / (int)val );
}
Int24& operator+= (const Int24& val)
{
*this = *this + val;
return *this;
}
Int24& operator-= (const Int24& val)
{
*this = *this - val;
return *this;
}
Int24& operator*= (const Int24& val)
{
*this = *this * val;
return *this;
}
Int24& operator/= (const Int24& val)
{
*this = *this / val;
return *this;
}
Int24 operator>> (const int val) const
{
return Int24( (int)*this >> val );
}
Int24 operator<< (const int val) const
{
return Int24( (int)*this << val );
}
operator bool() const
{
return (int)*this != 0;
}
bool operator! () const
{
return !((int)*this);
}
Int24 operator- ()
{
return Int24( -(int)*this );
}
bool operator== (const Int24& val) const
{
return (int)*this == (int)val;
}
bool operator!= (const Int24& val) const
{
return (int)*this != (int)val;
}
bool operator>= (const Int24& val) const
{
return (int)*this >= (int)val;
}
bool operator<= (const Int24& val) const
{
return (int)*this <= (int)val;
}
/* Define all operations you need below.. */
发布于 2011-09-14 13:08:27
干净和可移植的方式,假设你的样本是低字节顺序和未签名的:
static inline uint32_t getsample(uint8_t *buf, size_t pos)
{
return buf[3*pos] + 256UL*buf[3*pos+1] + 65536UL*buf[3*pos+2];
}
static inline void putsample(uint8_t *buf, size_t pos, uint32_t sample)
{
buf[3*pos]=sample;
buf[3*pos+1]=sample/256;
buf[3*pos+2]=sample/65536;
}
修复它使其适用于带符号的值,这需要更多的工作,特别是如果你想让它保持可移植性的话。请注意,如果在处理之前将整个样本窗口转换为更健全的格式,然后在处理完成后再转换回来,性能可能会更好。
发布于 2011-09-14 13:09:02
使用足以容纳24位数据的数据类型。它们都是在stdint.h中定义的int32_t
或uint32_t
你正在处理音频数据,所以你想要加法工作(你需要它来混合)。此外,有一些额外的8位也不是一件坏事,因为它为你提供了大约24dB的额外动态范围,你需要混合几个充分利用24位动态范围的信号源。
请注意,您刚才询问的是用于24位样本的数据类型。如果你打算读取一个整齐打包的24位样本帧流,你必须将其拆分。首先,您必须知道流是高字节优先的还是低字节优先的。然后,您可以使用类似以下内容将流重新排列为样本:
uint32_t bitstream_BE_to_sample(uint8_t bits[3])
{
return (bits[0] << 16) | (bits[1] << 8) | (bits[2]);
}
uint32_t bitstream_LE_to_sample(uint8_t bits[3])
{
return (bits[2] << 16) | (bits[1] << 8) | (bits[0]);
}
uint8_t *bitstream;
uint32_t *samples;
for(;;) {
*samples = bitstream_XX_to_sample(bitstream);
samples++;
bistream += 3;
if(end_of_bitstream())
break;
}
https://stackoverflow.com/questions/7416699
复制相似问题