0. 背景介绍
增强管道数据流转(EPDR, Enhanced Pipeine Data Routing)是彩鹰工作室提出的多进程合作架构。此架构通过各个进程的标准输入输出管道(stdio)吞吐数据,平台按照生产消费关系进行流转,联合多个子进程实现数据合作处理。EPDR主要的特点是低耦合性,特别适用于小规模工坊的跨语言、跨编译器合作开发。
taskBus 开源软件无线电平台将此架构运用于SDR领域。非计算机专业的工程师受惠于此平台,可迅速整合每个人最熟悉的开发语言、开发环境,让不同知识背景、教育层次的工程师共同完成实时波形处理软件。
在SDR软件开发中,水位控制是保证硬件及时获取数据,并防止数据堆积的有效手段。本文章基于taskBus平台,演示带水位控制的FM音乐电台的搭建技术,直接播放MP3文件到空中频率,主要流程如下:
1. 水位反馈控制
对于含有实时硬件系统的波形生成设备来说,硬件逻辑的优先级总是高于软件逻辑。如一个把MP3音乐变成调频广播的简单播放机,可存在4个模块。
- 文件读取模块:负责从音乐文件夹读取MP3数据,是系统里的生产者。
- lame解码模块:直接使用开源MP3解码器LAME.exe实现stdio管道解码。
- FM调制模块:负责把 lame.exe 音乐的振幅调制为FM的频率变化。
- SDR发射机。如USRP B210,负责把基带波形搬移到射频并发射出去,是最终消费者。
此时,为了保持音乐的连续性,需要注意几个问题:
- 无法确切控制mp3解码的节奏。Lame.exe解码速度很快,大大超过FM的自然速率。
- 如果上位机送入音乐的速度高于SDR发射机消费音乐的速度,则会出现数据堆积。
- 如果上位机送入音乐的速度低于SDR发射机消费音乐的速度,则会出现数据中断。
由于生产者和消费者的时钟不统一,而消费者是硬件,不好调整节奏,因此需要引入一种反馈机制,让生产者通过软件适时调整输出的速率,让消费者的缓存处于健康的状态(40-60%充盈率)。
这相当于生产者往一个水箱里注水,消费者在用水。生产者生产速度大于消费速度,但无法精确保持一致。此时,通过反馈水位给注水者,通知其调整进水的速率,使得水箱始终有水,又不至于溢出。
对应到SDR软件中,关键在于负责Tx(发射)的代码要不断地输出当前发射缓存中的水位,如下图所示:
2. taskBus UHD 模块的水位实现
水位就是一个整数,用来指示当前环状缓存器还有多少样点节的数据尚未发射出去。
2.1 消费者水位播报
在 taskBus 的UHD模块里,设置一个 waterMark 专题(topic/Subject),用于汇报水位。其核心逻辑如下:
//初始化环状缓存器
const quint64 sz_buffer_all = 128 * 1024 * 1024;
std::vector<SPTYPE> buf_tx_array(sz_buffer_all,0);
//In IQ Samples, RF io
quint64 tx_pos = 0, stdin_pos = 0;
//...
qint64 watM = stdin_pos[0] - tx_pos;
TASKBUS::push_subject(
i_txWaterMark,
instance,
sizeof(qint64),
(unsigned char *) &watM);
通过不断向stdout输出当前的缓存状态,可以让生产者及时知道缓存的盈亏。
2.2 生产者水位控制
在生产者(这里是文件读取器)里,检查当前水位是不是充盈,如果充盈,则降速或者停止生产:
int i_watermark =0;
std::atomic<long long> g_watermark (0);
//刷新水位
while (false==bfinished)
{
subject_package_header header;
std::vector<unsigned char> packagedta = pull_subject(&header);
if (header.subject_id==i_watermark)
{
long long * ptr = (long long *)packagedta.data();
g_watermark = *ptr;
}
}
//......
//水位控制
if (minmark > 0 && i_watermark > 0)
{
while(g_watermark > minmark)
{
QThread::msleep(20);
}
}
3. 范例工程搭建
3.1 下载 lame.exe
去网上下载mp3解码器 lame.exe,放在当前文件夹。这个解码器可以直接接受 stdin的输入,并输出到 stdout (这简直就是为了管道应用而设计的!优雅!)。其参数:
C:\> lame.exe --decode --flush -S --mp3input - -
解释:
LAME 32bits version 3.98.4 (http://www.mp3dev.org/)
usage: f:\lame.exe [options] <infile> [outfile]
<infile> and/or <outfile> can be "-", which means stdin/stdout.
--flush flush output stream as soon as possible
-S don't print progress report, VBR histograms
--decode input=mp3 file, output=wav
--mp3input input file is a MPEG Layer III file
该工具通过封装器模块直接引入工程。封装器模块使得所有支持stdio的程序都可以直接放进来用。
注意:如果运行时没有声音,而弹出了配置栏,那很可能是lame.exe路径不对。
3.2 设置文件源,并连接反馈
设置文件源 source_files, 监视音乐文件夹,文件类型mp3,生产速率每秒50次,每次10000字节。这个生产速率高于绝大多数Mp3文件的速率。同时,设置关键水位门限为1MB。当水位小于1MB时,会触发生产。注意,这个1MB是解码后的WAV的大小,并不是mp3的大小。
注意,这种反馈是级联的反馈,源头生产者生产的数据,经过2层处理后,才给消费者。
4. 执行效果
我们把文件夹中放入mp3文件,就可以直接用收音机收听了!整个过程稳定、连续。
今天的文章DIY调频(FM) MP3电台-基于增强管道数据流转(EPDR)的taskBus实时水位控制技术分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/26628.html