c语言 - 将 2 的补码转换为整数并计算 rms 值



Need最快的转换2';s是C中小数的补码,但我不能用它来得到答案,所以发布这个。。。

我有来自音频传感器的32位数据,格式如下:-数据格式为I2S,24位,2的互补,MSB优先。数据精度为18位;未使用的位为零

在没有任何音频输入的情况下,我可以从传感器读取以下数据:-

  • 0xFA578000
  • 0xFA8AC000
  • 0xFA85C000
  • 0xFA828000
  • 0xFA800000
  • 0xFA7E4000
  • 0xFA7D0000
  • 0xFA7BC000

等等…

我需要使用这些数据样本来计算它们的RMS值,然后进一步使用这个RMS值来计算分贝(20*log(RMS((。

这是我的代码和评论:-

//I have 32-bits, with data in the most-significant 24 bits.
inputVal &= 0xFFFFFF00;    //Mask the least significant 8 bits.
inputVal = inputVal >> 8;  //Data is shifted to least 24 bits. 24th bit is the sign bit.
inputVal &= 0x00FFFFC0;  //Mask the least 6 bits, since data precision is 18 bits.
//So, I have got 24-bit data with masked 6 lsb bits. 24th bit is sign bit.
//Converting from 2's complement.
const int negative = (inputVal & (1 << 23)) != 0;
int nativeInt;
if (negative)
nativeInt = inputVal | ~((1 << 24) - 1);
else
nativeInt = inputVal;
return (nativeInt * nativeInt);   //Returning the squared value to calculate RMS

之后,我取平方和值的平均值,并计算其根以获得RMS值。

我的问题是,

  1. 我是否正确地进行了数据位操作
  2. 是否需要将数据样本从2的补码转换为整数以计算其RMS值

***************************************第2部分****************************

继续@Johnny Johansson的回答:-

看起来你所有的样本值都接近-6800,所以我认为这是你需要考虑的偏移量

为了规范化样本集,我计算了样本集的平均值,并将其从样本集中的每个值中减去。

然后,我找到了样本集的最大值和最小值,并计算了峰间值。

// I have the sample set, get the mean
float meanval = 0;
for (int i=0; i <actualNumberOfSamples ; i++)
{
meanval += samples[i];
}
meanval /= actualNumberOfSamples;
printf("Average is: %fn", meanval);
// subtract it from all samples to get a 'normalized' output
for (int i = 0; i < actualNumberOfSamples; i++)
{
samples[i] -= meanval;
}
// find the 'peak to peak' max
float minsample = 100000;
float maxsample = -100000;
float peakToPeakMax = 0.0;
for (int i = 0; i < actualNumberOfSamples; i++)
{
minsample = fmin(minsample, samples[i]);
maxsample = fmax(maxsample, samples[i]);
}
peakToPeakMax = (maxsample - minsample);
printf("The peak-to-peak maximum value is: %fn", peakToPeakMax);

(这不包括RMS部分,它在您有正确的有符号整数值之后出现(

现在,我通过将峰间值除以2的平方根来计算均方根值。然后,20*log10(rms(给出了相应的分贝值。

rmsValue = peak2peakValue / sqrt2;
DB_Val = 20 * log10(rmsValue);
  1. 以上代码是否处理了您提到的"偏移量">
  2. 我还没有找到一个测试计划来验证计算的分贝,但我在数学上正确计算了分贝值吗

2’complement部分看起来应该可以工作,但它不必要地复杂,因为正则整数是用2’compound表示的(除非你使用的是一些非常奇特的硬件(。你可以简单地这样做:

signed int signedInputVal = (signed int)inputVal;
signedInputVal >>= 14;

这将为您提供一个范围为-(2^17(到(2^17-1(的值。

看起来你所有的样本值都接近-6800,所以我认为这是你需要考虑的偏移量。

(这不包括RMS部分,它在您有正确的带符号整数值之后出现(

相关内容

  • 没有找到相关文章

最新更新