iOS开发之音频口通信-通过方波来收发数据

之前做过的项目有需要通过音频口通信用方波来收发数据,由于这方面的资料比较少,下面就介绍下其原理,希望能给大家帮助。

一. 音频通信简介
大家应该都知道支付宝声波支付和拉卡拉吧,它们都是利用手机的音频口(手机耳机口)来实现全双工的通信(手机与设备之间的双向通信)。其优点是低成本,编码芯片成本低,手机的 3.5mm 通信接口广泛。

二. 市场应用
支付宝声波支付
手机刷卡器
皮肤检测仪
检测如甲醛、气压、温度、湿度等等
心率、血压等等
.......................

三. 通信原理
手机上用的耳机大多都是3.5mm的四芯座,在这四个芯中,分别是:地(GND)、左声道(L)、右声道(R)和线控开关(MIC)。
左右声道作用:向外设扩展头供电和发送数据
MIC作用:接收数据
市场上耳机主要有两种标准:国内标准(如下图所示),国际标准(MIC和GND和国内标准是反的,其他一样)

国内标准

声音波形调制有调幅(AM)、调频(FM)和调相(PM)三种,而调制又有模拟调制和数字调制之分。(模拟调制和数字调制基本知识参考来源)

模拟调制:这种编码方式是将数字数据调制成模拟信号进行传输。通常采用三种模拟信号的载波特性(振幅、频率和相位)之一来表示被调制的数字数据,并由此产生三种基本调制方式。

模拟信号三种调制方式

(1) 幅移键控(ASK)法

ASK(Amplitude Shift Keying)是使用载波频率的两个不同振幅来表示两个二进制值。在一般情况下,用振幅恒定载波的存在与否来表示两个二进制字。ASK方式的编码效率较低,容易受增益变化的影响,抗干扰性较差。在音频电话线路上,一般只能达到 1200 b/s的传输速率。

(2) 频移键控(FSK)法

FSK(Frequency Shift Keying)是使用载波频率附近的两个不同频率来表示两个二进制值。FSK比ASK的编码效率高,不易受干扰的影响,抗干扰性较强。在音频电话线路上的传输速率可以大于1 200 b/s。

(3) 相移键控(PSK)法

PSK(Phase Shift Keying)是使用载波信号的相位移动来表示二进制数据。在PSK方式中,信号相位与前面信号序列同相位的信号表示 0,信号相位与前面信号序列反相位的信号表示 1。PSK方式也可以用于多相的调制,例如在四相调制中可把每个信号序列编码为两位。PSK方式具有很强的抗干扰能力,其编码效率比FSK还要高。在音频线路上,传输速率可达 9600b/s。
这些信号调制技术主要用于调制解调器(Modem)中。在实际的Modem中,一般将这些基本的调制技术组合起来使用,以增强抗干扰能力和编码效率。常见的组合是PSK和FSK方式的组合或者PSK和ASK方式的组合。

数字信号编码: 对于传输数字信号来说,最简单的信号编码方法是用信号的两个不同电压值来表示两个二进制数据。例如,用无电压来表示 0,用恒定的正电压表示 1;也可用正电压表示 1,而用负电压表示 0。然而,为了提高信号抗干扰能力,并且便于信号接收同步,通常采用更为有效的信号编码方法。

常用的数字信号编码有不归零 NRZ (Non Return to Zero)码、差分不归零DNRZ 码、曼彻斯特(Manchester)码及差分曼彻斯特(Differential Manchester)码等。

(1) NRZ码

NRZ码是用信号的幅度来表示二进制数据的,通常用正电压表示数据“1”,用负电压表示数据“0”,并且在表示一个码元时,电压均无需回到零,故称不归零码。NRZ码的特点是一种全宽码,即一位码元占一个单位脉冲的宽度。全宽码的优点:一是每个脉冲宽度越大,发送信号的能量就越大这对于提高接收端的信噪比有利;二是脉冲时间宽度与传输带宽成反比关系,即全宽码在信道上占用较窄的频带,并且在频谱中包含了码位的速度。

