C++ VS2015 调频FM接收机程序调试(RTL SDR)

最近在业余的时间里一直在搞C++ 版本的FM解调程序,使用的硬件是RTLSDR, 很便宜的一个淘宝货,FM解调的C++代码网上有很多,但是很多都是linux 下的, 嫌麻烦,又要装虚拟机之类的,(其实后来还是迫不得已装了),想在WIN7下实现,用的是VS2015,网上还没有现成的代码,都是自己东拼西凑的。

代码涉及的技术:

  1. RTLSDR的IQ数据获取
  2. FM的解调
  3. 信号滤波
  4. 音频播放
  5. 多线程,线程间通信,资源冲突
  6. 数据缓冲,缓存
  7. 程序速度问题
  8. 界面
  9. FFT频谱

别小看这么一个收音机程序,这里所涉及的知识足以让一个工程师搞上一阵子,要把这么多东西柔和在一起,不但需要扎实的射频功底,也是非常锻炼C++功底的。其实搞这个RTL的收音机程序最主要目的是锻炼自己C++代码搬砖。

 

最核心的,FM的解调代码部分最主要是参考这个JvanKatwijk老大爷的,一个退休的工程师。

https://github.com/JvanKatwijk

http://www.sdr-j.tk/

https://www.sdr-j.tk/index.html

 

音频播放,WIN7下我找到了两种方式的声音播放方法。

  • Windows WaveOut, 用这个最主要是如何处理好音频数据缓冲,以及音频数据格式的转换, 一般来说解调完的FM信号是double类型的,需要转换成Int16声卡可以接受的形式, 数据的缓冲可以参考这篇double buffering的文章,

http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=4422&lngWId=3

 

  • LabVIEW有个lvsound2.dll,这个其实好用多了,只管往里丢数据

 

多线程的问题

IQ数据获取 -> 滤波 -> FM解调 -> audio播放, 这些必要的操作有的快有的慢,不可能只放在一个线程里操作,电波里传来的FM信号是连续的,需要实时不断的处理这些信号,可以参考JvanKatwijk这个老家伙的处理方法,其实就是生产者-消费者的模式,实际就是

  1. IO数据获取一个线程(生产者1)
  2. FM解调一个线程(消费者1,同时也是生产者2--音频数据的生产者)
  3. Audio播放一个线程(消费者2)

这里最大的问题是大量的数据如何在线程间传递,消费者如果处理不过来,最终播放的时候会产生严重的卡顿。

 

速度问题

如果程序的运行速度不够快,不管是多线程还是单线程,音频播放都会出现卡顿。在这里,FM的解码(decode)部分是最慢最占资源的函数,由于FM的解码太慢,单一线程解码不够快,声音播放卡顿,,于是尝试开辟了10个线程同时进行FM解码,结果发现解码更慢了,线程越多是有代价的,各种线程的花销,和线程间的切换,导致了FM 解码更慢。所以最终还是回到了一个FM解码线程的结构。

提高VS2015代码运行速度的方法:

  1. 有debug模式改为release模式,这可以让执行程序快好几十倍。
  2. 项目属性 --> C/C++ --> Optimization, 选择最大速度,速度优先等等,如下图。这也可以让程序快很多。
  3. C++ VS2015 调频FM接收机程序调试(RTL SDR)