自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(54)
  • 收藏
  • 关注

原创 HarmonyOS 弦乐调音器开发实战 05:UIAbility 如何串起启动、窗口与配置更新

拆解原生 ArkTS 的 Stage 启动链:EntryAbility 建立 AppStorage 状态,WindowStage 加载首页、监听窗口宽度并初始化服务;说明配置更新、备份入口空实现及未实机验证边界。

2026-08-04 20:30:51 206

原创 HarmonyOS 弦乐调音器开发实战 04:Flutter 页面如何通过 ArkTS 插件接入系统音频

解析 Flutter 与 ArkTS 插件的音频桥接:MethodChannel 传命令,EventChannel 推送帧;梳理隐私权限、AudioCapturer 采音、NSDF 检测及 release HAP 未实机回归边界。

2026-08-04 20:02:31 244

原创 HarmonyOS 弦乐调音器开发实战 03:参考音、调音历史与 AppStorage 如何形成闭环

围绕 StringtTuning 原生 ArkTS 1.0.7,梳理参考音播放、AppStorage 与 Preferences 的部分设置同步、调音会话保存和历史读取,并说明 PCM/合成分支、renderer 竞态及实机验证边界。

2026-08-04 19:42:57 323

原创 HarmonyOS 弦乐调音器开发实战 02:AudioCapturer 与 NSDF 怎样完成实时音高检测

基于 StringtTuning 原生 ArkTS 1.0.7 源码,拆解 AudioCapturer 采集、4096 点窗口、NSDF 音高估计、跳变抑制、平滑与音分换算,并严格区分源码与实机验证边界。

2026-08-04 19:19:35 377

原创 HarmonyOS 弦乐调音器开发实战 01:先分清 ArkTS 1.0.7 与 Flutter 1.0.8 两条工程线

从真实 StringtTuning 项目出发,梳理原生 ArkTS 1.0.7 与 Flutter 1.0.8 两条 HarmonyOS 工程线,明确版本、入口、截图、构建产物和验证边界。

2026-08-04 18:49:05 356

原创 OpenHarmony 小鸿 AI 开发实战 17:从长文本到发热量化的端到端验收

也没有真实温升、电流、CPU 或无线占空比数据。建议的记录表包含:固件 SHA-256、供电电压、采样时间、环境温度、板上测点温度、电流平均值、电流峰值、屏幕亮度、音量、Wi-Fi RSSI、会话次数、TTS 播放占比、队列 overflow 次数和异常日志。前者通过 FakeWriter 收集 WebSocket frame,并用替换后的 ASR、LLM、TTS 函数检查 hello、listen、协议 v1/v2/v3 包头、音色切换、重连、三条 TTS JSON 和四个下行 Opus 包。

2026-07-30 16:37:38 234

原创 OpenHarmony 小鸿 AI 开发实战 16:systemd + Nginx 部署、回滚与安全边界

本文不连接生产服务器、不读取本地凭据文件,也不执行上传、重启、Nginx reload 或公网探测。因此,当前可以确认的是部署脚本包含上传前预检、备份、环境更新、安装、重启、详细 health、模型 smoke 和后半段异常回滚;文章不复述该文件位置和内容。当前旧片段如下,它具备 WebSocket 所需的 HTTP/1.1、Upgrade、Connection、Host 和长读超时,但 upstream 仍为 18088,路径仍为兼容命名,并且没有展示 TLS、访问控制、请求大小限制、日志脱敏或限流。

2026-07-30 16:26:41 334

原创 OpenHarmony 小鸿 AI 开发实战 15:从回答文本到 CI1302 扬声器的 TTS 下行链路

设备每包解码后通常得到 1280 字节 PCM,10 包约 12800 字节,能形成三个完整 4096 字节块并留下尾段,既满足启动缓冲,又没有一开始就超过 OpenHarmony 路径的四槽队列。用户听到扬声器播出一句回答之前,项目里至少经过了五种不同的数据形态:LLM 返回的回答文本、Fish Audio 或离线 VITS 生成的 PCM、服务端编码出的 16 kHz Opus、WebSocket 二进制帧、WS63 解码后的 PCM,以及最终送往 CI1302 的。是 4,每槽最多 4096 字节。