NRZ码的主要缺点是:当数据流中连续出现0 或1时,接收端很难以分辨1个信号位的开始或结束,必须采用某种方法在发送端和接收端之间提供必要的信号定时同步。同时,这种编码还会产生直流分量的积累问题,这将导致信号的失真与畸变,使传输的可靠性降低,并且由于直流分量的存在,使得无法使用一些交流耦合的线路和设备。因此,一般的数据传输系统都不采用这种编码方式。

(2) DNRZ码

DNRZ码是一种NRZ码的改进形式,它是用信号的相位变化来表示二进制数据的,一个信号位的起始处有跳变表示数据“1”,而无跳变表示数据“0”。DNRZ码不仅保持了全宽码的优点,同时提高了信号的抗干扰性和易同步性。

近年来,越来越多的高速网络系统采用了DNRZ码,成为主流的信号编码技术,在FDDI、100BASE-T及100VG-AnyLAN等高速网络中都采用了DNRZ编码。其原因是在高速网络中要求尽量降低信号的传输带宽,以利于提高传输的可靠性和降低对传输介质带宽的要求。而DNRZ编码中的码元速率与编码时钟速率相一致,具有很高的编码效率,符合高速网络对信号编码的要求。同时,为了解决数据流中连续出现0 或1时所带来的信号编码问题,通常采用两级编码方案,第一级是预编码器,对数据流进行预编码,使编码后的数据流不会出现连续 0 或连续 1,常用的预编码方法有4B5B、5B6B等;第二级是DNRZ编码,实现物理信号的传输。这种两级编码方案的编码效率可达到 80%以上。例如,在4B5B编码中,每4位数据用5位编码来表示,即4位数据就会增加 1 位的编码开销,编码效率仍为80%。

(3) 曼彻斯特码

在曼彻斯特码中,用一个信号码元中间电压跳变的相位不同来区分数据“1”和“0”,它用正的电压跳变表示“0”;用负的电压跳变表示“1”。因此,这种编码也是一种相位码。由于电压跳变都发生在每一个码元的中间,接收端可以方便地利用它作为位同步时钟,因此这种编码也称为自同步码。10Mb/s 以太网(Ethernet)采用这种曼彻斯特码。

(4) 差分曼彻斯特码

差分曼彻斯特码是一种曼彻斯特码的改进形式,其差别在于:每个码元的中间跳变只作为同步时钟信号;而数据“0”和“1”的取值是用信号位的起始处有无跳变来表示,若有跳变则为“0”;若无跳变则为“1”。这种编码的特点是每一位均用不同电平的两个半位来表示,因而始终能保持直流的平衡。这种编码也是一种自同步编码。
令牌环(Token-Ring)网采用这种差分曼彻斯特编码。

这两种曼彻斯特编码主要用于中速网络(Ethernet为 10 Mb/s;Token-Ring最高为16 Mb/s)中,而高速网络并不采用曼彻斯特编码技术。其原因是它的信号速率为数据速率的两倍,即对于 10 Mb/s的数据速率,则编码后的信号速率为 20 Mb/s,编码的有效率为 50%。对于 100 Mb/s的高速网络来说,200 Mb/s的信号速率无论对传输介质的带宽的要求,还是对传输可靠性的控制都未免太高了,将会增加信号传输技术的复杂性和实现成本,难以推广应用。因此,高速网络主要采用两级的DNRZ编码方案,而中速网络采用曼彻斯特编码方案,尽管它增加了传输所需的带宽,但在实现起来简单易行。

要实现手机端和扩展头的全双工通信,必须满足2个条件:1.信号必须在音频频率之内;2.需要是低功耗的。第一个条件限制了信号带宽,第二个条件限制了成本和功率。在这2种限制条件下,主要有2种方式实现这种同时的双向通信:FSK调制和基于曼彻斯特编码的直接数字通信。

这里主要讲解下通过数字调制中的FSK调频调制方波。FSK有2FSK(2进制调制)、4FSK(4进制调制)、8FSK(8进制调制)等等。

由于在数字系统中,使用的是0、1表示的二进制数据,在这里,我使用了2FSK来作为信号的调制。

2FSK调频调制方波的原理:用一个频率表示1,另一个不同的频率表示0。比如使用613Hz的信号代表0,1226Hz的信号代表1。如下图所示

方波可以用Cool Edit Pro工具生成,方便调试和研究。具体方法是:
打开工具,新建文件,然后会弹出下面窗口

   这里根据你需求设置波形的采样率,声道和采样精度(一般是44100HZ,单声道,16位采样精度)

