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

时间: 2024-12-11 01:59:52

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

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

#!/usr/bin/env python # -*- coding: utf-8 -*- """ 绘制波形图 plottingWaveform.py """ import wave import pylab as pl import numpy as np print('working') # 打开wav文档 file = wave.open(r"mic4.wav", "rb") # 读取格式信息 # (

iOS 绘制1像素的线

一.Point Vs Pixel iOS中当我们使用Quartz,UIKit,CoreAnimation等框架时,所有的坐标系统采用Point来衡量.系统在实际渲染到设置时会帮助我们处理Point到Pixel的转换. 这样做的好处隔离变化,即我们在布局的事后不需要关注当前设备是否为Retina,直接按照一套坐标系统来布局即可. 实际使用中我们需要牢记下面这一点: One point does not necessarily correspond to one physical pixel. 1

转:iOS绘制一个UIView

绘制一个UIView 绘制一个UIVIew最灵活的方式就是由它自己完成绘制.实际上你不是绘制一个UIView,你只是子类化了UIView并赋予子类绘制自己的能力.当一个UIVIew需要执行绘图操作的时,drawRect:方法就会被调用.覆盖此方法让你获得绘图操作的机会.当drawRect:方法被调用,当前图形上下文也被设置为属于视图的图形上下文.你可以使用Core Graphics或UIKit提供的方法将图形画到该上下文中. 你不应该手动调用drawRect:方法!如果你想调用drawRect:

C#实现wav波形图

看了一下网上的资料,实现不难,接下来要研究fft 归一按照网上资料,补码/32768 程序分作了两部分,wav格式的定义网上资料很多 读取wav,保存音频数据到txt using System.IO; using System; using System.Text; namespace 音频处理 { class Program { const int byteSample = 2; const int dataPosition = 40; //0x16 2byte 0002 双声道 //0x22

原创 ios绘制 圆形气泡

效果: 1 先自定义一个view #import <UIKit/UIKit.h> #define kCalloutWidth   80.0   //气泡高度 #define kCalloutHeight  95.0   //气泡宽度 #define kArrorHeight    15      //底部距离高度 @interface CallOutContentView : UIView @end 2实现代码 #import "CallOutContentView.h"

IOS 绘制PDF -转

-(void)createPdf:(UIImage *)img andText:(NSString *)text{ 2 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 3 NSString *saveDirectory = [paths objectAtIndex:0]; 4 NSString *saveFileName = @"myPDF.pdf&

iOS绘制手势解锁密码

手势解锁这个功能其实已经用的越来越少了.但是郁闷不知道我公司为什么每次做一个app都要把手势解锁加上.....于是就自己研究了一下手势解锁页面的实现.. 要想实现这个页面,先说说需要掌握哪些: UIPanGestureRecognizer的基本使用 CGRectContainsPoint(<#CGRect rect#>, <#CGPoint point#>) UIBezierPath贝塞尔曲线的绘制 drawRect 和 layoutIfNeeded 知道何时,如何使用 只要掌握上

ios绘制基本图形之水印背景

1 @interface NJTextImage : UIView 2 @end 3 4 5 @implementation NJTextImage 6 7 - (void)drawRect:(CGRect)rect 8 { 9 // [self test]; 10 // 1.加载图片到内存中 11 UIImage *image = [UIImage imageNamed:@"bg"]; 12 13 // 利用OC方法将图片绘制到layer上 14 // 将图片绘制到指定的位置 15

iOS绘制收益柱状图

项目需求,参考了其他绘图demo,自己绘制出来了,不过代码改得有点乱,添加了很多变量,时间关系没用太合适的命名,逻辑处理也没进行优化. 看看效果图(虚线区域都是画的,其他区域添加的都是控件),附上源码 #import <UIKit/UIKit.h> typedef enum : NSUInteger { CSYieldTypeWeek = 0,    //周收益 CSYieldTypeMonth = 1,   //月收益 CSYieldTypeYear = 2,    //年收益 } CSYi