2026-07-30 16:19:03 600

原创 OpenHarmony 小鸿 AI 开发实战 14:可替换 LLM Provider 的现状与目标边界

Provider 抽象落地时可以引入有限的错误类别,例如 configuration、authentication、rate_limit、timeout、invalid_response 和 unavailable,并保持面向设备的提示稳定。需要比较的指标不只是“有回答”:还包括首个模型响应耗时、总调用次数、超时回退、答案长度、TTS 是否收到完整句、同一设备历史是否隔离,以及切换 Provider 后知识问题是否仍经过独立复核。设备固件、OTA 响应、文章、截图和公开日志都不能包含真实 LLM key。

2026-07-30 16:02:13 339

原创 OpenHarmony 小鸿 AI 开发实战 13:libopus 与 sherpa-onnx 怎样完成中文 ASR

OpenHarmony WS63 设备把一段语音送到服务端时,上传的不是 WAV 文件,也不是可以直接交给识别模型的浮点数组,而是一串有先后关系的 Opus packet。本轮没有在 Linux 服务器加载实际 Zipformer INT8 模型,没有用真实普通话录音测字错率,也没有重新连接 WS63 实机验证噪声、远场、口音、丢包和并发。后续若要把“模型可用”提升为“设备体验可用”,至少还需要固定语料集、识别准确率、首字/整句时延、并发排队时间,以及一条从 CI1302 到设备播报的可回放端到端记录。

2026-07-30 15:49:49 564

原创 OpenHarmony 小鸿 AI 开发实战 12:Python asyncio 语音服务怎样接住设备

下一步继续扩展功能前,最值得先补的是端到端可观测性:为每个 session 贯通 device id、session id、audio frame count、ASR 文本、LLM 耗时、TTS 首帧和 close reason。Session 记录 session id、设备对应的 dialogue key、voice key、协议版本、音频格式、采样率、帧时长、累计 binary frame/byte 以及本轮 Opus packet。关键顺序是 packet 收集、stop、ASR、LLM、TTS;

2026-07-28 17:41:39 323

原创 OpenHarmony 小鸿 AI 开发实战 11:WS63 Agent 与 WebSocket 协议状态机

当前事件包括 Wi-Fi 连接变化、短按切换对话、长按配网、唤醒词、TTS 开始/停止、音频通道关闭、发送音频以及 CI1302 的 VAD 段结束。+ LiteOS-M 的小设备来说,可靠的语音交互不靠一个“连接成功”日志,而靠状态、事件、协议握手、音频顺序和有界资源共同成立。下一篇将转到 Python asyncio 服务端,逐段对应 OTA、WebSocket、Session、ASR、LLM 和 TTS 如何接住这里发出的消息。,发送 client hello,再等待 server hello。

2026-07-28 17:40:00 310

原创 OpenHarmony 小鸿 AI 开发实战 10:CI1302 语音上行的 UART 帧、Opus 与 VAD

它能证明 Python 逻辑和协议顺序,没有替代 CI1302 麦克风、UART 921600、真实 Opus 内容和无线链路的实机测试。这说明“是否上行”不能只看 WebSocket 是否连接,还要同时看 Agent 状态、监听模式、pending stop 和 stop 已发送标志。、LiteOS-M 上的 CI1302 UART ring、帧解析、Opus bridge 和 Agent 排序逻辑整理。更换 VAD、帧长或语音场景后,应通过真实语料统计重新调整,而不是把源码常量当成硬件规格。

2026-07-28 17:38:25 472

原创 OpenHarmony 小鸿 AI 开发实战 09:从 SoftAP 到家庭 Wi-Fi 的中文配网链路

本轮源码核对通过,但没有重新拿手机连接热点、选择 SSID、输入错误密码、重试、成功回写、断电重启和长按清除配置。扫描结果上限来自 SDK 的接口容量,代码按 SSID 长度和内容匹配目标 BSS,再复制 BSSID、SSID 和 pre-shared key,指定动态 DHCP。扫描代码等待 4 秒,最多收集配置限定数量的非空 SSID,把它们编码为 JavaScript 可用的字符串列表,随后启动 SoftAP 和 HTTP server。,任务结束时再次检查并释放,避免一次配网失败后留下堆内存。

