我如何让这个 c++ 程序生成一个工作的 wav 文件
how do i get this c++ program to generate a working wav file
我正在尝试制作一个 wav 文件编写器并想出了这个
#include <iostream>
#include <fstream>
using namespace std;
char riff[5] = {'R', 'I', 'F', 'F', '[=10=]'};
unsigned int chunksize;
char format[5] = {'W', 'A', 'V', 'E', '[=10=]'};
char subchunk1ID[5] = {'f', 'm', 't', ' ', '[=10=]'};
unsigned int subchunk1size;
unsigned short int audioformat = 1;
unsigned short int numchannels = 1;
unsigned int samplerate;
unsigned int byterate;
unsigned short int blockalign;
unsigned short int bitspersample;
char subchunk2ID[5] {'d', 'a', 't', 'a', '[=10=]'};
unsigned int subchunk2size;
int x = 0;
char a = 0;
char b = 4;
int main()
{
subchunk1size = 16;
subchunk2size = 1000;
chunksize = 1036;
samplerate = 500;
bitspersample = 8;
byterate = 500;
blockalign = 1;
ofstream myfile;
myfile.open("test2.wav");
myfile << riff << chunksize << format
<< subchunk1ID << subchunk1size << audioformat
<< numchannels << samplerate << byterate << blockalign
<< bitspersample << subchunk2ID << subchunk2size;
while (x < 1000) {
if (x%2 == 1) {
myfile << a;
}
else {
myfile << b;
}
x=x+1;
}
myfile.close();
return 0;
}
然而,当我尝试打开文件时出现错误 "windows media player encountered a problem while playing the file"(因为我认为它的 header 被搞砸了)
我试着把它写成 .txt 而不是 .wav 并且整数被写成数字这让我认为问题是从变量的二进制值到 .wav 文件的非文字翻译
如果这是问题所在,是否有解决此问题的简单方法
您展示的代码离成为一个可行的 WAV 编写器还差得很远。对于初学者,您正在以文本模式而不是二进制模式编写文件。但除此之外,您对所有内容都使用 <<
运算符,这意味着您将所有数据写入格式化字符串而不是二进制整数和原始字节。
尝试更像这样的东西:
#include <iostream>
#include <fstream>
using namespace std;
char riff[4] = {'R', 'I', 'F', 'F'};
unsigned int chunksize;
char format[4] = {'W', 'A', 'V', 'E'};
char subchunk1ID[4] = {'f', 'm', 't', ' '};
unsigned int subchunk1size;
unsigned short int audioformat = 1;
unsigned short int numchannels = 1;
unsigned int samplerate;
unsigned int byterate;
unsigned short int blockalign;
unsigned short int bitspersample;
char subchunk2ID[4] = {'d', 'a', 't', 'a'};
unsigned int subchunk2size;
char a = 0;
char b = 4;
int main()
{
subchunk1size = 16;
subchunk2size = 1000;
chunksize = 1036;
samplerate = 500;
bitspersample = 8;
byterate = 500;
blockalign = 1;
ofstream myfile;
myfile.open("test2.wav", std::ios::binary);
myfile.write(riff, 4);
myfile.write(reinterpret_cast<char*>(&chunksize), sizeof(chunksize));
myfile.write(format, 4);
myfile.write(subchunk1ID, 4);
myfile.write(reinterpret_cast<char*>(&subchunk1size), sizeof(subchunk1size));
myfile.write(reinterpret_cast<char*>(&audioformat), sizeof(audioformat));
myfile.write(reinterpret_cast<char*>(&numchannels), sizeof(numchannels));
myfile.write(reinterpret_cast<char*>(&samplerate), sizeof(samplerate));
myfile.write(reinterpret_cast<char*>(&byterate), sizeof(byterate));
myfile.write(reinterpret_cast<char*>(&blockalign), sizeof(blockalign));
myfile.write(reinterpret_cast<char*>(&bitspersample), sizeof(bitspersample));
myfile.write(subchunk2ID, 4);
myfile.write(reinterpret_cast<char*>(&subchunk2size), sizeof(subchunk2size));
for (int x = 0; x < 1000; ++x)
{
if ((x % 2) == 1)
myfile.put(a);
else
myfile.put(b);
}
myfile.close();
return 0;
}
或者:
#include <iostream>
#include <fstream>
using namespace std;
char riff[4] = {'R', 'I', 'F', 'F'};
unsigned int chunksize;
char format[4] = {'W', 'A', 'V', 'E'};
char subchunk1ID[4] = {'f', 'm', 't', ' '};
unsigned int subchunk1size;
unsigned short int audioformat = 1;
unsigned short int numchannels = 1;
unsigned int samplerate;
unsigned int byterate;
unsigned short int blockalign;
unsigned short int bitspersample;
char subchunk2ID[4] = {'d', 'a', 't', 'a'};
unsigned int subchunk2size;
char a = 0;
char b = 4;
template<typename T>
void writeToFile(ofstream &ofs, const T &value)
{
ofs.write(reinterpret_cast<const char*>(&value), sizeof(value));
}
template<>
void writeToFile<char>(ofstream &ofs, const char &value)
{
ofs.put(value);
}
template<const int len>
void writeToFile(ofstream &ofs, char(&value)[len])
{
ofs.write(value, len);
}
int main()
{
subchunk1size = 16;
subchunk2size = 1000;
chunksize = 1036;
samplerate = 500;
bitspersample = 8;
byterate = 500;
blockalign = 1;
ofstream myfile;
myfile.open("test2.wav", std::ios::binary);
writeToFile(myfile, riff);
writeToFile(myfile, chunksize);
writeToFile(myfile, format);
writeToFile(myfile, subchunk1ID);
writeToFile(myfile, subchunk1size);
writeToFile(myfile, audioformat);
writeToFile(myfile, numchannels);
writeToFile(myfile, samplerate);
writeToFile(myfile, byterate);
writeToFile(myfile, blockalign);
writeToFile(myfile, bitspersample);
writeToFile(myfile, subchunk2ID);
writeToFile(myfile, subchunk2size);
for (int x = 0; x < 1000; ++x)
{
if ((x % 2) == 1)
writeToFile(myfile, a);
else
writeToFile(myfile, b);
}
myfile.close();
return 0;
}
甚至:
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
#pragma pack(push, 1)
struct chk_header
{
char id[4];
unsigned int size;
void set(char(&newid)[4], unsigned int newsize)
{
std::copy(&newid[0], &newid[3], id);
size = newsize;
}
};
struct pcm_wavefmt_data
{
unsigned short int audioformat;
unsigned short int numchannels;
unsigned int samplerate;
unsigned int byterate;
unsigned short int blockalign;
unsigned short int bitspersample;
};
#pragma pack(pop)
template<typename T>
void writeToFile(ofstream &ofs, const T &value)
{
ofs.write(reinterpret_cast<const char*>(&value), sizeof(value));
}
template<>
void writeToFile<char>(ofstream &ofs, const char &value)
{
ofs.put(value);
}
template<const int len>
void writeToFile(ofstream &ofs, char(&value)[len])
{
ofs.write(value, len);
}
const char cRiff[4] = {'R', 'I', 'F', 'F'};
const char cWave[4] = {'W', 'A', 'V', 'E'};
const char cFmt[4] = {'f', 'm', 't', ' '};
const char cData[4] = {'d', 'a', 't', 'a'};
char a = 0;
char b = 4;
int main()
{
chk_header chk;
pcm_wavefmt_data pcm;
pcm.audioformat = 1;
pcm.numchannels = 1;
pcm.samplerate = 500;
pcm.byterate = 500;
pcm.blockalign = 1;
pcm.bitspersample = 8;
ofstream myfile;
myfile.open("test2.wav", std::ios::binary);
chk.set(cRiff, 1036);
writeToFile(myfile, chk);
writeToFile(myfile, cWAVE);
chk.set(cFmt, sizeof(pcm));
writeToFile(myfile, chk);
writeToFile(myfile, pcm);
chk.set(cData, 1000);
writeToFile(myfile, chk);
for (int x = 0; x < 1000; ++x)
{
if ((x % 2) == 1)
writeToFile(myfile, a);
else
writeToFile(myfile, b);
}
myfile.close();
return 0;
}
我正在尝试制作一个 wav 文件编写器并想出了这个
#include <iostream>
#include <fstream>
using namespace std;
char riff[5] = {'R', 'I', 'F', 'F', '[=10=]'};
unsigned int chunksize;
char format[5] = {'W', 'A', 'V', 'E', '[=10=]'};
char subchunk1ID[5] = {'f', 'm', 't', ' ', '[=10=]'};
unsigned int subchunk1size;
unsigned short int audioformat = 1;
unsigned short int numchannels = 1;
unsigned int samplerate;
unsigned int byterate;
unsigned short int blockalign;
unsigned short int bitspersample;
char subchunk2ID[5] {'d', 'a', 't', 'a', '[=10=]'};
unsigned int subchunk2size;
int x = 0;
char a = 0;
char b = 4;
int main()
{
subchunk1size = 16;
subchunk2size = 1000;
chunksize = 1036;
samplerate = 500;
bitspersample = 8;
byterate = 500;
blockalign = 1;
ofstream myfile;
myfile.open("test2.wav");
myfile << riff << chunksize << format
<< subchunk1ID << subchunk1size << audioformat
<< numchannels << samplerate << byterate << blockalign
<< bitspersample << subchunk2ID << subchunk2size;
while (x < 1000) {
if (x%2 == 1) {
myfile << a;
}
else {
myfile << b;
}
x=x+1;
}
myfile.close();
return 0;
}
然而,当我尝试打开文件时出现错误 "windows media player encountered a problem while playing the file"(因为我认为它的 header 被搞砸了)
我试着把它写成 .txt 而不是 .wav 并且整数被写成数字这让我认为问题是从变量的二进制值到 .wav 文件的非文字翻译 如果这是问题所在,是否有解决此问题的简单方法
您展示的代码离成为一个可行的 WAV 编写器还差得很远。对于初学者,您正在以文本模式而不是二进制模式编写文件。但除此之外,您对所有内容都使用 <<
运算符,这意味着您将所有数据写入格式化字符串而不是二进制整数和原始字节。
尝试更像这样的东西:
#include <iostream>
#include <fstream>
using namespace std;
char riff[4] = {'R', 'I', 'F', 'F'};
unsigned int chunksize;
char format[4] = {'W', 'A', 'V', 'E'};
char subchunk1ID[4] = {'f', 'm', 't', ' '};
unsigned int subchunk1size;
unsigned short int audioformat = 1;
unsigned short int numchannels = 1;
unsigned int samplerate;
unsigned int byterate;
unsigned short int blockalign;
unsigned short int bitspersample;
char subchunk2ID[4] = {'d', 'a', 't', 'a'};
unsigned int subchunk2size;
char a = 0;
char b = 4;
int main()
{
subchunk1size = 16;
subchunk2size = 1000;
chunksize = 1036;
samplerate = 500;
bitspersample = 8;
byterate = 500;
blockalign = 1;
ofstream myfile;
myfile.open("test2.wav", std::ios::binary);
myfile.write(riff, 4);
myfile.write(reinterpret_cast<char*>(&chunksize), sizeof(chunksize));
myfile.write(format, 4);
myfile.write(subchunk1ID, 4);
myfile.write(reinterpret_cast<char*>(&subchunk1size), sizeof(subchunk1size));
myfile.write(reinterpret_cast<char*>(&audioformat), sizeof(audioformat));
myfile.write(reinterpret_cast<char*>(&numchannels), sizeof(numchannels));
myfile.write(reinterpret_cast<char*>(&samplerate), sizeof(samplerate));
myfile.write(reinterpret_cast<char*>(&byterate), sizeof(byterate));
myfile.write(reinterpret_cast<char*>(&blockalign), sizeof(blockalign));
myfile.write(reinterpret_cast<char*>(&bitspersample), sizeof(bitspersample));
myfile.write(subchunk2ID, 4);
myfile.write(reinterpret_cast<char*>(&subchunk2size), sizeof(subchunk2size));
for (int x = 0; x < 1000; ++x)
{
if ((x % 2) == 1)
myfile.put(a);
else
myfile.put(b);
}
myfile.close();
return 0;
}
或者:
#include <iostream>
#include <fstream>
using namespace std;
char riff[4] = {'R', 'I', 'F', 'F'};
unsigned int chunksize;
char format[4] = {'W', 'A', 'V', 'E'};
char subchunk1ID[4] = {'f', 'm', 't', ' '};
unsigned int subchunk1size;
unsigned short int audioformat = 1;
unsigned short int numchannels = 1;
unsigned int samplerate;
unsigned int byterate;
unsigned short int blockalign;
unsigned short int bitspersample;
char subchunk2ID[4] = {'d', 'a', 't', 'a'};
unsigned int subchunk2size;
char a = 0;
char b = 4;
template<typename T>
void writeToFile(ofstream &ofs, const T &value)
{
ofs.write(reinterpret_cast<const char*>(&value), sizeof(value));
}
template<>
void writeToFile<char>(ofstream &ofs, const char &value)
{
ofs.put(value);
}
template<const int len>
void writeToFile(ofstream &ofs, char(&value)[len])
{
ofs.write(value, len);
}
int main()
{
subchunk1size = 16;
subchunk2size = 1000;
chunksize = 1036;
samplerate = 500;
bitspersample = 8;
byterate = 500;
blockalign = 1;
ofstream myfile;
myfile.open("test2.wav", std::ios::binary);
writeToFile(myfile, riff);
writeToFile(myfile, chunksize);
writeToFile(myfile, format);
writeToFile(myfile, subchunk1ID);
writeToFile(myfile, subchunk1size);
writeToFile(myfile, audioformat);
writeToFile(myfile, numchannels);
writeToFile(myfile, samplerate);
writeToFile(myfile, byterate);
writeToFile(myfile, blockalign);
writeToFile(myfile, bitspersample);
writeToFile(myfile, subchunk2ID);
writeToFile(myfile, subchunk2size);
for (int x = 0; x < 1000; ++x)
{
if ((x % 2) == 1)
writeToFile(myfile, a);
else
writeToFile(myfile, b);
}
myfile.close();
return 0;
}
甚至:
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
#pragma pack(push, 1)
struct chk_header
{
char id[4];
unsigned int size;
void set(char(&newid)[4], unsigned int newsize)
{
std::copy(&newid[0], &newid[3], id);
size = newsize;
}
};
struct pcm_wavefmt_data
{
unsigned short int audioformat;
unsigned short int numchannels;
unsigned int samplerate;
unsigned int byterate;
unsigned short int blockalign;
unsigned short int bitspersample;
};
#pragma pack(pop)
template<typename T>
void writeToFile(ofstream &ofs, const T &value)
{
ofs.write(reinterpret_cast<const char*>(&value), sizeof(value));
}
template<>
void writeToFile<char>(ofstream &ofs, const char &value)
{
ofs.put(value);
}
template<const int len>
void writeToFile(ofstream &ofs, char(&value)[len])
{
ofs.write(value, len);
}
const char cRiff[4] = {'R', 'I', 'F', 'F'};
const char cWave[4] = {'W', 'A', 'V', 'E'};
const char cFmt[4] = {'f', 'm', 't', ' '};
const char cData[4] = {'d', 'a', 't', 'a'};
char a = 0;
char b = 4;
int main()
{
chk_header chk;
pcm_wavefmt_data pcm;
pcm.audioformat = 1;
pcm.numchannels = 1;
pcm.samplerate = 500;
pcm.byterate = 500;
pcm.blockalign = 1;
pcm.bitspersample = 8;
ofstream myfile;
myfile.open("test2.wav", std::ios::binary);
chk.set(cRiff, 1036);
writeToFile(myfile, chk);
writeToFile(myfile, cWAVE);
chk.set(cFmt, sizeof(pcm));
writeToFile(myfile, chk);
writeToFile(myfile, pcm);
chk.set(cData, 1000);
writeToFile(myfile, chk);
for (int x = 0; x < 1000; ++x)
{
if ((x % 2) == 1)
writeToFile(myfile, a);
else
writeToFile(myfile, b);
}
myfile.close();
return 0;
}