В настоящее время я написал программу (в Visual Studio C ++) на основе имеющегося примера кода «libsndfile», в которой я только что добавил функцию вычитания для вычитания одного (канала a) WAV-файла с другим.
Программа отлично работала для файлов с лимитом 4 канала.
Проблема в том, что как только я загружаю файл с 5 или более каналами, программа отказывается выполнять функцию. Это не зависит от размера кадра, так как мне удалось обработать 4-канальные файлы, которые были во много раз больше, чем некоторые 5/6-канальные файлы, которые я использовал.
Кто-нибудь сталкивался с этой или подобной проблемой раньше? По запросу я предоставлю исходный код.
Приношу свои извинения за плохую структуру, я не оптимизирую, пока не добьюсь успеха.
Код:
#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;
}
Функции чтения файлов (элементы)
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 — так что это потерпит неудачу.
О проблеме, которую завершает программа как будто расчеты имели место: добавить соответствующую обработку ошибок.
Других решений пока нет …