WEBSDR
WEBSDR将本地收听的电台信号共享到互联网上,让您可以随时随地选择频率收听FM电台,而不用购买任何专业硬件设备。网站也附带了实时接收的频谱与瀑布图,是学习通信、信号处理的优秀平台。
概览
硬件
我们目前使用820T2+RTL2832U
USB软件无线电,它支持DVB-T+FM+DAB
,最大采样率为3.3MHZ。
软件
软件代码部分使用Python
进行IQ数据处理与解调,计划使用WebSocket
传输实时数据到服务器上,通过Canvas
渲染数据,调用Web Audio API
等实时播放音频。
实现过程
下图是一个简要的程序实现流程。
首先,我们通过820T2+RTL2832U
USB软件无线电设备在一个信号良好的地方(比如建筑物高层外围)收集附近的无线电信号,得到IQ数据。这里我们使用RTL-SDR
项目支持的设备的简单Python
接口pyrtlsdr
,一个依赖C
语言的librtlsdr
的Python
包装器(基于Realtek RTL2832U
的SDR的驱动程序)来驱动设备并获得IQ数据。
获取IQ数据后,接下来进行数字信号处理(DSP)。
首先使用非常适合于进行交互式绘图的
matplotlib
子包pylab
的psd
函数(Power Spectral Density Estimates Using FFT)计算功率谱密度,得到信号的频谱。目前我们以91.2MHz为中心频率及2.8MHz的采样率进行采样,从网站渲染的频谱图可以看见,平时能收听到所在地(北京)3~4个无线电台,具有典型性。接着,使用Python中最经典的开源的数学、科学和工程计算包
scipy
分析信号。对于每次的采样数据,应用抗混叠滤波器(这里使用了带汉明窗的30点FIR滤波器)后,对信号进行下采样;对于信号解调,有很多对FM信号进行解调的方法,我们选取了一种高效而简单的FM解调方法。信号在时域中的微分等效于信号的傅里叶变换乘以虚斜坡函数。也就是说,要对信号求导,请将其传递给具有响应 H(ω)=jω 的滤波器。使用firls
和differentiator
选项获得逼近理想的微分器,为节约运行时间,代码部分已经直接以数组形式呈现。最后将IQ信号实部和虚部分别卷积处理后,再次下采样输出为音频信号,保存为流媒体格式。该部分核心核心代码如下:
for data in datas: a = -2j*np.pi*(CFFREQ-RFFREQ)*(np.arange(1, len(data)+1)/RFRATE) x = np.exp(a) x = np.transpose(x) data = data * x data = signal.decimate(data, DOWN_FACTOR, ftype="fir") # design differentiate # b = signal.firls(30,[0 .9],[0 1],'differentiator'); b = [0.0005, -0.0017, 0.0032, -0.0052, 0.0079, -0.0115, 0.0162, -0.0223, 0.0302, -0.0406, 0.0548, -0.0752, 0.1077, -0.1699, 0.3502, 0, -0.3502, 0.1699, -0.1077, 0.0752, -0.0548, 0.0406, -0.0302, 0.0223, -0.0162, 0.0115, -0.0079, 0.0052, -0.0032, 0.0017, -0.0005] ndata = data/abs(data) rd = ndata.real ids = ndata.imag audiodata = (rd*signal.convolve(ids, b, 'same')-ids * signal.convolve(rd, b, 'same'))/(rd*rd+ids*ids) # rd*rd+ids*ids=1 audiodata = signal.decimate(audiodata, AUDIO_FACTOR, ftype="fir") audiodata_amp = audiodata*1e4 # astype用于转化dateframe某一列的数据类型;这里是转为i2:int16 snd_data = audiodata_amp.astype(np.dtype('<i2')).tostring() wav.append(snd_data) # 向音频Queue添加数据 save_wav(WAVE_OUTPUT_FILENAME, CHANNELS, 2, AUDIORATE, wav)
最后,在DSP处理完成之后,上传到Web服务器上。网站服务器根据功率谱密度通过echarts
框架的JavaScript
代码实时渲染频谱图和瀑布图,同时函数触发器判断用户实时选择操作与服务器完成交互。根据我们测试,传统的实时解调最多只能同时支持4~8人收听不同的信号(Intel i7 CPU),为避免大规模的访问导致服务器带宽、性能不足,我们接入了内容分发网络(CDN)
技术,依靠腾讯云部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。这样虽然牺牲了一部分实时性,即有部分更新缓存延迟,但是可以支持更多用户同时使用网站、收听信号,解决了高并发的一大难题。
整个流程自动推进,并在主机上不断运行。在异步处理和多线程的运行形式下,主要功能已经无人值守地实现。
其他
目前网站是一个实现形式的Demo,还在不断完善中,发现bug欢迎在下方留言。