gpt4 book ai didi

c++ - 使用 libsndfile 处理大文件

转载 作者:太空狗 更新时间:2023-10-29 21:44:45 26 4
gpt4 key购买 nike

目前,我已经根据可用的“libsndfile”示例代码编写了一个程序(在 Visual Studio C++ 中),其中我刚刚添加了一个减法函数,用于将一个( channel )WAV 文件与另一个相减.

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

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

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

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

代码:

#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 1\n");
printf("\n\nPress 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 << "\n\n" << 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 2\n");
printf("\n\nPress 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 << "\n\n" << std::endl;// Print Samplerate
//{
//std::cout << "Format differs from eachother, abort program.";
//printf("\n\nPress 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("\n\nPress 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("\n\nPress 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("\n\nPress 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("\n\nPress any key to exit."); // Exit-text
return 0;
}

最佳答案

documentation states :

File Read Functions (Items)

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) ;

The file read items functions fill the array pointed to by ptr with the requested number of items. The items parameter must be an integer product of the number of channels or an error will occur

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

关于程序完成就好像已经进行了计算的问题:添加适当的错误处理。

关于c++ - 使用 libsndfile 处理大文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19377942/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com