【GNURadio实验报告】实验3-关于GNU Radio和HackRF的采样率问题
一、采样率的定义二、GNU Radio的采样率问题(一)【Audio Source】的采样率含义(二)【Wav File Source】的采样率含义(三)【Vector Source】的采样率含义(四)【Signal Source】的采样率含义 三、HackRF的采样率问题论据一:OOK/2ASK调制信号码元宽度异常论据二:AM调制信号速率异常本文在写作过程中,得到了开源SDR实验室/OpenSourceSDR?type=blog大佬们的悉心指导,并参考借鉴了/OpenSourceSDR/article/details/108361877等文章内容,在这里向你们的无私帮助表示衷心感谢!
博主本人非通信专业出身,本文仅为个人在学习GNU Radio和HackRF过程中记录的知识点笔记,文中难免会出现错误和疏漏,恳请走过路过的大佬不吝赐教斧正。
期待能够为GNU Radio中文社区增添一份贡献!
【核心结论】
一、软件信号仿真和硬件处理信号,采样率的作用不同
软件信号仿真:数字信号转数字信号,没有A/D过程,接收机(例如【QT GUI Frequency Sink】示波器、【Audio Sink】播放器)所谓的“采样”,实际是调节数据流的流速,传进来多少数据点就照单全收多少点,只不过处理的速度有变,故将成比例改变原始信号的频率。
硬件处理信号:采样是将连续的模拟信号转化为离散的数字信号,采样率的不同,决定的是数字信号与原始模拟信号的相似度,即信号丢失得多少(声音失真),而不会改变原始信息(语速变快、音调变高等;在满足奈奎斯特采样定理的情况下)。
二、使用HackRF发射信号时,采样率应控制在[200kHz,18MHz]之间,否则将导致信号失真
尽管HackRF最大采样率为20MHz(AD采样率20MSPS),但发射数字信号时,采样率若超过18MHz或小于200kHz,实际发射信号的码元宽度将于待发射信号不相符;发射模拟信号时,音频流速将出现异常。
一、采样率的定义
引用知乎百科:采样频率,也称为采样速度或者采样率,定义了每秒从连续信号中提取并组成离散信号的采样个数,用赫兹(Hz)来表示。
我们使用麦克风录音时,声音的信号是连续的。
声音进入麦克风后,计算机每隔一段时间采集一次当前时间点的声音样本(如下图所示),将连续的模拟信号转化为离散的数据流,这一过程即采样,再经量化等步骤后,生成波形文件/样本文件。
采样频率描述了计算机采集声音样本的速率,也即每秒采集多少个声音样本。从上图中我们可以看出,采样频率越高,即采样的间隔时间越短,声音波形的表示也越准确,占用的存储空间也越来越大;采样频率越低,也就相对越来越失真。采样率再低也不宜低于信号中最高频率fmax的2倍,否则声音将会发生混叠,这个极限值被称为奈奎斯特频率。通常在实际应用中保证采样频率为信号最高频率的2.56~4倍。
二、GNU Radio的采样率问题
GNU Radio常用的信号源大致可以分为4种:
【Signal Source】≈常规信号生成器,可生成锯齿波、正弦波、方波等常用信号。
【Vector Source】≈数据流模块,例如下图中该模块将持续输出01001。
【Wav File Source】≈波形文件播放器,从.wav波形文件中读取信息形成数据流输出。
【Audio Source】≈麦克风,直接从硬件麦克风读取用户输入的声音。
(一)【Audio Source】的采样率含义
(最好讲的放在一开始来说……)
【Audio Source】对应于连接到计算机上的麦克风,是对输入音频设备的一种抽象。
当我们对着麦克风说话时,我们喉咙发出的声音是1种模拟信号,它的波形连续的。【Audio Source】的采样率Sample Rate,表示计算机要以多大的时间间隔对我们的声音进行采样,即1秒钟采集多少个点。下图所示的48kHz,即1秒采集48k个点。这个值设置得太低,采集到的声音就会失真;越高,音质就越好,但是生成的文件也就越大。
从时域角度来看,采样频率越高,意味着数字信号的波形也就越能够贴合原始的模拟信号,采集的也就越完整。
从频域角度来看,采样率越高,代表着采集的带宽也就越大,囊括进来的原始信号的频率信息也就越完整,保留更多的声音细节。
例如,邓紫棋唱歌的高音很好听,但是音调高=频率高,为了能够采集到这些高音,就需要拓宽采样率。如下图所示,假如歌曲人声+乐器的“音调”范围在0-10kHz之间,而我最大的采样率能够达到48kHz(奈奎斯特:采样频率要大于最高频率的2倍),也就能够保留更多的声音细节,音质自然也就越高。
但是,如下图所示,当某个音的音调太高,以至于超出了采样率的范围,那么这个音会跑到屏幕之外吗?不会,它会被采样“窗口”右边的边界“弹回来”,由原来的“高音”被扭曲称了“低音”,这个现象叫做混叠。
(引用自知乎文章《什么是混叠》/p/23923059的这张gif动图可以很好的展示发生混叠的这一过程)
(二)【Wav File Source】的采样率含义
【Wav File Source】的用途是从波形文件(.wav等)里面读取数据,形成数据流。
以.wav文件为例,这种文件会在文件头偏移位置18H处记录下该文件的原始采样率(图片引用自/p/456281177),也就是我们右键文件属性里面给出的这个信息。这一数值存在的目的,是当我们使用网易云等音乐播放器播放音频文件时,音频文件会告诉播放器,应当以多少采样率来播放自己。
但是!对于【Wav File Source】模块而言,wav文件里面的数据没有时间戳!这是什么意思?
在【Wav File Source】模块看来,波形文件存储的数据,是这样的一串数组:
[1,2,3,4,5,4,3,2,1,2,3,4,5……]#仔细看,这是一串正弦波的幅度值
如果有时间戳的话,那波形文件存储的数据应该如下这样,类似于字幕文件,以键值对的形式记录每个数值(每句台词)应当出现的时间点:
[(0s,1),(0.1s,2),(0.3s,3),(0.4s,4),(0.5s,5)……]#以键值对形式存储数据
然而,wav文件仅仅是以一维方式记录了波形的采样数据,即一连串的幅度值。播放器选择以什么样的速率去播放这串数据流,必然会影响音频播放的流速(例如语速变快)。但丢失波形信息了吗?没有,因为wav文件存储的每个数据都被播放出来了,只不过播放得快/慢了一点。
当我们使用【Audio Sink】模块分别以16kHz、48kHz(文件原始采样率)、96kHz去播放这段音乐,语速分别会像蜗牛一样、正常、非常快且声音尖锐,但声音细节并没有丢失。
(三)【Vector Source】的采样率含义
【Vector Source】数据流模块。该模块从1个向量中提取数据并输出。下图所示的输出数据为0123456789。
如下图所示,使用【QT GUI Time Sink】时域示波器来播放这串数据。将该示波器的采样频率Sample Rate设为10,即1秒内读取10个点。
结果如图,数字0-9在时间轴上依次排列开来,数字9的点恰好出现在0.9s处,下一个数字0刚好在1s处,表明这串数字正在以10Hz的速率被读取输出。
增加1个【Repeat】模块,令每个码元重复10次(Interpolation=10),这意味着计算机每秒输出10个点,1个码元占10个点,故每个码元时长就拉长为1秒*10Hz/10次=1秒。
(四)【Signal Source】的采样率含义
【Signal Source】常规信号发生器。可生成恒定波形(阶跃信号)、正弦信号、余弦信号、方波信号、三波信号、锯齿波信号。
如下图所示,使用该模块生成一个频率为2kHz的余弦波信号(每秒2000个周期),并以32kHz的速率(每秒采集32k个点)来对这个余弦波进行采样。由此我们可知:每个波形周期将采样16个点,也即每16个点为一组能复原出一个周期的余弦波形。
【Signal Source】模块的作用,是生成数据点而不是发送数据点:它在内存里写入了一连串的数据,这些数据的规则是每16个点为一个周期(例如[0 1 2 3 4 5 4 3 2 1 0 -1 -2 -3 -4 -5 -4 -3 -2 -1 0 1……]),但要注意,这串数据并没有时间戳信息。我们使用【QT GUI Frequency Sink】频域示波器来播放这串数据时,若采样率设置为32kHz,示波器模块就会在1秒内从内存里取出32k个点,而每16个可组合为一个余弦波形周期,那么32k个点之中就有32k/16=2000个周期,1s-2000周期即2kHz,因此示波器将显示该信号频率为2kHz。
而当采样率为16kHz时,Sink模块在1秒内从内存里拿出来16k个点,那么16k个点就有16k/16=1000个周期,1s-1000周期,频率自然是1kHz!!!
同理,当采样率提高到64kHz,就是1s内拿出64k个点,即1秒内将出现64k/16=4000个余弦波周期,频率自然是4kHz!!!
三、HackRF的采样率问题
HackRF的采样率最高可以达到20MHz,但根据博主实践情况来看,当使用HackRF发射信号时,实际可用采样率在[200kHz-18MHz]区间内,超出该区间发射的信号会失真,数字信号的码元宽度、模拟信号的频率都将出现异常。
论据一:OOK/2ASK调制信号码元宽度异常
详细实验过程见本专栏第2篇【GNURadio实验报告】实验2-使用GNURadio仿真OOK信号。注:实验过程中请遵守当地无线电法规。博主是将发射机和接收机用双绞线+负载直接对接进行的实验,没有实际发射电磁波。
下图所示的grc流程图实现的是向外发送OOK(On-Off Keying)开关键控/通断键控信号,基带信息为二进制数据流01001,码元宽度为1s*100k/200k=0.5s,载波频率为409.750MHz。
实际发射效果如下图所示。这里使用了RTL-SDR接收机+SDR#软件完成信号采样,采样率设为2.048MSPS,带宽32kHz,设自动增益控制,解调方式选择了CW,录制内容为音频数据;录制的音频wav文件使用Adobe Audition进行分析。由图可知,RTL-SDR成功在409.750MHz接收到来自HackRF发送的01001,且码元宽度为0.5s。
博主先后试验了100k、200k、250k、10M、15M、17M、18M、19M、20M采样率,当且仅当采样率为200k-18M的情况下,接收到的码元宽度为0.5s;将HackRF发射机的采样率设置为100kHz或20MHz时,码元宽度出现异常,部分实验数据和截图证据如下。
需要说明的是:之所以接收机的采样率没有影响码元宽度,是因为在使用硬件实际发射、接收无线电信号时,接收机的采样是把从空间中捕获下来的连续的模拟信号转换为离散的数字信号,这些模拟信号的流速是给定的,接收机采样率的大小不会到影响发射机信号,即码元宽度不会变化,这和单纯使用软件进行信号仿真(数字信号转数字信号)是不一样的。例如,在KTV用1个采样率很低的廉价麦克风去唱歌,只会导致音质很差,但没听说用嘴唱出来的歌和麦克风采录进去的歌语速发生了变化。
在本次实验过程中还发现:HackRF的频偏会随着时间增大。如上图所示(横轴为时间,纵轴为频率,可以看到随时间推移,频率越来越大),接收到的OOK信号,音频音调越来越高。
论据二:AM调制信号速率异常
下图所示grc流程图展示了一个简易的AM电台发射机:通过【Wav File Source】模块读取原始采样率为48kHz的音频文件,【Multiply Const】用于调整音频响度;【Rational Resampler】重采样模块将原信号的48kHz采样率扩展成为9.6MHz;最后【osmocom Sink】模块以9.6MHz采样率对原始信号进行采样后,上变频到409.75MHz发射到空间中。
仍然使用RTL-SDR+SDR#作为接收机,采样率设置2.048MSPS。此时在接收机端收听到的音频音频有失真(出现杂音噪声),但语速正常。
调整发射机的采样率到200kHz时,语速依然正常。
而当调整为100kHz、96kHz、48kHz时,语速出现异常。
题外话:
1.【Wav File Source】模块流出的数据经过【Rational Resampler】重采样后,采样率由48kHz增大到200kHz,但是【osmocom Sink】模块的采样率我也设置了同步提高到200kHz。信号最开始1秒有48k个点,重采样后变成1秒有200k个点等待传递给下一个模块,【osmocom Sink】模块如果1秒仍然只接收48k个点,那么数据流就会“堵车”、“迟滞”;调整到200kHz后就能够正常处理数据流了,基带信息以正常的速度被调制到载波上,没有发生语速变快的情况。
2.如果此时把上图中的【osmocom Sink】模块换成【Audio Sink】模块,整个grc流程图就变成了纯信号仿真,即数字信号转数字信号。此时【Audio Sink】模块的采样率如果与【Rational Resampler】重采样模块输出的信号采样率不一致,将影响计算机声卡播放出来的音频语速。例如下图中使用采样率为400kHz采样率的【Audio Sink】模块播放音频时,听到的音频语速就会非常快。因为200kHz采样率(可以理解为数据流流速)的原始信号被以400kHz的采样率播放,数据流速快了1倍。
3.那么为什么接收机端的采样率和发射端的不一致,还能够继续听到正常语速的音频呢?这就是前面一直在说的,使用硬件设备处理信号时,所谓“采样”就是模数转换的过程,从空间中捕捉下来连续的模拟信号,流速是给定的,接收机的采样只能影响生成的数字信号是否更拟合原始信号,却改变不了原始信号的流速。