在应用 FFT 之前从 wav 文件中读取数据

Posted

技术标签:

【中文标题】在应用 FFT 之前从 wav 文件中读取数据【英文标题】:Read data from wav file before applying FFT 【发布时间】:2015-12-15 18:45:33 【问题描述】:

这是我第一次使用波形文件。 问题是我并不完全了解如何正确读取存储的数据。我的阅读代码:

    uint8_t* buffer = new uint8_t[BUFFER_SIZE];
    std::cout << "Buffering data... " << std::endl;
    while ((bytesRead = fread(buffer, sizeof buffer[0], BUFFER_SIZE / (sizeof buffer[0]), wavFile)) > 0)
    
        //do sth with buffer data
    

样本文件头告诉我数据是 PCM(1 通道),每个样本 8 位,采样率为 11025Hz。

输出数据给我(更新后)从 0 到 255 的值,因此这些值是 8 位调制的正确 PCM 值。但是,知道正确读取这些值需要什么 BUFFER_SIZE 吗?

我正在使用的 WAV 文件:http://www.wavsource.com/movies/2001.htm (daisy.wav)

TXT 输出:https://paste.ee/p/pXGvm

【问题讨论】:

您的意思是 -128 到 127(而不是 172)吗?您看到签名值的原因是您将它们存储在已签名的 int8 中。 uint8 未签名 是的,我的错,我已经更改了我的代码。现在它给了我四个不同的值:128、127、87、0。我仍然不知道它是如何正确的? 我们没有您的数据,所以我不知道我们如何知道这些值是否正确。 我正在使用的文件:wavsource.com/snds_2015-12-13_4694675918641206/movies/2001/… 正在输出到 txt 文件。 好的,我刚刚用附加信息编辑了我的问题。 【参考方案1】:

您有两种常见的情况。第一个是 WAV 文件代表一个简短的音频样本,您希​​望将整个内容读入内存并对其进行操作。所以 BUFFER_SIZE 是一个变量。基本上,您会寻找文件的末尾以获取其大小,然后加载它。

第二种常见情况是 WAV 文件代表相当长的录音,您希望分段处理它,通常通过实时写入输出设备。所以 BUFFER_SIZE 需要足够大以容纳一口大小的块,但又不能大到需要过多的内存。现在通常音频“帧”的大小由输出设备本身给出,它预计每秒 25 个样本与视频或类似的东西同步。您通常需要一个双缓冲器,以确保您在 DAC(数模转换器)用完时始终能够满足对更多样本的需求。然后在给出一个样本时,你从磁盘加载下一个数据块。有时,块大小没有“正确”的值,您只需要使用相当合理的方法来平衡内存占用与调用次数。

如果您需要进行 FFT,通常使用 2 次方的缓冲区大小,以使快速变换更简单。您需要的大小取决于您感兴趣的最低频率。

【讨论】:

以上是关于在应用 FFT 之前从 wav 文件中读取数据的主要内容,如果未能解决你的问题,请参考以下文章

这是读取音频文件 FFT 的正确方法吗? (python + wav)

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

返回 Numpys FFT 的数据并在音频文件中找到每秒的幅度和频率

从android上的wav文件中读取原始数据

在 Python 中用 24 位数据从立体声 wav 文件 wav 中读取单个通道的数据

对 8 位 PCM 信号进行 FFT