2026-07-28 17:36:48 332

原创 OpenHarmony 小鸿 AI 开发实战 08:LittleFS 与流式 binfont 的完整中文显示链

当前小鸿工程采用的办法不是继续扩大内置 C 数组,而是把二进制字库放进外部 W25Q128,由 LittleFS 管理文件,通过 HTTP Range 支持续传,最后由 LVGL 按需读取字形。LittleFS 的起始地址和容量直接引用 P0 宏,读写粒度为 16 bytes,块大小引用扇区,cache 为一页,lookahead 为 32 bytes。排查方框字时,应先确认挂载,再确认文件,再确认 bin 格式和码点范围,而不是看到 UI 有文字就断定外部字库已经工作。重命名成正式文件,并重新探测。

2026-07-28 17:33:50 376

原创 OpenHarmony 小鸿 AI 开发实战 07:用 LVGL 构建 240×240 语音伙伴界面

当前小鸿界面要同时容纳状态栏、语音焦点、状态提示、对话文本、音量反馈和配网/升级页面,还要在 WS63 的 SRAM 与 LiteOS-M 任务模型下稳定刷新。源码层已经确认 240×240 尺寸、对象层次、五种视觉模式、16 行局部缓冲、单任务 tick、1~20 ms 等待、512 字节 pending buffer、144/108 字节分页和 3.2 秒停留。在 LVGL 任务初始化时创建状态栏、焦点环、12 个环段、核心区、图像、5 个波形条、互动文字、回答页装饰、全屏文字和音量覆盖层。

2026-07-24 12:32:12 287

原创 OpenHarmony 小鸿 AI 开发实战 06:LiteOS-M 多任务与事件队列怎样接住三个按键

三个实体按键看起来只是 GPIO 输入,但在当前小鸿 WS63 OpenHarmony 固件中,一次短按要经过电平采样、稳定去抖、时长分类、事件回调、主消息队列,再分发到音频、显示或 Agent 任务。本文已经从当前源码确认三键映射、30/60/80/400 ms 时序阈值、500/5000 ms 长按边界、事件数据表、四个消息队列的容量,以及音量、亮度和中键的实际分支。这里有一个容易忽略的设计:5 秒事件必须先于普通长按判断,否则 5000 ms 同时满足 500 ms,永远只会进入普通长按。

2026-07-24 12:06:00 325

原创 OpenHarmony 小鸿 AI 开发实战 05:烧录成功仍黑屏的 GPIO14/PWR_ON 故障复盘

本轮没有重新烧入黑屏包,也没有再次用当前源码构建后完成三键、显示、Wi-Fi 与 Agent 的整机回归。这次故障最容易误判的地方,是 BurnTool 已经完成写入,设备却黑屏。要确认修复进入新包,还应重新构建并保存产物哈希,烧入后读取启动串口,观察早期显示日志,再检查三键。对于 PWR_ON、复位、Flash 片选、LCD 片选和背光等关键脚,应建立保留表,并让编译期或静态脚本拒绝通用扫描覆盖。恢复包可以点亮,而试验包稳定黑屏时,硬件突然损坏的可能性会显著下降,调查应优先转向两个包之间的板级差异。

2026-07-24 11:46:30 341

原创 OpenHarmony 小鸿 AI 开发实战 04:WS63 BurnTool 烧录、Loader、导出与回滚

的过程拆开,这一篇继续处理构建之后最容易混淆的部分:BurnTool 到底证明了什么、Loader 在什么时候参与、怎样做完整内部 Flash 导出,以及出问题后如何回到已知可工作的固件。本文依据小鸿项目自带的 Windows 烧录指南、本地真实固件包和一份已经完成长度、内容分布与 SHA-256 核对的 4 MiB 原始备份整理,不把官方操作说明、历史烧录结果和本轮文件核验混成同一条证据。如果只截图最后一行 success,而没有保存文件哈希,之后无法判断烧录的是刚生成的包、恢复包还是同名旧包。