接下来选择菜单项-生成

你会看到如下界面,这里可以通过设置不同频率和设置调味为方波生成波形了

方波

那么在iOS下如何接收方波解析和发送方波咧?

每段波形其实是由N(N=采样率/位持续时间(每位数据频率))个有符号的数据点组成,这些有正有负的数组成了一段段波形,比如波形0则有N个127组成的波峰波形或者N个-128组成的波底波形,而波形1则有N/2个波峰+N/2个波低组成,这个波峰波底具体数值定义可自已灵活定义,如下图所示

波形组成原理

举个例子:比如发送个数据5,其二进制数据为0000 0101 ,这里设置采样率为44100HZ,每段波形时间频率1000HZ,定义波形为0 波峰上全是44个127,波形为0 波底上全是44个-128,波形为1的数据 半个 波峰上全是44/2个127,半个 波底上全是44/2个-128,那么5 生成波形的数据就是 0(44个127) 0 (44个-128) 0(44个127) 0 (44个-128) 0(44个127)1(44/2个-128+44/2个127)0(44个-128)1(44个127)。知道这个原理了方波解析和发送数据就简单了。

音频使用的基本步骤如下:

1.设置音频格式和采样率

mAudioFormat.mSampleRate=AUDIO_SAMPLE_RATE;//采样率
mAudioFormat.mFormatID=kAudioFormatLinearPCM;//PCM格式
mAudioFormat.mFormatFlags        = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
mAudioFormat.mFramesPerPacket    = 1;//每个数据包多少帧
mAudioFormat.mChannelsPerFrame   = kChannels/2;//1单声道,2立体声
mAudioFormat.mBitsPerChannel     = 16;//语音每采样点占用位数
mAudioFormat.mBytesPerFrame      = mAudioFormat.mBitsPerChannel*mAudioFormat.mChannelsPerFrame/8;//每帧的bytes数
mAudioFormat.mBytesPerPacket     = mAudioFormat.mBytesPerFrame*mAudioFormat.mFramesPerPacket;//每个数据包的bytes总数,每帧的bytes数*每个数据包的帧数
mAudioFormat.mReserved           = 0;

2.设置remote io unit的渲染回调,从输入硬件获得采样传入到回调函数进行渲染,从而获得录音数据解析数据. 向回调函数填数据,从而向输出硬件提供数据进行放音发送数据.
CheckError(AudioUnitSetProperty(toneUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, disable, &mAudioFormat, sizeof(mAudioFormat)), "couldn‘t set the remote I/O unit‘s output client format");
CheckError(AudioUnitSetProperty(toneUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, enable, &mAudioFormat, sizeof(mAudioFormat)), "couldn‘t set the remote I/O unit‘s input client format");

回调函数OSStatus RenderTone(
                void *inRefCon,
                AudioUnitRenderActionFlags     *ioActionFlags,
                const AudioTimeStamp         *inTimeStamp,
                UInt32                         inBusNumber,
                UInt32                         inNumberFrames,
                AudioBufferList             *ioData);通过这个回调函数就可以发送数据和解析数据

数据编码发送具体代码可参考demo里,知道了编码原理,解码对你来说就简单了

参考文档:
http://blog.csdn.net/it1988888/article/details/9073767
http://www.seeedstudio.com/wiki/index.php?title=Hijack
http://blog.csdn.net/xiejx618/article/details/9790709

时间: 2024-12-16 00:40:05

iOS开发之音频口通信-通过方波来收发数据的相关文章

iOS开发系列--音频播放、录音、视频播放、拍照、视频录制

iOS开发系列--音频播放.录音.视频播放.拍照.视频录制 转载:http://www.cnblogs.com/kenshincui/p/4186022.html#avFoundationCamera --iOS多媒体 概览 随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制,还是对麦克风.摄像头的操作都提供了多套API.在今天的文章中将会对这些内容进行一一介绍: 音频 音

iOS开发拓展篇—应用之间的跳转和数据传递

