尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

welle.io如何实现DAB数据业务:PAD解码与MOT幻灯片图片接收完全讲解

welle.io如何实现DAB数据业务:PAD解码与MOT幻灯片图片接收完全讲解 welle.io如何实现DAB数据业务PAD解码与MOT幻灯片图片接收完全讲解【免费下载链接】welle.ioA DAB/DAB Software Defined Radio (SDR)项目地址: https://gitcode.com/gh_mirrors/we/welle.iowelle.io 是一款开源的 DAB/DAB 软件定义收音机SDR除了高保真音频播放它还能接收数字音频广播里的数据业务——比如电台滚动字幕和 MOT 幻灯片图片。这篇文章将完整讲解 welle.io 内部的 PAD 解码与 MOT 幻灯片图片接收流程广播帧如何被拆解、数据组如何校验、图片片段如何被重新拼接最终显示到你的屏幕上。什么是 DAB 数据业务先搞懂 PAD 和 MOT 两个概念 DAB 广播除了音频之外还携带一类随路数据官方术语是PADProgram Associated Data节目关联数据。在 welle.io 中PAD 由两部分组成F-PAD固定部分每帧固定存在包含 4 字节用于声明本帧 X-PAD 的结构类型、指示位、CI 标志位等。X-PAD扩展部分长度可变真正承载数据内容内部由一串数据子域Data Subfield组成前面跟着一个 CI 列表Content Indicator List说明每段数据是什么类型。而MOTMoving Object Transfer移动对象传输就是 ETSI EN 301 234 定义的数据传输协议专门用来在 PAD 通道里下载文件。DAB 台常用的 MOT 幻灯片就是用 MOT 协议把 JPEG/PNG 图片切成小片段轮流播出接收端攒齐后还原成完整图片形成轮播。一句话概括PAD 是信封MOT 是信件投递规则幻灯片图片是信件内容。PAD 解码流程从广播帧到数据组的完整链路 第 1 步解码器从帧体中提取 PADwelle.io 的后端解码器在解出每一帧音频数据后会把帧尾部的 PAD 区域单独切出来交给统一的处理入口DABMPEG-1 Audio Layer II 服务dab_decoder.cpp 中调用observer-ProcessPAD(...)X-PAD 长度来自帧结构DABAAC 服务dabplus_decoder.cpp 中解析同步帧后调用ProcessPAD此处exact_xpad_len为 true表示长度必须严格匹配DAB 规范要求长度不符时应丢弃 X-PAD若无 X-PAD则用全零的 F-PAD 占位调用。这两处都通过观察者接口回调到 decoder_adapter.cpp 的ProcessPAD再转发给核心类PADDecoder。第 2 步解析 X-PAD 的 CI 列表PADDecoder::Processpad_decoder.cpp是整个数据业务的调度中枢它做几件事字节序还原X-PAD 在传输中是倒序存放的先反转为正常字节序构建 CI 列表根据 F-PAD 中的xpad_ind字段判断是短 X-PAD1 个 CI长度固定 3 字节还是可变长度 X-PAD最多 4 个 CI处理隐式延续如果本帧没有 CI 列表但上一帧有说明数据组是延续的——这里 welle.io 还做了容错loose模式兼容一些不符合标准的发射端长度校验若声明的 X-PAD 长度与可用长度不匹配则报错或丢弃对应PADLengthError回调。第 3 步按 CI 类型分发数据子域CI 类型决定了数据子域交给哪个子解码器处理核心分支在 pad_decoder.cpp 的Process函数中CI 类型含义对应解码器1数据组长度指示器DGLIDGLI解码器2 / 3动态标签开始 / 延续动态标签解码器12 / 13MOT 数据组开始 / 延续MOT解码器几个关键细节DGLI 先行类型 1 的 DGLI 告诉解码器下一个数据组有多长它自带 CRC16 校验解码成功后其长度值会喂给 MOT 解码器作为预期数据组长度mot_decoder.SetLen(dgli_len)。动态标签类型 2/3 的数据被拆成最多 8 个片段DL_SEG由DL_SEG_REASSEMBLER按片段号排序、用 Toggle 位检测新一轮传输拼完整后按对应字符集解码成电台滚动字幕。MOT 匹配DecoderAdapter初始化时通过padDecoder.SetMOTAppType(12)声明只关心类型 12开始/13延续的数据组其余类型一律忽略——这就是只接收幻灯片、不接收其他数据业务的开关。第 4 步CRC16 校验数据组完整性MOTDecoder继承自DataGroup基类pad_decoder.h所有子域先攒进缓冲区攒够 DGLI 声明的长度后做 CRC16-CCITT 校验CheckCRC。校验失败立即丢弃重置保证交给上层的数据组一定是完好的。这是 welle.io 数据业务可靠性的第一道防线。MOT 幻灯片重组把碎片拼回一张图片 ️MOTManager三层解析结构数据组交棒给 mot_manager.cpp 中的MOTManager::HandleMOTDataGroup它按 MOT 协议从外到内解析三层头部数据组头Data Group Header区分是 MOT 传输内容还是普通对象头会话头Session Header携带会话号、传输 ID 和last_seg标志用于区分对象头会话和对象主体会话分段头Segmentation Header给出分段号与分段长度。图片按 MOT 协议被切成许多小段Segment分散在连续的多个广播帧里发送。MOTObject内部维护两个MOTEntity——分别负责对象头和对象主体的片段缓存segs_t映射表按分段号归位收到last_seg标志表示该会话接收完毕。MOT_FILE图片的身份证头对象解析完成后ParseCheckHeader会填充一个MOT_FILE结构mot_manager.h它就像图片的身份证content_type/content_sub_type内容类型幻灯片只认CONTENT_TYPE_IMAGE0x02且子类型必须是JFIFJPEG或PNGcontent_name、category、slide_id、category_titleMOT 幻灯片扩展头里的分类与编号信息用于多栏目轮播管理click_through_url、expire_time附带跳转链接与过期时间。PADDecoder在拿到重组好的文件后pad_decoder.cpp会再过滤一次只有图片类型 JPEG/PNG 子类型的组合才会触发observer-PADChangeSlide(new_slide)其他内容静默丢弃。图片如何到达你的屏幕GUI 显示链路 回调链最后一级是 GUI 层路径如下PADDecoder → PADChangeSlide → DecoderAdapter::PADChangeSlide → myInterface.onMOT(mot_file) → CGUIHelper::motUpdate → CMOTImageProvider → MotView.qml 刷新gui_helper.cpp 的motUpdate把原始字节按子类型加载为QImage支持 GIF/JPEG/BMP/PNG并按分类号/分类标题/幻灯片号/内容名生成图片路径存入CMOTImageProviderQML 界面 MotView.qml 提供MOT Slide Show视图通过image://SLS/...的 URL 方案实时取图轮播用户还可以一键把已接收的全部幻灯片保存到本地文件夹guiHelper.saveMotImages。至此一张幻灯片从电台中被发射、切割、逐帧接收、CRC 校验、片段重组到屏幕上显示welle.io 的完整数据业务链路就跑通了。核心源码路径速查表 想深入阅读时按这个顺序看效率最高模块文件路径职责PAD 提取入口dab_decoder.cpp、dabplus_decoder.cpp从帧中切出 PAD 并回调PAD 解码中枢pad_decoder.h、pad_decoder.cppCI 列表解析、DGLI、动态标签、MOT 数据组 CRCMOT 重组管理mot_manager.h、mot_manager.cpp会话/分段解析、图片文件还原解码器适配层decoder_adapter.h、decoder_adapter.cpp观察者实现、SetMOTAppType(12)配置GUI 图片管理gui_helper.cpp图片加载、缓存、保存幻灯片视图MotView.qml轮播显示与交互小结welle.io 的 DAB 数据业务实现堪称教科书级分层清晰提取 → 解析 → 校验 → 重组 → 展示、防御性强处处 CRC 校验 长度匹配 类型白名单、容错友好loose 模式兼容非标准发射端。理解了 PAD 解码与 MOT 重组这两块你就掌握了数字广播数据业务的通用套路——这套架构对研究 DAB、DAB 乃至其他 SDR 数据接收项目都有很强的参考价值。【免费下载链接】welle.ioA DAB/DAB Software Defined Radio (SDR)项目地址: https://gitcode.com/gh_mirrors/we/welle.io创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表