DIY调频(FM) MP3电台-基于增强管道数据流转(EPDR)的taskBus实时水位控制技术

DIY调频(FM) MP3电台-基于增强管道数据流转(EPDR)的taskBus实时水位控制技术EPDR通过各个进程的标准输入输出管道(stdio)吞吐数据,平台按照生产消费关系进行数据流转,联合多个子进程实现数据合作处理。开源软件无线电平台taskBus将此架构运用于SDR领域。非计算机专业的工程师受惠于此平台,可迅速整合每个人最熟悉的开发语言、开发环境,让不同知识背景、教育层次的工程师共同完成实时波形处理软件。在SDR软件开发中,水位控制是保证硬件及时获取数据,并防止数据堆积的有效手段。本文基于taskBus,介绍水位控制在mp3文件夹FM发射机搭建中的应用。

0. 背景介绍

增强管道数据流转(EPDR, Enhanced Pipeine Data Routing)彩鹰工作室提出的多进程合作架构。此架构通过各个进程的标准输入输出管道(stdio)吞吐数据,平台按照生产消费关系进行流转,联合多个子进程实现数据合作处理。EPDR主要的特点是低耦合性,特别适用于小规模工坊的跨语言、跨编译器合作开发。

taskBus 开源软件无线电平台将此架构运用于SDR领域。非计算机专业的工程师受惠于此平台,可迅速整合每个人最熟悉的开发语言、开发环境,让不同知识背景、教育层次的工程师共同完成实时波形处理软件。

在SDR软件开发中,水位控制是保证硬件及时获取数据,并防止数据堆积的有效手段。本文章基于taskBus平台,演示带水位控制的FM音乐电台的搭建技术,直接播放MP3文件到空中频率,主要流程如下:

Mp3文件夹

Lame.exe在线解码

FM调制

UHD发射

1. 水位反馈控制

对于含有实时硬件系统的波形生成设备来说,硬件逻辑的优先级总是高于软件逻辑。如一个把MP3音乐变成调频广播的简单播放机,可存在4个模块。

  1. 文件读取模块:负责从音乐文件夹读取MP3数据,是系统里的生产者。
  2. lame解码模块:直接使用开源MP3解码器LAME.exe实现stdio管道解码。
  3. FM调制模块:负责把 lame.exe 音乐的振幅调制为FM的频率变化。
  4. SDR发射机。如USRP B210,负责把基带波形搬移到射频并发射出去,是最终消费者。

此时,为了保持音乐的连续性,需要注意几个问题:

  1. 无法确切控制mp3解码的节奏。Lame.exe解码速度很快,大大超过FM的自然速率。
  2. 如果上位机送入音乐的速度高于SDR发射机消费音乐的速度,则会出现数据堆积。
  3. 如果上位机送入音乐的速度低于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的程序都可以直接放进来用。

Wrapper注意:如果运行时没有声音,而弹出了配置栏,那很可能是lame.exe路径不对。

3.2 设置文件源,并连接反馈

设置文件源 source_files, 监视音乐文件夹,文件类型mp3,生产速率每秒50次,每次10000字节。这个生产速率高于绝大多数Mp3文件的速率。同时,设置关键水位门限为1MB。当水位小于1MB时,会触发生产。注意,这个1MB是解码后的WAV的大小,并不是mp3的大小。

水位反馈
注意,这种反馈是级联的反馈,源头生产者生产的数据,经过2层处理后,才给消费者。

4. 执行效果

我们把文件夹中放入mp3文件,就可以直接用收音机收听了!整个过程稳定、连续。

TaskBus Good
相关源码参考代码仓库。

今天的文章DIY调频(FM) MP3电台-基于增强管道数据流转(EPDR)的taskBus实时水位控制技术分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/26628.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注