2026-07-24 11:30:13 593

原创 OpenHarmony 小鸿 AI 开发实战 03:从 mini 产品到 .fwpkg 的 WS63 构建实录

遇到失败时按“目标图、产品依赖、工具链 PATH、写权限、业务源码”的顺序定位,通常比从最后一条编译器输出倒猜更稳定。这一步的正确结论是“本机经过兼容适配后构建成功”,不是“仓库原始检出开箱即构建成功”。这个边界看起来严格,却能避免最常见的固件混淆:源码改的是一份、打包来自另一份、烧录选中第三份,最终又拿旧串口日志证明全部通过。这不是把 README 命令再抄一遍,而是记录 2026 年 7 月 24 日在本地完整源码树中真正执行过的命令、遇到的失败、采用的兼容路径,以及最后产物的大小和 SHA-256。

2026-07-24 10:41:20 483

原创 OpenHarmony 小鸿 AI 开发实战 02:从板级源码读懂 WS63、CI1302、ST7789 与外部 Flash

本文依据 OpenHarmony WS63 当前板级源码,核对 P13/P12/P11 按键、P14 PWR_ON、ST7789 与 W25Q128 共享 SPI1、CI1302 UART2 921600 8N1、16 MiB 外部 Flash 与 4 MiB 固件备份边界,并明确尚未完成的实机验证。

2026-07-23 19:26:53 349

原创 OpenHarmony 小鸿 AI 开发实战 01:先认对工程,WS63 与 ESP32-P4 路径怎么选

本文依据 OpenHarmony-6.1.0.31-Release 分支及源码快照,梳理小鸿本体 WS63、xiaohong-se 与 ESP32-P4 工程边界,说明 config.json、BUILD.gn、LiteOS-M 消息队列、固件产物和 BurnTool 的验证边界。

2026-07-23 18:55:28 348

原创 原生鸿蒙像素画板实战 22:快捷键与鼠标交互

键盘和鼠标应增强现有像素编辑流程,而不是制造第二套状态。本文结合 bitArt,说明快捷键映射、焦点保护、撤销重做、滚轮缩放及桌面与移动布局的输入边界。

2026-07-23 18:10:36 222

原创 原生鸿蒙像素画板实战 21:编辑器设置

编辑器设置的难点不在控件数量,而在输入边界和副作用。本文结合 bitArt,说明自动保存、导出倍率、历史上限、背景与洋葱皮等设置如何规范化、刷新并持久化。

2026-07-23 17:47:24 261

原创 原生鸿蒙像素画板实战 20:拼豆模板生成

拼豆模板不应只是一张参考图。本文结合 bitArt,拆解字符矩阵如何映射为像素、图层、画布尺寸与调色板,并说明预览采样、透明语义和可编辑项目的验证方法。

2026-07-23 17:15:38 218

原创 原生鸿蒙像素画板实战 19:远程素材缓存

本文拆解远程素材加载、JSON 结构校验、内存缓存和本地兜底流程,说明如何让 bitArt 在网络异常、接口空数据或缓存过期时仍保持素材库可用。

2026-07-22 16:25:00 313

原创 原生鸿蒙像素画板实战 18:素材库预览

本文以 MaterialLibraryService 为核心,拆解本地像素素材的元数据、缩略预览、完整模板与导入流程,说明如何让预览和可编辑图层共享同一份像素数据。

2026-07-22 16:21:44 150

原创 原生鸿蒙像素画板实战 17:项目合并

本文拆解 bitArt 项目合并流程:统一画布尺寸、复制并重命名图层、创建新项目身份,同时保留原项目不被覆盖,并给出 ArkTS 实现与验证清单。

2026-07-22 16:17:09 206

原创 原生鸿蒙像素画板实战 16:多项目管理

