我如何获得这个c ++程序来生成一个有效的wav文件

时间:2015-12-30 02:49:22

标签: c++ wav

我试图制作一个wav文件编写器并想出了这个

#include <iostream>
#include <fstream>

using namespace std;

char riff[5] = {'R', 'I', 'F', 'F', '\0'};
unsigned int chunksize;
char format[5] = {'W', 'A', 'V', 'E', '\0'};
char subchunk1ID[5] = {'f', 'm', 't', ' ', '\0'};
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', '\0'};
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在播放文件时遇到问题”(因为它的标题搞砸了我假设)

我尝试将其写为.txt而不是.wav,并将整数写为数字,这使我认为问题是从变量的二进制值到.wav文件的非字面翻译 如果这是问题,有一个简单的方法围绕这个

1 个答案:

答案 0 :(得分:1)

您展示的代码甚至不是一个可行的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;
}