我试图在c ++中合并两个wav文件。我正在做的是我打开两个wav文件作为二进制ifstream,并创建一个新的ofstream输出wavfile。
ifstream wavFileA("fileA.wav",ios::binary) ;
ifstream wavFileB("fileB.wav",ios::binary);
ofstream wavoutputfile("output.wav",ios::binary);
然后我将整个wavfileA及其标题复制到输出文件中,然后我复制了wavfileB,省略了前44位(即wavfileB的标题信息)。
wavFileA.seekg(0,ios::end);
int leng2 = wavFileA.tellg();
cout << leng2 << endl;
wavFileA.seekg(0,ios::beg);
int pos;
pos = wavoutputfile.tellp();
cout << pos << endl << endl;
for(int i = 0; i < leng2 ; i++)
{
byteB = readByte(wavFileA);
wavoutputfile << byteB;
}
pos = wavoutputfile.tellp();
cout <<"current pos-"<< pos << endl << endl;
wavoutputfile.seekp(pos, ios::beg);
wavFileB.seekg(0,ios::end);
int leng3 = wavFileB.tellg();
wavFileB.seekg(44,ios::beg);
cout<<"length --"<<leng3<<endl;
for(int i= 0 ; i < leng3-44 ; i++)
{
byteC = readByte(wavFileB);
wavoutputfile << byteC;
}
pos = wavoutputfile.tellp();
cout <<"end pos--"<< pos << endl << endl;
接下来我修改了输出wav文件中的头信息,并将头中的ChunkSize更改为(我的输出文件的大小减去( - )4bytes)(即RIFF的大小),然后我将标题中的Subchunk2Size更改为(我的整个文件大小减去( - )标题的大小)。
int fsize = pos-8;
unsigned char bArray[4];
wavoutputfile.seekp(4, ios::beg);
bArray[0] = ((fsize >> 24) & 0xFF);
bArray[1] = ((fsize >> 16) & 0xFF);
bArray[2] = ((fsize >> 8) & 0xFF);
bArray[3] = ((fsize) & 0xFF);
for (int i=0; i<4 ; i++)
{
wavoutputfile << bArray[i];
}
int dataSize = (pos-44);
wavoutputfile.seekp(42, ios::beg);
bArray[0] = ((dataSize >> 24) & 0xFF);
bArray[1] = ((dataSize >> 16) & 0xFF);
bArray[2] = ((dataSize >> 8) & 0xFF);
bArray[3] = ((dataSize) & 0xFF);
for (int i=0; i<4 ; i++)
{
wavoutputfile << bArray[i];
}
wavoutputfile.seekp(0, ios::end);
wavFileA.close();
wavFileB.close();
wavoutputfile.close();
此代码成功合并文件并且它也正确播放文件,但文件的持续时间显示的错误值远大于实际持续时间。谁能帮我这个?
答案 0 :(得分:0)
接下来我修改了输出wav文件中的头信息 将标题中的ChunkSize更改为(我的输出文件的大小) 减去( - )4字节)(即RIFF的大小)
这可能是您的主要问题:您应该将文件大小减去8个字节(而不是4个字节)以获取ChunkSize。还要确保Subchunk2Size实际上是没有标题的原始音频数据的大小 - 不要使用像pos - 44
这样的幻数,这会使您的代码难以阅读和理解。使用样本计数,通道数和每个样本的位数来更好地计算它。即。
Subchunk2Size = sampleCount * channelCount * bitDepth/8;
如果一切无效,请向我们展示您保存的波形文件的标题(大约前72个字节)(以十六进制表示)以及预期的长度。
答案 1 :(得分:0)
感谢Constantin的帮助。但我发现了我出错的地方。
我忘了考虑ChunkSize和SubChunkSize2是在小端系统中订购的。 所以我更改了我在标题中输入这些信息的部分,整个过程开始工作。
for (int i=3; i>=0 ; i--) //I made the change here
{
outputWavFile << bArray[i];
}