iOS开发拓展篇—应用之间的跳转和数据传 说明:本文介绍app如何打开另一个app,并且传递数据. 一.简单说明 新建两个应用,分别为应用A和应用B. 实现要求:在appA的页面中点击对应的按钮,能够打开appB这个应用. 1.新建两个应用,分别为A和B.     2.设置应用B的url. 3.在应用A中编写打开app的代码 点击之后,会跳转到新的控制器. 注意:打开应用B的过程中,B有两种状态. 第一种状态:B并没有启动,那么会启动B.并调用下面的方法. 第二种状态:此时B已经启动了,但是在后

iOS开发系列--音频播放、录音、

音频 在iOS中音频播放从形式上可以分为音效播放和音乐播放.前者主要指的是一些短音频播放,通常作为点缀音频,对于这类音频不需要进行进度.循环等控制.后者指的是一些较长的音频,通常是主音频,对于这些音频的播放通常需要进行精确的控制.在iOS中播放两类音频分别使用AudioToolbox.framework和AVFoundation.framework来完成音效和音乐播放. 音效 AudioToolbox.framework是一套基于C语言的框架,使用它来播放音效其本质是将短音频注册到系统声音服务(

IOS开发之音频--录音

前言:本篇介绍录音. 内容大纲: 1.录音应用场景. 2.录音功能实现. 3.概念补充. 4.开发经验. 正文: 1.录音应用场景 ① 语言聊天:在即时通讯APP中,例如即时通讯APP中,例如微信.QQ等等,都有语音发送功能. ②语音备忘录:录一段音频,来记录某件事情. 2.录音功能实现 ①导入AVFoundation框架 一些多媒体的处理,基本都使用这个框架. ②使用AVAudioRecorder进行录音 <1>创建录音文件存放路径 <2>设置录音附件设置项(#import &l

iOS开发之音频播放、录音

iOS的音频播放可以分为短音频播放(例如:音效等点缀音频)和长音频播放(例:音乐等主音频).前者不需要对进度.循环等进行控制,而后者需要精确的控制.在iOS中播放这两种音频分别使用AudioToolbox.framework和AVFoundation.framework来完成. 短音频音效 AudioToolbox.framework是一套基于C语言的框架,使用它来播放音效其本质是将短音频注册到系统声音服务(System Sound Service).System Sound Service是一

iOS开发之 音频播放

音频播放 1.介绍 - 功能介绍 用于播放比较长的音频.说明.音乐 ,使用到的是AVFoundation - 框架介绍 * AVAudioPlayer * 初始化: 注意 : (3)必须声明全局变量的音乐播放对象.或者是属性的音乐播放对象  才可以播放 (4)在退出播放页面的时候 一定要把播放对象置空  同时把delegate置空 导入框架:#import <AVFoundation/AVFoundation.h> 声明全局变量 @interface ViewController ()<

iOS开发——WAVE音频文件解析

WAV文件也分了好几类,相应的非数据信息存储在文件的头部,下面简单的提一下,然后在最后重点介绍44字节的那种,一般用的都是这个. 1.8KHz采样.16比特量化的线性PCM语音信号的WAVE文件头格式表(共44字节) 偏移地址  字节数  数据类型   内容  文件头定义为 00H   4   char     "RIFF"  char riff_id[4]="RIFF"   04H   4   long   文件总长-8     long int size0=文总

ios开发-程序压后台后,悄悄的抓取数据~~

我们使用某个app的时候,当我们将程序压到后台之后,我们希望它还能从服务器抓取一些数据,类似微博,微信,qq这些程序压后台 之后,我们依然能看到icon上显示未读数量.但是ios系统是伪多任务操作系统. 当我们将程序压后台之后,大概过1分钟,程序就会被关闭.就不能抓取数据了.很久之前的做法是:压后台之后,播放一个没有声音 的音频,保证程序存活.然后苹果很快发现了这种方法,并禁止了.我们用这种方法提交审核之后,一般都会被苹果驳回.当然,苹果 依然很贴心的给我提供了相应的解决办法.(使用swift演

iOS开发-使用第三方库AFNetWorking解析JSON和XML数据

利用第三方库AFNetWorking解析网络请求的JSON和MXL数据具有很多方便的地方. 第三方库的下载地址:https://github.com/AFNetworking/AFNetworking 导入的包和宏定义 1 #import "ViewController.h" 2 #import "AFNetworking.h" 3 #import "GDataXMLNode.h" 4 5 //json地址 6 #define kJSONUrlS