【发布时间】:2021-04-25 14:10:16
【问题描述】:
我正在尝试通过我的 RaspberryPi 4 in c 上的 ALSA 项目对 pcm 数据进行采样。录制东西就像一种魅力,但篡改样本本身会让我感到困惑,特别是因为我已经在另一个项目 (ESP32) 上做过同样的事情。
将“缓冲区”视为每个会话大小不同的数组(ALSA 每次分配不同),其中包含存储为 8 位值的 32 位 44100Hz 离散音频样本(需要 int32_t 转换)。为了获得与一个缓冲区一样大的时间段的 dBFS 值,我想对每个样本进行平方,将它们加在一起,除以样本数,得到 sqrt,除以 INT32_MAX 值并从中提取 log10,最后乘以 20。标准 rms,然后是 dBFS 计算:
uint32_t sum = 0;
int32_t* samples = (int32_t*)buffer;
for(int i = 0; i < (size / (BIT_DEPTH/8)); i ++){
sum += (uint32_t)pow(samples[i], 2);
}
double rms = sqrt(sum / (size / (BIT_DEPTH/8)));
int32_t decibel = (int32_t)(20 * log10(rms / INT32_MAX));
fprintf(stderr, "sum = %d\n", sum);
fprintf(stderr, "rms = %d\n", rms);
fprintf(stderr, "%d dBFS\n", decibel);
但是对于稍微安静的房间(打开的窗户)或麦克风旁边的扬声器,我得到的不是合理的值,而是大约 -134 dBFS 的不变的真正安静值。是的,增益很低,所以-134 是可能的,但我更不了解的是当我打印出变量 sum 和 rms 时会发生什么:
buffersize: 262144
sum = -61773
rms = -262146
-138 dBFS
他们怎么可能是消极的?这可能是我目前看不到的经典c-issue。
再次:将样本写入文件会产生高质量但低增益的 wav 文件(需要标头)。有什么帮助吗?谢谢。
【问题讨论】:
-
你的 RPi 和 esp32 可以有不同的字节序吗?或者,如何从设备中采样/排序 32 位数据?
-
以后在寻求调试帮助时,请在问题中提供minimal reproducible example。
-
只是一个小提示:在计算 dB_rms 时,您可以省略平方和的平方根,然后乘以 10 而不是 20。事实上,这样做可以更好地表示相对于基础物理而言,dB 意味着什么。
-
好吧,要重现这一点,我需要包含整个 ALSA pcm-init,并且您需要准备好两个 i2s-MEMS-mics。这就是为什么我认为我应该保持简短并专注于有问题的领域,从答案来看,这完全取决于数学和 c 标准
标签: c audio raspberry-pi sampling pcm