1、wav音频文件的格式

wav文件由文件头采样数据2部分组成。

文件头又分为RIFF(Resource Interchange File Format)、WAVE文件标识段 和 声音数据格式说明段组成。

各段的起始地址分别由RIFF标识符、WAVE标识符、以及波形格式标识符(FMT)标定。

(1)文件头格式

注意:下面的地址是连续的

(2)数据格式

虽然上图给出的数据标识符起始地址刚好是文件头的末地址+1,但并不代表总是这样。

因此,我们在读取数据时最好是找到数据标识符,该标识符的4个字节刚好是'd'、‘a’、‘t’、‘a’。

2、C语言读取wav文件

首先对一些类型使用了重定义

typedef unsigned char  uchar;
typedef unsigned char  uint8;
typedef unsigned short uint16;
typedef unsigned long  uint32;
typedef char           sint8;
typedef short          sint16;
typedef long           sint32;
typedef float          fp32;
typedef double         fp64;typedef enum BOOLEAN
{TRUE  = 1,FALSE = 0
} boolean;

(1)wav结构体定义

//wave文件头
typedef struct WaveHeader
{uint8 riff[4];             //资源交换文件标志uint32 size;               //从下个地址开始到文件结尾的字节数uint8 wave_flag[4];        //wave文件标识uint8 fmt[4];              //波形格式标识uint32 fmt_len;            //过滤字节(一般为00000010H)uint16 tag;                //格式种类,值为1时,表示PCM线性编码uint16 channels;           //通道数,单声道为1,双声道为2uint32 samp_freq;          //采样频率uint32 byte_rate;          //数据传输率 (每秒字节=采样频率×每个样本字节数)uint16 block_align;        //块对齐字节数 = channles * bit_samp / 8uint16 bit_samp;           //bits per sample (又称量化位数)
} wave_header_t;typedef struct WaveStruct
{FILE *fp;                  //file pointerwave_header_t header;      //headeruint8 data_flag[4];        //数据标识符uint32 length;             //采样数据总数uint32 *pData;             //data
} wave_t;
wave_t wave;

(2)读取文件头信息

/** open *.wav file*/
void WaveOpen(char *file, int raw, int mono_stereo)
{uchar temp = 0;uint8 read_bytes = 0;char *channel_mappings[] = {NULL,"mono","stereo"};uint32 total_time = 0;struct PlayTime        //播放时间{uint8 hour;uint8 minute;uint8 second;} play_time;if(NULL == (wave.fp=fopen(file, "rb")))                               /* open file */{printf("file %s open failure!\n", file);   }/* read heade information */if(4 != fread(wave.header.riff, sizeof(uint8), 4, wave.fp))           /* RIFF chunk */{printf("read riff error!\n");return;}if(1 != fread(&wave.header.size, sizeof(uint32), 1, wave.fp))         /* SIZE : from here to file end */{printf("read size error!\n");return;}if(4 != fread(wave.header.wave_flag, sizeof(uint8), 4, wave.fp))      /* wave file flag */{printf("read wave_flag error!\n");return;}if(4 != fread(wave.header.fmt, sizeof(uint8), 4, wave.fp))             /* fmt chunk */{printf("read fmt error!\n");return;}if(1 != fread(&wave.header.fmt_len, sizeof(uint32), 1, wave.fp))       /* fmt length */{printf("read fmt_len error!\n");return;}if(1 != fread(&wave.header.tag, sizeof(uint16), 1, wave.fp))           /* tag : PCM or not */{printf("read tag error!\n");return;}if(1 != fread(&wave.header.channels, sizeof(uint16), 1, wave.fp))      /* channels */{printf("read channels error!\n");return;}if(1 != fread(&wave.header.samp_freq, sizeof(uint32), 1, wave.fp))      /* samp_freq */{printf("read samp_freq error!\n");return;}if(1 != fread(&wave.header.byte_rate, sizeof(uint32), 1, wave.fp))      /* byte_rate : decode how many bytes per second */{                                                                       /* byte_rate = samp_freq * bit_samp */printf("read byte_rate error!\n");return;}if(1 != fread(&wave.header.block_align, sizeof(uint16), 1, wave.fp))       /* quantize bytes for per samp point */{printf("read byte_samp error!\n");return;}if(1 != fread(&wave.header.bit_samp, sizeof(uint16), 1, wave.fp))        /* quantize bits for per samp point */{                                                                        /* bit_samp = byte_samp * 8 */printf("read bit_samp error!\n");return;} /* jump to "data" for reading data */do{fread(&temp, sizeof(uchar), 1, wave.fp);}while('d' != temp);wave.data_flag[0] = temp;if(3 != fread(&wave.data_flag[1], sizeof(uint8), 3, wave.fp))                 /* data chunk */{printf("read header data error!\n");return;}if(1 != fread(&wave.length, sizeof(uint32), 1, wave.fp))                  /* data length */{printf("read length error!\n");}/* jduge data chunk flag */if(!StrCmp(wave.data_flag, "data", 4)){printf("error : cannot read data!\n");return;}total_time = wave.length / wave.header.byte_rate;play_time.hour = (uint8)(total_time / 3600);play_time.minute = (uint8)((total_time / 60) % 60);play_time.second = (uint8)(total_time % 60);/* printf file header information */printf("%s %ldHz %dbit, DataLen: %ld, Rate: %ld, Length: %2ld:%2ld:%2ld\n",channel_mappings[wave.header.channels],             //声道wave.header.samp_freq,                              //采样频率wave.header.bit_samp,                               //每个采样点的量化位数wave.length,wave.header.byte_rate,play_time.hour,play_time.minute,play_time.second);//fclose(wave.fp);                                               /* close wave file */
}

