ios 绘制wav波形图

最近研究了如何在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波形图的更多相关文章
- C# NAudio录音和播放音频文件-实时绘制音频波形图(从音频流数据获取,而非设备获取)
NAudio的录音和播放录音都有对应的类,我在使用Wav格式进行录音和播放录音时使用的类时WaveIn和WaveOut,这两个类是对功能的回调和一些事件触发. 在WaveIn和WaveOut之外还有对 ...
- SurfaceView绘制录音波形图
本文简单记录由View绘制转为SurfaceView绘制的波形图问题. 上代码: public class VoiceLineView extends View { private final int ...
- Python绘制wav文件音频图(静态)[matplotlib/wave]
#!/usr/bin/env python # -*- coding: utf-8 -*- """ 绘制波形图 plottingWaveform.py "&qu ...
- 应用wavesurfer.js绘制音频波形图小白极速上手总结
一.简介 1.1 引 人生中第一份工作公司有语音识别业务,需要做一个web网页来整合语音引擎的标注结果和错误率等参数,并提供人工比对的语音标注功能(功能类似于TranscriberAG等),(博 ...
- iOS绘制坐标图,折线图-Swift
坐标图,经常会在各种各样的App中使用,最常用的一种坐标图就是折线图,根据给定的点绘制出对应的坐标图是最基本的需求.由于本人的项目需要使用折线图,第一反应就是搜索已经存在的解决方案,因为这种需求应该很 ...
- 转:iOS绘制一个UIView
绘制一个UIView 绘制一个UIVIew最灵活的方式就是由它自己完成绘制.实际上你不是绘制一个UIView,你只是子类化了UIView并赋予子类绘制自己的能力.当一个UIVIew需要执行绘图操作的时 ...
- iOS 绘制1像素的线
一.Point Vs Pixel iOS中当我们使用Quartz,UIKit,CoreAnimation等框架时,所有的坐标系统采用Point来衡量.系统在实际渲染到设置时会帮助我们处理Point到P ...
- iOS绘制线条的使用
1.相关简介 1.1.iOS之UIBezierPath贝塞尔曲线属性简介 1.2.iOS之CAShapeLayer属性简介 2.绘制曲线 2.1.方法详解 - (void)addQuadCurveTo ...
- C# NAudio录音和播放音频文件及实时绘制音频波形图(从音频流数据获取,而非设备获取)
下午写了一篇关于NAudio的录音.播放和波形图的博客,不太满意,感觉写的太乱,又总结了下 NAudio是个相对成熟.开源的C#音频开发工具,它包含录音.播放录音.格式转换.混音调整等功能.本次介绍主 ...
随机推荐
- mockServer学习
mockServer学习 很喜欢mockserver官方主页的背景颜色和格式 官方主页如下: http://www.mock-server.com/
- zookeeper管理solr的配置文件
zookeeper可以管理solr和其他软件的配置文件.配置文件还是保存在linux服务器的磁盘上,但是不是改变solr读取solr/home配置的配置文件的位置. 现在solr/home配置文件的位 ...
- memcache缓存命中深入理解转载
http://www.iteye.com/topic/225692 memcache的方法有 add,set,replace,get,delete,getstats,increment,decreme ...
- .NET中删除空白字符串的10大方法
介绍 我们有无数方法可用于删除字符串中的所有空白.大部分都能够在绝大多数的用例中很好工作,但在某些对时间敏感的应用程序中,是否采用最快的方法可能就会造成天壤之别. 如果你问空白是什么,那说起来还真是有 ...
- Hadoop参数优化
dfs.block.size 决定HDFS文件block数量的多少(文件个数),它会间接的影响Job Tracker的调度和内存的占用(更影响内存的使用), mapred.map.tasks.spec ...
- C#结课报告
Revision History Date Issue Description Author 18/May/2015 v1.0 Initial creation 邓彪翼 模拟图书馆的查询系统 1.ob ...
- Linq中字段数据类型转换问题(Linq to entity,LINQ to Entities 不识别方法"System.String ToString()"问题解决)
1.在工作中碰到这样一个问题: 使用linq时,需要查询两个表,在这两张表中关联字段分别是int,和varchar()也就是string,在linq中对这两个字段进行关联, 如果强制类型转换两个不同类 ...
- Struts2 处理表单重复提交
* 在表单页面中增加一个隐藏域:<s:token></s:token>(需要在表单内) * 创建一个struts.xml的配置文件,具体配置如下: ...
- 在eclipse中运行wordcount,控制台打印log4j警告
log4j:WARN No appenders could be found for logger (org.apache.hadoop.util.Shell).log4j:WARN Please i ...
- 比file_get_contents稳定的curl_get_contents
相信使用过file_get_contents函数的朋友都知道,当获取的$url访问不了时,会导致页面漫长的等待,甚至还能导致PHP进程占用CPU达100%,因此这个函数就诞生了 分享一个实际在用的函数 ...