网上找的一个读取wave文件的代码片段
来源:互联网 发布:外汇交易大师软件 编辑:程序博客网 时间:2024/04/28 11:02
1 struct RIFF_HEADER 2 { 3 char szRiffID[4]; // 'R','I','F','F' 4 DWORD dwRiffSize; 5 char szRiffFormat[4]; // 'W','A','V','E' 6 }; 7 8 struct WAVE_FORMAT 9 {10 WORD wFormatTag;11 WORD wChannels;12 DWORD dwSamplesPerSec;13 DWORD dwAvgBytesPerSec;14 WORD wBlockAlign;15 WORD wBitsPerSample;16 };17 struct waveHead18 {19 RIFF_HEADER riff;20 char szFmtID[4]; // 'f','m','t',' '21 DWORD dwFmtSize;22 WAVE_FORMAT wavFormat;23 };24 25 struct FACT_BLOCK26 {27 char szFactID[4]; // 'f','a','c','t'28 DWORD dwFactSize;29 };30 31 struct DATA_BLOCK32 {33 char szDataID[4]; // 'd','a','t','a'34 DWORD dwDataSize;35 };36 37 #define WAVE_FORMAT_PCM 0x0001 38 #define WAVE_FORMAT_ADPCM 0x000239 40 else if (m_iSoundType == wavesound)41 {42 waveHead aHeader;43 fseek(m_soundf, 0, SEEK_SET);44 fread(&aHeader, 1, sizeof(waveHead), m_soundf);45 if (aHeader.wavFormat.wFormatTag != WAVE_FORMAT_PCM)46 {47 PGELOG(LOG_ERROR, "不支持的Wave格式:%s", caFile);48 fclose(m_soundf);49 m_soundf = 0;50 return -1;51 }52 memcpy(&m_wformat, &(aHeader.wavFormat), sizeof(WAVE_FORMAT));53 m_wformat.cbSize = 0;54 //if (aHeader.dwFmtSize == 18)55 //fread(&(m_wformat.cbSize), 1, sizeof(WORD), m_soundf);56 fseek(m_soundf, aHeader.dwFmtSize-16, SEEK_CUR);57 FACT_BLOCK fact;58 DATA_BLOCK data;59 fread(&fact, 1, sizeof(FACT_BLOCK), m_soundf);60 if (*((DWORD*)fact.szFactID) == *((DWORD*)"fact"))61 {62 fseek(m_soundf, fact.dwFactSize, SEEK_CUR);63 fread(&data, 1, sizeof(DATA_BLOCK), m_soundf);64 }65 else if (*((DWORD*)fact.szFactID) == *((DWORD*)"data"))66 memcpy(&data, &fact, sizeof(DATA_BLOCK));67 m_iDataStart = ftell(m_soundf);68 m_iDataSize = data.dwDataSize;69 fread(m_pWaveData, 1, m_iDataSize, m_soundf);70 }
附上wave文件格式:
下面我们具体地分析 WAVE 文件的格式
endian
field name
Size
bigChunkID4文件头标识,一般就是" RIFF" 四个字母littleChunkSize4整个数据文件的大小,不包括上面ID和Size本身bigFormat4一般就是" WAVE" 四个字母bigSubChunk1ID4格式说明块,本字段一般就是"fmt "littleSubChunk1Size4本数据块的大小,不包括ID和Size字段本身littleAudioFormat2音频的格式说明littleNumChannels2声道数littleSampleRate4采样率littleByteRate4比特率,每秒所需要的字节数littleBlockAlign2数据块对齐单元littleBitsPerSample2采样时模数转换的分辨率bigSubChunk2ID4真正的声音数据块,本字段一般是"data"littleSubChunk2Size4本数据块的大小,不包括ID和Size字段本身littleDataN音频的采样数据以下是对各个字段的详细解说:
ChunkID4bytesASCII 码表示的“RIFF”。(0x52494646)ChunkSize4bytes36+SubChunk2Size,或是4 + ( 8 + SubChunk1Size ) + ( 8 + SubChunk2Size ),
这是整个数据块的大小(不包括ChunkID和ChunkSize的大小)Format4bytesASCII 码表示的“WAVE”。(0x57415645) SubChunk1ID 新的数据块(格式信息说明块)
ASCII 码表示的“fmt ”——最后是一个空格。(0x666d7420)SubChunk1Size4bytes本块数据的大小(对于PCM,值为16)。AudioFormat2bytesPCM = 1 (比如,线性采样),如果是其它值的话,则可能是一些压缩形式NumChannels2bytes1 => 单声道 | 2 => 双声道SampleRate4bytes采样率,如 8000,44100 等值ByteRate4bytes等于: SampleRate * numChannels * BitsPerSample / 8BlockAlign2bytes等于:NumChannels * BitsPerSample / 8BitsPerSample2bytes采样分辨率,也就是每个样本用几位来表示,一般是 8bits 或是 16bits SubChunk2ID4bytes新数据块,真正的声音数据
ASCII 码表示的“data ”——最后是一个空格。(0x64617461)SubChunk2Size4bytes数据大小,即,其后跟着的采样数据的大小。DataN bytes真正的声音数据
对于Data块,根据声道数和采样率的不同情况,布局如下(每列代表8bits):
1. 8 Bit 单声道:
采样1采样2数据1数据22. 8 Bit 双声道
采样1 采样2 声道1数据1声道2数据1声道1数据2声道2数据21. 16 Bit 单声道:
采样1 采样2 数据1低字节数据1高字节数据1低字节数据1高字节2. 16 Bit 双声道
采样1 声道1数据1低字节声道1数据1高字节声道2数据1低字节声道2数据1高字节采样2 声道1数据2低字节声道1数据2高字节声道2数据2低字节声道2数据2高字节
下面我们看一个具体的例子,声音文件如下:
52 49 46 46 24 08 00 00 57 41 56 45 66 6d 74 20 10 00 00 00 01 00 02 00 22 56 00 00 88 58 01 00 04 00 10 00 64 61 74 61 00 08 00 00 00 00 00 00 24 17 1e f3 3c 13 3c 14 16 f9 18 f9 34 e7 23 a6 3c f2 24 f2 11 ce 1a 0d
对应的分析如下图所示:
自己测试了下暂时还没有弄通。
0 0
- 网上找的一个读取wave文件的代码片段
- 读取ini文件的例子(在网上找的)
- 在网上找了一个读取文件夹下面的所有文件到txt的code 已验证
- 网上找的c语言读取配置文件
- 在网上找的一个Flex文件上传代码,记录下来,以后用到的时候可以马上能用:
- C# 读取Excel文件代码的几种片段收集
- C# 读取Excel文件代码的几种片段收集
- 网上找来的用java读取word文档的代码
- 网上找的文章分页类代码
- 从网上找的加入收藏夹 代码
- 网上找的Android实用代码
- 网上找的一些效果代码
- 发一个网上找的日历脚本
- 我从网上找来的用C#读取txt文件的方法
- 网上找的点击文件直接上传
- 刚从网上找的一个学生数据管理系统的代码。
- 一个用摄像头录像的程序源码,比较菜.很多都是在网上找的代码,
- 读取七位数的代码片段
- 最近遇到的几个c++笔试题
- 调用OpenSL ES NDK播放声音
- c/c++ 检查指定目录是否存在,不存在则创建改目录
- Aspose.Cells中文版文档
- c/c++ 收集string的操作汇总
- 网上找的一个读取wave文件的代码片段
- 数字签名是什么?
- 使用opensl 的BufferQueueAudioPlayer对wav文件的播放
- 用c++简单实现智能指针(转)
- 战略项目管理(高层视野下的项目管理:决策人项目管理:组织执行力提升课程)
- 我是一个程序员
- websocket 连接 C Server的尝试
- 如何从DLL或者DEF文件生成LIB文件<转>
- c语言获取当前工作路径(转)