WAV文件中的字节序

时间:2019-03-25 15:47:37

标签: c++ audio wav

我试图做一个简单的wav作家。我想这样做,以便可以读入wav文件(使用预先存在的wav阅读器),对音频数据进行重新采样,然后将重新采样的数据写入另一个wav文件。输入文件可以是16 bitsPerSample或32 bitsPerSample,我想用相同数量的bitsPerSample保存重新采样的音频。

作者正在工作,但是有一些我不了解与字节顺序有关的事情,我希望有人可以帮助我吗?

我以前没有读取或写入二进制文件的经验。我首先从网上查找wav文件格式,然后尝试按照正确的格式写入数据。最初,编写工作不起作用,但是后来我发现wav文件是低位优先的,并且它试图使我的文件编写器与此保持一致,这带来了我的大部分问题。 我已经让wav编写器现在可以工作(通过测试,我可以读取wav文件并检查是否可以写入未采样的音频并再现完全相同的文件),但是我仍然不确定要注意的几点与字节序有关,我希望有人可以帮助我吗?

假设这里已经设置了相关变量,这是我为wav编写器编写的代码:

// Write RIFF header
out_stream.write(chunkID.c_str(),4);
out_stream.write((char*)&chunkSize,4);
out_stream.write(format.c_str());

// Write format chunk
out_stream.write(subchunk1ID.c_str(),4);
out_stream.write((char*)&subchunk1Size,4);
out_stream.write((char*)&audioFormat,2);
out_stream.write((char*)&numOfChannels,2);
out_stream.write((char*)&sampleRate,4);
out_stream.write((char*)&byteRate,4);
out_stream.write((char*)&blockAlign,2);
out_stream.write((char*)&bitsPerSample,2);

// Write data chunk
out_stream.write(subchunk2ID.c_str(),4);
out_stream.write((char*)&subchunk2Size,4);

// Variables for writing 16 bitsPerSample data
std::vector<short> soundDataShort;
soundDataShort.resize(numSamples);
char theSoundDataBytes [2];

// soundData samples are written as shorts if bitsPerSample=16 and floats if bitsPerSample=32
switch( bitsPerSample )
{ 
    case (16):
        // cast each of the soundData samples from floats to shorts
        // then save the samples in little-endian form (requires reversal of byte-order of the short variable)
        for (int sample=0; sample < numSamples; sample++)
    {
        soundDataShort[sample] = static_cast<short>(soundData[sample]);
            theSoundDataBytes[0] = (soundDataShort[sample]) & 0xFF;
            theSoundDataBytes[1] = (soundDataShort[sample] >> 8) & 0xFF;
            out_stream.write(theSoundDataBytes,2);          
    }   
    break;

    case (32):
        // save the soundData samples in binary form (does not require change to byte order for floats)
        out_stream.write((char*)&soundData[0],numSamples);
}

我的问题是:

  1. 在soundData向量中,为什么shorts向量的字节序很重要,而floats向量却没有关系?在我的代码中,我反转了短裤的字节顺序,但没有反转浮点数。

  2. 最初,我尝试编写短裤而不颠倒字节顺序。当我写文件时,文件的大小原来应该是原来的一半(即音频数据丢失了一半,但听起来一半正确),为什么会这样?

  3. 在其他单个变量中,我并没有反转短裤和多头的字节顺序,这些变量基本上是构成wav文件的所有其他字段,例如sampleRate,numOfChannels等,但这似乎并不影响wav文件的播放。仅仅是因为媒体播放器没有使用这些字段(因此我不能说我弄错了这些字段),还是因为这些变量的字节顺序无关紧要?

1 个答案:

答案 0 :(得分:1)

  

在soundData向量中,为什么shorts向量的字节序很重要,而floats向量却没有?在我的代码中,我反转了短裤的字节顺序,但没有反转浮点数。

实际上,如果仔细看一下代码,您会发现根本没有反转短裤的字节序。您也不需要在Intel CPU(或任何其他低端CPU)上。

  

最初,我尝试编写短裤而不颠倒字节顺序。当我写文件时,文件的大小原来应该是原来的一半(即丢失了一半的音频数据,但是那一半听起来是正确的),为什么会这样?

我不知道代码就不知道,但我怀疑还有其他因素在起作用。

  

我没有在其他单个变量中反转短裤和多头的字节顺序,这些变量基本上是构成wav文件的所有其他字段,例如sampleRate,numOfChannels等,但这似乎并不影响wav文件的播放。仅仅是因为媒体播放器不使用这些字段(因此我不能说我弄错了)还是因为这些变量的字节顺序无关紧要?

这些字段实际上非常重要,并且必须是低位字节序,但是,正如我们所看到的,您也不需要交换这些字段。