我正在尝试从.wav读取数据并将其放到fft中。
要读取wav文件,我正在使用sndfile库。
SNDFILE* infile;
SF_INFO sfinfo ;
memset (&sfinfo, 0, sizeof (sfinfo)) ;
infile = sf_open ("sound.wav", SFM_READ, &sfinfo);
double data [BUF_SIZE];
while (readcount = (int)sf_readf_double (infile, data, BUF_SIZE))
{
for (int i = 0; i < readcount; i++)
{
cout << data[i] << " ";
}
}
但是此文件(和其他文件)中的每个值都在(-1; 1)之间。
它是否正确?为什么每个值都那么小?预计我会在时域(声音的音量)中读取振幅。
最佳答案
这是浮点样本的规范格式。使用float
值,您可以获得完整的32位精度。剪裁也很容易表示。如果样本值大于1或小于-1,则表示样本被裁剪。对于整数值,没有办法知道。
浮点数也是一种简单的示例格式,可以对其进行操作。例如,混合是微不足道的(您只需将样本值相加即可。)
因此,即使一开始看起来很奇怪,它也是音频样本表示的最佳格式。将所需的运算应用于浮点值后,然后将它们转换为想要输出的格式(例如16位整数)。此运算很简单。这是一个将浮点样本转换并裁剪为当前使用的任何已知整数样本格式的函数:
#include <limits>
/* Convert and clip a float sample to an integer sample. This works for
* all usual integer sample types (8-bit, 16-bit, 32-bit, signed or
* unsigned.)
*/
template <typename T>
T floatSampleToInt(float src) noexcept
{
if (src >= 1.f)
return std::numeric_limits<T>::max();
if (src < -1.f)
return std::numeric_limits<T>::min();
return src * (float)(1UL << (sizeof(T) * 8 - 1))
+ ((float)(1UL << (sizeof(T) * 8 - 1))
+ (float)std::numeric_limits<T>::min());
}
例如,如果要将浮点样本转换为带符号的16位整数样本,请执行以下操作:
int16_t intSample = floatSampleToInt<int16_t>(floatSample);
请注意,32位覆盖了24位整数样本。 32位样本也是有效的24位样本。它的低8位被截断。
关于c++ - wav文件中的数据介于-1和1之间,c++,sndfile,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47518980/