最近研究了如何在iOS上绘制wav波形图。查了很多资料,都没能找到一个很完整的介绍,我这里总结一下一些经验。

首先需要了解wav的这3个重要指标:采样率、采样位数、声道数。下面以16KHz, 16Bit, 单声道为例来说明。

采样率:(也称为采样速度或者采样频率)定义了每秒从连续信号中提取并组成离散信号的采样个数,单位用赫兹(Hz)来表示。采样频率的倒数是采样周期(也 称为采样时间),它表示采样之间的时间间隔。采样率为16KHz,表明每秒钟采样有16K次,即0.001秒内采集16个值。

采样位数:即采样值或取样值,用来衡量声音波动变化的参数,是指声卡在采集和播放声音文件时所使用数字声音信号的二进制位数。声卡的位客观地反映了数字声音信号对输入声音信号描述的准确程度。16Bit表示用计算机的16位(即2字节)来标示一个值。

声道数:是指支持能不同发声的音响的个数。常见的有单声道和双声道。

比特率:每秒传送的比特(bit)数,等于采样率*采样位数,单位为bps(Bit Per Second)。示例音频的比特率为256kbps。

C语言没有提供专门的wav音频文件处理框架,因此,我们只能通过读取文件的2进制值来分析wav音频的波形。这里就需要对wav音频的格式有一定的了解。

wav音频分为文件头和数据块两大部分。

表1 WAV文件的文件头

偏移地址

字节数

类型

内容

00H~03H

4

字符