用户真正需要的是:新建一个项目不会覆盖旧画布,切换项目前会把当前修改收束,重命名不会让列表和当前标题不一致,删除当前项目后还能自然回到一个可用状态。普通模式下如果点击当前项目则关闭面板,点击其他项目才依次停止动画、结束笔触、保存当前项目、读取目标项目、应用持久化状态、重新安排自动保存并刷新摘要。删除动作完成后,如果删掉的是当前项目,工作流要从刷新后的摘要中打开第一个剩余项目,若一个也没有则创建默认项目。项目可以并列存在之后,下一篇继续处理更难的情况:怎样把多个项目合成一个新项目,而不覆盖原稿。

2026-07-22 15:50:37 237

原创 原生鸿蒙像素画板实战 15:自定义调色板

如果这些入口各自保存一份颜色文本,最终常见的结果是色轮显示一种色、RGB 输入框是另一种色,确认后又把错误颜色写回调色板。先以当前画笔颜色打开弹窗并确认,再以画布背景和图层背景分别打开,观察同一个确认按钮是否把颜色写到正确字段。输入还不完整时保留用户正在编辑的文本,但不把它写入实际项目颜色。色轮触点与颜色之间也需要双向同步,但它们只是 UI 的表示层,真正可保存的仍是规范化后的颜色字符串。当前版本管理的是离散颜色值,取色器可以读取可见图层的合成色,但不提供 ICC 色彩管理、渐变编辑或带容差的近似色选择。

2026-07-22 15:45:02 232

原创 原生鸿蒙像素画板实战 14:工具状态管理

另一个常见问题是 UI 直接写 activeTool 后,历史面板、顶部状态条、工具栏又各自写一遍“当前工具名称”,形状或选区状态一变,就有一个区域忘了更新。工具状态可以用一张切换表来回归:先为铅笔设置尺寸和透明度,再为橡皮擦设置另一组值,为填充设置第三组透明度,然后按照“铅笔—填充—橡皮擦—形状—选区—铅笔”的顺序切换。若其中一个值被上一个工具覆盖,问题通常不在控件,而在参数归属或归一化服务。工具栏只展示当前工具真正可用的控制项,形状工具显示形状选择,选区工具显示范围信息,取色器不显示无效的画笔尺寸。

2026-07-21 00:20:02 214

原创 原生鸿蒙像素画板实战 13:矩形选区编辑

松手时再比较快照和现状,确认真的变化后才记录一条名为“移动选区”的撤销快照,并同步当前动画帧。可以先框选一个同时包含透明和不透明像素的区域,在 64×64 画布里快速向右、向左、再向下拖动,最后停在边缘。因为选区的移动不是视觉覆盖层,而是一笔真实的像素修改,所以它应与画笔、填充一样进入撤销、帧同步和自动保存路径。选区工具优先处理自己的触控状态。只有没有进入选区移动时,才把 Down、Move、Up 交给通用的矩形选区逻辑。选区的临时快照在松手后必须释放,活动帧则在真正改变时同步,防止下一次操作沿用旧会话。

2026-07-21 00:00:32 168

原创 原生鸿蒙像素画板实战 12:填充与取色

本文结合 bitArt 源码,拆解洪泛填充与取色工具,重点说明可见图层合成取色、活动图层写入、透明色处理、选区限制与历史记录。

2026-07-19 11:55:06 232

原创 原生鸿蒙像素画板实战 11:像素图形工具

本文结合 bitArt 源码,拆解直线、矩形、三角形、圆、椭圆与曲线工具的离散栅格算法,并说明预览快照、选区限制、图层写入和撤销记录如何协同。

2026-07-19 11:49:25 364

原创 原生鸿蒙像素画板实战 10:多端响应式布局

复杂编辑器的响应式设计,重点不是让每个控件在所有尺寸中同时出现,而是决定每个尺寸下哪些信息常驻、哪些按需展开、哪些必须滚动,以及画布如何拿到稳定的剩余空间。每种组合都要观察顶部栏是否避开挖孔、底部按钮是否高于手势区、画布是否保持完整比例、侧栏能否滚到底、弹窗是否越界、长项目名是否截断,以及旋转后缩放和平移是否仍在合理范围。bitArt 在横屏使用窄侧栏:图层和调色板内容可滚动,帧卡片放入两列网格,新增、删除、播放和展开操作固定在面板底部。设置、项目管理和素材库以浮层出现,关闭后立即把空间还给画布。

