zoukankan      html  css  js  c++  java
  • 【转帖】Wave文件结构

    原作者:

    http://www.cnblogs.com/armstrong-cn/archive/2011/08/24/2151713.html

    读取wave文件配置信息

    第一部分:

    WAV文件结构解析:

    WAVE文件由"块"组成。块的基本结构如下:

    ------------------------------
    偏移量  名称    字节数    类型    
    ------------------------------
    00      块标志    4       字符    
    04      块长度    4       长整型 
    08      块内容             数据   
    --------------------------------

    WAVE文件一般有四种块,它们依次是:RIFF块、格式块、附加块(可选),数据块

    --------------------------------
    名称    字节数         说明
    --------------------------------
    RIFF块   12          RIFF WAVE Chunk 
    格式块   24或26      Format Chunk
    附加块   12          Fact Chunk 
    数据块   不定        Data Chunk
    --------------------------------

    1.RIFF块的数据结构
    ---------------------------------------------------
    偏移量    名称      字节数   数据类型       内容
    ---------------------------------------------------
    00     标志符      4       字符     “RIFF”的Ascii码

    04     文件长度   4       长整形    文件的总字节数

    08     WAV标志    4       字符     “WAVE”的Ascii码
    ---------------------------------------------------

    2.格式块的数据结构
    ----------------------------------------------------------------------------
    偏移地址  字节数    数据类型      内容
    ----------------------------------------------------------------------------
    0C         4         字符       波形格式标志“fmt ”
    10         4         长整型     格式块长度(一般=16,若=18表示最后有2字节附加信息)
    14         2         整型      格式类别(值=1表示编码方式为PCMμ律编码)
    16         2         整型       声道数(单声道=1,双声音=2)
    18         4         长整型    采样频率(每秒样本数,表示每个通道的播放速度)
    1C         4         长整型     数据传送速率(每秒字节=采样频率×每个样本字节数)
    20         2         整型       每个样本字节数(又称基准块=每个样本位数×声道数÷8)
    22         2        整型      每个样本位数(又称量化位数)
    24         2         整型      附加信息(可选,通过块长度来判断有无)
    ----------------------------------------------------------------------------


    3.附加块的数据结构
    ---------------------------------------------------
    偏移地址      字节数   数据类型     内容
    ---------------------------------------------------
    24         4         字符     标志符“fact”
    28         4         长整形   块长度(=4)
    2C         4 
    ---------------------------------------------------


    4.数据块的数据结构
    ----------------------------------------
    偏移地址 字节数   类型         内容
    ----------------------------------------
    24          4        字符      数据标志符“data” 
    28          4        长整型    样本数据长度 
    2C       不定           样本数据 
    ----------------------------------------

    第二部分:

    参考VC代码:

    void CWAVinfoDlg::OnBnClickedLoad() //读取信息,存入Buf中
    {
    DWORD dwFileLen;
    pBuf
    = NULL;

    CFileDialog fileDlg(TRUE);
    fileDlg.m_ofn.lpstrTitle
    =_T("打开文件");
    fileDlg.m_ofn.lpstrFilter
    =_T("Wav音频文件(*.wav)\0*.wav\0");
    if(IDOK == fileDlg.DoModal())
    {
    m_nPath
    = fileDlg.GetPathName();
    FileName
    = fileDlg.GetFileName();
    }
    CFile file(m_nPath,CFile::modeRead
    |CFile::typeBinary|CFile::shareDenyWrite);
    dwFileLen
    = file.GetLength();
    FileSize
    = dwFileLen;

    //pBuf = new BYTE[dwFileLen + 1];
    pBuf = new unsigned char[dwFileLen + 1]; //定义pBuf缓冲区,长度为 存档文件的长度 +1
    pBuf[dwFileLen] = 0; //设置pBuf的索引(最后一个元素)为0,表示结束
    file.Read(pBuf,dwFileLen); //将长度为dwFileLen的字符串从file中写到pBuf中,也就是全部,//**可以将二进制文件全部读入
    file.Close();
    UpdateData(FALSE);

    analyse();
    }

      


    void CWAVinfoDlg::analyse()//分析wav文件信息
    {
    bool riff = false; //首先判断wav文件标志
    bool wave = false;
    bool fmt = false;

    if ((pBuf[0] == 'R') && (pBuf[1] == 'I') && (pBuf[2] == 'F') && (pBuf[3] == 'F'))
    {
    riff
    = true;
    }
    if ((pBuf[8] == 'W') && (pBuf[9] == 'A') && (pBuf[10] == 'V') && (pBuf[11] == 'E'))
    {
    wave
    = true;
    }
    if ((pBuf[12] == 'f') && (pBuf[13] == 'm') && (pBuf[14] == 't'))
    {
    fmt
    = true;
    }

    if (riff && wave && fmt) //wav文件标志正确
    {
    CString wav_size_str;
    CString FileSize_str;
    unsigned
    double wav_size = 0.0;
    int channel_num = 0;
    int sample_rate = 0;
    int sample_bit = 0;
    unsigned
    double length = 0.0;
    CString length_str;

    wav_size
    = pBuf[43]*256*256*256 + pBuf[42]*256*256 + pBuf[41]*256 + pBuf[40];
    channel_num
    = pBuf[23]*256 + pBuf[22];
    sample_rate
    = pBuf[27]*256*256*256 + pBuf[26]*256*256 + pBuf[25]*256 + pBuf[24];
    sample_bit
    = pBuf[35]*256 + pBuf[34];

    if (wav_size >= (1024*1024)) //通过文件信息得到wav大小
    {
    wav_size_str.Format(L
    "%.2f MB",(wav_size/(1024.0*1024.0)));
    }
    else if (wav_size >= 1024)
    {
    wav_size_str.Format(L
    "%.2f KB",(wav_size/1024.0));
    }
    else
    {
    wav_size_str.Format(L
    "%f B",wav_size);
    }
    //通过wav大小得到持续时间(单位:秒)
    length = (wav_size*8.0)/(sample_rate*channel_num*sample_bit*1.0);

    if (FileSize >= (1024*1024)) //文件实际大小
    {
    FileSize_str.Format(L
    "%.2f MB",(FileSize/(1024.0*1024.0)));
    }
    else if (FileSize >= 1024)
    {
    FileSize_str.Format(L
    "%.2f KB",(FileSize/1024.0));
    }
    else
    {
    FileSize_str.Format(L
    "%f B",FileSize);
    }

    CTimeSpan ts(length);
    //格式化时间显示
    length_str = ts.Format(_T("%H:%M:%S"));

    MessageBox(L
    "wav文件载入成功");
    m_nInfo.Format(L
    "文件大小: %s\r\nWav大小: %s\r\n通道数目: %d\r\n采样率 : %d HZ\r\n采样位数: %d bits\r\n持续时间: %s\r\n",FileSize_str,wav_size_str,channel_num,sample_rate,sample_bit,length_str);
    UpdateData(FALSE);
    }
    else
    {
    MessageBox(L
    "wav文件验证错误,不是正确的wav文件");
    }
    }

    第三部分:

    相关参考资料:

    http://www.cnblogs.com/CPFlying/archive/2011/05/13/2045510.html

  • 相关阅读:
    odoo开发笔记 -- 新建模块扩展原模块增加菜单示例
    div内部div居中
    Css中!important的用法
    SQLServer日期格式转换
    jquery中innerheight outerHeight()与height()的区别
    简单明了区分escape、encodeURI和encodeURIComponent
    PDF预览之PDFObject.js总结
    PDFObject.js,在页面显示PDF文件
    System.IO.Directory.GetCurrentDirectory与System.Windows.Forms.Application.StartupPath的用法
    angular 模块 @NgModule的使用及理解
  • 原文地址:https://www.cnblogs.com/81/p/2291615.html
Copyright © 2011-2022 走看看