按结构体一点点的读出文件头的信息,请注意

/* jump to "data" for reading data */

的那一段,“先识别data标识符,再接着往下读取”。

(3)读数据

在读完数据长度之后就全是数据了,直接使用fread按uint32格式读取数据即可,我这里每次读取1152个数据(即一帧)。

/** get wave data */
uint32* GetWave(void)
{static uint32 buffer[1152] = {0}; uint16 n = 1152;uint16 p = 0;p = fread(buffer, sizeof(uint32), n, wave.fp);if(!p){return 0;}else{for(; p<n; p++){buffer[p] = 0;}return buffer;}
}

上面程序中注意几点,

(1)不要定义大容量的局部变量,因为局部变量存放在堆栈中。如果一定要定义,要定义成static类型。

(2)不要返回局部变量的的地址,因为在堆栈中的地址值是不确定的。

(3)对于for(; p<n; p++)指当读出的数据不满一帧的时候,在后面补0到一帧,一般这样方便后期处理

上面的程序返回局部数组的指针,前提是 已经将数据存放在静态数据存储区。

但不管怎样,返回局部变量的地址总是不好的。

读取*.wav音频文件相关推荐

  1. 如何用C语言编写wav读取函数,C++读取WAV音频文件的头部数据的实现方法

    C++读取WAV音频文件的头部数据的实现方法 前言: 在这里分享一下自己的心得,希望和大家一起分享技术,如果有什么不足,还请大家指正.写出这篇目的,就是希望大家一起成长,我也相信技术之间没有高低,只有 ...

  2. python音频频谱_Python 读取WAV音频文件 画频谱的实例

    Python 读取WAV文件 import wave import struct from scipy import * from pylab import * #读取wav文件,我这儿读了个自己用p ...

  3. c语言 文件 long double 读取,读取*.wav音频文件

    1.wav音频文件的格式 wav文件由文件头和采样数据2部分组成. 文件头又分为RIFF(Resource Interchange File Format).WAVE文件标识段 和 声音数据格式说明段 ...

  4. python音频频谱_Python读取WAV音频文件 画频谱的方法

    Python 读取WAV文件 import wave import struct from scipy import * from pylab import * #读取wav文件,我这儿读了个自己用p ...

  5. python 读取wav 音频文件的两种方式

    python 中,常用的有两种可以读取wav音频格式的方法,如下所示: 1 import scipy 2 from scipy.io import wavfile 3 4 import soundfi ...

  6. Python 读取WAV音频文件 画频谱

    import wave import struct from scipy import * from pylab import * #读取wav文件,我这儿读了个自己用python写的音阶的wav f ...

  7. Python读取wav音频文件

    第一种方式:蜂鸣声 import winsound # 系统音效 winsound.Beep(300,500)# 响铃:300频率,500持续时间 第二种方式:音乐(wav格式或mp3格式) 安装pl ...

  8. python读取音频文件_python 读取wav 音频文件的两种方式

    JavaScript算法(冒泡排序.选择排序与插入排序) 冒泡排序.选择排序与插入排序复杂度都是二次方级别的,放在一起说吧. 介绍一些学习这三个排序方法的比较好的资料.冒泡排序看介绍的冒泡排序,选择排 ...

  9. python用os.system打开wav文件_使用python读取wav格式文件

    ** 使用python读取wav格式文件 ** - 基本概念 [采样频率] 即取样频率, 指每秒钟取得声音样本的次数.采样频率越高,声音的质量也就越好,声音的还原也就越真实,但同时它占的资源比较多.由 ...

最新文章

  1. 新手UI设计师必需要掌握的知识和技能
  2. 漂亮好用的ASP.NET图表控件 免费的
  3. 查看LoadRunner脚本请求日志和服务器返回值方法
  4. MySQL 和 PostgreSQL 对比
  5. NOIP2011 选择客栈
  6. ZOJ-2342 Roads 二分图最小权值覆盖
  7. 现在的计算机电源都要经过,电脑待机后必须关闭电源才能开启
  8. redis用list做消息队列
  9. java基数排序简单实现_基数排序简单Java实现
  10. java游戏初始化参数过多,从头认识java-4.6 成员的初始化
  11. 我的山寨敏捷四季之春
  12. python生成图像公章_科学网—python pillow库 python界的ps 实现数据批量盖章 并打包成exe - 李鸿斌的博文...
  13. C语言编程猜谜语,简单的一字谜语合集
  14. 一个官网很详细的富文本编辑器
  15. illumina 二代测序原理及过程
  16. 深度图+灰度图 可视化判断灰度图区域是否有深度
  17. NR PUCCH(三) PUCCH resource 的配置与调用
  18. 神经网络 深度神经网络,主流的神经网络的框架
  19. 1235 -- 古明地觉的节操教育
  20. STM32——I2S简介硬件连接

热门文章

  1. PTA阿泽的交友标准
  2. leetcode每日一题1219. 黄金矿工 DFS深搜 暴力AC 正月初五祝大家财源广进~
  3. 关于Windows日志
  4. 分贝,功率,功率谱,功率谱密度,信噪比
  5. 两分钟了解什么是CDN
  6. 基于SSH的框架的银行业务管理系统
  7. TIOBE 8 月编程语言排行榜:没有一门语言能比得上 Python
  8. [pysyft-006]联邦学习pysyft从入门到精通--使用protocol
  9. Excel阅读模式/单元格行列指示/聚光灯开发 技术要点再分享
  10. Edge浏览器安装插件报错:显示出现错误 Download interrupted