2026-07-17 02:57:46 807

原创 原生鸿蒙像素画板实战 09:图片导入导出

系统返回临时授权失败时,界面只提示重试,不应伪报成功。像素画编辑器里的图片导入导出,看起来像两组文件选择按钮,实际跨过了相册选择器、文件 URI、图片解码、像素格式、缩放、图层合成、临时文件、图库资产和动画编码。只要忽略其中一个环节,就会出现很典型的问题:导入后比例变形、透明背景变黑、JPG 显示脏色、GIF 只有第一帧,或者界面提示保存成功但图库里找不到文件。把 URI 当 URI 处理、把透明与无透明格式分开、导出前同步最后一笔、图库与文件出口分别设计,能避开大多数“代码返回成功但作品不对”的问题。

2026-07-17 02:38:00 433

原创 原生鸿蒙像素画板实战 08:项目持久化

持久化的目标不是把所有字段一股脑写成 JSON,而是建立明确的数据所有权和保存时机:运行时状态由页面维护,项目快照由会话服务组装,文件与清单由存储服务负责,生命周期只发出保存信号。bitArt 的持久化项目包含画布尺寸、图层元信息、每层像素、活动图层、动画帧、活动帧、颜色和工具设置、调色板、撤销重做栈、时间轴与面板状态等。重新进入后,逐项确认项目列表、活动项目、像素、图层顺序、帧、历史和设置。导入项目时读取 JSON、解析、校验,并分配新的项目 ID,避免覆盖本机已有项目。不是直接拿页面里的旧帧数组。

2026-07-16 16:32:21 194

原创 原生鸿蒙像素画板实战 07:逐帧动画

静态编辑器只有一份图层状态,动画编辑器却要同时维护多份彼此隔离的画面,还要处理切帧前的同步、逐帧时长、缩略图、播放定时器、洋葱皮和导出。bitArt 先取得同步后的帧数组,再按活动帧索引读取相邻帧,最后合成为只读像素数组交给画布叠加层。当前帧直接读取工作区像素,非活动帧读取帧内副本,这一点很关键:用户正在画当前帧时,缩略图不必等下一次显式同步才能反映变化。切帧的顺序也很重要。下一步自然会落到持久化:帧、图层、时长、面板状态和历史记录都已经变多,应用退到后台或重新打开时,必须能恢复到离开前的编辑现场。

2026-07-16 16:15:03 375

原创 原生鸿蒙像素画板实战 06:撤销重做设计

没有保存所有项目设置,这是一个比较合理的粒度:撤销绘制时,不应该连导出格式、自动保存间隔、面板开合状态一起回退。用户正在拖动时,如果突然撤销,必须先把当前笔触状态收束,否则上一点、当前点、临时形状预览都可能影响恢复结果。对移动端创作工具来说,先用快照把行为做稳,再按性能瓶颈局部优化,是更稳妥的路线。撤销之后,如果用户又画了一笔,未来历史就不再成立,redo 栈应该清空。像素数组是引用类型,如果直接把当前数组推进栈里,后续绘制会修改同一份数据,历史记录就失效了。虽然这是 UI 细节,但对复杂编辑器很有帮助。

2026-07-15 18:11:57 319

原创 原生鸿蒙像素画板实战 05:多图层系统

合并图层前后截图对比,视觉结果应一致,同时目标层透明度应回到 1。下一篇会继续处理图层状态的历史记录,说明撤销与重做为什么采用快照,以及快照边界应该保存到哪里。没有图层时,所有像素都在同一张画布上,画错了只能撤销或擦掉。对程序来说,这意味着所有画笔操作都要从“改一张像素矩阵”变成“改当前图层,再合成最终画面”。否则只优化 Canvas 绘制,没有优化图层合成,性能收益会打折。返回新数组后,页面层可以统一替换状态并刷新,而不是在原数组上做难以追踪的原地修改。图层锁定不是 UI 装饰,而是要在服务层生效。

2026-07-15 17:52:23 196

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除