c++ 如何使用libsndfile将.wav文件加载到数组中?

to94eoyn  于 2023-01-15  发布在  其他
关注(0)|答案(4)|浏览(124)

我看过一些使用libsndfile的示例程序,但是无法编译它们中的任何一个。我希望能够将.wav文件读入整数(或双精度)数组,而不必担心它是什么类型的.wav文件,甚至不必担心文件头中的任何内容。我只关心将数据读入数组,这样我就可以对各个示例进行自己的处理。
我已经下载了libsndfile的源代码。有这么多的文件和文件夹,我不知道从哪里开始。我需要包括什么?我需要使用什么方法?有人有一个简单的例子,实际工作?

l7wslrjt

l7wslrjt1#

我是libsndfile的主要作者/维护者。
预编译的二进制包包含windows DLL、文档、头文件和一些示例VC 7和VC 9项目文件。
您需要源代码的唯一原因是如果源代码是tarball,则查看examples/目录中的示例程序。

j8ag8udp

j8ag8udp2#

有点老了,但我想我会为未来的读者插话。
两个答案都没有回答主要问题:如何使用libsndfile将. wav文件加载到数组中?
使用SndFileHandle和C++17的答案(17真的不必要,但嘿,我喜欢鼓励使用):

#include <sndfile.hh>
std::filesystem::path path = "file/path.wav";
if (std::filesystem::path::is_regular_file(path))
{
  SndfileHandle myf = SndfileHandle(&path.string()[0]);
  std::vector<float> array(myf.frames());
  myf.read(&array[0], int(myf.frames());
}

更多信息可在此处找到:http://ofdsp.blogspot.com/2011/07/loading-wav-file-with-sndfilehandle.html(本例就是受此启发而产生的)
还要注意的是,我选择将它读入一个浮点向量。可能是任何东西只要记住你得到的可能取决于wav(或其他声音类型)文件的比特率,虽然我相信libsndfile的编写是为了让你在很大程度上忘记这一点。
至于第一项问题的其他部分,其他答复应已足够。

p3rjfoxz

p3rjfoxz3#

这里似乎是 * libsndfile,* 预编译和打包,便于在Windows 7上安装:http://www.mega-nerd.com/libsndfile/libsndfile-1.0.25-w64-setup.exe.
(Of当然,没有什么能阻止你在任何你喜欢的时候研究源代码,只要你感兴趣;但是,即使源代码确实让您感兴趣,您使用预编译包的实践也会帮助您了解源代码。看起来 * libsndfile的 * 本机平台是Debian GNU/Linux,所以在Windows下使用源代码可能会有一点困难。不过幸运的是,如果预编译包适合您,那么您就不必再为源代码担心了。

1tu0hz3e

1tu0hz3e4#

对于每个读到这篇文章的人来说,上面的解决方案并不是最好的,所以我也把这个放在这里。它把一个wav文件读入一个双数组。你需要包含sndfile lib。要做到这一点,首先执行ReadMe中的cmake安装部分,然后执行cmake inlcude部分

#include <stdio.h>
#include <iostream>
#include <filesystem>
#include <vector>

#include <sndfile.hh>

int main(){
    std::cout << "STARTING MAIN\n" << std::endl;

    SF_INFO info;
    info.format = 0;

    // Open the wave file for reading
    SNDFILE *sndfile = sf_open("absolute path to .wav", SFM_READ, &info);

    if (!sndfile) {
        std::cerr << "Error: could not open file" << std::endl;
        return 1;
    }

    // Print some information about the file
    std::cout << "Sample rate: " << info.samplerate << std::endl;
    std::cout << "Channels: " << info.channels << std::endl;
    std::cout << "Samples: " << info.frames << std::endl;

    // Allocate memory for the samples
    // old: double samples[info.frames * info.channels];
    std::vector<double> samples(info.frames * info.channels);

    // Read the samples into the array
    // old: sf_readf_double(sndfile, samples, info.frames);
    sf_readf_double(sndfile, &samples[0], info.frames);

    // Close the file
    sf_close(sndfile);

    // print the size of the samples and print the first element
    // old: std::cout << "\nElements in samples: " << sizeof(samples)/sizeof(samples[0]) << std::endl;
    std::cout << "\nElements in samples: " << samples.size() << std::endl;

    // Loop through the array until the first position where the value is not 0. Print this value and postion
    for (int i = 0; i < info.frames * info.channels; i++){
        if (samples[i] != 0){
            std::cout << "Samples(" << i << "): " << samples[i] << std::endl;
            break;
        }
    }

    std::cout << "FINISHED MAIN\n" << std::endl;

    return 0;
}

相关问题