资源交换文件标志(RIFF注意字符大小写!

04H~07H

4

长整数

从下个地址开始到文件尾的总字节数

08H~0BH

4

字符

WAV文件标志(WAVE注意字符大小写!

0CH~0FH

4

字符

波形格式标志(fmt注意字符大小写!

10H~13H

4

整数

过滤字节(一般为00000010H)

14H~15H

2

整数

格式种类(值为1时,表示数据为线性PCM编码)

16H~17H

2

整数

通道数,单声道为1,双声音为2

18H~1BH

4

长整数

采样频率

1CH~1FH

4

长整数

波形数据传输速率(每秒平均字节数)

20H~21H

2

整数

数据的调整数(按字节计算)

22H~23H

2

整数

样本数据位数

表2 WAV声音文件的数据块

偏移地址

字节数

类型

内容

24H~27H

4

字符

数据标志符(data注意字符大小写!

28H~2BH

4

长整型

采样数据总数

2CH...

...

...

采样数据

WAVE文件是由若干个Chunk组成的。按照在文件中的出现位置包括:

RIFF WAVE Chunk,位置00H~0BH。

Format Chunk,以'fmt'作为标示。一般情况下Size为16,此时最后附加信息没有;如果为18则最后多了2个字节的附加信息。主要由一些软件制成的wav格式中含有该2个字节的附加信息。位置0CH ~23H。

Fact Chunk,可选字段,一般当wav文件由某些软件转化而成,则包含该Chunk。

Data Chunk,是真正保存wav数据的地方,以'data'作为该Chunk的标示。然后是数据的大小。紧接着就是wav数据。从24H开始。

其中除了Fact Chunk外,其他三个Chunk是必须的。每个Chunk有各自的ID,位于Chunk最开始位置,作为标示,而且均为4个字节。并且紧跟在ID后面的是Chunk大
小(去除ID和Size所占的字节数后剩下的其他字节数目),4个字节表示,低字节表示数值低位,高字节表示数值高位。

在了解了wav文件的结构后,我们就可以轻松的取出wav的相应信息了。接下来就是绘制曲线,我们使用Quartz来绘图。苹果官方提供了一套例子,参考

http://developer.apple.com/library/ios/#samplecode/QuartzDemo/Introduction/Intro.html

其中关键是QuartzView和QuartzLines这两个文件。在QuartzLines.m文件中可以找到我们想要的绘制曲线方法,可以作为参考。

接下来的事情就很简单了,我们只需要从2CH的位置开始,每2个字节(与采样位数有关)的取数据,然后画到屏幕中。因此,音频数据点的个数为:采样数据总
数/2。如果需要将图像绘制到界面上,x坐标范围10~310,y坐标范围200~400,只需要将这些点做个映射就行了。

注意:

源码中只考虑了没有Fact Chunk的情况。实际上在读取data的时候应该加上判断
if(strcmp(id, "data")!=0){//not eq data
//TODO 读取Fact Chunk
//结构是4字节的Fact Chunk数据长度+Fact Chunk数据
}

//---------------------------以上数据为转载数据---------------------------------//

后面添加两个下载连接:

参考示例QuartzLines.m(为了达到更好的显示效果,对y进行了放大处理)

http://download.csdn.net/detail/daiyelang/6617369

demo:

http://download.csdn.net/detail/daiyelang/6617383

ios 绘制wav波形图的更多相关文章

  1. C# NAudio录音和播放音频文件-实时绘制音频波形图(从音频流数据获取,而非设备获取)

    NAudio的录音和播放录音都有对应的类,我在使用Wav格式进行录音和播放录音时使用的类时WaveIn和WaveOut,这两个类是对功能的回调和一些事件触发. 在WaveIn和WaveOut之外还有对 ...

  2. SurfaceView绘制录音波形图

    本文简单记录由View绘制转为SurfaceView绘制的波形图问题. 上代码: public class VoiceLineView extends View { private final int ...

  3. Python绘制wav文件音频图(静态)[matplotlib/wave]

    #!/usr/bin/env python # -*- coding: utf-8 -*- """ 绘制波形图 plottingWaveform.py "&qu ...

  4. 应用wavesurfer.js绘制音频波形图小白极速上手总结

    一.简介 1.1  引   人生中第一份工作公司有语音识别业务,需要做一个web网页来整合语音引擎的标注结果和错误率等参数,并提供人工比对的语音标注功能(功能类似于TranscriberAG等),(博 ...

  5. iOS绘制坐标图,折线图-Swift

    坐标图,经常会在各种各样的App中使用,最常用的一种坐标图就是折线图,根据给定的点绘制出对应的坐标图是最基本的需求.由于本人的项目需要使用折线图,第一反应就是搜索已经存在的解决方案,因为这种需求应该很 ...

  6. 转:iOS绘制一个UIView

    绘制一个UIView 绘制一个UIVIew最灵活的方式就是由它自己完成绘制.实际上你不是绘制一个UIView,你只是子类化了UIView并赋予子类绘制自己的能力.当一个UIVIew需要执行绘图操作的时 ...

  7. iOS 绘制1像素的线

    一.Point Vs Pixel iOS中当我们使用Quartz,UIKit,CoreAnimation等框架时,所有的坐标系统采用Point来衡量.系统在实际渲染到设置时会帮助我们处理Point到P ...

  8. iOS绘制线条的使用

    1.相关简介 1.1.iOS之UIBezierPath贝塞尔曲线属性简介 1.2.iOS之CAShapeLayer属性简介 2.绘制曲线 2.1.方法详解 - (void)addQuadCurveTo ...

  9. C# NAudio录音和播放音频文件及实时绘制音频波形图(从音频流数据获取,而非设备获取)

    下午写了一篇关于NAudio的录音.播放和波形图的博客,不太满意,感觉写的太乱,又总结了下 NAudio是个相对成熟.开源的C#音频开发工具,它包含录音.播放录音.格式转换.混音调整等功能.本次介绍主 ...

随机推荐

  1. 单篇文章JS模拟分页

    废话部分 前两天做了一个前台分页插件,支持ajax读取数据绑定前台 和 url带页码参数跳转两种方式.于是稍加改动,做了一个单篇文章js模拟分页的代码,为什么说是模拟分页呢?因为在服务器响应HTML请 ...

  2. HTTP头信息解读

    本文为多篇“HTTP请求头相关文章”及<HTTP权威指南>一书的阅读后个人汇总整理版,以便于理解. 通常HTTP消息包括客户机向服务器的请求消息和服务器向客户机的响应消息.客户端向服务器发 ...

  3. Android 如何调用自写APK和非自写APK

    由于项目需要,调用一个现成的APK,总结之余,顺便把怎么调用自写APK的方法也写上,以做比较 1.如何调用现成的APK: 先上调用代码,然后再一一解释: Intent mIntent = new In ...

  4. 有用的前端demo

    js定时器循环切换字体和背景颜色<script type="text/javascript"> var flashId = 0; setInterval(functio ...

  5. 控制弹出div显示在鼠标附近的位置

    前一个页面: $("#txt_ocname").click(function () { art.dialog.open("/SelPosAll.aspx", { ...

  6. JS+CSS+HTML简单计算器

    <!doctype html> <html> <head> <title>计算器</title> <meta charset=&quo ...

  7. THINK PHP U的用法

    public function index(){ //$db=new \Think\Model(); //$db=M('msg'); //$result=$db->query("sel ...

  8. mac 常用的开发工具

    http://www.oschina.net/news/53946/mac-dev-tools 要清楚的认识到,我们寻找的不是开始按钮,而是程序入口,任何一个操作系统,用户要做的事情并不是找到开始菜单 ...

  9. [JavaScript] JavaScript作用域深度解析

    JavaScript作用域 JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里. -- JS权威指南 在JS里,一切皆对象,函数也是. 一.有什么用 什么时候会用到它? ...

  10. poj 3232 Accelerator

    http://poj.org/problem?id=3232 题意:有一个含有n辆车的车队,当前距离终点的距离已知,有m个加速器,每个加速器在一个时刻只能给一辆车用,一旦使用就会使得其速度由1变成k, ...