A1: meow_audiod 独占音频服务(agent-244 骨架 + agent-246 真机收尾)

- meow_audiod:启动门控(/tmp/meow_boot_mode 非 meow exit 0)、IO/播放/路由三线程、
  ring ~200ms、ALSA UAPI 独占直开、切率 mute-重配-恢复、抢占(后开赢+PREEMPTED)、
  socket EOF 回收、xrun PREPARE 恢复;meow_route 轮询逻辑并入路由线程
- meow_audio CLI:status/tone/route/vol;services.d/audiod.conf(trigger=manual,on-fail)
- SDK meow_ui_audio.c 编进 meow_ui.a:懒连接/读线程分发 PREEMPTED 回调/EPIPE 标死/
  无 audiod 返回 MEOW_ERR_NOENT 不隐式直开(MEOW_AUDIO_DIRECT=1 仅调试)
- launcher:确认 MeowOS 模式后 meow_svcd start audiod(double-fork best-effort 不阻塞)
- meow_route 退役:S89 预置换 audiod.conf + 清理旧 meow_route.conf(防拉起已删二进制
  重启循环);fw_content.conf 删 meow_route、加 meow_audiod+meow_audio(md5 打包时填)
- 真机定位并修复 ALSA UAPI 两大坑(即 ncm 播放无声根因):
  ① hw_params 须全放行初始化(mask 全 1/interval [0,UINT_MAX]),memset 0 interval
     等价只能取 0 → refine 必空 → HW_PARAMS 恒 EINVAL
  ② access/format mask 先清零再单点(pmask 只 OR),全 1 被 choose 成 MMAP_INTERLEAVED
     → write() 恒 EINVAL
- 附带修复:dev_write fd<0 防日志风暴丢 PCM 限频日志;SDK state 解析 app_id 截空白;
  meow_ui.h 文档负错误码表述修正
- 验证:宿主 FILE sink 全 IPC 链+抢占+tone WAV 20/20,SDK 客户端 13/13;
  qemu-mipsel 同过;真机 tone 44.1k/96k 切率 written=played、underrun=0、日志完整
- meow_ui.a 53a3edd2 → ncm 重链 d2031829(已热更到卡);launcher a2f932a1
This commit is contained in:
MeowOS committed 2026-08-31 22:40:08 +08:00
1 parent 94874107b6
commit ade0a57353
24 files changed
+2795 -11

No files matched your search

+25
View File
@@ -1684,6 +1684,30 @@ static void usage(void)
* M2.89 回归修复用,见 main() 内「开机选单期不抢屏」。 */
#define MEOW_BOOT_MODE_PATH "/tmp/meow_boot_mode"
/* 拉起独占音频服务(AUDIOD_DESIGN.md §1):launcher 确认 MeowOS 模式后 `meow_svcd start audiod`。
* 幂等(svcd cmd_start 在 pid>0 时 no-op)、best-effort(audiod 未装/失败静默)、
* 不阻塞主循环(double-fork + 仅 waitpid 立即退出的中间子进程,避免僵尸 + 不占用 fb)。
* 双重门控:audiod 自身读 /tmp/meow_boot_mode,非 meow 即 exit(0)——HibyOS 下物理不存在。 */
static void meow_audiod_kick(void)
{
if (access("/usr/bin/meow_audiod", X_OK) != 0) return; /* 固件未装 audiod → 静默 */
pid_t pid = fork();
if (pid < 0) return;
if (pid == 0) {
pid_t pid2 = fork(); /* double-fork:隔离执行者,防僵尸 */
if (pid2 != 0) _exit(0); /* 中间子进程立即退出,由父进程 waitpid 回收 */
{
/* 执行者:重定向 stdio 到 /dev/null,exec meow_svcd start audiod */
int devnull = open("/dev/null", O_RDWR);
if (devnull >= 0) { dup2(devnull, 1); dup2(devnull, 2); if (devnull > 2) close(devnull); }
execl("/usr/bin/meow_svcd", "meow_svcd", "start", "audiod", (char *)0);
_exit(127);
}
}
waitpid(pid, NULL, 0); /* 等中间子进程退出(即刻返回,不实质阻塞) */
logmsg("audiod: meow_svcd start audiod requested");
}
int main(int argc, char **argv)
{
long sim_hotkey = 0, sim_tap = 0, sim_exit = 0, dumpkeys = 0;
@@ -1931,6 +1955,7 @@ int main(int argc, char **argv)
/* M2.2 拔营:启动即尝试挂 TF 卡 + 联网(非阻塞);失败由 run_menu 后台周期重试。 */
ensure_card_mounted();
ensure_wifi();
meow_audiod_kick(); /* 确认 MeowOS 模式 → 拉起独占音频服务(幂等、best-effort、不阻塞主循环) */
struct app apps[MAX_APPS];
int n = scan_apps(apps);
int state = (n < 0) ? (n == -1 ? 1 : 2) : (n == 0 ? 2 : 0);