lm68140318 发表于 2023-8-2 21:43:06

WAV音频文件格式


        //*******存储声音文件**********
        CFile m_file;
        CFileException fileException;
       
        CString m_csFileName = _T("D:\\audio.wav");

        m_file.Open(m_csFileName, CFile::modeCreate | CFile::modeReadWrite, &fileException);

        DWORD m_WaveHeaderSize = 38;
        DWORD m_WaveFormatSize = 18;//WAVEFORMATEX结构大小
        //WAVEFORMATEX结构看:https://www.cnblogs.com/liming19680104/p/17538589.html

        m_file.SeekToBegin();


        m_file.Write("RIFF", 4);//写入标识符RIFF
       
        unsigned int Sec = (sizeof(pSaveBuffer) + m_WaveHeaderSize);
        //Sec=42
        m_file.Write(&Sec, sizeof(Sec));
        m_file.Write("WAVE", 4);   //写入格式辨别吗


        //***********fmt子块****************
        m_file.Write("fmt ", 4);//写入fmt
        m_file.Write(&m_WaveFormatSize, sizeof(m_WaveFormatSize));//写入WAVEFORMATEX结构大小

        //写入WAVEFORMATEX结构的6个或7个成员值
        m_file.Write(&waveform.wFormatTag, sizeof(waveform.wFormatTag));
        m_file.Write(&waveform.nChannels, sizeof(waveform.nChannels));
        m_file.Write(&waveform.nSamplesPerSec, sizeof(waveform.nSamplesPerSec));
        m_file.Write(&waveform.nAvgBytesPerSec, sizeof(waveform.nAvgBytesPerSec));
        m_file.Write(&waveform.nBlockAlign, sizeof(waveform.nBlockAlign));
        m_file.Write(&waveform.wBitsPerSample, sizeof(waveform.wBitsPerSample));
        m_file.Write(&waveform.cbSize, sizeof(waveform.cbSize));



        m_file.Write("data", 4);
        m_file.Write(&dwDataLength, sizeof(dwDataLength));
        //dwDataLength=缓冲区大小

        m_file.Write(pSaveBuffer, dwDataLength);//写入音频数据

        m_file.Seek(dwDataLength, CFile::begin);
        m_file.Close();
       


我的问题:这是一段通过麦克风录音代码,DWORD m_WaveHeaderSize = 38   这个38是怎么算出来的??
               m_file.Write(&Sec, sizeof(Sec))      这个sec是什么数据   ??

isdkz 发表于 2023-8-2 21:43:23

DWORD m_WaveHeaderSize = 38这个值是根据WAV文件格式中的头部信息计算得出的。WAV文件格式的头部包含了多个字段,用于描述音频数据的属性和格式。在你的代码中,这个头部信息被写入到文件中以确保正确的文件格式。具体来说,这个38是以下部分的总和:

1. "RIFF" 标识符占用4字节。
2. 用于存储文件大小信息的 4 字节整数( unsigned int Sec )。
3. "WAVE" 标识符占用4字节。
4. "fmt " 标识符占用4字节。
5. 用于存储 WAVEFORMATEX 结构大小的 4 字节整数。
6. WAVEFORMATEX 结构中的成员,如waveform.wFormatTag 、 waveform.nChannels 、 waveform.nSamplesPerSec等,各占用 2 或 4 字节。

将这些值加起来,你得到了38,这是整个头部信息的总字节数。

关于m_file.Write(&Sec, sizeof(Sec)) , Sec是用于存储整个文件大小的变量,它包括音频数据大小和头部信息的大小。在这段代码中, Sec的值被写入到文件中,以便在文件的头部信息中记录整个文件的大小,以便后续读取时可以正确解析音频数据。

总之,这段代码的目的是按照WAV文件格式的规范创建一个包含音频数据的WAV文件。

Mike_python小 发表于 2023-8-2 21:43:23

麦克风录音代码中的一些解释和回答

首先,我会解释一下代码中涉及到的几个问题:

1. m_WaveHeaderSize = 38: m_WaveHeaderSize 是用来存储 WAV 文件头部信息的大小。WAV 文件中的头部包含了文件格式、采样率、声道数等信息。在你的代码中,头部信息的大小为 38 字节,这是根据 WAV 文件格式规范来确定的。具体来说,它包括了 RIFF 标识符(4 字节),表示文件格式为 RIFF;长度字段(4 字节),表示整个文件的长度;WAVE 标识符(4 字节),表示音频数据为 WAVE 格式;以及其他一些格式信息。

2. m_file.Write(&Sec, sizeof(Sec)): 这里的 Sec 表示文件的长度,它是指存储音频数据的部分的总字节数(包括文件头部信息和实际的音频数据)。在你的代码中,Sec 的取值为 (sizeof(pSaveBuffer) + m_WaveHeaderSize),即音频数据缓冲区的大小加上头部信息大小。这个值会被写入文件中的长度字段,用于表示整个文件的长度。

希望以上解释能够帮助你理解代码中的这两个问题。如果你还有其他疑问,请随时提出。

学习编程中的Ben 发表于 2023-8-2 21:43:27

关于Wave文件的头部

在这段代码中,DWORD m_WaveHeaderSize = 38 是指Wave文件头部的大小。Wave文件头部包含了一些固定大小的信息,用于描述音频数据的格式和属性。

Wave文件头部的结构如下:

- "RIFF"(4字节):文件标识符,表示是一个RIFF文件。
- 文件大小(4字节):文件总大小,包括所有数据块和文件头。
- "WAVE"(4字节):文件类型标识符,表示是一个Wave文件。
- "fmt "(4字节):fmt子块标识符,表示接下来是格式子块。
- fmt子块大小(4字节):格式子块的大小。
- WAVEFORMATEX结构体(变长):包含了音频数据的格式信息,如采样率、声道数、样本大小等。
- "data"(4字节):data子块标识符,表示接下来是音频数据。
- 音频数据大小(4字节):音频数据的大小。
- 音频数据:实际的音频数据。

根据上述结构,可以将各部分大小加起来:

4 + 4 + 4 + 4 + m_WaveFormatSize + 4 + dwDataLength

对应的就是 m_WaveHeaderSize = 38。

关于Sec的数据

unsigned int Sec = (sizeof(pSaveBuffer) + m_WaveHeaderSize) 是一个用于存储数据块大小的变量。

在这段代码中,sizeof(pSaveBuffer) 表示音频数据缓冲区 pSaveBuffer 的大小,而 m_WaveHeaderSize 是Wave文件头部的大小。

因此,Sec 的值等于音频数据缓冲区大小加上Wave文件头部大小。

希望能够解答你的问题!如果还有其他疑问,请继续提问。

如果回答对你有帮助,请给我一个最佳答案!{:10_254:}{:10_254:}{:10_254:}

学习编程中的Ben 发表于 2023-8-2 22:17:47

求最佳!!!
页: [1]
查看完整版本: WAV音频文件格式