声波传输编码

这篇文章是系列文章的第2篇。第一篇在这里声波配网原理


在声波传输的发送端,我们要做的事情用下面这张图就可以概括:

发送端

也就是通过三步,我们就可以把我们要传输的文本信息变成声音发送出去。

下面我们来一步一步的看:

1.从字符到数组角标的映射:

这一步可以看成是第二步的预处理,从字符到频率映射的一个过渡。把字符对应的频率存储在一个叫FREQUENCIES的数组中:

FREQUENCIES {1760,1810,1870,......}

FREQUENCES数组

因为默认是支持ASCII码字符,而键盘能输入的字符其实只在32到127之间,所以把这96个字符映射到FREQUENCIES数组中角标0~95的频率。而我们在用Base64规则转码中文字符时也只需要用到这96个字符中的(0-9,A-Z,a-z,+,-,=)。所以其实用来传递信息的数据区的话,数据区域有96个频率就足够了。

代码

关于重复标志和顺序标志的使用,在后面的文章之进一步优化-提高传输速率中会提到,暂时先忽略~~~

开始标志:需要一个信号告诉我们的接收端在什么时候可以开始解析了,同时这个标志还有一个重要的作用->对齐音节,这个作用在写解码的时候会详细的描述。

结束标志:需要一个信号告诉我们的接收端本次传输结束。

2.根据角标查找频率:

这个不用蠢作者多说了吧~数组查询O(1)~没毛病

3.把频率变成正弦波音频信号:

建立字符和频率的一一映射关系之后,如果我们想发出”单频率”的声音,就需要自己构造特定频率的正弦函数。

1)正弦波生成公式:

energy =

正弦波生成公式

这个是蠢作者采用的正弦波生成公式,其中frame是采样点的位置,sample_rate是采样率(44100Hz),frequency是需要生成正弦波的频率。回忆一下高中数学,这个正弦波的周期应该是:T=sample_rate/frequency。

正弦波的频率F是:F=2*pi*frequency/sample_rate

所以解码端通过快速傅里叶变换解码出正弦波的频率F以后,该正弦波携带的信息频率应该是frequency = F*sample_rate/(2*pi)。

正弦波公式的选取可以随意调整,保证能正确的逆向解析出其中的信息频率就好。

MAX_VOLUME可以用来调节最后生产的音频信号的响度(振幅)大小,识别成功率和播放的音频的响度也有很大的关系。

2)将正弦波存成PCM数据格式:

有了energy公式,相当于有了从频域到时域的传输门,但要把时域上连续的声音信号变成我们的设备能播放的数字信号,我们还需要了解两个基本知识:

NO1.采样率(sample_rate):

是指每一秒要采集声音的次数。因为自然界的音频信号,例如人说话,产生的是模拟信号(时间连续的信号)。如果我们想把声音录制下来的话,并没有办法把整个连续的声音信号都录制下来,只能离散的采样,每隔一段时间采集一次数据,将模拟信号转化成数字信号,这样才能在计算机的数字世界中存储。很明显,采样点的多少大大的影响着录制音频记录声音信息的多少,也就是音频的质量。如果采样点多,那么质量就高,听起来就和原声的差别小;相对的,采样点少,质量就次,听起来就和原声不一样。

NO2.采样定理:

既然采样率高,录音的质量就高,那么,是不是采样率越高越好呢?

当然不是啦。

心情复杂

随着采样率的提高,虽然质量提高了,但是采样的难度也对应的增加了,而且,采样出来的数据需要存储,采样率越高,产生的数据文件就越大,那么在网络中传输用的时间就越长。质量高的音乐比一般的音乐体积大就是这个原因。

那么采样率到底设成多少比较好了?

啊啊啊

有一个有名的采样定理“奈奎斯特定理”帮我们解决了这个难题:

如果采样的频率高于信号最高频率的两倍,采样之后的数字信号就可以完整的保留下原始信号中的信息。

因为人的听力范围在20HZ-20000HZ,所以一般采样频率在44.1kHZ,也就是一分钟44100次。选择44100Hz的采样率,肯定能很好的记录我们的正弦波了。

蠢作者建议,我们字符映射的范围在人耳听力的范围内比较好,因为这样一般的硬件设备才能够播放,过高或者过低,就不能兼容所有的手机机型或者其他硬件设备了。当然低频段由于受环境的噪音干扰比较大,也不太建议采用。蠢作者自己用了1700HZ到15000Hz之间的频率,宝宝们可以自己调整。不要小看这些频率的选定哈,对识别的成功率影响很大。因为高频的低频分量很可能会干扰我们正确的解码。

好啦,知道了数字世界通过采样的方式来记录声音信息,那么我们怎么把采样的结果存储下来呢?我选用了PCM文件格式来存储音频数据。

知识点:

NO1.每个音节持续时间(duration)

如果把传输一个字符的正弦波看做是一个音节,那么每个音节的持续时间同样也影响到我们对声音信号的记录和还原。对识别声波的成功率有着重要的影响。当durantion变大时,音节持续时间变成,采样点变多,声音信号的还原度变高,解析出的音频中携带的频率信息出错率变低。同时,采样点变多,PCM文件变大,音节变长,传输过程变长,传输速率降低。

蠢作者选择了0.1S的持续时间,这个宝宝们可以自己定。

NO2.每个音节的采样点unit_sample

我们已经选定了采样率和每个音节的持续时间。很自然的就可以计算出存储每个音节信息的采样点数目unit_sample = duration * sample_rate。

在发送端我们只要把每个采样点都通过energy公式计算出来,存储下来就OK了。

NO3.每个采样点的存储方式

那么每个采样点到底怎么存了?需要稍稍了解一下PCM文件格式。

每个采样数据记录的是振幅,采样精度取决于储存空间的大小:

1字节(也就是8bit)只能记录256个数,也就是只能将振幅划分成256个等级;

2字节(也就是16bit)可以细到65536个数,这已是CD标准了;

4字节(也就是32bit)能把振幅细分到4294967296个等级,好好好厉害有没有~~~~~

所以我们在发送端生成的振幅和接收端录音收到的振幅大小并不能保证完全一样,况且这个值是受播放设备和录音设备两者之间距离的影响的,后面我们分析接收端解码的时候要注意到这一点。

PCM数据格式

通常我们说的双声道(stereo),意味着采样是双份的,文件也差不多要大一倍。PCM中的声音数据是没有压缩的,如果是单声道的文件,采样数据按时间的先后顺序依次存入。如果是双声道的文件,采样数据按时间先后顺序交叉地存入。

我们采用16位单声道的PCM格式存储就足够了,8位的也太粗糙了一点。

由上述energy公式计算出的值是float的,要转成PCM文件让播放器播放,需要将float先转成16位的整数:

float frame_value_16 = MAX_SHORT * frame_value_float;

MAX_SHORT= 32767.

在接收端也需要从16位整数转回float:

float f_value = (float) tempShort[j]/32768.0;

所以大概的从频率到音频信号的代码大概是这样:

代码

这样生成的PCM文件,我们可以直接丢给播放器播放,也可以写到本地存储,写到本地存储的应用场景是,由服务器生成一段携带文本信息的音频,然后客户端拉取之后播放。

好啦~~~~声波传输编码的过程就是这样啦~~~比较简单~~~

我要用洪荒之力写解码的过程啦~

心累写不出来

------------

喜欢的话记得点个喜欢奥~

笔芯

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容