使用 libsndfile 处理大文件

Processing large files with libsndfile

本文关键字:文件 处理 libsndfile 使用      更新时间:2023-10-16

目前,我已经根据"libsndfile"的可用示例代码编写了一个程序(在Visual Studio C++中),其中我刚刚添加了一个减法函数来减去一个(通道)WAV文件与另一个。

该程序非常适合限制为 4 个通道的文件。

问题是,一旦我上传一个多达 5 个或更多通道的文件,程序就会拒绝执行该功能。这与帧大小无关,因为我设法处理了比我使用过的一些 5/6 通道文件大很多倍的 4 通道文件。

以前有没有人遇到过这个或类似的问题?如果需要,我将提供源代码。

对于糟糕的结构,我深表歉意,在我让整个交易工作之前,我不会真正优化。

法典:

#include <sndfile.hh>
#include <tinyxml2.h>
#include <iostream>
#include <fstream>
#define BLOCK_SIZE 32
using TiXmlDocument = tinyxml2::XMLDocument;
using CStdStringA = std::string;
int main(int argc, char* argv[])
{
    SNDFILE *infile  = NULL;
    SNDFILE *infile2 = NULL;
    SNDFILE *outfile = NULL;
    SF_INFO    sfinfo;
    SF_INFO    sfinfo2;
    SF_INFO    sfinfoOut;
    sf_count_t readcount;
    //int filetype = SF_FORMAT_WAV | SF_FORMAT_PCM_24;                  // 24-bit Wav-Files
    TiXmlDocument iDoc;                                               // Init tinyXML
    int i;                                                            // Iteration-var;
    short BufferIn[BLOCK_SIZE];                                       // Buffer1
    short BufferIn2[BLOCK_SIZE];                                      // Buffer2
    short BufferOut[BLOCK_SIZE];
    CStdStringA FileLoc, FileName, FileLocWav, FileLocTxt,FileLocRaw; // OutputFile locationstring
    CStdStringA WavName, WavName2, FileIn, FileIn2;
    FileLoc = "C:\Testfiles\";
    //TextTitle(FileLoc);                                             // Print console-header
    printf("Name Wavefile 1:n");
    std::cin >> WavName;
    FileIn = FileLoc + WavName + ".wav";
    if((infile = sf_open(FileIn.c_str(),SFM_READ,&sfinfo)) == NULL)   // Open Wav-file 2 instance
    {
        printf("Not able to open input file 1n");
        printf("nnPress any key to exit.");                         // Exit-text if file not present
        puts(sf_strerror(NULL)) ;
        return 1;
    }
    std::cout << "Wav file 1 succesfully opened." <<  std::endl;
    std::cout << "nChannels: " << sfinfo.channels << "nFrames: " << sfinfo.frames << std::endl; // Print Channels & Frames
    std::cout << "Samplerate: " << sfinfo.samplerate << "nn" <<  std::endl;// Print Samplerate
    printf("Name Wavefile 2:n");
    std::cin >> WavName2;
    FileIn2 = FileLoc + WavName2 + ".wav";
    if((infile2 = sf_open(FileIn2.c_str(),SFM_READ,&sfinfo2)) == NULL) // Open Wav-file 2 instance
    {
        printf("Not able to open input file 2n");
        printf("nnPress any key to exit.");                          // Exit-text if file not present
        puts(sf_strerror(NULL)) ;
        return 1;
    }
    std::cout << "Wav file 2 succesfully opened." <<  std::endl;
    std::cout << "nChannels: " << sfinfo2.channels << "nFrames: " << sfinfo2.frames  << std::endl; // Print Channels & Frames
    std::cout << "Samplerate: " << sfinfo2.samplerate << "nn" <<  std::endl;// Print Samplerate
//{
    //std::cout << "Format differs from eachother, abort program.";
    //printf("nnPress any key to exit.");                     // Exit-text
    //return 1;
//}
    if(sfinfo.channels != sfinfo2.channels)                                // Abort if channels not the same
    {
        std::cout << "Channelammount differs from eachother, abort program.";
        printf("nnPress any key to exit.");                     // Exit-text
        return 1;
    }
    if(sfinfo.samplerate != sfinfo2.samplerate)                   // Abort if samplerate not the same
    {
        std::cout << "Samplerate differs from eachother, abort program.";
        printf("nnPress any key to exit.");                     // Exit-text
        return 1;
    }
    std::cout << "Give a filename for Txt- & Wav-file: ";
    std::cin >> FileName;
    FileLoc += FileName;                                          // Fuse Filelocation with given name
    FileLocTxt = FileLoc + ".txt";
    FileLocWav = FileLoc + ".wav";
    FileLocRaw = FileLoc + "Raw.txt";
    sfinfoOut.channels = sfinfo.channels;
    sfinfoOut.format = sfinfo.format;
    sfinfoOut.samplerate = sfinfo.samplerate;
    if((outfile = sf_open(FileLocWav.c_str(),SFM_WRITE,&sfinfoOut)) == NULL)      // Open Wav-file 2 instance
    {
        printf("Not able to create output file n");
        printf("nnPress any key to exit.");                      // Exit-text if file not present
        puts(sf_strerror(NULL)) ;
        return 1;
    }
    std::ofstream myfile;
    myfile.open(FileLocTxt.c_str(),std::ios::app);
    std::ofstream myfileRaw;
    myfileRaw.open(FileLocRaw.c_str(),std::ios::app);
    while((readcount = sf_read_short(infile, BufferIn, BLOCK_SIZE)))     // While there are still frames to be processed
    {
        //process_data (data, readcount, sfinfo.channels) ;
        auto readcount2 = sf_read_short(infile2, BufferIn2, BLOCK_SIZE);
        for(i = 0; i < BLOCK_SIZE; i++)                                  // BLOCK_SIZE decides the chunk-size
        {
            BufferOut[i] = BufferIn[i] - BufferIn2[i];
            myfileRaw << BufferOut[i];
        }
        sf_write_short(outfile, BufferOut, BLOCK_SIZE) ;                 // Write the data to a new file
    }
    sf_close(infile);                                                    // Close Wav-file handlers
    sf_close(infile2);
    sf_close(outfile);
    myfile.close();                                                      // Close text-file handlers
    printf("nnPress any key to exit.");                                // Exit-text
    return 0;
}

文档指出:

文件读取功能(项目)

sf_count_t  sf_read_short   (SNDFILE *sndfile, short *ptr, sf_count_t items) ;
sf_count_t  sf_read_int     (SNDFILE *sndfile, int *ptr, sf_count_t items) ;
sf_count_t  sf_read_float   (SNDFILE *sndfile, float *ptr, sf_count_t items) ;
sf_count_t  sf_read_double  (SNDFILE *sndfile, double *ptr, sf_count_t items) ;

文件读取项目函数用请求的项目数填充 ptr 指向的数组。items 参数必须是通道数的整数乘积,否则会发生错误

有你的问题,因为BLOCK_SIZE 1,2,4 的倍数,但不是 3 和 5 的倍数 - 所以这会失败。

关于程序完成的问题,就好像计算已经发生一样:添加适当的错误处理。