wav 文件中的数据在 -1 和 1 之间,c++,sndfile

Posted

技术标签:

【中文标题】wav 文件中的数据在 -1 和 1 之间,c++,sndfile【英文标题】:Data from wav file are between -1 and 1, c++, sndfile 【发布时间】:2017-11-27 20:07:33 【问题描述】:

我正在尝试从 .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) 之间。 它是否正确?为什么每个值都那么小?我被要求读取时域中的幅度(音量)。

【问题讨论】:

mega-nerd.com/libsndfile/api.html#note1 在使用浮点数时,从负 1 到正 1 的范围很大——这是大多数精度所在。如果正1是最大音量,负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);

请注意,24 位整数样本被 32 位覆盖。 32 位样本也是有效的 24 位样本;它的低 8 位被截断。

【讨论】:

以上是关于wav 文件中的数据在 -1 和 1 之间,c++,sndfile的主要内容,如果未能解决你的问题,请参考以下文章

写入 WAV 文件 C++

在 C++ 中连接 .wav 文件

在 C++ 中使用 libsndfile 从 WAV 文件中提取原始音频数据

QT (C++) 中的简单声音 (.wav) 播放应用程序

C++ 读取 WAV 文件的数据部分

[C++]我想从wav文件中获取PCM数据